Grade & Layout

Container centralizado em --container-max (1280px), padding lateral responsivo via --container-pad e grade estruturada em base 8 — três breakpoints, um único sistema.

Princípio

A unidade mínima de espaçamento é 8px. Todo padding, margin e gap de layout é múltiplo direto dessa base — 8, 16, 24, 32, 48, 64, 96, 128. O container de conteúdo usa max-width: var(--container-max) (1280px) e margin: 0 auto para centralização. O padding lateral é sempre var(--container-pad): 48px em desktop, 32px em tablet, 24px em mobile — o tokens.css redefine o valor em cada breakpoint via @media, e quem usa o token herda o ajuste sem redeclarar as regras. No shell desktop, o shell.css define grid-template-columns: 280px 1fr, ancorando a sidebar fixa à esquerda e deixando a área de conteúdo fluida.

A escala completa de tokens de espaçamento — de --space-8 a --space-128 — está documentada na página Espaçamento. No contexto de grade e layout, a regra é direta: padding, margin e gap com valores que não são múltiplos de 8 (13px, 17px, 22px) são violação. A única exceção são ajustes ópticos de glifo tipográfico — alinhamentos finos que o olho exige e o grid de 8 não resolve — e nesses casos o valor permitido é múltiplo de 4, nunca arbitrário, nunca em posições de layout.

Tokens de layout

Três tokens cobrem todo o sistema de grade: largura máxima do conteúdo, padding lateral responsivo e altura da topbar mobile. O --container-pad merece atenção: não são três tokens com um por breakpoint — é um único token cujo valor é redefinido por @media no tokens.css. Os valores completos estão em design-system/tokens/tokens.css.

TokenValorContexto de usoPapel
--container-max1280pxTodos os breakpoints — desktop, tablet e mobile.Largura máxima do conteúdo centralizado. Qualquer container de conteúdo usa max-width: var(--container-max) + margin: 0 auto.
--container-padvar(--space-48) → desktop
var(--space-32) → tablet
var(--space-24) → mobile
Ajustado via @media no tokens.css: 48px acima de 1024px, 32px entre 768px e 1024px, 24px abaixo de 768px. Um único token — não declarar os três valores diretamente nos componentes.Padding lateral do container de conteúdo. Um único token — o tokens.css redefine seu valor em cada breakpoint via @media. Nunca usar valor fixo em px onde --container-pad cabe.
--header-height64pxMobile e tablet — topbar sticky. Em desktop, a topbar não é renderizada.Altura da topbar mobile. Usada para calcular padding-top de conteúdo e posicionamento do drawer em viewports estreitas. Em desktop, a topbar não é renderizada — o shell usa sidebar fixa.

Três breakpoints

O sistema opera em três faixas: desktop (≥ 1025px), tablet (768–1024px) e mobile (< 768px). Os pontos de quebra são definidos no tokens.css via @media e propagados pelo token --container-pad. O shell.css e os componentes consomem o token — nenhum componente redefine os breakpoints por conta própria.

Desktop — >= 1025px

A sidebar fica fixa à esquerda em 280px — o shell.css define o shell como grid-template-columns: 280px 1fr. A área de conteúdo ocupa o restante da largura disponível, limitada a --container-max (1280px) com margin: 0 auto. O padding lateral é var(--container-pad), que em desktop resolve para var(--space-48) (48px = 6×8). Tipografia nos tamanhos padrão do tokens.css--type-size-display em 64px.

Tablet — 768–1024px

A sidebar sai do fluxo e vira drawer off-canvas, acionado pelo botão de hamburger na topbar sticky. A topbar ocupa --header-height (64px) no topo da viewport. A área de conteúdo ocupa 100% da largura disponível menos o padding lateral — o tokens.css redefine --container-pad para var(--space-32) (32px = 4×8) nessa faixa. A tipografia se ajusta: --type-size-display-lg cai de 80px para 64px, --type-size-display cai de 64px para 56px, --type-size-2xl cai de 48px para 40px, --type-size-xl cai de 40px para 32px.

Mobile — < 768px

Mesma estrutura de drawer do tablet. O --container-pad cai para var(--space-24) (24px = 3×8), preservando espaço respirável numa viewport estreita. A tipografia mantém os valores do tablet: --type-size-display em 56px, --type-size-xl em 32px, --type-size-display-lg em 64px, --type-size-2xl em 40px — sem redução adicional no mobile. O grid de cards colapsa para 1 coluna — nenhum card divide largura com outro na tela.

Card Grid responsivo

O Card Grid opera com 3 colunas em desktop, 2 em tablet e 1 em mobile. O gap entre cards é sempre múltiplo de 8 — --space-24 (24px) como valor padrão. O grid usa CSS Grid com grid-template-columns responsivo definido no grade-e-layout.css; os componentes não declaram media queries próprias. O contexto de breakpoint vem dos tokens, que propagam o ajuste de --container-pad de forma centralizada.

Compromisso vence hoje

Luz · R$ 127,30. Pago ou deixa pra mim?

Saldo projetado

R$ 2.140 em 15/mai · R$ 380 acima do mês anterior.

Gasto em delivery

R$ 230 este mês · R$ 80 abaixo da média.

Em desktop, os três cards ficam lado a lado em colunas iguais. Em tablet, o grid colapsa para 2 colunas — dois cards na primeira linha, um na segunda. Em mobile, os três ficam empilhados em coluna única.

Regras de uso

  • Layout ancorado em tokens — nunca valores arbitrários. Todo espaçamento de layout — padding, gap, margin — usa --space-*. Todo limite de largura usa --container-max. Valor em px avulso que não seja múltiplo de 8 é violação direta do anti-padrão #12.
  • --container-max (1280px) em qualquer conteúdo centralizado. Todo wrapper de conteúdo usa max-width: var(--container-max) com margin: 0 auto. Conteúdo que ultrapasse 1280px sem justificativa documentada é violação — não é exceção de design, é revisão necessária.
  • Padding lateral sempre via --container-pad. Os três valores de padding lateral (48 / 32 / 24px) vivem no tokens.css. Componentes não devem redeclarar esses valores em media queries próprias. Quem usa var(--container-pad) herda o comportamento responsivo sem custo adicional.
  • Grid colapsa em múltiplos de 8: 3 → 2 → 1 colunas. A sequência de colapso do Card Grid por breakpoint é 3 → 2 → 1. O gap entre colunas é sempre múltiplo de 8. Não pular de 3 para 1 sem passar por 2 — exceto em grids que nascem com 2 colunas, que podem colapsar direto para 1.
  • Sidebar vira drawer em < 1025px. Abaixo de 1025px, a sidebar some do fluxo de layout e vira drawer off-canvas acionado por hamburger na topbar. O shell.css e o ds-nav.js já implementam esse comportamento. Componentes novos não redeclaram a lógica de drawer — consomem o shell como está.
  • Scroll vertical é aceito; scroll horizontal é violação. Nenhuma superfície de produto produz overflow horizontal. A única exceção é tabela dentro de .peppe-table-wrap com overflow-x: auto explícito. Qualquer componente que rompa a largura do viewport sem esse wrapper é violação — não é decisão de layout, é correção obrigatória.

Anti-padrões referenciados

Anti-padrões com relação direta a decisões de grade e layout. O arquivo-fonte está em .claude/ui-design/anti-patterns.md. Links permanentes serão atualizados quando a seção de anti-padrões visuais for publicada.

  • #12 — Espaçamento fora da escala estruturalPadding, margin ou gap com valores que não são múltiplos de 8 — 13px, 17px, 22px, 10px. A escala começa em --space-8 e sobe em múltiplos. Múltiplos de 4 são aceitos apenas para ajustes ópticos de glifo tipográfico, nunca em posições de layout. Um componente com gap: 10px numa tela onde tudo usa base-8 produz desalinhamento que se acumula silenciosamente — cada elemento ligeiramente fora do grid, sem que nenhum isoladamente explique o resultado.
  • Responsividade — overflow horizontal não declaradoQualquer elemento que produza scroll horizontal sem wrapper explícito é violação. Os casos mais comuns: imagens sem max-width: 100%, textos com white-space: nowrap sem contenção, e tabelas sem .peppe-table-wrap. A página deve caber em qualquer largura de viewport de produto — se um componente força overflow, é o componente que muda, não a viewport que acomoda.

Consultar .claude/ui-design/anti-patterns.md na íntegra para demais anti-padrões visuais.