{
  "meta": {
    "name": "RiLiGar Zen",
    "version": "1.0.0",
    "source": "@riligar/components-kit",
    "docs": "website/branding/",
    "componentCount": 24,
    "primitiveCount": 6
  },
  "tokens": {
    "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 em perda quantificada)",
          "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}, ls=\"1px\"",
          "Í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"
        ]
      }
    ],
    "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_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
      }
    ],
    "DESTRUCTIVE": {
      "holdMs": 3000,
      "tickMs": 50,
      "feedback": "RingProgress thickness 2 sobre o ícone",
      "cancel": "onMouseUp · onMouseLeave · onTouchEnd",
      "variants": "ícone (tabela) · texto com contagem regressiva (formulário)",
      "escalation": "Impacto irreversível e amplo → Modal dedicado listando o que será perdido"
    },
    "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"
      }
    ],
    "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"
      },
      {
        "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 RiLiGar",
        "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": "RiLiGar Zen",
      "version": "1.0.0",
      "source": "@riligar/components-kit",
      "docs": "website/branding/",
      "componentCount": 24,
      "primitiveCount": 6
    },
    "MOTION": {
      "transition": "transform 0.2s ease, filter 0.2s ease",
      "transform": "translateY(-1px)",
      "filter": "brightness(1.1)"
    },
    "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."
      }
    ],
    "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": "white",
        "hex": "#FFFFFF",
        "usage": "Palco padrão"
      },
      {
        "name": "surfaceAlt",
        "token": "gray.1",
        "hex": "#F9FAFB",
        "usage": "Palco alternado"
      }
    ],
    "SIDEBAR_SPEC": [
      {
        "part": "largura",
        "spec": "300px expandida · 64px colapsada"
      },
      {
        "part": "superfície",
        "spec": "bg white · borderRight 1px gray.2"
      },
      {
        "part": "marca",
        "spec": "Wordmark 28px no topo"
      },
      {
        "part": "contexto",
        "spec": "Switcher org → aplicação em Popover, com busca própria"
      },
      {
        "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 branco · fw 800"
      },
      {
        "part": "item inativo",
        "spec": "transparente · gray.7 · fw 500"
      },
      {
        "part": "rodapé",
        "spec": "Docs, suporte e conta, 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."
      }
    ],
    "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": "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>RiLiGar</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 RiLiGar'"
          ],
          [
            "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: 'https://auth.riligar.click/',\n            target: '_blank',\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"
          ]
        ],
        "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: 'RiLiGar', height: 28 }}\n    description=\"Infraestrutura em português para quem constrói produto brasileiro.\"\n    sections={[\n        { title: 'Produtos', links: [{ label: 'Auth', href: 'https://auth.riligar.click/' }] },\n    ]}\n    socialLinks={[\n        { href: 'https://github.com/...', label: 'GitHub', icon: <IconBrandGithub size={18} stroke={1.5} /> },\n    ]}\n    copyrightText={`© ${new Date().getFullYear()} RiLiGar.`}\n    background=\"gray\"\n/>"
      },
      {
        "name": "LegalPrivacy",
        "job": "Política de privacidade completa em português (LGPD).",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'RiLiGar'"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ]
        ],
        "example": "<LegalPrivacy companyName=\"Acme Ltda\" productName=\"o Acme Cloud\" />"
      },
      {
        "name": "LegalTerms",
        "job": "Termos de uso e licenciamento (EULA).",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'RiLiGar'"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ]
        ],
        "example": "<LegalTerms companyName=\"Acme Ltda\" productName=\"o Acme Cloud\" />"
      },
      {
        "name": "LegalSecurity",
        "job": "Protocolos de segurança e infraestrutura.",
        "group": "Fechamento",
        "props": [
          [
            "companyName",
            "string",
            "Default: 'RiLiGar'"
          ],
          [
            "productName",
            "string",
            "Default: 'nossos produtos'"
          ]
        ],
        "example": "<LegalSecurity companyName=\"Acme Ltda\" productName=\"o Acme Cloud\" />"
      }
    ],
    "PITFALLS": [
      {
        "wrong": "import { theme } from './meu-theme'",
        "right": "import { theme } from '@riligar/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": "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: 'RiLiGar', 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 '@riligar/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', ls: '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\" ls=\"1.5px\">\n                        + Acme · Produção · Faturas\n                    </Text>\n                    <Title order={1} fz={36} fw={900} lh={1} ls=\"-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\" ls=\"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\" ls=\"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 '@riligar/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 '@riligar/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 '@riligar/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 @riligar/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 '@riligar/components-kit/style.css'\n\nimport { MantineProvider } from '@mantine/core'\nimport { theme } from '@riligar/components-kit'\n\nexport default function App() {\n    return (\n        <MantineProvider theme={theme} defaultColorScheme=\"light\">\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."
    }
  }
}