CSS/SASS Style Guide

Guia completo de estilos, arquitetura e boas práticas para desenvolvimento CSS/Sass no projeto.

Versão: 2.0
Última atualização: 04/2026
Metodologia: ITCSS + BEM + Utility-First


📋 Índice

  1. Princípios do CSS no Projeto
  2. Arquitetura e Estrutura
  3. Design Tokens
  4. Mixins e Utilitários
  5. Breakpoints e Responsividade
  6. Grid System e Utilities
  7. Componentes (BEM)
  8. Tipografia
  9. Animações e Transições
  10. Performance
  11. Acessibilidade
  12. Checklist para Pull Requests

Princípios do CSS no Projeto

Nossos princípios orientam todas as decisões de estilização:

Princípio Descrição
Mobile-First Estilos base para mobile, progressão via media queries
DRY Não se repita — use mixins, variáveis e utilities
Semântica Nomes de classes descrevem função, não aparência
Composição Components pequenos e reutilizáveis > CSS monolítico
Acessibilidade CSS inclusivo por padrão (focus, reduced-motion, etc.)
Performance Animações GPU-accelerated, mínimo de repaints

Camadas ITCSS

O projeto segue ITCSS (Inverted Triangle CSS), organizando estilos do genérico ao específico:

┌─────────────────────────────────────┐
│ 1. Abstracts (Configurações)        │ → Variáveis, mixins, breakpoints
│    └─ Não gera CSS direto           │
├─────────────────────────────────────┤
│ 2. Core (Fundação)                  │ → Reset, tipografia, grid, utilities
│    └─ Estilos globais de baixo nível│
├─────────────────────────────────────┤
│ 3. Components (Interface)           │ → Componentes específicos (BEM)
│    └─ Estilos scoped por componente │
└─────────────────────────────────────┘

Arquitetura e Estrutura

Estrutura de Diretórios

src/styles/
├── global.sass              # Arquivo principal de entrada
├── abstract/                # Configurações e ferramentas (não gera CSS)
│   ├── index.sass           # Barrel file (@forward)
│   ├── _tokens.sass         # Design tokens (cores, spacing, etc.)
│   ├── _mixins.sass         # Mixins e funções utilitárias
│   └── _breakpoints.sass    # Definição de breakpoints e mixins
├── core/                    # Estilos base e fundação
│   ├── _reset.sass          # Normalize/reset de browser
│   ├── _general.sass        # Estilos globais do body/html
│   ├── _typography.sass     # Sistema tipográfico completo
│   └── _grid.sass           # Grid system e utility classes
└── components/              # Componentes de interface (BEM)
    ├── index.sass           # Barrel file de componentes
    ├── _buttons.sass        # Botões e variações
    ├── _content.sass        # Conteúdo de artigos
    └── _post-content.sass   # Conteúdo específico de posts

Arquivo Principal (global.sass)

// global.sass
// 1. Configurações (Não gera CSS — apenas disponibiliza variáveis/mixins)
@use 'abstract' as *

// 2. Fundação (Camadas baixas do ITCSS)
@use 'core/reset'
@use 'core/general'
@use 'core/typography'
@use 'core/grid'

// 3. Interface (Componentes específicos)
@use 'components'

Convenções de Nomenclatura de Arquivos

Tipo Prefixo Exemplo Propósito
Partial _ _tokens.sass Arquivo importado, não compilado isoladamente
Barrel index index.sass Agrega e exporta múltiplos partials com @forward
Componente _ _buttons.sass Stylescope de um componente específico

Design Tokens

Design tokens são as unidades atômicas do sistema de design. Definidos em abstract/_tokens.sass.

Cores

Paleta Neutra (Cores Puras)

// abstract/_tokens.sass
$neutral-900: hsl(180, 4%, 4.9%)    // Preto base
$neutral-800: hsl(216, 4.3%, 22.9%) // Grafite
$neutral-500: hsl(218.2, 4.3%, 50%) // Cinza médio
$neutral-300: hsl(214.3, 4.3%, 68%) // Cinza claro
$neutral-100: hsl(220, 4.2%, 86.1%) // Quase branco
$neutral-000: hsl(0, 0%, 100%)      // Branco puro

Tokens Semânticos (Use estes!)

// abstract/_tokens.sass

// Text colors
$text-primary: $neutral-300     // pale-slate - Texto principal
$text-secondary: $neutral-100   // alabaster-grey - Texto de destaque/títulos
$text-inverse: $neutral-900     // black - Texto em fundo claro
$text-muted: $neutral-500       // dim-grey - Texto secundário/desativado
$text-white: $neutral-000       // white - Texto branco explícito

// Background colors
$bg-primary: $neutral-900       // black - Fundo principal da página
$bg-secondary: $neutral-800     // graphite - Fundo de cards/seções
$bg-tertiary: $neutral-500      // dim-grey - Fundo terciário
$bg-light: $neutral-100         // alabaster-grey - Fundo claro
$bg-white: $neutral-000         // white - Fundo branco

// UI Elements
$ui-border: $neutral-500        // dim-grey - Bordas
$ui-divider: $neutral-300       // pale-slate - Linhas divisórias
$ui-surface: $neutral-000       // white - Superfícies/cards
$ui-card-bg: $neutral-800       // graphite - Background de cards

// Status colors
$status-success: hsl(127.4, 55.3%, 42.9%)
$status-warning: hsl(46, 90.7%, 53.5%)
$status-error: hsl(351.9, 100%, 69.4%)
$status-info: hsl(186, 67.1%, 46.5%)
$status-success-light: hsl(71.5, 88.7%, 89.6%)
$status-warning-light: hsl(52, 95.7%, 90.8%)
$status-error-light: hsl(15, 100%, 93.7%)
$status-info-light: hsl(101.7, 93.7%, 87.6%)

Como Usar Cores

@use '../abstract' as *

// ✅ CORRETO: Use a função color() com tokens semânticos
.card
  background-color: color('bg-secondary')
  color: color('text-primary')
  border: 1px solid color('ui-border')

// ❌ ERRADO: Evite usar variáveis diretas de cor
.card
  background-color: $neutral-800  // Não faz isso
  color: $neutral-300             // Perde semântica

Status Colors

$status-success: hsl(145, 63%, 42%)  // Verde
$status-warning: hsl(38, 92%, 50%)   // Amarelo/Laranja
$status-error: hsl(0, 84%, 60%)      // Vermelho
$status-info: hsl(200, 100%, 50%)    // Azul

Spacing (Base 8px)

Sistema de espaçamento baseado em rem, com escala consistente.

// abstract/_tokens.sass
$spacing: (
  'none': 0,
  'xs': 0.5rem,    // 8px
  'sm': 1rem,      // 16px
  'md': 1.5rem,    // 24px
  'lg': 2.5rem,    // 40px
  'xl': 3rem,      // 48px
  '2xl': 4rem,     // 64px
  '3xl': 6rem,     // 96px
)

// Variáveis individuais para acesso direto
$spacing-none: map.get($spacing, 'none')
$spacing-xs: map.get($spacing, 'xs')
$spacing-sm: map.get($spacing, 'sm')
$spacing-md: map.get($spacing, 'md')
$spacing-lg: map.get($spacing, 'lg')
$spacing-xl: map.get($spacing, 'xl')
$spacing-2xl: map.get($spacing, '2xl')
$spacing-3xl: map.get($spacing, '3xl')

Como usar:

@use '../abstract' as *

.card
  padding: spacing('md')
  margin-bottom: spacing('lg')

  @include up('md')
    padding: spacing('lg')

Border Radius

$radii: (
  'none': 0,
  'sm': 0.25rem,   // 4px
  'md': 0.375rem,  // 6px
  'lg': 0.5rem,    // 8px
  'xl': 0.75rem,   // 12px
  '2xl': 1rem,     // 16px
  'full': 9999px,  // Circular
)

Como usar:

@use '../abstract' as *

.button
  border-radius: radius('md')

.avatar
  border-radius: radius('full')

.card--rounded
  border-radius: radius('xl')

Shadows (Sistema de Elevação)

// abstract/_tokens.sass
$shadows: (
  'sm': (0 1px 2px 0 hsla(180, 11%, 2%, 0.05)),
  'md': (0 4px 6px -1px hsla(180, 11%, 2%, 0.1), 0 2px 4px -1px hsla(180, 11%, 2%, 0.06)),
  'lg': (0 10px 15px -3px hsla(180, 11%, 2%, 0.1), 0 4px 6px -2px hsla(180, 11%, 2%, 0.05)),
  'xl': (0 20px 25px -5px hsla(180, 11%, 2%, 0.1), 0 10px 10px -5px hsla(180, 11%, 2%, 0.04)),
)

// Variáveis individuais
$shadow-sm: map.get($shadows, 'sm')
$shadow-md: map.get($shadows, 'md')
$shadow-lg: map.get($shadows, 'lg')
$shadow-xl: map.get($shadows, 'xl')

Como usar:

@use '../abstract' as *

.card
  @include shadow('lg')

  &:hover
    @include shadow('xl')

Text Shadows (Elevação Tipográfica)

// abstract/_tokens.sass
$text-shadows: (
  'sm': 0 1px 2px hsla(180, 11%, 2%, 0.2),
  'md': 0 2px 4px hsla(180, 11%, 2%, 0.3),
  'lg': 0 4px 8px hsla(180, 11%, 2%, 0.4),
  'xl': 0 6px 12px hsla(180, 11%, 2%, 0.5),
  'glow': 0 0 10px hsla(0, 0%, 100%, 0.25),
  'inverse': 0 1px 3px rgba(255, 255, 255, 0.35)
)

// Uso com mixin
.glowing-text
  @include text-shadow('glow')

Z-Index Scale

$z-index: (
  'negative': -1,
  'base': 0,
  'elevation-1': 10,
  'elevation-2': 20,
  'elevation-3': 30,
  'dropdown': 1000,
  'sticky': 1020,
  'fixed': 1030,
  'modal-backdrop': 1040,
  'modal': 1050,
  'popover': 1060,
  'tooltip': 1070,
)

Como usar:

@use '../abstract' as *

.modal
  z-index: z('modal')

.dropdown
  z-index: z('dropdown')

Gradientes

// abstract/_tokens.sass
$gradient-nav: linear-gradient(to right, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.65) 90%, rgba(0,0,0,0) 100%)
$gradient-hero: linear-gradient(to top, $bg-primary 0%, transparent 70%)
$gradient-card: linear-gradient(to top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.8) 100%)
$gradient-dark-diagonal: linear-gradient(135deg, $bg-primary, $bg-secondary, $bg-tertiary)

// Mixin para gradiente do hero
@mixin gradient-hero($direction: to top, $start-color: $bg-primary, $transparent-at: 70%)
  background: linear-gradient($direction, $start-color 0%, transparent $transparent-at)

Tipografia

// abstract/_tokens.sass

// Fontes
$font-primary: 'Azeret Mono', monospace
$font-heading: 'Belgant', sans-serif
$font-primary-fallback: 'Courier New', Courier, monospace
$font-heading-fallback: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif

// Pesos disponíveis
$font-weights: (
  'light': 300,
  'regular': 400,
  'medium': 500,
  'semibold': 600,
  'bold': 700,
  'extrabold': 800,
  'black': 900,
)

// Variáveis individuais
$font-light: map.get($font-weights, 'light')
$font-regular: map.get($font-weights, 'regular')
$font-medium: map.get($font-weights, 'medium')
$font-semibold: map.get($font-weights, 'semibold')
$font-bold: map.get($font-weights, 'bold')
$font-extrabold: map.get($font-weights, 'extrabold')
$font-black: map.get($font-weights, 'black')

Transições

$transition-durations: (
  'fast': 150ms,
  'base': 300ms,
  'slow': 500ms,
  'ultra-slow': 700ms,
)

$easings: (
  'linear': linear,
  'ease': ease,
  'ease-in': ease-in,
  'ease-out': ease-out,
  'ease-in-out': ease-in-out,
  'smooth': cubic-bezier(0.4, 0, 0.2, 1),
  'gentle': cubic-bezier(0.25, 0.1, 0.25, 1),
  'snappy': cubic-bezier(0.2, 0, 0, 1),
  'slide-up': cubic-bezier(0.16, 1, 0.3, 1),
)

Mixins e Utilitários

Layout Mixins

@use '../abstract' as *

// Flexbox layouts
@include flex-between      // justify-content: space-between; align-items: center;
@include flex-center       // justify-content: center; align-items: center;
@include flex-column       // flex-direction: column;
@include flex-row          // flex-direction: row;
@include grid-layout       // display: grid;

Exemplo:

.nav
  @include flex-between

.hero
  @include flex-column
  @include flex-center

Acessibilidade

@use '../abstract' as *

// Esconder visualmente mas manter acessível para screen readers
.sr-only
  @include visually-hidden

// Focus visible customizado
.button
  @include focus-visible($offset: 2px, $color: color('text-primary'))

Tipografia

@use '../abstract' as *

// Fonte responsiva fluida (usa clamp())
.heading
  @include responsive-font($min-size: 1.5rem, $max-size: 3rem)

// Truncar texto com ellipsis
.card__title
  @include text-truncate

// Text balance para títulos (evita viúvas)
h1, h2, h3
  @include text-balance

// Text shadow
.glowing-text
  @include text-shadow($level: glow)  // sm, md, lg, xl, glow, inverse

Interação e Animação

@use '../abstract' as *

// Respeitar preferência por movimento reduzido
.animated-element
  @include prefers-reduced-motion
    transition: none
    animation: none

// Fade in
.fade-in
  @include fade-in($duration: base, $easing: ease-out)

  &.is-visible
    opacity: 1

// Slide up
.slide-up
  @include slide-up($distance: 2rem, $duration: base, $easing: slide-up)

  &.is-visible
    opacity: 1
    transform: translateY(0)

// Scale in
.scale-in
  @include scale-in($scale: 0.95, $duration: base)

// Hover lift (efeito de elevação no hover)
.card
  @include hover-lift($distance: 4px, $duration: fast)

// Transição suave de cor
.button
  @include transition-color($duration: fast)

Efeitos Visuais

@use '../abstract' as *

.card
  @include shadow('lg')
  @include radius('md')
  @include gradient('hero')

Mídia e Assets

@use '../abstract' as *

// Imagem cover (object-fit)
.hero__image
  @include cover-image

// Aspect ratio
.video-container
  @include aspect-ratio(16, 9)

Funções Helper

@use '../abstract' as *

.element
  margin: spacing('md')      // Retorna valor do mapa de spacing
  border-radius: radius('lg') // Retorna valor do mapa de radii
  box-shadow: shadow('xl')    // Retorna valor do mapa de shadows
  z-index: z('modal')         // Retorna valor do mapa de z-index
  color: color('text-primary') // Retorna valor do mapa de colors

Breakpoints e Responsividade

Mapa de Breakpoints (Mobile-First)

$breakpoints: (
  'xs': 0,       // Mobile Portrait (BASE)
  'sm': 576px,   // Smartphones Landscape / Phablets
  'md': 768px,   // Tablets Portrait (iPad)
  'lg': 992px,   // Tablets Landscape / Laptops pequenos
  'xl': 1200px,  // Desktops Padrão (Full HD)
  'xxl': 1440px, // Monitores Grandes / Hi-Res
)

Mixins de Media Query

@use '../abstract' as *

// ✅ RECOMENDADO: Mínimo (Mobile First)
.component
  // Mobile styles (base)
  padding: spacing('sm')

  @include up('md')
    // Tablet styles
    padding: spacing('md')

  @include up('lg')
    // Desktop styles
    padding: spacing('lg')

// Máximo (Legado / Casos específicos)
.legacy-component
  @include down('sm')
    // Apenas para telas menores que sm

// Entre dois breakpoints
.responsive-element
  @include between('md', 'lg')
    // Estilos aplicados apenas entre md e lg

Aliases de Conveniência

@use '../abstract' as *

.component
  @include mobile    // Equivalente a @include down('md')
    // Estilos apenas para mobile

  @include tablet    // Equivalente a @include between('md', 'lg')
    // Estilos apenas para tablet

  @include desktop   // Equivalente a @include up('lg')
    // Estilos para desktop e acima

Boas Práticas de Responsividade

@use '../abstract' as *

// ✅ CORRETO: Progressão mobile-first
.card
  // Base (mobile)
  padding: spacing('sm')
  font-size: var(--font-size-sm)

  @include up('md')
    padding: spacing('md')
    font-size: var(--font-size-base)

  @include up('lg')
    padding: spacing('lg')
    font-size: var(--font-size-md)

// ❌ ERRADO: Desktop-first com override para mobile
.card
  @include down('sm')
    padding: spacing('sm')  // Override desnecessário

  // Desktop styles na base
  padding: spacing('lg')

Grid System e Utilities

Container

.container
  width: 100%
  max-width: 1400px
  margin-inline: auto
  padding-inline: spacing('lg')

// Container fluido (100% width)
.container--fluid

Grid

// Grid base
.grid
  display: grid
  gap: spacing('md')

// Grid auto-fit responsivo automático
.grid-auto-fit
  display: grid
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))
  gap: spacing('md')

Exemplo HTML:

<div class="grid-auto-fit">
  <!-- Colunas criadas automaticamente com minmax(250px, 1fr) -->
</div>

Colunas (1-12)

.cols-1 through .cols-12     // Define número de colunas do grid
.span-1 through .span-12     // Span de colunas
.row-span-1 through .row-span-12

Exemplo HTML:

<div class="grid md:cols-12">
  <div class="md:span-8">Ocupa 8 colunas</div>
  <div class="md:span-4">Ocupa 4 colunas</div>
</div>

Gap Utilities

.gap-none, .gap-sm, .gap-md, .gap-lg, .gap-xl, .gap-2xl

Display Utilities

.flex, .inline-flex
.block, .inline-block
.grid-display
.hidden

Flex Utilities

// Direction
.flex-row, .flex-col

// Wrap
.flex-wrap, .flex-nowrap

// Align Items
.items-start, .items-center, .items-end, .items-stretch, .items-baseline

// Justify Content
.justify-start, .justify-center, .justify-end, .justify-between, .justify-around, .justify-evenly

// Align Self
.self-start, .self-center, .self-end, .self-stretch, .self-baseline

// Grow/Shrink
.flex-1, .flex-auto, .flex-none

Spacing Utilities (Logical Properties)

// Margins
.m-xs, .m-sm, .m-md, .m-lg, .m-xl, .m-2xl, .m-3xl
.mt-{size}, .mb-{size}, .ms-{size}, .me-{size}
.mx-{size}, .my-{size}

// Paddings
.p-xs, .p-sm, .p-md, .p-lg, .p-xl, .p-2xl, .p-3xl
.pt-{size}, .pb-{size}, .ps-{size}, .pe-{size}
.px-{size}, .py-{size}

// Auto margins
.mx-auto, .my-auto, .mt-auto, .mb-auto, .ms-auto, .me-auto, .m-auto

Responsive Utilities

Sintaxe: {breakpoint}\:{classe}

md:flex, lg:cols-4, xl:gap-lg

Exemplo HTML:

<div class="grid cols-1 md:cols-2 lg:cols-4 gap-md">
  <div class="span-6 lg:span-4">Conteúdo</div>
</div>

Componentes BEM

Nomenclatura BEM

Block__Element--Modifier
  • Block: Componente principal (.nav)
  • Element: Parte do bloco (.nav__link)
  • Modifier: Variação do bloco/elemento (.btn--primary)

Exemplo: Botões

// Base
.btn
  display: inline-block
  padding: spacing('sm') spacing('lg')
  border-radius: radius('md')
  @include transition-color(fast)
  @include hover-lift(2px, fast)

// Modifiers
.btn--primary
  background: color('bg-primary')
  color: color('text-inverse')

.btn--secondary
  background: color('bg-tertiary')
  color: color('text-inverse')

.btn--uppercase
  text-transform: uppercase

Uso:

<button class="btn btn--primary">Primário</button>
<button class="btn btn--secondary btn--uppercase">Secundário</button>

Exemplo: Navegação

.nav
  // Base styles

  &__menu
    // Menu container

  &__logo
    // Logo area

  &__links
    // Lista de links

  &__link
    // Link individual
    &--with-children
      // Link com submenu
    &.is-active
      // Link ativo

  &__sublinks
    // Submenu
    &.is-expanded
      // Submenu expandido

  &__social
    // Redes sociais

Exemplo: Post Card

.post-card
  display: flex
  flex-direction: column
  background-image: $gradient-card, var(--card-bg-image)
  border-radius: radius('md')
  box-shadow: shadow('xl')

  &:hover
    transform: scale(1.02)

  &__content
    display: contents

  &__title
    font-family: $font-heading
    font-size: var(--font-size-h5)

  &__summary
    font-size: var(--font-size-xs)

Tipografia

CSS Custom Properties (Fluid Typography)

:root {
  --font-size-base: clamp(0.875rem, 2vw, 1.125rem);
  --font-size-h1: clamp(2rem, 6vw, 3.75rem);
  --font-size-h2: clamp(1.5rem, 5vw, 2.5rem);
  --line-height-tight: 1.2;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;
}

Headings

h1, h2, h3, h4, h5, h6
  font-family: $font-heading, $font-heading-fallback
  font-weight: $font-bold
  line-height: var(--line-height-tight)
  color: color('text-secondary')
  @include text-balance

Utilities Tipográficas

// Font sizes
.text-xs, .text-sm, .text-base, .text-lg, .text-xl
.text-2xl, .text-3xl, .text-4xl, .text-5xl, .text-6xl

// Font weights
.font-light, .font-regular, .font-medium
.font-semibold, .font-bold, .font-extrabold

// Text alignment
.text-left, .text-center, .text-right, .text-justify

// Text transform
.uppercase, .lowercase, .capitalize, .normal-case

// Line height
.leading-tight, .leading-normal, .leading-relaxed, .leading-loose

// Letter spacing
.tracking-tight, .tracking-normal, .tracking-wide, .tracking-wider

// Semantic colors
.text-primary, .text-secondary, .text-white, .text-dark

// Utilities
.truncate, .break-words, .break-all

Boas Práticas

1. Use @use em vez de @import

// ✅ Correto
@use '../abstract' as *
@use 'sass:map'
@use 'sass:color'

// ❌ Evitar
@import '../abstract/tokens'

2. Prefira Variáveis Semânticas

// ✅ Correto
background-color: color('bg-primary')
color: color('text-primary')

// ❌ Evitar
background-color: $color-black
color: $color-pale-slate

3. Mobile-First Sempre

// ✅ Correto
.component
  // Mobile styles (base)
  padding: spacing('sm')

  @include up('md')
    // Tablet styles
    padding: spacing('md')

// ❌ Evitar
.component
  @include down('sm')
    // Mobile override

4. Use Utilities para Layout

<!-- ✅ Preferível -->
<div class="flex items-center justify-between gap-md p-lg">
  <!-- ❌ Evitar criar classes novas para layouts simples -->
  <div class="my-custom-flex-container"></div>
</div>

5. Nomenclatura BEM Consistente

// ✅ Correto
.card
  &__header
    &--featured

// ❌ Evitar
.card-header-featured
.cardHeaderFeatured

6. Acessibilidade

  • Use @include visually-hidden para conteúdo apenas para screen readers
  • Sempre inclua estados :focus-visible
  • Respeite prefers-reduced-motion
.button
  &:focus-visible
    outline: 2px solid color('text-primary')
    outline-offset: 2px

  @include prefers-reduced-motion
    transition: none

7. Performance

  • Use transform e opacity para animações (GPU-accelerated)
  • Evite animações de propriedades como width, height, top, left
  • Use will-change com moderação
// ✅ Performático
.card
  transition: transform $transition-base, opacity $transition-base

// ❌ Evitar
.card
  transition: width $transition-base, height $transition-base

Grid System e Utilities

O sistema de grid e utilities está definido em core/_grid.sass.

Container

// Container centralizado com largura máxima
.container
  width: 100%
  max-width: 1400px
  margin-inline: auto
  padding-inline: spacing('lg')

// Container fluido (100% width)
.container--fluid
  max-width: 100%

Grid Base

// Grid container base
.grid
  display: grid
  gap: spacing('md')

// Grid auto-fit responsivo automático
.grid-auto-fit
  display: grid
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))
  gap: spacing('md')

Colunas (1-12)

// Classes de colunas do grid
.cols-1 through .cols-12     // Define número de colunas do grid
.span-1 through .span-12     // Span de colunas
.row-span-1 through .row-span-12

Exemplo:

<div class="grid cols-1 md:cols-2 lg:cols-4 gap-md">
  <div class="span-6 lg:span-4">Conteúdo</div>
</div>

Gap Utilities

.gap-none, .gap-sm, .gap-md, .gap-lg, .gap-xl, .gap-2xl

Display Utilities

.flex, .inline-flex
.block, .inline-block
.grid-display
.hidden

Flex Utilities

// Direction
.flex-row, .flex-col

// Wrap
.flex-wrap, .flex-nowrap

// Align Items
.items-start, .items-center, .items-end, .items-stretch, .items-baseline

// Justify Content
.justify-start, .justify-center, .justify-end, .justify-between, .justify-around, .justify-evenly

// Align Self
.self-start, .self-center, .self-end, .self-stretch, .self-baseline

// Grow/Shrink
.flex-1, .flex-auto, .flex-none

Spacing Utilities (Logical Properties)

Usando propriedades lógicas para melhor suporte a internacionalização:

// Margins
.m-xs, .m-sm, .m-md, .m-lg, .m-xl, .m-2xl, .m-3xl
.mt-{size}, .mb-{size}, .ms-{size}, .me-{size}
.mx-{size}, .my-{size}

// Paddings
.p-xs, .p-sm, .p-md, .p-lg, .p-xl, .p-2xl, .p-3xl
.pt-{size}, .pb-{size}, .ps-{size}, .pe-{size}
.px-{size}, .py-{size}

// Auto margins
.mx-auto, .my-auto, .mt-auto, .mb-auto, .ms-auto, .me-auto, .m-auto

Responsive Utilities

Sintaxe: {breakpoint}\:{classe}

md:flex, lg:cols-4, xl:gap-lg

Exemplo HTML:

<div class="grid cols-1 md:cols-2 lg:cols-4 gap-md">
  <div class="span-6 lg:span-4">Conteúdo</div>
</div>

Componentes (BEM)

Nomenclatura BEM

Block__Element--Modifier
Parte Descrição Exemplo
Block Componente principal independente .nav, .card, .btn
Element Parte interna do bloco .nav__link, .card__title
Modifier Variação/estado do bloco ou elemento .btn--primary, .nav__link.is-active

Exemplo: Botões

@use '../abstract' as *

// Block base
.btn
  display: inline-block
  padding: spacing('sm') spacing('lg')
  border-radius: radius('md')
  @include transition-color(fast)
  @include hover-lift(2px, fast)

// Modifiers de variante
.btn--primary
  background: color('bg-primary')
  color: color('text-inverse')

.btn--secondary
  background: color('bg-tertiary')
  color: color('text-inverse')

// Modifier de estilo
.btn--uppercase
  text-transform: uppercase

Uso no HTML:

<button class="btn btn--primary">Primário</button>
<button class="btn btn--secondary btn--uppercase">Secundário</button>

Exemplo: Navegação

@use '../abstract' as *

.nav
  @include flex-between

  &__menu
    // Menu container

  &__logo
    // Logo area

  &__links
    // Lista de links
    @include flex-row

  &__link
    // Link individual
    @include transition-color(fast)

    &--with-children
      // Link com submenu

    &.is-active
      // Link ativo (estado)

  &__sublinks
    // Submenu
    &.is-expanded
      // Submenu expandido (estado)

  &__social
    // Redes sociais

Exemplo: Post Card

@use '../abstract' as *

.post-card
  display: flex
  flex-direction: column
  background-image: $gradient-card, var(--card-bg-image)
  border-radius: radius('md')
  @include shadow('xl')

  &:hover
    transform: scale(1.02)

  &__content
    display: contents

  &__title
    font-family: $font-heading
    font-size: var(--font-size-h5)

  &__summary
    font-size: var(--font-size-xs)
    color: color('text-muted')

Estados vs Modifiers

// ✅ CORRETO: Modifier para variações estruturais
.btn--large
.btn--small

// ✅ CORRETO: Estado com prefixo is- para estados dinâmicos
.is-active
.is-expanded
.is-hidden
.is-loading

// ❌ ERRADO: Misturar estado com modifier
.btn--active       // Não faça isso
.btn--is-loading   // Não faça isso

Tipografia

CSS Custom Properties (Fluid Typography)

Definido em core/_typography.sass:

:root {
  /* Font sizes - Fluid clamp system */
  --font-size-base: clamp(0.875rem, 2vw, 1.125rem);
  --font-size-h1: clamp(2rem, 6vw, 3.75rem);
  --font-size-h2: clamp(1.5rem, 5vw, 2.5rem);
  --font-size-h3: clamp(1.25rem, 4vw, 2rem);
  --font-size-h4: clamp(1.125rem, 3vw, 1.75rem);
  --font-size-h5: clamp(1rem, 2.5vw, 1.5rem);
  --font-size-h6: clamp(0.875rem, 2vw, 1.25rem);

  /* Line heights */
  --line-height-tight: 1.2;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;
  --line-height-loose: 2;
}

Headings

@use '../abstract' as *

h1, h2, h3, h4, h5, h6
  font-family: $font-heading, $font-heading-fallback
  font-weight: $font-bold
  line-height: var(--line-height-tight)
  color: color('text-secondary')
  @include text-balance

Utilities Tipográficas

// Font families
.font-primary
  font-family: $font-primary, $font-primary-fallback

.font-heading
  font-family: $font-heading, $font-heading-fallback

// Font sizes
.text-xs, .text-sm, .text-base, .text-lg, .text-xl
.text-2xl, .text-3xl, .text-4xl, .text-5xl, .text-6xl

// Font weights
.font-light, .font-regular, .font-medium
.font-semibold, .font-bold, .font-extrabold

// Text alignment
.text-left, .text-center, .text-right, .text-justify

// Text transform
.uppercase, .lowercase, .capitalize, .normal-case

// Line height
.leading-tight, .leading-normal, .leading-relaxed, .leading-loose

// Letter spacing
.tracking-tight, .tracking-normal, .tracking-wide, .tracking-wider

// Semantic colors
.text-primary, .text-secondary, .text-white, .text-dark

// Utilities
.truncate, .break-words, .break-all

Animações e Transições

Quando Usar Animações

Caso Recomendação
Feedback de interação ✅ Sim (hover, focus, click)
Transições de estado ✅ Sim (expandir, colapsar)
Entrada de elementos ✅ Sim (fade-in, slide-up)
Loading states ✅ Sim (skeleton, spinner)
Decorativo puro ⚠️ Com moderação
Movimento contínuo ❌ Evite (causa náusea)

Propriedades Performáticas

Use apenas estas propriedades para animações suaves (GPU-accelerated):

// ✅ PERFORMÁTICO (compositor-only)
.card
  transition: transform 300ms ease-out, opacity 300ms ease-out

// ❌ EVITAR (causa layout/paint)
.card
  transition: width 300ms, height 300ms, top 300ms, left 300ms

Padrões de Animação

@use '../abstract' as *

// Fade in genérico
.fade-in
  opacity: 0
  @include fade-in($duration: base, $easing: ease-out)

  &.is-visible
    opacity: 1

// Slide up (entrada de baixo para cima)
.slide-up
  opacity: 0
  @include slide-up($distance: 2rem, $duration: base)

  &.is-visible
    opacity: 1
    transform: translateY(0)

// Scale in (zoom suave)
.scale-in
  opacity: 0
  @include scale-in($scale: 0.95, $duration: base)

  &.is-visible
    opacity: 1
    transform: scale(1)

// Hover lift (elevação no hover)
.card
  @include hover-lift($distance: 4px, $duration: fast)

Respeitando Preferências do Usuário

Sempre inclua suporte a prefers-reduced-motion:

@use '../abstract' as *

.animated-component
  @include slide-up(2rem, base)

  @include prefers-reduced-motion
    transition: none
    animation: none
    opacity: 1
    transform: none

Performance

Boas Práticas de Performance CSS

1. Use Transform e Opacity para Animações

// ✅ PERFORMÁTICO (GPU-accelerated)
.card
  transition: transform 300ms ease-out, opacity 300ms ease-out

  &:hover
    transform: translateY(-4px)
    opacity: 0.9

// ❌ LENTO (causa reflow/repaint)
.card
  transition: margin 300ms, width 300ms

  &:hover
    margin-top: -4px
    width: 105%

2. Evite Seletor Universal e Aninhamento Excessivo

// ❌ LENTO
* { box-sizing: border-box }
div ul li a span { color: red }

// ✅ RÁPIDO
.card__link { color: red }

3. Use will-change com Moderação

// ✅ Use apenas quando necessário
.hero-image
  will-change: transform

  // Remova após animação completar via JS

// ❌ Não use em tudo
* { will-change: transform }  // Pior que não usar

4. Contain para Isolamento de Layout

// Isole componentes complexos
.post-grid
  contain: layout style

5. Evite @import em CSS

// ✅ CORRETO (Sass modules)
@use 'abstract' as *
@use 'components/nav'

// ❌ ERRADO (CSS imports bloqueiam render)
@import url('https://fonts.googleapis.com/...');

Otimização de Assets

// Use imagens modernas com fallback
.picture
  @include aspect-ratio(16, 9)

  img
    @include cover-image
    // Prefira WebP/AVIF com fallback

Acessibilidade

Focus Visible

Sempre estilize estados de foco:

@use '../abstract' as *

.button
  @include focus-visible($offset: 2px, $color: color('text-primary'))

a
  &:focus-visible
    outline: 2px solid color('text-primary')
    outline-offset: 2px

Conteúdo Apenas para Screen Readers

@use '../abstract' as *

// Esconde visualmente mas mantém acessível
.sr-only
  @include visually-hidden

// Uso:
<button>
  <svg aria-hidden="true">...</svg>
  <span class="sr-only">Abrir menu</span>
</button>

Reduced Motion

Respeite preferências de movimento reduzido:

@use '../abstract' as *

.animated-element
  @include slide-up(2rem, base)

  @include prefers-reduced-motion
    transition: none
    animation: none
    opacity: 1
    transform: none

Contraste de Cores

Use tokens semânticos que garantem contraste adequado:

@use '../abstract' as *

// ✅ Bom contraste
.text-on-dark
  color: color('text-secondary')  // Claro sobre escuro

.text-on-light
  color: color('text-inverse')    // Escuro sobre claro
// Diferencie links de texto comum
a
  color: color('text-secondary')

  &:hover
    text-decoration: underline  // Indicador visual adicional

  &:focus-visible
    outline: 2px solid color('text-primary')
    outline-offset: 2px

// Botões devem parecer clicáveis
.btn
  cursor: pointer

  &:disabled
    cursor: not-allowed
    opacity: 0.5

Checklist para Pull Requests

Antes de submeter um PR com mudanças CSS/Sass, verifique:

Estrutura e Organização

  • O código segue a estrutura ITCSS (Abstracts → Core → Components)?
  • Arquivos partials começam com _?
  • Barrel files usam @forward corretamente?
  • O componente foi colocado na pasta correta?

Nomenclatura

  • Classes seguem BEM (Block__Element–Modifier)?
  • Modificadores usam -- (duplo hífen)?
  • Elementos usam __ (duplo underscore)?
  • Estados usam prefixo is- ou has-?
  • Nomes descrevem função, não aparência?

Design Tokens

  • Cores usam color('token') em vez de valores hard-coded?
  • Spacing usa spacing('token')?
  • Radius usa radius('token')?
  • Shadows usam shadow('token') ou @include shadow()?

Responsividade

  • Estilos base são mobile-first?
  • Media queries usam mixins (@include up(), etc.)?
  • Breakpoints seguem o mapa definido?

Acessibilidade

  • Estados de foco estão estilizados (:focus-visible)?
  • Animações respeitam prefers-reduced-motion?
  • Contraste de cores é adequado?
  • Conteúdo decorativo está oculto para screen readers quando necessário?

Performance

  • Animações usam apenas transform e opacity?
  • Evitou animações de width, height, top, left?
  • Seletores são específicos mas não excessivamente aninhados?
  • Não há CSS duplicado ou desnecessário?

Boas Práticas Gerais

  • Usa @use em vez de @import?
  • Mixins e funções são reutilizáveis?
  • Comentários explicam “porquê”, não “o quê”?
  • Código foi testado em múltiplos viewports?

Referências Rápidas

Atalhos de Spacing

Token Valor Pixel (base 16px)
none 0 0px
xs 0.5rem 8px
sm 1rem 16px
md 1.5rem 24px
lg 2rem 32px
xl 3rem 48px
2xl 4rem 64px
3xl 6rem 96px

Breakpoints

Token Valor Dispositivo
xs 0 Mobile Portrait (base)
sm 576px Smartphone Landscape
md 768px Tablet Portrait
lg 992px Tablet Landscape / Laptop
xl 1200px Desktop
xxl 1440px Monitores Grandes

Cores Semânticas

Token Uso
bg-primary Fundo principal
bg-secondary Fundo secundário
bg-tertiary Fundo terciário
text-primary Texto primário
text-secondary Texto secundário/de destaque
text-inverse Texto em fundo claro
text-muted Texto desativado/secundário
ui-border Bordas de UI
ui-divider Divisórias

Easings

Token Valor Uso
ease ease Padrão
ease-out ease-out Saída (entradas)
ease-in ease-in Entrada (saídas)
smooth cubic-bezier(0.4, 0, 0.2, 1) Movimentos premium
slide-up cubic-bezier(0.16, 1, 0.3, 1) Slide para cima
snappy cubic-bezier(0.2, 0, 0, 1) Resposta rápida

Este guia é vivo e deve ser atualizado conforme a evolução do design system do projeto.

Contribuidores: Time de Front-end
Revisão: Semestral ou quando mudanças significativas ocorrerem