{
  "meta": {
    "name": "Zen",
    "version": "1.0.0",
    "source": "@ciromaciel/components-kit",
    "docs": "ciromaciel.click/design-system",
    "componentCount": 28,
    "primitiveCount": 7
  },
  "tokens": {
    "APPLE_REFERENCE": [
      {
        "group": "Adotado",
        "note": "Entrou no components-kit e no dashboard-kit; vale em todo site e todo painel.",
        "items": [
          {
            "topic": "Movimento",
            "rule": "Sob \"Reduzir movimento\", deslocamento vira nada ou esmaecimento.",
            "here": "Hover, pressão e rolagem suave desligam; o menu lateral do painel aparece em vez de deslizar."
          },
          {
            "topic": "Pressão",
            "rule": "Todo botão mostra que foi apertado.",
            "here": "Botão pressionado volta ao chão e escurece (brightness 0.92)."
          },
          {
            "topic": "Foco",
            "rule": "O anel segue a forma do elemento; um só em toda a interface.",
            "here": "2px gray.9 a 2px de distância, quadrado. Eram três cores diferentes."
          },
          {
            "topic": "Contraste",
            "rule": "Toda cor própria tem uma variante de contraste aumentado.",
            "here": "prefers-contrast: more desloca gray.2–gray.6 um degrau para o escuro."
          },
          {
            "topic": "Alvo de toque",
            "rule": "44×44 para o dedo; 28 é o padrão denso do desktop.",
            "here": "Ponteiro grosso ganha piso de 44px em Button, ActionIcon e CloseButton."
          },
          {
            "topic": "Tempo",
            "rule": "Prefira fechar à mão a sumir sozinho.",
            "here": "notify.error fica até ser fechada; sucesso e info saem em 5s."
          },
          {
            "topic": "Erro",
            "rule": "Diga como resolver, perto do problema, sem culpar e sem \"Ops\".",
            "here": "LeadForm: \"Preencha o campo E-mail\" no lugar de \"Obrigatório\"."
          },
          {
            "topic": "Rastreamento",
            "rule": "Texto pequeno abre, texto grande fecha.",
            "here": "O tracking dos labels nunca chegava à tela (prop ls, que o Mantine ignora). Agora é lts, nos 152 arquivos."
          },
          {
            "topic": "Escrita",
            "rule": "Verbo no botão, reticências quando falta informação, tooltip ≤75 caracteres.",
            "here": "Grupo \"Escrita\" no checklist."
          },
          {
            "topic": "Sucesso",
            "rule": "Uma cor por significado, nunca sozinha.",
            "here": "Verde para todo \"deu certo\" (green.6 preenche, green.7 escreve). Eram três."
          },
          {
            "topic": "Texto",
            "rule": "Hierarquia pela cor do papel, não por acaso.",
            "here": "Texto sem cor herda o corpo gray.6; título diz gray.9. O padrão era gray.9 nos sites e #000 nos painéis."
          },
          {
            "topic": "Modo escuro",
            "rule": "A base recua; o que sobe clareia. Não é a rampa invertida.",
            "here": "Rampa por elevação nos dois kits; padrão Automático; um botão que alterna, com o estado dito em palavras."
          },
          {
            "topic": "Consistência",
            "rule": "O mesmo papel com a mesma aparência em todo lugar.",
            "here": "Um panelTheme no dashboard-kit para os 18 painéis. h2 era 48px sobre um h1 de 36px."
          }
        ]
      },
      {
        "group": "Já era assim",
        "note": "A Apple chega pelo outro lado à mesma regra — confirma, não muda.",
        "items": [
          {
            "topic": "Cor",
            "rule": "Nunca só a cor para significar.",
            "here": "Glifo carrega o estado, palavra carrega o significado."
          },
          {
            "topic": "Hierarquia",
            "rule": "Uma tinta em vários níveis; superfícies por papel, não por valor.",
            "here": "A rampa de dez cinzas com papéis nomeados."
          },
          {
            "topic": "Forma",
            "rule": "Raio interno = raio externo − respiro.",
            "here": "Raio 0 satisfaz por construção."
          },
          {
            "topic": "Marca",
            "rule": "A marca cede ao conteúdo; o logo não se repete.",
            "here": "Lei 1: conteúdo sobre cromo."
          },
          {
            "topic": "Carregamento",
            "rule": "Placeholder com a forma do que vem.",
            "here": "Skeleton com a grade real é bloqueio de merge."
          },
          {
            "topic": "Exclusão",
            "rule": "Desfazer vence confirmar; confirmar só o irreversível; destrutivo nunca como ação primária.",
            "here": "undoable com Desfazer e ⌘Z; hold de 3s para credencial; no modal de exclusão, Cancelar primeiro e destrutivo em contorno."
          },
          {
            "topic": "Modal",
            "rule": "Um de cada vez, nunca empilhado.",
            "here": "useExclusiveModal."
          }
        ]
      },
      {
        "group": "Não adotado",
        "note": "Regras de plataforma ou que contrariam uma decisão deste sistema.",
        "items": [
          {
            "topic": "Caixa do botão",
            "rule": "Title Case em botões e menus.",
            "here": "Não existe em português. O botão continua em caixa alta, peso 800, 1px."
          },
          {
            "topic": "Liquid Glass",
            "rule": "Vidro translúcido na camada de controles.",
            "here": "Contraria a lei 1. O cromo se separa por filete e posição, não por desfoque."
          },
          {
            "topic": "Cápsula",
            "rule": "Controles em cápsula para o toque.",
            "here": "Contraria o raio 0."
          },
          {
            "topic": "Tracking do SF",
            "rule": "Tabela de tracking positivo acima de 24pt.",
            "here": "É da troca óptica da SF Display. A Montserrat fecha em display: −0.04em."
          },
          {
            "topic": "Peso 600",
            "rule": "Semibold como peso de ênfase.",
            "here": "O sistema pula de 500 para 700. Ênfase continua sendo 800."
          }
        ]
      }
    ],
    "BLOCKERS": [
      {
        "symptom": "border-radius diferente de 0",
        "law": 1
      },
      {
        "symptom": "Texto de conteúdo abaixo de 12px",
        "law": 2
      },
      {
        "symptom": "Erro e sucesso com a mesma cor",
        "law": 5
      },
      {
        "symptom": "Métrica ou tabela sem skeleton com a forma do conteúdo",
        "law": 3
      },
      {
        "symptom": "box-shadow em qualquer lugar",
        "law": 1
      },
      {
        "symptom": "Cor fora da rampa gray",
        "law": 1
      },
      {
        "symptom": "Salto tipográfico <2× entre níveis",
        "law": 2
      },
      {
        "symptom": "Corpo em gray.9",
        "law": 2
      },
      {
        "symptom": "Seção que reimplementa o palco",
        "law": 3
      },
      {
        "symptom": "Prop que aceita JSX arbitrário",
        "law": 4
      },
      {
        "symptom": "Métrica grande sem nota",
        "law": 5
      }
    ],
    "BORDERS": [
      {
        "name": "Padrão",
        "value": "1px solid gray.2",
        "usage": "Delimitação neutra",
        "width": 1,
        "color": "#F3F4F6"
      },
      {
        "name": "Acento",
        "value": "4px solid gray.2",
        "usage": "Topo do CTABanner: \"aja aqui\"",
        "width": 4,
        "color": "#F3F4F6"
      },
      {
        "name": "Citação",
        "value": "2px solid gray.3",
        "usage": "Compete com texto, não com fundo",
        "width": 2,
        "color": "#E5E7EB"
      },
      {
        "name": "Input",
        "value": "1px solid gray.2",
        "usage": "Borda inteira, radius 0",
        "width": 1,
        "color": "#F3F4F6"
      }
    ],
    "BREAKPOINTS": [
      {
        "token": "xs",
        "em": "36em",
        "px": 576,
        "usage": "Raro"
      },
      {
        "token": "sm",
        "em": "48em",
        "px": 768,
        "usage": "1 col → 2 col"
      },
      {
        "token": "md",
        "em": "62em",
        "px": 992,
        "usage": "O salto principal: mobile → desktop"
      },
      {
        "token": "lg",
        "em": "75em",
        "px": 1200,
        "usage": "2 col → 4 col"
      },
      {
        "token": "xl",
        "em": "88em",
        "px": 1408,
        "usage": "Raro"
      }
    ],
    "CHECKLIST": [
      {
        "group": "Tokens",
        "items": [
          "Zero hex literal no componente — tudo via c=\"gray.N\" / bg / var(--mantine-color-gray-N)",
          "Zero px de fonte hardcoded em título — usa var(--fz-*)",
          "Peso é 500, 700, 800 ou 900. Nenhum outro valor",
          "letter-spacing é -0.04em, 1px, 1.5px ou 2px",
          "radius=\"0\" em todo elemento que aceita raio"
        ]
      },
      {
        "group": "Tipografia",
        "items": [
          "Salto entre níveis adjacentes é ≥3×",
          "Corpo é gray.6; dado tabular é gray.7 — nunca gray.9",
          "Título é gray.9 — nunca gray.6",
          "Todo label uppercase tem fw={800} e tracking positivo",
          "gray.4 só aparece em label uppercase, nunca em parágrafo",
          "Um único <h1> na página",
          "<br /> manual em título está dentro de .hide-mobile-br"
        ]
      },
      {
        "group": "Cor",
        "items": [
          "Nenhuma cor fora da rampa gray, exceto red.6 (perda, erro) e green.6/green.7 (sucesso) — sempre com palavra ou glifo",
          "Toda borda é 1px solid gray.2 — salvo o topo 4px do CTABanner e a citação 2px gray.3",
          "Fundo de palco é white ou gray.1, alternando com o palco anterior",
          "Sem gradiente, sem sombra colorida"
        ]
      },
      {
        "group": "Espaço",
        "items": [
          "Palco usa py={{ base: 80, md: 120 }} e Container size=\"lg\"",
          "Stack gap=\"xl\" entre anúncio e conteúdo",
          "Corpo tem maw ≤ 780",
          "Mobile (base) é 1 coluna",
          "Onde há filete divisor, spacing={0}",
          "Borda divisória tem media query que a desliga quando a grade empilha"
        ]
      },
      {
        "group": "Forma",
        "items": [
          "Sem sombra",
          "Paper só onde a superfície precisa se declarar; caso contrário Card ou Box",
          "Input tem borda inteira de 1px gray.2 e radius 0",
          "Botão é uppercase, fw={800}, lts=\"1px\"",
          "Botão carregando mantém a cor e mostra as barras (14px no painel, 16px no site), centralizadas; sem camada por cima",
          "Ícone é Tabler com stroke={1.5}"
        ]
      },
      {
        "group": "Arquitetura",
        "items": [
          "Componente envolve Section em vez de refazer o palco",
          "Props são dados, não JSX",
          "Contrato padrão presente: id, badge, subtitle, title, background",
          "Usa primitivas em vez de reimplementar",
          "cta segue o shape universal",
          "Exportado em src/index.js",
          "Padrão repetido em 3+ componentes foi promovido a primitiva"
        ]
      },
      {
        "group": "Painel (telas de aplicação)",
        "items": [
          "Texto tabular usa o papel \"dado\" (12–14px), não o corpo de 16px",
          "Nenhum texto abaixo de 12px, exceto label uppercase (10–11px)",
          "Skeleton reproduz a grade real do conteúdo, não um retângulo genérico",
          "Refetch não pisca skeleton por cima de dado já visível",
          "Erro usa red.6 — nunca a mesma cor do sucesso",
          "Só um componente registra ⌘K por tela",
          "Busca cancela a requisição anterior (AbortController)",
          "Ação destrutiva pede permanência (hold 3s), não um \"tem certeza?\"",
          "Ação destrutiva é acionável por teclado",
          "Linha de tabela inteira é clicável quando leva a um detalhe"
        ]
      },
      {
        "group": "Acessibilidade",
        "items": [
          "Imagem tem alt; vídeo tem aria-label",
          "CTA com href renderiza <a>; com onClick, <button>",
          "Contraste ≥4,5:1 em todo texto de corpo",
          "Seção usa <section> semântico com id",
          "Alvo de toque ≥44px em mobile",
          "Foco visível é o anel do sistema (2px gray.9, 2px de distância) — nunca outline: none sem substituto",
          "Nada se desloca sob prefers-reduced-motion — nem hover, nem rolagem suave",
          "Botão tem estado de pressão (:active), não só hover",
          "Botão só de ícone tem aria-label; ícone decorativo tem aria-hidden",
          "Informação nunca só na cor: estado é glifo + palavra"
        ]
      },
      {
        "group": "Escrita",
        "items": [
          "Botão e link começam com verbo — nunca \"clique aqui\" nem \"saiba mais\"",
          "Ação que pede mais informação antes de concluir termina em reticências: \"Exportar…\"",
          "Erro diz o que houve e como resolver: \"Preencha o campo E-mail\", não \"Obrigatório\"",
          "Sem \"Ops\", sem culpa, sem \"nós\": \"Não foi possível carregar\", não \"Tivemos um problema\"",
          "Notificação de erro fica até ser fechada; sucesso e info saem sozinhos",
          "Tooltip tem no máximo 75 caracteres e não repete o nome do controle",
          "Controle desabilitado diz por quê (tooltip ou texto de ajuda)",
          "Placeholder é exemplo (nome@exemplo.com), nunca o único rótulo do campo",
          "Gráfico tem título que diz a conclusão, não só o nome da série"
        ]
      },
      {
        "group": "Modo escuro",
        "items": [
          "Nenhum hexadecimal da rampa na interface — cor é c=\"gray.N\" ou var(--mantine-color-gray-N)",
          "Palco de seção é gray.0; white é cartão (a superfície elevada no escuro)",
          "Nunca color=\"dark\" nem dark.N — o preto do sistema é gray.9",
          "Superfície escura nos dois temas (terminal, código) usa cor literal, e o comentário diz por quê",
          "Prévia de peça externa (formulário, e-mail) não vira com o tema",
          "Nunca theme.colors.gray[N] nem 'white' literal num estilo — var(--mantine-color-gray-N) e var(--mantine-color-white)",
          "Item ativo é igual a qualquer ativo, mesmo se for muted — o cinza discreto só vale fora do ativo",
          "Selo de status é o Tag do dashboard-kit, nunca o Badge do Mantine — preenchido só para o que está no ar",
          "MantineProvider com defaultColorScheme=\"auto\", nunca forceColorScheme",
          "index.html tem o script do tema no <head>, antes do CSS"
        ]
      }
    ],
    "COLOR_SCHEME_TOGGLE": {
      "component": "ColorSchemeToggle (components-kit e dashboard-kit)",
      "cycle": "Automático → Claro → Escuro",
      "default": "Automático — segue o aparelho",
      "label": "Tema: Claro. Mudar para Escuro.",
      "where": "Painel: ao lado do cartão do usuário, no pé da coluna · Site: no cabeçalho, antes dos botões"
    },
    "CONTAINERS": [
      {
        "size": "md",
        "width": 980,
        "usage": "Leitura contínua: legal, FAQ, artigo"
      },
      {
        "size": "lg",
        "width": 1180,
        "usage": "Padrão de toda seção de landing"
      },
      {
        "size": "xl",
        "width": 1320,
        "usage": "Faixas full-width: Header, Footer"
      }
    ],
    "CONTRAST_MORE": [
      {
        "token": "gray.2",
        "from": "#F3F4F6",
        "to": "#9CA3AF",
        "why": "O filete some em tela clara"
      },
      {
        "token": "gray.3",
        "from": "#E5E7EB",
        "to": "#9CA3AF",
        "why": "Borda muda e desabilitado"
      },
      {
        "token": "gray.4",
        "from": "#9CA3AF",
        "to": "#4B5563",
        "why": "Label: 2,6:1 → 7,5:1"
      },
      {
        "token": "gray.5",
        "from": "#6B7280",
        "to": "#374151",
        "why": "Legenda: 4,9:1 → 10,4:1"
      },
      {
        "token": "gray.6",
        "from": "#4B5563",
        "to": "#374151",
        "why": "Corpo: 7,5:1 → 10,4:1"
      }
    ],
    "CONTRAST_TABLE": [
      {
        "token": "gray.9",
        "ratio": "16,8:1",
        "status": "AAA",
        "pass": true
      },
      {
        "token": "gray.7",
        "ratio": "10,4:1",
        "status": "AAA",
        "pass": true
      },
      {
        "token": "gray.6",
        "ratio": "7,5:1",
        "status": "AAA",
        "pass": true
      },
      {
        "token": "gray.5",
        "ratio": "4,9:1",
        "status": "AA em corpo",
        "pass": true
      },
      {
        "token": "gray.4",
        "ratio": "2,6:1",
        "status": "Falha AA em corpo",
        "pass": false
      }
    ],
    "DARK_RAMP": [
      {
        "token": "gray.0",
        "light": "#FFFFFF",
        "dark": "#0B0F12",
        "usage": "Base da página, palco padrão (SECTION_BACKGROUNDS.white)"
      },
      {
        "token": "gray.1",
        "light": "#F9FAFB",
        "dark": "#12181D",
        "usage": "Palco alternado (SECTION_BACKGROUNDS.gray), hover"
      },
      {
        "token": "white",
        "light": "#FFFFFF",
        "dark": "#1A2127",
        "usage": "Cartão, Paper, modal — a superfície elevada. Nunca palco"
      },
      {
        "token": "elevated-2",
        "light": "#FFFFFF",
        "dark": "#232B32",
        "usage": "Menu, popover, lista suspensa, notificação"
      },
      {
        "token": "gray.2",
        "light": "#F3F4F6",
        "dark": "#222A31",
        "usage": "Filete"
      },
      {
        "token": "gray.3",
        "light": "#E5E7EB",
        "dark": "#2F3840",
        "usage": "Borda forte, desabilitado"
      },
      {
        "token": "gray.4",
        "light": "#9CA3AF",
        "dark": "#8A94A0",
        "usage": "Label caixa alta (4,7:1 até no menu)"
      },
      {
        "token": "gray.5",
        "light": "#6B7280",
        "dark": "#98A1AC",
        "usage": "Legenda, nota"
      },
      {
        "token": "gray.6",
        "light": "#4B5563",
        "dark": "#B6BEC8",
        "usage": "Corpo"
      },
      {
        "token": "gray.7",
        "light": "#374151",
        "dark": "#D3D8DE",
        "usage": "Dado de tabela"
      },
      {
        "token": "gray.9",
        "light": "#11181C",
        "dark": "#F3F4F6",
        "usage": "Título, botão"
      }
    ],
    "DESTRUCTIVE": {
      "holdMs": 3000,
      "tickMs": 50,
      "feedback": "RingProgress thickness 2 sobre o ícone",
      "cancel": "onMouseUp · onMouseLeave · onTouchEnd · soltar Espaço/Enter",
      "variants": "ícone (tabela) · texto com contagem regressiva (formulário)",
      "undo": "Exclusão frequente (campo, bloco, nota, resposta) → undoable: sai na hora, Desfazer e ⌘Z por 6s, envia depois",
      "holdOnlyFor": "Chave, webhook, domínio, integração, agenda: revogar tem que valer na hora",
      "escalation": "Alvo que pode ser confundido → DeleteModal, digitar o identificador",
      "modalFooter": "Cancelar primeiro; destrutivo por último, contorno red.7"
    },
    "FLUID_SCALE": [
      {
        "token": "--fz-hero",
        "value": "clamp(2.5rem, 8vw + 1rem, 6rem)",
        "range": "40 → 96px",
        "usage": "Primeira dobra"
      },
      {
        "token": "--fz-section-title",
        "value": "clamp(2rem, 5vw + 1rem, 3.5rem)",
        "range": "32 → 56px",
        "usage": "Título de seção — o mais frequente"
      },
      {
        "token": "--fz-big-metric",
        "value": "clamp(3rem, 10vw + 1rem, 7.5rem)",
        "range": "48 → 120px",
        "usage": "Métrica — a mais dramática"
      },
      {
        "token": "--fz-big-metric-sm",
        "value": "clamp(3rem, 5vw, 4.5rem)",
        "range": "48 → 72px",
        "usage": "Métrica em grade de 4 colunas"
      }
    ],
    "FOCUS_RING": {
      "outline": "2px solid gray.9",
      "offset": "2px",
      "shape": "quadrado, como o elemento (raio 0)",
      "danger": "red.7 em .rlg-danger — muda só a cor"
    },
    "FONT_FAMILY": "Montserrat, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
    "FONT_WEIGHTS": [
      {
        "value": 900,
        "name": "Black",
        "usage": "Títulos, métricas, wordmark",
        "count": 44
      },
      {
        "value": 800,
        "name": "ExtraBold",
        "usage": "Labels uppercase, botões, badges",
        "count": 20
      },
      {
        "value": 700,
        "name": "Bold",
        "usage": "Ênfase em corpo, rótulo de métrica",
        "count": 10
      },
      {
        "value": 500,
        "name": "Medium",
        "usage": "Legenda técnica, letra miúda",
        "count": 5
      }
    ],
    "FORM_SPEC": [
      {
        "rule": "Modal",
        "detail": "size md · centered · padding xl"
      },
      {
        "rule": "Título",
        "detail": "ThemeIcon 32 + título h4 + descrição em gray.6"
      },
      {
        "rule": "Validação",
        "detail": "@mantine/form, síncrona, mensagem inline em português"
      },
      {
        "rule": "Botões",
        "detail": "Submit à direita; destrutivo à esquerda. Sem \"Cancelar\" — o X do modal basta. No diálogo cujo ato é excluir, o contrário: Cancelar e o destrutivo por último"
      },
      {
        "rule": "Feedback",
        "detail": "notifications.show no sucesso e no erro, com cores distintas"
      },
      {
        "rule": "Loading",
        "detail": "Botão com loading + disabled; overlay no corpo se a carga for longa"
      }
    ],
    "GRAY_RAMP": [
      {
        "step": 0,
        "hex": "#FFFFFF",
        "token": "gray.0",
        "role": "App base",
        "usage": "Fundo branco puro",
        "count": null
      },
      {
        "step": 1,
        "hex": "#F9FAFB",
        "token": "gray.1",
        "role": "Superfície alternada",
        "usage": "Palco alternado, numeral fantasma",
        "count": null
      },
      {
        "step": 2,
        "hex": "#F3F4F6",
        "token": "gray.2",
        "role": "Filete padrão",
        "usage": "Toda borda do sistema",
        "count": 10
      },
      {
        "step": 3,
        "hex": "#E5E7EB",
        "token": "gray.3",
        "role": "Borda muda",
        "usage": "Citação, estado desabilitado",
        "count": null
      },
      {
        "step": 4,
        "hex": "#9CA3AF",
        "token": "gray.4",
        "role": "Texto quaternário",
        "usage": "Label uppercase apenas",
        "count": 7
      },
      {
        "step": 5,
        "hex": "#6B7280",
        "token": "gray.5",
        "role": "Texto terciário",
        "usage": "Rótulos, legendas",
        "count": 20
      },
      {
        "step": 6,
        "hex": "#4B5563",
        "token": "gray.6",
        "role": "Texto secundário",
        "usage": "Corpo — a cor mais usada",
        "count": 50
      },
      {
        "step": 7,
        "hex": "#374151",
        "token": "gray.7",
        "role": "Corpo enfático",
        "usage": "Descrição de destaque",
        "count": 6
      },
      {
        "step": 8,
        "hex": "#1F2937",
        "token": "gray.8",
        "role": "Texto primário escuro",
        "usage": "Raro",
        "count": 4
      },
      {
        "step": 9,
        "hex": "#11181C",
        "token": "gray.9",
        "role": "Preto da marca",
        "usage": "Títulos, métricas, botão preenchido",
        "count": 36
      }
    ],
    "ICONS": {
      "library": "@tabler/icons-react",
      "stroke": 1.5
    },
    "LAYERS": [
      {
        "name": "Tokens",
        "items": "theme.js · global.css · tokens.js",
        "role": "Os valores"
      },
      {
        "name": "Primitivas",
        "items": "Section · SectionHeader · CTAButton · MediaBlock · Wordmark · BrandLogo",
        "role": "Átomos reutilizáveis"
      },
      {
        "name": "Seções",
        "items": "Hero · FeaturesGrid · StatsGrid · Pricing · FAQ · CTABanner …",
        "role": "Blocos de página"
      },
      {
        "name": "Páginas",
        "items": "website · auth · hoster · storage · payments",
        "role": "Instâncias"
      }
    ],
    "LINE_HEIGHTS": [
      {
        "value": 1,
        "usage": "Métrica",
        "count": 7
      },
      {
        "value": 1.1,
        "usage": "Hero",
        "count": 1
      },
      {
        "value": 1.2,
        "usage": "Título de seção",
        "count": 3
      },
      {
        "value": 1.4,
        "usage": "Rótulo compacto",
        "count": 6
      },
      {
        "value": 1.5,
        "usage": "Nota",
        "count": 3
      },
      {
        "value": 1.6,
        "usage": "Corpo curto",
        "count": 16
      },
      {
        "value": 1.7,
        "usage": "Corpo padrão",
        "count": 25
      },
      {
        "value": 1.8,
        "usage": "Bloco longo (legal)",
        "count": 6
      }
    ],
    "LOSS_COLOR": {
      "token": "red.6",
      "hex": "#E03131",
      "usage": "Custo/perda quantificada"
    },
    "MEASURES": [
      {
        "maw": 900,
        "usage": "Título centralizado"
      },
      {
        "maw": 800,
        "usage": "Título padrão (default de Section)"
      },
      {
        "maw": 780,
        "usage": "Parágrafo de introdução"
      },
      {
        "maw": 700,
        "usage": "Título de CTABanner"
      },
      {
        "maw": 620,
        "usage": "Corpo longo — 60–75 caracteres"
      },
      {
        "maw": 550,
        "usage": "Descrição centralizada de CTA"
      },
      {
        "maw": 220,
        "usage": "Nota sob métrica"
      }
    ],
    "META": {
      "name": "Zen",
      "version": "1.0.0",
      "source": "@ciromaciel/components-kit",
      "docs": "ciromaciel.click/design-system",
      "componentCount": 28,
      "primitiveCount": 7
    },
    "MOTION": {
      "transition": "transform 0.2s ease, filter 0.2s ease",
      "transform": "translateY(-1px)",
      "filter": "brightness(1.1)",
      "active": "translateY(0) + brightness(0.92)",
      "reduced": "sem transform, sem transição; scroll-behavior smooth só em no-preference"
    },
    "PAGE_HEADER": [
      {
        "part": "crumb",
        "spec": "fz 10 · fw 800 · gray.4 · uppercase · ls 1.5px",
        "role": "Onde você está"
      },
      {
        "part": "title",
        "spec": "fz 36 · fw 900 · lh 1 · ls -0.04em",
        "role": "O que é esta tela"
      },
      {
        "part": "subtitle",
        "spec": "fz 15 · fw 500 · gray.6 · lh 1.5",
        "role": "O que dá para fazer aqui"
      },
      {
        "part": "actions",
        "spec": "Group gap md, à direita",
        "role": "Um botão primário; busca opcional"
      }
    ],
    "PANEL_LAYOUT": {
      "sidebar": {
        "width": 300,
        "collapsed": 64,
        "bg": "white",
        "border": "1px solid gray.2"
      },
      "content": {
        "px": 48,
        "pt": 40,
        "pb": 80,
        "maw": 1280
      },
      "pageHeaderMb": 32,
      "blockGap": 16
    },
    "PRINCIPLES": [
      {
        "n": 1,
        "name": "Conteúdo sobre cromo",
        "summary": "Cada elemento de cromo precisa responder \"que informação eu comunico?\". Se a resposta for \"nenhuma, é estética\", ele sai.",
        "detail": "Sobreviveram ao corte: o filete de 1px (comunica separação), o numeral fantasma de Steps (comunica ordem), o badge dot (categoria com mínimo de tinta). Foram cortados: sombras, bordas de Card, raio.",
        "corollary": "Quando a página parece vazia demais, o erro está no conteúdo, não no design. A resposta é escrever melhor, não adicionar moldura."
      },
      {
        "n": 2,
        "name": "Hierarquia massiva",
        "summary": "Não existe cor de destaque. A ênfase vem de contraste de escala, e o contraste precisa ser violento: salto de 3× a 6× entre níveis, nunca 1,2×.",
        "detail": "O par canônico é o cabeçalho de palco: label minúsculo, leve em tinta e disperso em tracking, imediatamente acima de um título enorme, pesado e apertado. Opostos em cinco dimensões ao mesmo tempo — é isso que cria a tensão.",
        "corollary": "Implementado em SectionHeader. Toda seção do kit passa por ele."
      },
      {
        "n": 3,
        "name": "O Palco",
        "summary": "Toda seção é um palco: fundo próprio, respiro vertical generoso, e um anúncio antes da performance.",
        "detail": "Não é opcional nem reimplementado por seção — é a primitiva Section. As únicas exceções (Header, Hero, SocialProof, Footer) existem porque têm geometria própria.",
        "corollary": "Palcos consecutivos alternam white ↔ gray.1. É a única marcação de ritmo da página."
      },
      {
        "n": 4,
        "name": "Config-driven, não JSX",
        "summary": "O consumidor passa dados, nunca marcação.",
        "detail": "Não é preferência de API — é o que mantém as leis 1–3 aplicáveis. Se o consumidor puder injetar JSX, ele injeta cromo, e o sistema erode em três sprints.",
        "corollary": "Contrato padrão: id, badge, subtitle, title, background, items, cta, note."
      },
      {
        "n": 5,
        "name": "Honestidade verificável",
        "summary": "Cada afirmação forte carrega o que a torna checável.",
        "detail": "Por isso StatsGrid tem description sob cada número e note sob a grade; Callout tem rodapé de honestidade; Hero tem note com o que custa experimentar. A nota é sempre o degrau mais baixo: 13px, gray.6, lh 1.5.",
        "corollary": "Sem esta lei, hierarquia massiva vira só um número grande sem lastro. A nota é o que separa design de propaganda."
      },
      {
        "n": 6,
        "name": "Um lugar por item",
        "summary": "No cabeçalho, cada item mora num menu só. O rodapé é o mapa do site, não a cópia do cabeçalho.",
        "detail": "O cabeçalho mostra tipos de coisa, não o catálogo: no máximo três menus, até quatro colunas, cerca de oito itens por coluna, e a lista completa na página índice (/books, /tools). O rodapé leva às páginas índice, a quem conduz, ao contato e às páginas legais: quatro colunas, até sete links cada, nunca uma linha por livro ou por ferramenta. Em 30/10/2026 o cabeçalho tinha 58 itens, 17 deles duas vezes, e o rodapé 56 links; ficaram 28 e 23.",
        "corollary": "Coisa nova entra no seu lugar único: um livro novo, em \"Para quem\"; uma ferramenta nova, em /tools. Só entra no menu se for um tipo novo."
      }
    ],
    "RADIUS": {
      "value": "0",
      "occurrences": 57,
      "exceptions": 0
    },
    "SEARCH_SPEC": {
      "shortcut": "⌘K / Ctrl+K",
      "minLength": 2,
      "debounceMs": 250,
      "iconSize": 16,
      "escape": "Limpa o termo e devolve o foco",
      "abort": "AbortController cancela a requisição anterior a cada tecla",
      "dropdown": "Nunca abre vazio: ou tem resultado, ou tem o aviso de nenhum",
      "rightSection": "Kbd com o atalho quando vazio; Loader 14px durante a busca"
    },
    "SECTION_VOCABULARY": [
      {
        "job": "Abertura",
        "components": [
          "Header",
          "Hero",
          "SocialProof"
        ]
      },
      {
        "job": "Prova",
        "components": [
          "StatsGrid",
          "Testimonials",
          "TrustBadge",
          "FounderCard"
        ]
      },
      {
        "job": "Explicação",
        "components": [
          "FeatureSplit",
          "FeaturesGrid",
          "Steps",
          "Callout"
        ]
      },
      {
        "job": "Decisão",
        "components": [
          "Comparison",
          "CriteriaList",
          "Pricing",
          "FAQ"
        ]
      },
      {
        "job": "Conversão",
        "components": [
          "CTABanner",
          "LeadForm",
          "ProductGrid"
        ]
      },
      {
        "job": "Fechamento",
        "components": [
          "Footer",
          "LegalPrivacy",
          "LegalTerms",
          "LegalSecurity"
        ]
      },
      {
        "job": "Estrutura",
        "components": [
          "Layout",
          "Section"
        ]
      }
    ],
    "SEMANTIC_COLORS": [
      {
        "name": "textHeading",
        "token": "gray.9",
        "hex": "#11181C",
        "usage": "Títulos e métricas"
      },
      {
        "name": "textBody",
        "token": "gray.6",
        "hex": "#4B5563",
        "usage": "Corpo padrão"
      },
      {
        "name": "textEmphasis",
        "token": "gray.7",
        "hex": "#374151",
        "usage": "Corpo com presença"
      },
      {
        "name": "textLabel",
        "token": "gray.4",
        "hex": "#9CA3AF",
        "usage": "Label uppercase"
      },
      {
        "name": "border",
        "token": "gray.2",
        "hex": "#F3F4F6",
        "usage": "Toda borda"
      },
      {
        "name": "surface",
        "token": "gray.0",
        "hex": "#FFFFFF",
        "usage": "Palco padrão"
      },
      {
        "name": "surfaceAlt",
        "token": "gray.1",
        "hex": "#F9FAFB",
        "usage": "Palco alternado"
      }
    ],
    "SIDEBAR_SPEC": [
      {
        "part": "largura",
        "spec": "300px · a coluna não recolhe"
      },
      {
        "part": "componente",
        "spec": "SidebarShell do dashboard-kit — coluna nova não é desenhada à mão"
      },
      {
        "part": "superfície",
        "spec": "bg gray.0 · borderRight 1px gray.2"
      },
      {
        "part": "marca",
        "spec": "Wordmark 28px no topo · a linha do painel embaixo (ColumnBrand)"
      },
      {
        "part": "contexto",
        "spec": "Em /, a lista dos recursos; dentro de um, o nome dele e as seções"
      },
      {
        "part": "busca",
        "spec": "36px · bg gray.1 · borda 1px gray.2 · ícone 16px · fz 13"
      },
      {
        "part": "criar",
        "spec": "CreateButton: quadrado de 36px, bg gray.9, \"+\" 16px, colado à direita da busca · nome da ação na dica e no rótulo acessível · no limite do plano, contorno gray.4 e ícone gray.5 · sem busca, volta a ser um item escrito"
      },
      {
        "part": "label de seção",
        "spec": "fz 10 · fw 800 · gray.4 · uppercase · ls 1.5px"
      },
      {
        "part": "item",
        "spec": "fz 13 · px 12 · py 9 · ícone 18px stroke 1.5 · radius 0"
      },
      {
        "part": "item ativo",
        "spec": "bg gray.9 · texto gray.0 · fw 800"
      },
      {
        "part": "item inativo",
        "spec": "transparente · gray.7 · fw 500"
      },
      {
        "part": "rodapé",
        "spec": "Cartão do usuário (Docs, suporte e conta no menu dele) e o botão de tema à direita, separados por borderTop 1px gray.2"
      }
    ],
    "SPACE_SCALE": [
      {
        "token": "xs",
        "px": 10,
        "usage": "Dentro de um par (label ↔ título)",
        "count": 18
      },
      {
        "token": "sm",
        "px": 12,
        "usage": "Itens de uma lista",
        "count": 12
      },
      {
        "token": "md",
        "px": 16,
        "usage": "Padding de controle",
        "count": 7
      },
      {
        "token": "lg",
        "px": 20,
        "usage": "Padding de card compacto",
        "count": 5
      },
      {
        "token": "xl",
        "px": 32,
        "usage": "Entre blocos de uma seção",
        "count": 18
      }
    ],
    "STAGE_RHYTHM": [
      {
        "name": "Padrão",
        "value": "{ base: 80, md: 120 }",
        "usage": "Toda Section"
      },
      {
        "name": "Hero",
        "value": "{ base: 80, sm: 100, md: 140 }",
        "usage": "Primeira dobra respira mais"
      },
      {
        "name": "Denso",
        "value": "{ base: 40, md: 60 }",
        "usage": "SocialProof, Footer"
      }
    ],
    "STATES": [
      {
        "state": "Carregando (primeira vez)",
        "pattern": "Skeleton com a grade exata do conteúdo",
        "spec": "Mesmo gridTemplateColumns, mesmo padding. radius 0."
      },
      {
        "state": "Carregando (refetch)",
        "pattern": "Nada, ou LoadingOverlay sutil",
        "spec": "O dado antigo continua legível — não pisca skeleton por cima."
      },
      {
        "state": "Vazio (sem dado)",
        "pattern": "Label uppercase + subtítulo + ação",
        "spec": "Stack align center py 56 · título fz 10 fw 800 gray.4 uppercase ls 1.5px"
      },
      {
        "state": "Vazio (busca sem resultado)",
        "pattern": "Mesma anatomia, citando o termo",
        "spec": "\"Nenhum resultado para «termo»\" + botão de limpar busca"
      },
      {
        "state": "Erro",
        "pattern": "Notificação vermelha, nunca cinza",
        "spec": "red.6 com IconAlertCircle. Sucesso e erro precisam ser distinguíveis sem ler."
      },
      {
        "state": "Bloqueado (falta contexto)",
        "pattern": "Gate com skeleton",
        "spec": "Sem aplicação selecionada, a tela mostra a forma, não um erro."
      }
    ],
    "SUCCESS_COLOR": {
      "fill": {
        "token": "green.6",
        "hex": "#16A34A"
      },
      "ink": {
        "token": "green.7",
        "hex": "#15803D"
      },
      "css": "--rlg-success / --rlg-success-ink",
      "usage": "Notificação de sucesso, \"No ar\", barras de status, \"Salvo\""
    },
    "SURFACES": [
      {
        "name": "Palco",
        "job": "Convencer",
        "where": "Landing, marketing, legal, 404",
        "rhythm": "py 80–120 · Container lg · gap xl",
        "type": "Corpo 15–20px · display 32–120px",
        "density": "Generosa — o vazio é o que cria calma"
      },
      {
        "name": "Painel",
        "job": "Operar",
        "where": "Dashboard, listas, formulários, configurações",
        "rhythm": "px 48 · pt 40 · maw 1280 · gap 16–32",
        "type": "Dado 12–14px · título de página 36px",
        "density": "Compacta — a tela cabe mais linhas"
      }
    ],
    "TABLE_SPEC": [
      {
        "part": "componente",
        "spec": "DataTable do dashboard-kit — a única tabela · getRowTone · renderDetail · stackOnPhone · bare"
      },
      {
        "part": "selo de status",
        "spec": "Tag do dashboard-kit · 10px · fw 800 · uppercase · ls 1.5px · filete 1px · neutral (gray.3/gray.6) · dark preenchido só para o que está no ar · up com quadrado verde · no em red · ícone de 12px para o que pede atenção"
      },
      {
        "part": "container",
        "spec": "Card p={0} withBorder · overflow hidden"
      },
      {
        "part": "header",
        "spec": "bg gray.1 · padding 12px 24px · borderBottom 1px gray.2"
      },
      {
        "part": "header cell",
        "spec": "fz 10 · fw 800 · gray.5 · uppercase · ls 1.5px"
      },
      {
        "part": "row",
        "spec": "padding 14px 24px · borderBottom 1px gray.2 (exceto a última)"
      },
      {
        "part": "cell",
        "spec": "fz 13 · gray.7 · lh 1.4 — o papel \"dado\""
      },
      {
        "part": "hover",
        "spec": "background gray.1 · transition 120ms"
      },
      {
        "part": "destaque",
        "spec": "background gray.1 + boxShadow inset 2px 0 0 gray.9"
      },
      {
        "part": "grade",
        "spec": "gridTemplateColumns com fr + coluna fixa 40px para ações"
      }
    ],
    "TRACKING": [
      {
        "name": "tight",
        "value": "-0.04em",
        "usage": "Todo display e título",
        "count": 2
      },
      {
        "name": "control",
        "value": "1px",
        "usage": "Botão, link de navegação",
        "count": 5
      },
      {
        "name": "label",
        "value": "1.5px",
        "usage": "Todo label uppercase",
        "count": 10
      },
      {
        "name": "wide",
        "value": "2px",
        "usage": "Label de destaque, wordmark",
        "count": 19
      }
    ],
    "TYPE_ROLES": {
      "label": {
        "name": "Label",
        "tagline": "o anúncio",
        "fontSize": "10–13px",
        "fontWeight": 800,
        "letterSpacing": "1.5px",
        "textTransform": "uppercase",
        "color": "gray.4",
        "lineHeight": 1.4
      },
      "body": {
        "name": "Corpo",
        "tagline": "a performance",
        "fontSize": "15–20px",
        "fontWeight": 400,
        "letterSpacing": "normal",
        "textTransform": "none",
        "color": "gray.6",
        "lineHeight": 1.7
      },
      "data": {
        "name": "Dado",
        "tagline": "a evidência",
        "fontSize": "12–14px",
        "fontWeight": 500,
        "letterSpacing": "normal",
        "textTransform": "none",
        "color": "gray.7",
        "lineHeight": 1.4
      },
      "display": {
        "name": "Display",
        "tagline": "a declaração",
        "fontSize": "32–120px",
        "fontWeight": 900,
        "letterSpacing": "-0.04em",
        "textTransform": "none",
        "color": "gray.9",
        "lineHeight": 1.2
      }
    },
    "UNIVERSAL_PROPS": [
      {
        "prop": "id",
        "type": "string",
        "role": "Âncora de scroll"
      },
      {
        "prop": "badge",
        "type": "string",
        "role": "Selo pontilhado acima do label"
      },
      {
        "prop": "subtitle",
        "type": "string",
        "role": "Label uppercase — o anúncio"
      },
      {
        "prop": "title",
        "type": "string | node",
        "role": "Título massivo"
      },
      {
        "prop": "description",
        "type": "string",
        "role": "Parágrafo de introdução"
      },
      {
        "prop": "background",
        "type": "'white' | 'gray'",
        "role": "Fundo do palco"
      },
      {
        "prop": "ta",
        "type": "'left' | 'center'",
        "role": "Alinhamento"
      },
      {
        "prop": "items",
        "type": "object[]",
        "role": "Os dados"
      },
      {
        "prop": "cta",
        "type": "{ label, href, icon, variant, target }",
        "role": "Ação"
      },
      {
        "prop": "note",
        "type": "string",
        "role": "Nota de verificação (Lei 5)"
      }
    ]
  },
  "api": {
    "ALIASES": [
      [
        "Navbar",
        "Header"
      ],
      [
        "SecondaryCTA",
        "CTABanner"
      ],
      [
        "SeloExclusivo",
        "TrustBadge"
      ]
    ],
    "COMPONENTS": [
      {
        "name": "Layout",
        "job": "Wrapper raiz. Flex column com minHeight 100vh — um <main style={{flex:1}}> empurra o rodapé para o fim.",
        "group": "Estrutura",
        "props": [
          [
            "children",
            "ReactNode",
            ""
          ],
          [
            "style",
            "object",
            "Mesclado ao style interno"
          ],
          [
            "...props",
            "any",
            "Encaminhado ao Box (bg, etc.)"
          ]
        ],
        "example": "<Layout>\n    <Header ... />\n    <main style={{ flex: 1 }}>{/* seções */}</main>\n    <Footer ... />\n</Layout>"
      },
      {
        "name": "Header",
        "job": "Barra de navegação. Alias legado: Navbar.",
        "group": "Abertura",
        "props": [
          [
            "logo",
            "{ src, alt, height } | ReactNode",
            "Imagem ou <Wordmark>"
          ],
          [
            "navLinks",
            "{ label, href, component?, to? }[]",
            "Aceita Link do react-router via `component`"
          ],
          [
            "loginCta",
            "{ label, href }",
            "CTA secundário"
          ],
          [
            "signupCta",
            "{ label, href }",
            "CTA primário"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ]
        ],
        "example": "<Header\n    logo={<Wordmark>Infrastructure</Wordmark>}\n    navLinks={[\n        { label: 'Produtos', href: '#produtos' },\n        { label: 'Preço', href: '#preco' },\n    ]}\n    loginCta={{ label: 'Entrar', href: '/login' }}\n    signupCta={{ label: 'Criar conta', href: '/signup' }}\n/>"
      },
      {
        "name": "Hero",
        "job": "Primeira dobra. Texto à esquerda, mídia à direita (ou centralizado sem mídia).",
        "group": "Abertura",
        "props": [
          [
            "subtitle",
            "string",
            "Label uppercase"
          ],
          [
            "title",
            "string | ReactNode",
            "Aceita <br /> — envolva em .hide-mobile-br"
          ],
          [
            "description",
            "string",
            "Parágrafo de abertura"
          ],
          [
            "cta",
            "{ label, href, icon, size, variant, color, px }",
            "CTA principal"
          ],
          [
            "secondaryCta",
            "mesmo shape de cta",
            "Renderizado ao lado"
          ],
          [
            "note",
            "string",
            "Letra miúda sob os botões — o que custa experimentar"
          ],
          [
            "video",
            "{ src, filter, width }",
            ""
          ],
          [
            "image",
            "string",
            "Alternativa ao vídeo"
          ],
          [
            "mediaMaw",
            "string | number",
            "Max-width da mídia"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "titleFz",
            "string",
            "Default: 'var(--fz-hero)'"
          ],
          [
            "descriptionFz",
            "string",
            "Default: 'xl'"
          ]
        ],
        "example": "<Hero\n    subtitle=\"Infraestrutura em português\"\n    title={<>Login pronto<br />em uma tarde.</>}\n    description=\"Autenticação, sessões e permissões sem três semanas de trabalho.\"\n    cta={{ label: 'Começar grátis', href: '/signup', icon: <IconArrowRight size={18} /> }}\n    secondaryCta={{ label: 'Ver a documentação', href: '/docs', variant: 'outline' }}\n    note=\"Grátis até 1.000 usuários ativos. Sem cartão.\"\n    image=\"https://images.exemplo.com/auth.webp\"\n    mediaMaw={500}\n/>"
      },
      {
        "name": "SocialProof",
        "job": "Faixa densa de logos. Não usa palco — retorna null sem logos.",
        "group": "Abertura",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "title",
            "string",
            "Label acima dos logos"
          ],
          [
            "logos",
            "{ src, alt }[]",
            "Obrigatório"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ]
        ],
        "example": "<SocialProof\n    title=\"Quem já usa\"\n    logos={[\n        { src: '/logos/a.webp', alt: 'Empresa A' },\n        { src: '/logos/b.webp', alt: 'Empresa B' },\n    ]}\n/>"
      },
      {
        "name": "StatsGrid",
        "job": "Big Type Metrics em grade dividida por filete. Cada número carrega sua nota.",
        "group": "Prova",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "items",
            "{ value, label, description }[]",
            "description é a nota de verificação (Lei 5)"
          ],
          [
            "cols",
            "number",
            "Colunas a partir de lg. Default: 4"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ],
          [
            "note",
            "string",
            "Nota de rodapé sob a grade"
          ]
        ],
        "example": "<StatsGrid\n    subtitle=\"No ar agora\"\n    title=\"O que você confere sem falar com ninguém\"\n    items={[\n        { value: '4', label: 'Produtos no ar', description: 'Abra os quatro e teste' },\n        { value: '99,9%', label: 'Uptime', description: 'Medido nos últimos 90 dias' },\n    ]}\n    note=\"Todo número aqui é verificável em dois minutos.\"\n/>"
      },
      {
        "name": "Testimonials",
        "job": "Prova social com depoimentos e iniciais.",
        "group": "Prova",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "items",
            "{ quote, name, role, company }[]",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ]
        ],
        "example": "<Testimonials\n    subtitle=\"Quem já fez\"\n    title=\"O que dizem\"\n    items={[\n        { quote: 'Subimos em uma tarde.', name: 'Ana Souza', role: 'CTO', company: 'Acme' },\n    ]}\n/>"
      },
      {
        "name": "TrustBadge",
        "job": "Selo de confiança. Alias legado: SeloExclusivo.",
        "group": "Prova",
        "props": [
          [
            "text",
            "string",
            "Default: 'Selo Exclusivo'"
          ],
          [
            "color",
            "string",
            "Default: 'green.6'"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ]
        ],
        "example": "<TrustBadge text=\"Dados no Brasil\" />"
      },
      {
        "name": "FounderCard",
        "job": "Citação editorial do fundador, com credenciais como métricas.",
        "group": "Prova",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "avatar",
            "{ src, alt }",
            ""
          ],
          [
            "name",
            "string",
            ""
          ],
          [
            "role",
            "string",
            ""
          ],
          [
            "quote",
            "string",
            "A citação"
          ],
          [
            "credentials",
            "{ value, label }[]",
            "Credenciais em Big Type"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ]
        ],
        "example": "<FounderCard\n    subtitle=\"Quem responde\"\n    title=\"O suporte é quem escreveu o código\"\n    avatar={{ src: '/foto.webp', alt: 'Ciro Maciel' }}\n    name=\"Ciro Cesar Maciel\"\n    role=\"Fundador\"\n    quote=\"Se quebrar às duas da manhã, é o meu telefone que toca.\"\n    credentials={[{ value: '20+', label: 'Anos em sistemas críticos' }]}\n/>"
      },
      {
        "name": "FeatureSplit",
        "job": "Texto de um lado, mídia do outro. `reverse` inverte.",
        "group": "Explicação",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "featuresList",
            "string[]",
            "Lista com ícone de check"
          ],
          [
            "cta",
            "{ label, href, icon }",
            ""
          ],
          [
            "video",
            "{ src, filter, width }",
            ""
          ],
          [
            "image",
            "string",
            ""
          ],
          [
            "mediaMaw",
            "string | number",
            ""
          ],
          [
            "reverse",
            "boolean",
            "Inverte a ordem. Default: false"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ]
        ],
        "example": "<FeatureSplit\n    subtitle=\"Como funciona\"\n    title=\"Uma linha para proteger uma rota.\"\n    description=\"O middleware resolve sessão, refresh e permissão.\"\n    featuresList={['Sessões com refresh automático', 'RBAC por rota']}\n    image=\"https://images.exemplo.com/codigo.webp\"\n    reverse\n/>"
      },
      {
        "name": "FeaturesGrid",
        "job": "Grade assimétrica de recursos com visual dinâmico por item.",
        "group": "Explicação",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "badge",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "items",
            "{ label, title, description, visual, span }[]",
            "Ver shapes de `visual` abaixo"
          ],
          [
            "note",
            "string",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'left'"
          ]
        ],
        "nested": {
          "title": "Shapes de `visual` (5 tipos)",
          "rows": [
            [
              "type: 'metric'",
              "{ value, label, badge? }",
              "Número grande com rótulo"
            ],
            [
              "type: 'ring'",
              "{ value, label, sublabel?, size?, thickness? }",
              "Anel de progresso"
            ],
            [
              "type: 'bars'",
              "{ data: number[], highlight?, height? }",
              "Barras; `highlight` é o índice destacado"
            ],
            [
              "type: 'typography'",
              "{ text?, fontSize?, height? }",
              "Amostra tipográfica. Default: 'Aa'"
            ],
            [
              "type: 'icon-large'",
              "{ icon, size?, stroke? }",
              "Ícone Tabler grande"
            ]
          ]
        },
        "example": "<FeaturesGrid\n    subtitle=\"Por que usar\"\n    title=\"O essencial para publicar.\"\n    items={[\n        {\n            label: 'Config-driven',\n            title: 'Passe dados, não JSX',\n            description: 'Cinco linhas para uma seção inteira.',\n            visual: { type: 'metric', value: '5 linhas', label: 'por seção' },\n            span: { base: 12, md: 7 },\n        },\n        {\n            label: 'Performance',\n            title: 'Sem runtime extra',\n            description: 'Só Mantine e React.',\n            visual: { type: 'ring', value: 98, label: '98', sublabel: 'Lighthouse' },\n            span: { base: 12, md: 5 },\n        },\n    ]}\n/>"
      },
      {
        "name": "Steps",
        "job": "Processo numerado. O ordinal vira numeral fantasma de 120px atrás do card.",
        "group": "Explicação",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "badge",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "items",
            "{ number?, icon?, title, description }[]",
            "`number` cai para o índice se ausente"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ]
        ],
        "example": "<Steps\n    badge=\"Como funciona\"\n    title=\"Três passos. Zero atrito.\"\n    items={[\n        { number: '01', icon: IconCloudUpload, title: 'Você envia', description: 'Suba o projeto.' },\n        { number: '02', icon: IconSettings, title: 'A gente configura', description: 'Domínio e SSL.' },\n        { number: '03', icon: IconRocket, title: 'Está no ar', description: 'Em menos de dois minutos.' },\n    ]}\n/>"
      },
      {
        "name": "Callout",
        "job": "Card de declaração com leads em negrito e rodapé de honestidade.",
        "group": "Explicação",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "cardLabel",
            "string",
            "Label acima da lista"
          ],
          [
            "items",
            "{ lead, text }[]",
            "`lead` sai em negrito"
          ],
          [
            "footnote",
            "{ lead, text }",
            "O que ainda falta — a nota de honestidade"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ]
        ],
        "example": "<Callout\n    badge=\"Antes de qualquer coisa\"\n    title=\"Se a gente sumir amanhã, seu app continua de pé\"\n    cardLabel=\"O que isso quer dizer na prática\"\n    items={[{ lead: 'Padrões abertos.', text: 'Seus dados saem em formatos que outra ferramenta lê.' }]}\n    footnote={{ lead: 'O que ainda falta:', text: 'o export ainda não é um comando único.' }}\n/>"
      },
      {
        "name": "Comparison",
        "job": "Duas colunas: o jeito tradicional (com custo em red.6) contra o novo.",
        "group": "Decisão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "traditionalCol",
            "{ title, subtitle, items, totalLabel?, totalValue, footerText? }",
            "`items`: { label, value }[]"
          ],
          [
            "newCol",
            "{ title, badge?, description, items, pricingBox? }",
            "`items`: string[]"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ]
        ],
        "example": "<Comparison\n    subtitle=\"ROI do seu tempo\"\n    title=\"Construir do zero ou usar pronto\"\n    traditionalCol={{\n        title: 'Do zero',\n        subtitle: 'O caminho longo',\n        items: [{ label: 'Autenticação', value: '3 semanas' }],\n        totalValue: 'R$ 42.000',\n        footerText: 'Sem contar manutenção',\n    }}\n    newCol={{\n        title: 'Com o kit',\n        badge: 'RECOMENDADO',\n        description: 'Pronto para produção.',\n        items: ['Login em uma tarde', 'Suporte de quem escreveu'],\n        pricingBox: { label: 'Tempo até o ar', price: '30 min' },\n    }}\n/>"
      },
      {
        "name": "CriteriaList",
        "job": "Régua de comparação em coluna única: critério, resposta e a nota que a torna verificável.",
        "group": "Decisão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "items",
            "{ criterion, value, note, muted? }[]",
            "`muted: true` para \"ainda não medimos\""
          ],
          [
            "note",
            "string",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ]
        ],
        "example": "<CriteriaList\n    badge=\"A régua\"\n    title=\"Compare pelo que muda o seu dia\"\n    items={[\n        { criterion: 'Em que moeda você paga', value: 'Real', note: 'Sua fatura não muda porque o dólar mudou.' },\n        { criterion: 'Tempo de resposta', value: 'Ainda não medimos', note: 'Sem histórico suficiente.', muted: true },\n    ]}\n    note=\"Onde está escrito 'ainda não medimos', é porque ainda não medimos.\"\n/>"
      },
      {
        "name": "Pricing",
        "job": "Cards de planos com alternância mensal/anual controlada pelo consumidor.",
        "group": "Decisão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "badge",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "billingOptions",
            "{ label, value }[]",
            "Default: mensal/anual. `[]` remove o seletor"
          ],
          [
            "billing",
            "string",
            "Valor atual — estado do consumidor"
          ],
          [
            "setBilling",
            "function",
            "Setter do estado"
          ],
          [
            "promoBadge",
            "string",
            "Badge exibido quando billing === 'annual'"
          ],
          [
            "plans",
            "object[]",
            "Ver shape abaixo"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ]
        ],
        "nested": {
          "title": "Shape de `plans[]`",
          "rows": [
            [
              "name",
              "string",
              "Nome do plano"
            ],
            [
              "description",
              "string",
              "Uma linha"
            ],
            [
              "priceDisplay",
              "{ currency, whole, fraction }",
              "Preço numérico"
            ],
            [
              "priceText",
              "string",
              "Escape hatch: \"Sob consulta\" (ignora priceDisplay)"
            ],
            [
              "pricePrefix",
              "string | null",
              "Default: 'A partir de'. `null` remove"
            ],
            [
              "period",
              "string",
              "Ex.: '/mês'"
            ],
            [
              "priceNote",
              "string",
              "Nota sob o preço"
            ],
            [
              "features",
              "string[]",
              "Lista com check"
            ],
            [
              "highlight",
              "boolean",
              "Borda 2px gray.9"
            ],
            [
              "highlightBadge",
              "string",
              "Default: 'RECOMENDADO'"
            ],
            [
              "cta",
              "{ label, href, target, icon, variant, color, size }",
              ""
            ],
            [
              "note",
              "string",
              "Nota no rodapé do card"
            ]
          ]
        },
        "example": "const [billing, setBilling] = useState('monthly')\n\n<Pricing\n    subtitle=\"Preço\"\n    title=\"Escolha o tamanho\"\n    billing={billing}\n    setBilling={setBilling}\n    promoBadge=\"2 MESES GRÁTIS\"\n    plans={[\n        {\n            name: 'Pro',\n            description: 'Para times em produção.',\n            priceDisplay: { currency: 'R$', whole: '49', fraction: '90' },\n            period: '/mês',\n            features: ['Usuários ilimitados', 'Suporte em português'],\n            highlight: true,\n            cta: { label: 'Começar', href: '/signup' },\n        },\n        {\n            name: 'Enterprise',\n            description: 'Para quem precisa de contrato.',\n            priceText: 'Sob consulta',\n            pricePrefix: null,\n            features: ['SLA dedicado'],\n            cta: { label: 'Falar com vendas', href: '/contato' },\n        },\n    ]}\n/>"
      },
      {
        "name": "FAQ",
        "job": "Acordeão em duas colunas com card de contato. A numeração continua entre colunas.",
        "group": "Decisão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "badge",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "questions",
            "{ question, answer }[]",
            ""
          ],
          [
            "contactCard",
            "{ title, description, cta }",
            "Card lateral"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'left'"
          ]
        ],
        "example": "<FAQ\n    subtitle=\"Perguntas difíceis\"\n    title=\"O que costumam perguntar\"\n    questions={[\n        { question: 'Consigo exportar meus dados?', answer: 'Sim, em JSON e CSV, a qualquer momento.' },\n    ]}\n    contactCard={{\n        title: 'Ficou alguma dúvida?',\n        description: 'Responde quem escreveu o código.',\n        cta: { label: 'Falar no WhatsApp', href: 'https://wa.me/...' },\n    }}\n/>"
      },
      {
        "name": "ProductGrid",
        "job": "Catálogo de produtos, cada card com CTA de saída próprio.",
        "group": "Conversão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "items",
            "{ name, category, icon, headline, description, href, target, span }[]",
            "`icon` é o componente Tabler, não o elemento"
          ],
          [
            "ctaIcon",
            "ReactNode",
            "Ícone usado em todos os CTAs"
          ],
          [
            "note",
            "string",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'center'"
          ]
        ],
        "example": "<ProductGrid\n    badge=\"No ar agora\"\n    title=\"As quatro peças\"\n    ctaIcon={<IconArrowUpRight size={16} />}\n    items={[\n        {\n            name: 'Auth',\n            category: 'Login e sessões',\n            icon: IconLock,\n            headline: 'Três semanas de login, de novo.',\n            description: 'Autenticação pronta para produção.',\n            href: '/products/auth',\n            span: 7,\n        },\n    ]}\n/>"
      },
      {
        "name": "LeadForm",
        "job": "Captura de lead de baixo atrito que entrega a conversa ao WhatsApp.",
        "group": "Conversão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "badge",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "fields",
            "{ name, label, placeholder, type?, required?, span? }[]",
            "`span: 'full'` ocupa a linha"
          ],
          [
            "whatsappNumber",
            "string",
            "Só dígitos, com DDI"
          ],
          [
            "messageIntro",
            "string",
            "Default: 'Olá! Vim pelo site.'"
          ],
          [
            "submit",
            "{ label, icon }",
            "Config do botão"
          ],
          [
            "reassurance",
            "string",
            "Letra miúda sob o botão"
          ],
          [
            "onSubmit",
            "function",
            "Handler alternativo ao WhatsApp"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'. Um dos dois tons de palco"
          ]
        ],
        "example": "<LeadForm\n    badge=\"Contato\"\n    title=\"Conte o que você precisa\"\n    fields={[\n        { name: 'nome', label: 'Seu nome', placeholder: 'Como te chamamos', required: true },\n        { name: 'email', label: 'E-mail', type: 'email', required: true },\n        { name: 'msg', label: 'O que você precisa', span: 'full' },\n    ]}\n    whatsappNumber=\"5511986166966\"\n    submit={{ label: 'Enviar no WhatsApp' }}\n    reassurance=\"Responde quem escreveu o código, no mesmo dia.\"\n/>"
      },
      {
        "name": "CTABanner",
        "job": "Faixa final de conversão. Borda-topo de 4px — o único acento estrutural. Alias legado: SecondaryCTA.",
        "group": "Conversão",
        "props": [
          [
            "id",
            "string",
            ""
          ],
          [
            "subtitle",
            "string",
            ""
          ],
          [
            "title",
            "string",
            ""
          ],
          [
            "titleOrder",
            "number",
            "Default: 2. Use 1 quando for a única seção (404)"
          ],
          [
            "description",
            "string",
            ""
          ],
          [
            "featuresList",
            "string[]",
            "Lista entre descrição e CTA"
          ],
          [
            "featuresLabel",
            "string",
            "Lead-in em negrito acima da lista"
          ],
          [
            "cta",
            "{ label, href, icon, leftSection, target, size, variant, color, px }",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'gray'"
          ],
          [
            "ta",
            "'center' | 'left'",
            "Default: 'center'"
          ]
        ],
        "example": "<CTABanner\n    subtitle=\"Pronto para começar\"\n    title=\"Suba seu primeiro projeto hoje.\"\n    description=\"Grátis até 1.000 usuários. Sem cartão.\"\n    cta={{ label: 'Criar conta', href: '/signup', icon: <IconArrowRight size={18} /> }}\n/>"
      },
      {
        "name": "Footer",
        "job": "Rodapé com colunas de links e redes sociais.",
        "group": "Fechamento",
        "props": [
          [
            "logo",
            "{ src, alt, height } | ReactNode",
            ""
          ],
          [
            "description",
            "string | ReactNode",
            "Bloco à esquerda"
          ],
          [
            "sections",
            "{ title, links: { label, href, to? }[] }[]",
            "Colunas de links"
          ],
          [
            "socialLinks",
            "{ href, label, icon }[]",
            ""
          ],
          [
            "copyrightText",
            "string",
            ""
          ],
          [
            "madeByText",
            "string",
            ""
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ]
        ],
        "example": "<Footer\n    logo={{ src: '/logo.webp', alt: 'Infrastructure', height: 28 }}\n    description=\"Infraestrutura em português para quem constrói produto brasileiro.\"\n    sections={[\n        { title: 'Produtos', links: [{ label: 'Auth', href: '/products/auth' }] },\n    ]}\n    socialLinks={[\n        { href: 'https://github.com/...', label: 'GitHub', icon: <IconBrandGithub size={18} stroke={1.5} /> },\n    ]}\n    copyrightText={`© ${new Date().getFullYear()} Infrastructure.`}\n    background=\"gray\"\n/>"
      },
      {
        "name": "LegalPrivacy",
        "job": "Política de privacidade completa em português (LGPD).",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'Infrastructure'. A marca — é a voz do documento"
          ],
          [
            "legalEntity",
            "string",
            "Razão social + CNPJ. Só nas cláusulas que identificam a parte. Default: companyName"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ]
        ],
        "example": "<LegalPrivacy\n    companyName=\"Acme\"\n    legalEntity=\"Acme Tecnologia LTDA (CNPJ 00.000.000/0001-00)\"\n    productName=\"o Acme Cloud\"\n/>"
      },
      {
        "name": "LegalTerms",
        "job": "Termos de uso e licenciamento (EULA).",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'Infrastructure'. A marca — é a voz do documento"
          ],
          [
            "legalEntity",
            "string",
            "Razão social + CNPJ. Só nas cláusulas que identificam a parte. Default: companyName"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ],
          [
            "lastUpdated",
            "string",
            "Data da última revisão DO TEXTO, por extenso. Default: '20 de setembro de 2026'"
          ]
        ],
        "example": "<LegalTerms\n    companyName=\"Acme\"\n    legalEntity=\"Acme Tecnologia LTDA (CNPJ 00.000.000/0001-00)\"\n    productName=\"o Acme Cloud\"\n    lastUpdated=\"20 de setembro de 2026\"\n/>"
      },
      {
        "name": "LegalSecurity",
        "job": "Protocolos de segurança e infraestrutura.",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'Infrastructure'. A marca — é a voz do documento"
          ],
          [
            "legalEntity",
            "string",
            "Razão social + CNPJ. Só nas cláusulas que identificam a parte. Default: companyName"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ]
        ],
        "example": "<LegalSecurity\n    companyName=\"Acme\"\n    legalEntity=\"Acme Tecnologia LTDA (CNPJ 00.000.000/0001-00)\"\n    productName=\"o Acme Cloud\"\n/>"
      }
    ],
    "PITFALLS": [
      {
        "wrong": "import { theme } from './meu-theme'",
        "right": "import { theme } from '@ciromaciel/components-kit'",
        "why": "O theme do kit já traz paleta, tipografia e defaults. Redefinir no consumidor cria um segundo sistema."
      },
      {
        "wrong": "<Section><Container><Stack>…</Stack></Container></Section>",
        "right": "<Section>…</Section>",
        "why": "Section já é Box + Container + Stack. Aninhar outro Container dobra o padding e quebra a largura."
      },
      {
        "wrong": "items={[{ icon: <IconLock /> }]}",
        "right": "items={[{ icon: IconLock }]}",
        "why": "Steps e ProductGrid recebem o componente e o instanciam com o tamanho certo. Um elemento pronto ignora o dimensionamento."
      },
      {
        "wrong": "<Hero title={<>Linha um<br />Linha dois</>} />",
        "right": "<Hero title={<span className=\"hide-mobile-br\">Linha um<br />Linha dois</span>} />",
        "why": "Sem a classe, a quebra manual persiste no celular e corta a frase em lugar errado."
      },
      {
        "wrong": "<StatsGrid items={[{ value: \"99,9%\", label: \"Uptime\" }]} />",
        "right": "<StatsGrid items={[{ value: \"99,9%\", label: \"Uptime\", description: \"Medido nos últimos 90 dias\" }]} />",
        "why": "Lei 5: número forte sem nota de verificação é propaganda, não design."
      },
      {
        "wrong": "<Hero background=\"white\" /><StatsGrid background=\"white\" />",
        "right": "<Hero background=\"white\" /><StatsGrid background=\"gray\" />",
        "why": "Palcos consecutivos alternam. Dois brancos seguidos apagam o ritmo do scroll."
      },
      {
        "wrong": "<Text c=\"gray.9\">parágrafo longo…</Text>",
        "right": "<Text c=\"gray.6\">parágrafo longo…</Text>",
        "why": "Corpo em preto absoluto achata a hierarquia — o título deixa de liderar."
      },
      {
        "wrong": "<Paper radius=\"md\" shadow=\"sm\">",
        "right": "<Paper radius=\"0\" bd=\"1px solid var(--mantine-color-gray-2)\">",
        "why": "Raio e sombra são cromo sem informação. A delimitação é o filete de 1px."
      },
      {
        "wrong": "<Pricing plans={plans} />",
        "right": "const [billing, setBilling] = useState(\"monthly\")\n<Pricing billing={billing} setBilling={setBilling} plans={plans} />",
        "why": "O seletor mensal/anual é controlado. Sem o par billing/setBilling ele trava."
      },
      {
        "wrong": "<FeaturesGrid items={[{ visual: { type: \"chart\" } }]} />",
        "right": "<FeaturesGrid items={[{ visual: { type: \"bars\", data: [40, 70, 100] } }]} />",
        "why": "Só existem cinco tipos: metric, ring, bars, typography, icon-large. Um tipo desconhecido não renderiza nada."
      }
    ],
    "PRIMITIVES": [
      {
        "name": "Section",
        "job": "O palco. Envolve qualquer seção com fundo, respiro e cabeçalho.",
        "props": [
          [
            "children",
            "ReactNode",
            "Conteúdo — a performance"
          ],
          [
            "badge",
            "string",
            "Selo pontilhado acima do label"
          ],
          [
            "title",
            "string | ReactNode",
            "Título massivo"
          ],
          [
            "subtitle",
            "string | ReactNode",
            "Label uppercase — o anúncio"
          ],
          [
            "id",
            "string",
            "Âncora de scroll"
          ],
          [
            "background",
            "'white' | 'gray'",
            "Default: 'white'"
          ],
          [
            "py",
            "number | object",
            "Default: { base: 80, md: 120 }"
          ],
          [
            "maw",
            "number",
            "Max-width do título. Default: 800"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'left'"
          ],
          [
            "stackGap",
            "string",
            "Default: 'xl'"
          ]
        ],
        "example": "<Section\n    id=\"beneficios\"\n    badge=\"No ar agora\"\n    subtitle=\"Por que usar\"\n    title=\"O essencial para publicar.\"\n    background=\"gray\"\n>\n    {/* conteúdo */}\n</Section>"
      },
      {
        "name": "SectionHeader",
        "job": "O par canônico: label leve + título pesado.",
        "props": [
          [
            "badge",
            "string",
            "Selo pontilhado"
          ],
          [
            "subtitle",
            "string | ReactNode",
            "Label uppercase"
          ],
          [
            "title",
            "string | ReactNode",
            "Título"
          ],
          [
            "titleOrder",
            "number",
            "Nível do heading. Default: 2"
          ],
          [
            "titleFz",
            "string",
            "Default: 'var(--fz-section-title)'"
          ],
          [
            "ta",
            "'left' | 'center'",
            "Default: 'left'"
          ],
          [
            "maw",
            "number",
            "Max-width do título"
          ]
        ],
        "example": "<SectionHeader\n    subtitle=\"Prova verificável\"\n    title=\"Números que você pode conferir.\"\n    maw={800}\n/>"
      },
      {
        "name": "CTAButton",
        "job": "Botão padronizado. Vira <a> com href, <button> com onClick.",
        "props": [
          [
            "label",
            "string",
            "Texto do botão"
          ],
          [
            "href",
            "string",
            "URL — renderiza como <a>"
          ],
          [
            "onClick",
            "function",
            "Handler — renderiza como <button>"
          ],
          [
            "icon",
            "ReactNode",
            "Ícone à direita (rightSection)"
          ],
          [
            "leftSection",
            "ReactNode",
            "Ícone à esquerda"
          ],
          [
            "size",
            "string",
            "Default: 'lg'"
          ],
          [
            "variant",
            "string",
            "Default: 'filled'"
          ],
          [
            "color",
            "string",
            "Default: gray.9 (via theme)"
          ],
          [
            "target",
            "string",
            "'_blank' para link externo"
          ],
          [
            "px",
            "number | object",
            "Padding horizontal"
          ],
          [
            "fullWidth",
            "boolean",
            "Ocupa a largura do container"
          ]
        ],
        "example": "<CTAButton\n    label=\"Começar agora\"\n    href=\"/signup\"\n    icon={<IconArrowRight size={18} stroke={1.5} />}\n/>"
      },
      {
        "name": "MediaBlock",
        "job": "Vídeo ou imagem com a11y consistente.",
        "props": [
          [
            "video",
            "{ src, width, filter }",
            "Autoplay, loop, muted, playsInline"
          ],
          [
            "image",
            "string",
            "src da imagem (fallback quando não há vídeo)"
          ],
          [
            "width",
            "string",
            "Default: '100%'"
          ],
          [
            "maw",
            "string | number",
            "Max-width"
          ],
          [
            "alt",
            "string",
            "Alt da imagem / aria-label do vídeo"
          ]
        ],
        "example": "<MediaBlock\n    image=\"https://images.exemplo.com/dashboard.webp\"\n    alt=\"Painel de controle\"\n    maw={500}\n/>"
      },
      {
        "name": "Logotype",
        "job": "O logotipo das linhas: raio, palavra e \"by Ciro Cesar Maciel\". A assinatura tem tamanho fixo (11px no cabeçalho de 40px, 0,42 da palavra no grande) e começa onde a palavra começa; nunca estica até a largura da palavra.",
        "props": [
          [
            "word",
            "string",
            "A linha: \"Infrastructure\", \"Cleaner\""
          ],
          [
            "height",
            "number",
            "Altura do conjunto. Default: 40 (cabeçalho e rodapé)"
          ],
          [
            "signature",
            "string | null",
            "Default: 'by Ciro Cesar Maciel'. `null` no logotipo da raiz, o nome do Ciro: quem assina é o nome"
          ]
        ],
        "example": "<Logotype word=\"Infrastructure\" />"
      },
      {
        "name": "Wordmark",
        "job": "Logo em texto, para produtos sem logotipo em imagem.",
        "props": [
          [
            "children",
            "ReactNode",
            "O nome da marca"
          ],
          [
            "fz",
            "number",
            "Default: 28"
          ],
          [
            "c",
            "string",
            "Default: 'gray.9'"
          ]
        ],
        "example": "<Header logo={<Wordmark>Auth</Wordmark>} />"
      },
      {
        "name": "BrandLogo",
        "job": "Resolve a prop `logo` de Header/Footer: aceita objeto ou nó React.",
        "props": [
          [
            "logo",
            "{ src, alt, height } | ReactNode",
            "Imagem ou wordmark"
          ],
          [
            "objectPosition",
            "string",
            "Default: 'left'"
          ]
        ],
        "example": "<BrandLogo logo={{ src: '/logo.webp', alt: 'Infrastructure', height: 32 }} />"
      }
    ],
    "RECIPES": [
      {
        "name": "Landing page completa",
        "when": "Página de produto ou serviço, do topo ao rodapé.",
        "code": "import { useState } from 'react'\nimport { IconArrowRight, IconLock, IconRocket, IconSettings } from '@tabler/icons-react'\nimport {\n    Layout, Header, Hero, SocialProof, StatsGrid, FeatureSplit,\n    Steps, Comparison, Pricing, Testimonials, FAQ, CTABanner, Footer, Wordmark,\n} from '@ciromaciel/components-kit'\n\nexport default function LandingPage() {\n    const [billing, setBilling] = useState('monthly')\n\n    return (\n        <Layout>\n            <Header\n                logo={<Wordmark>Acme</Wordmark>}\n                navLinks={[{ label: 'Preço', href: '#preco' }]}\n                signupCta={{ label: 'Criar conta', href: '/signup' }}\n            />\n\n            <main style={{ flex: 1 }}>\n                {/* Palcos alternam white ↔ gray, sempre */}\n                <Hero\n                    background=\"white\"\n                    subtitle=\"Infraestrutura em português\"\n                    title={<>Login pronto<br />em uma tarde.</>}\n                    description=\"Autenticação, sessões e permissões sem três semanas de trabalho.\"\n                    cta={{ label: 'Começar grátis', href: '/signup', icon: <IconArrowRight size={18} /> }}\n                    note=\"Grátis até 1.000 usuários ativos. Sem cartão.\"\n                />\n\n                <SocialProof title=\"Quem já usa\" logos={[{ src: '/a.webp', alt: 'A' }]} />\n\n                {/* Prova antes de preço */}\n                <StatsGrid\n                    background=\"gray\"\n                    subtitle=\"No ar agora\"\n                    title=\"O que você confere sem falar com ninguém\"\n                    items={[\n                        { value: '99,9%', label: 'Uptime', description: 'Medido nos últimos 90 dias' },\n                        { value: '<200ms', label: 'Latência p95', description: 'Do Brasil, medido de fora' },\n                    ]}\n                    note=\"Todo número aqui é verificável em dois minutos.\"\n                />\n\n                <FeatureSplit\n                    background=\"white\"\n                    subtitle=\"Como funciona\"\n                    title=\"Uma linha para proteger uma rota.\"\n                    featuresList={['Sessões com refresh automático', 'RBAC por rota']}\n                    image=\"/codigo.webp\"\n                />\n\n                <Steps\n                    background=\"gray\"\n                    badge=\"Como funciona\"\n                    title=\"Três passos. Zero atrito.\"\n                    items={[\n                        { number: '01', icon: IconLock, title: 'Instale', description: 'Um comando.' },\n                        { number: '02', icon: IconSettings, title: 'Configure', description: 'Um arquivo.' },\n                        { number: '03', icon: IconRocket, title: 'No ar', description: 'Menos de dois minutos.' },\n                    ]}\n                />\n\n                <Comparison\n                    background=\"white\"\n                    subtitle=\"ROI do seu tempo\"\n                    traditionalCol={{\n                        title: 'Do zero', subtitle: 'O caminho longo',\n                        items: [{ label: 'Autenticação', value: '3 semanas' }],\n                        totalValue: 'R$ 42.000', footerText: 'Sem contar manutenção',\n                    }}\n                    newCol={{\n                        title: 'Com o kit', badge: 'RECOMENDADO',\n                        description: 'Pronto para produção.',\n                        items: ['Login em uma tarde'],\n                        pricingBox: { label: 'Tempo até o ar', price: '30 min' },\n                    }}\n                />\n\n                <Pricing\n                    background=\"gray\"\n                    subtitle=\"Preço\"\n                    billing={billing}\n                    setBilling={setBilling}\n                    plans={[{\n                        name: 'Pro',\n                        description: 'Para times em produção.',\n                        priceDisplay: { currency: 'R$', whole: '49', fraction: '90' },\n                        period: '/mês',\n                        features: ['Usuários ilimitados'],\n                        highlight: true,\n                        cta: { label: 'Começar', href: '/signup' },\n                    }]}\n                />\n\n                <Testimonials\n                    background=\"white\"\n                    subtitle=\"Quem já fez\"\n                    items={[{ quote: 'Subimos em uma tarde.', name: 'Ana', role: 'CTO', company: 'Acme' }]}\n                />\n\n                <FAQ\n                    background=\"gray\"\n                    subtitle=\"Perguntas difíceis\"\n                    questions={[{ question: 'Consigo exportar?', answer: 'Sim, JSON e CSV.' }]}\n                />\n\n                {/* CTABanner sempre fecha */}\n                <CTABanner\n                    background=\"white\"\n                    subtitle=\"Pronto para começar\"\n                    title=\"Suba seu primeiro projeto hoje.\"\n                    cta={{ label: 'Criar conta', href: '/signup', icon: <IconArrowRight size={18} /> }}\n                />\n            </main>\n\n            <Footer\n                background=\"gray\"\n                description=\"Infraestrutura em português.\"\n                sections={[{ title: 'Produto', links: [{ label: 'Preço', href: '#preco' }] }]}\n                copyrightText={`© ${new Date().getFullYear()} Acme.`}\n            />\n        </Layout>\n    )\n}"
      },
      {
        "name": "Tela de painel completa",
        "when": "Lista de dados numa aplicação: cabeçalho, busca, filtros, tabela, estados. É a receita para qualquer tela de dashboard.",
        "code": "import { useMemo, useState } from 'react'\nimport { Box, Card, Group, Skeleton, Stack, Text, Title } from '@mantine/core'\nimport { IconPlus, IconSearch } from '@tabler/icons-react'\n\nconst COLS = '2.4fr 1fr 1fr 40px'   // fr para conteúdo, px fixo para ações\nconst HEAD = { fz: 10, fw: 800, c: 'gray.5', tt: 'uppercase', lts: '1.5px' }\n\nexport default function InvoicesPage({ invoices = [], loading, onOpen, onCreate }) {\n    const [term, setTerm] = useState('')\n\n    const rows = useMemo(() => {\n        const q = term.trim().toLowerCase()\n        if (!q) return invoices\n        return invoices.filter(i => i.number.toLowerCase().includes(q) || i.customer.toLowerCase().includes(q))\n    }, [invoices, term])\n\n    return (\n        <Box px={48} pt={40} pb={80} maw={1280} mx=\"auto\">\n            {/* Cabeçalho: crumb + título + subtítulo, ações à direita */}\n            <Group justify=\"space-between\" align=\"flex-start\" wrap=\"nowrap\" gap={24} mb={32}>\n                <Stack gap={8} flex={1} miw={0}>\n                    <Text fz={10} fw={800} c=\"gray.4\" tt=\"uppercase\" lts=\"1.5px\">\n                        + Acme · Produção · Faturas\n                    </Text>\n                    <Title order={1} fz={36} fw={900} lh={1} lts=\"-0.04em\">Faturas</Title>\n                    <Text fz={15} fw={500} c=\"gray.6\" lh={1.5}>\n                        Tudo o que foi cobrado nesta aplicação.\n                    </Text>\n                </Stack>\n                <Group gap=\"md\" wrap=\"nowrap\" flex=\"none\">\n                    <Box\n                        component=\"button\"\n                        onClick={onCreate}\n                        px=\"md\" py={8} bg=\"gray.9\" c=\"white\" fz={12} fw={800} tt=\"uppercase\"\n                        style={{ letterSpacing: '1px', border: 'none', borderRadius: 0, cursor: 'pointer' }}\n                    >\n                        Nova fatura\n                    </Box>\n                </Group>\n            </Group>\n\n            <Card p={0} withBorder radius=\"0\" style={{ overflow: 'hidden' }}>\n                {/* Busca local — filtra a lista desta tela */}\n                <Group px=\"md\" py=\"sm\" justify=\"space-between\" wrap=\"nowrap\"\n                    style={{ borderBottom: '1px solid var(--mantine-color-gray-2)' }}>\n                    <Group gap=\"xs\" wrap=\"nowrap\" flex={1} px=\"sm\" py={6}\n                        style={{ border: '1px solid var(--mantine-color-gray-2)', borderRadius: 0 }}>\n                        <IconSearch size={16} stroke={1.5} color=\"var(--mantine-color-gray-4)\" />\n                        <Box\n                            component=\"input\"\n                            value={term}\n                            onChange={e => setTerm(e.currentTarget.value)}\n                            onKeyDown={e => e.key === 'Escape' && setTerm('')}\n                            placeholder=\"Buscar por número ou cliente…\"\n                            style={{ border: 'none', outline: 'none', background: 'transparent',\n                                fontFamily: 'inherit', fontSize: 13, width: '100%' }}\n                        />\n                    </Group>\n                    <Text fz={11} fw={800} c=\"gray.4\" tt=\"uppercase\" lts=\"1.5px\" style={{ flexShrink: 0 }}>\n                        {rows.length} {rows.length === 1 ? 'fatura' : 'faturas'}\n                    </Text>\n                </Group>\n\n                {/* Header da tabela */}\n                <Box bg=\"gray.1\" style={{ display: 'grid', gridTemplateColumns: COLS, gap: 12,\n                    alignItems: 'center', padding: '12px 24px',\n                    borderBottom: '1px solid var(--mantine-color-gray-2)' }}>\n                    <Text {...HEAD}>Fatura</Text>\n                    <Text {...HEAD}>Status</Text>\n                    <Text {...HEAD}>Valor</Text>\n                    <Box />\n                </Box>\n\n                {/* Carregando: o skeleton tem a MESMA grade da tabela */}\n                {loading && rows.length === 0 &&\n                    Array.from({ length: 5 }, (_, i) => (\n                        <Box key={i} style={{ display: 'grid', gridTemplateColumns: COLS, gap: 12,\n                            alignItems: 'center', padding: '14px 24px',\n                            borderBottom: '1px solid var(--mantine-color-gray-2)' }}>\n                            <Skeleton height={14} width=\"60%\" radius=\"0\" />\n                            <Skeleton height={14} width=\"50%\" radius=\"0\" />\n                            <Skeleton height={14} width=\"40%\" radius=\"0\" />\n                            <Box />\n                        </Box>\n                    ))}\n\n                {/* Vazio: label uppercase + subtítulo, citando o termo quando houver */}\n                {!loading && rows.length === 0 && (\n                    <Stack align=\"center\" gap={8} py={56}>\n                        <Text fz={10} fw={800} c=\"gray.4\" tt=\"uppercase\" lts=\"1.5px\">\n                            {term ? 'Nenhum resultado' : 'Sem faturas'}\n                        </Text>\n                        <Text fz={12} c=\"gray.5\" fs=\"italic\">\n                            {term ? `Nada encontrado para «${term}».` : 'Nada foi cobrado ainda.'}\n                        </Text>\n                    </Stack>\n                )}\n\n                {/* Linhas: a linha inteira é clicável; texto é o papel \"dado\" */}\n                {rows.map((row, i) => (\n                    <Box\n                        key={row.id}\n                        onClick={() => onOpen(row)}\n                        style={{ display: 'grid', gridTemplateColumns: COLS, gap: 12,\n                            alignItems: 'center', padding: '14px 24px', cursor: 'pointer',\n                            transition: 'background 120ms ease',\n                            borderBottom: i === rows.length - 1 ? 'none'\n                                : '1px solid var(--mantine-color-gray-2)' }}\n                        onMouseEnter={e => (e.currentTarget.style.background = 'var(--mantine-color-gray-1)')}\n                        onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}\n                    >\n                        <Box miw={0}>\n                            <Text fz={13} fw={700} c=\"gray.9\" lineClamp={1}>{row.number}</Text>\n                            <Text fz={12} c=\"gray.5\" lineClamp={1}>{row.customer}</Text>\n                        </Box>\n                        <Text fz={13} c=\"gray.7\">{row.status}</Text>\n                        <Text fz={13} c=\"gray.7\" ff=\"monospace\">{row.amount}</Text>\n                        <Text fz={13} c=\"gray.5\" ta=\"center\" aria-hidden>⋯</Text>\n                    </Box>\n                ))}\n            </Card>\n        </Box>\n    )\n}"
      },
      {
        "name": "Página 404",
        "when": "O CTABanner é a única seção — por isso titleOrder={1}.",
        "code": "import { CTABanner } from '@ciromaciel/components-kit'\nimport { IconArrowLeft } from '@tabler/icons-react'\n\nexport default function NotFoundPage() {\n    return (\n        <CTABanner\n            titleOrder={1}\n            subtitle=\"Erro 404\"\n            title=\"Esta página não existe.\"\n            description=\"O link pode ter mudado de lugar.\"\n            cta={{ label: 'Voltar ao início', href: '/', leftSection: <IconArrowLeft size={18} /> }}\n        />\n    )\n}"
      },
      {
        "name": "Página legal",
        "when": "Privacidade, termos ou segurança — container md, leitura contínua.",
        "code": "import { LegalPrivacy } from '@ciromaciel/components-kit'\n\nexport default function PrivacyPage() {\n    return <LegalPrivacy companyName=\"Acme Ltda\" productName=\"o Acme Cloud\" />\n}"
      },
      {
        "name": "Seção customizada",
        "when": "O vocabulário não cobre o caso. Envolva Section — nunca refaça o palco.",
        "code": "import { Box, SimpleGrid, Text } from '@mantine/core'\nimport { Section, CTAButton } from '@ciromaciel/components-kit'\n\nexport function IntegrationsGrid({ id, subtitle, title, items = [], cta, note, background = 'white' }) {\n    return (\n        <Section id={id} subtitle={subtitle} title={title} background={background}>\n            <SimpleGrid cols={{ base: 1, md: 3 }} spacing=\"xl\">\n                {items.map((item, i) => (\n                    <Box key={item.title || i}>\n                        <Text fz=\"lg\" fw={800} c=\"gray.9\" mb=\"xs\">{item.title}</Text>\n                        <Text c=\"gray.6\" lh={1.7}>{item.description}</Text>\n                    </Box>\n                ))}\n            </SimpleGrid>\n            {cta && <CTAButton {...cta} />}\n            {note && <Text size=\"sm\" c=\"gray.6\" mt={40}>{note}</Text>}\n        </Section>\n    )\n}"
      }
    ],
    "SETUP": {
      "install": "bun add @ciromaciel/components-kit @mantine/core @mantine/hooks @tabler/icons-react",
      "peerDeps": {
        "@mantine/core": "^7.0.0 || ^8.0.0",
        "@mantine/hooks": "^7.0.0 || ^8.0.0",
        "@tabler/icons-react": "^3.0.0",
        "react": "^18.0.0 || ^19.0.0",
        "react-dom": "^18.0.0 || ^19.0.0"
      },
      "entry": "import '@mantine/core/styles.css'\nimport '@ciromaciel/components-kit/style.css'\n\nimport { MantineProvider } from '@mantine/core'\nimport { theme } from '@ciromaciel/components-kit'\n\nexport default function App() {\n    return (\n        <MantineProvider theme={theme} defaultColorScheme=\"auto\">\n            {/* suas rotas */}\n        </MantineProvider>\n    )\n}",
      "note": "O theme exportado pelo kit já carrega toda a paleta, tipografia e defaults de componente. Não redefina tokens no consumidor — se um valor precisa mudar, ele muda no kit."
    }
  }
}