/* ============================================================================
   SHVIA-SITE — sistema visual da landing (shvia.org)
   ----------------------------------------------------------------------------
   Carregue SEMPRE depois de tokens.css: aqui não existe cor literal. Nenhum
   `#hex`, nenhum `rgb()`, nenhum `rgba(255,255,255,.06)` — só `var(--token)` e
   `color-mix()` sobre tokens. Motivo prático (e não estético): o vidro branco e
   o cinza cravado SOMEM nos presets claros (paper/sépia), e o site herda os 10
   temas do app pelo cookie `shvia_theme`. O harness em tests/ falha o build se
   aparecer cor literal fora de comentário, e checa contraste 4.5:1 nos 10
   presets com o fundo real composto.

   ── Redesign 2.0 (25/07) · "o instrumento liga" ──────────────────────────────
   A primeira versão era um painel correto e mudo. Esta tem LUZ, ORDEM DE
   ENTRADA e um objeto que se lembra. O que mudou e por quê:

     • ATMOSFERA (.atmo/.grain) — glow da marca + retícula blueprint + grão.
       Profundidade sem gradiente decorativo colorido: é a luz do aparelho, não
       enfeite. Tudo em camada fixa atrás, `pointer-events: none`.
     • BOOT (.boot-*) — a página LIGA: leitura → título → tese → porta, em
       cascata de 80ms. Só transform (ver a regra do tokens.css: animação que
       usa opacity deixa conteúdo invisível para sempre num renderizador que
       congela em t=0).
     • TRILHO (.rail) — substitui o §NN repetido em toda seção. Índice de
       instrumento com tiques; o ativo acende conforme se rola. Índice virou
       instrumento de navegação em vez de enfeite tipográfico.
     • RECIBO (.receipt) — a assinatura da página. O produto é "o gateway que
       mostra a conta"; então a conta aparece como conta, com serrilha, filete
       tracejado e total. É o objeto que a pessoa vai lembrar.
     • PORTA (.door) — acende a moldura inteira no `:focus-within`. O foco é
       estado, e estado se mostra.

   O que continua proibido (PRODUCT.md → Anti-references): grade de cards
   idênticos, eyebrow minúscula em toda seção, gradiente decorativo, animação
   que chama atenção para si mesma.

   ── Redesign 3.0 (30/07) · "o espaço-tempo" ─────────────────────────────────
   A retícula chapada de blueprint virou MALHA DE ESPAÇO-TEMPO: a mesma grade,
   agora deformada por dois poços nas posições dos glows — a massa que ilumina
   é a massa que curva (geometria em bin/gerar-malha.py, cor aqui). E a página
   ganhou as seções do que o gateway passou a fazer: FAIXA de números contáveis
   (.band), COMBOS com fallback pré-1º-token (.combo), ECONOMIA de tokens
   (.saver) e APONTE SEU CLI (.steps/.term). Ver docs/decisoes.md → ADR-013.
   ============================================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--tx);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.58;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;   /* a atmosfera é fixa e sangra; a página não rola de lado */
}

:root {
    --wrap: 1200px;                    /* largura do painel */
    --gut: clamp(18px, 4vw, 32px);     /* respiro lateral */
    --hair: 1px;                       /* filete do aparelho */

    /* Escala z semântica — nada de 999 espalhado pelo arquivo. */
    --z-atmo: 0;
    --z-grain: 1;
    --z-page: 2;
    --z-rail: 20;
    --z-topbar: 30;
    --z-skip: 40;
}

img, svg { max-width: 100%; }

a { color: var(--azure-strong); }

code {
    font-family: var(--font-mono);
    font-size: 0.92em;
    color: var(--tx);
    background: var(--bg-3);
    border: var(--hair) solid var(--line);
    border-radius: 6px;
    padding: 0.08em 0.38em;
}

/* Foco de teclado: um só tratamento, visível em qualquer preset. */
a:focus-visible,
button:focus-visible,
select:focus-visible,
summary:focus-visible,
input:focus-visible {
    outline: 2px solid var(--azure);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Pular para o conteúdo — aparece só no foco (o único caso em que esconder
   é correto: o link existe para quem navega por teclado). */
.skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: var(--z-skip);
    background: var(--bg-3);
    color: var(--tx);
    border: var(--hair) solid var(--azure-line);
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    font-size: 14px;
    text-decoration: none;
}
.skip:focus {
    left: 12px;
    top: 12px;
}

/* ============================================================================
   ATMOSFERA
   ----------------------------------------------------------------------------
   Três camadas fixas atrás de tudo. Nenhuma delas é "gradiente bonito": é a
   luz do instrumento (glow da marca), a malha de espaço-tempo e um grão fino
   que tira o plástico do dark chapado.

   A MALHA substituiu a retícula chapada de blueprint (0.2.x): a mesma grade
   discreta, agora deformada por dois poços gravitacionais nas MESMAS posições
   dos glows — a massa que ilumina é a massa que curva. A geometria é um SVG
   inline gerado por bin/gerar-malha.py; aqui ficam cor, peso e opacidade, em
   token, para a malha acompanhar os 10 temas. Estática de propósito: fundo
   não disputa atenção com conteúdo.

   O grão é feTurbulence em data-URI: sem requisição, sem binário no repo, e
   sem cor — é ruído em preto com 5% de opacidade.
   ============================================================================ */
.atmo {
    position: fixed;
    inset: 0;
    z-index: var(--z-atmo);
    pointer-events: none;
}
.atmo::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(900px 600px at 78% -10%, color-mix(in srgb, var(--azure) 11%, transparent), transparent 60%),
        radial-gradient(700px 500px at -8% 74%, color-mix(in srgb, var(--azure-deep) 9%, transparent), transparent 60%);
}

.spacetime {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0.55;
    /* Esmaece rumo ao rodapé: em máscara só o ALFA importa, então
       currentColor + color-mix mantém a regra token-pura. */
    -webkit-mask-image: linear-gradient(to bottom,
        currentColor 55%,
        color-mix(in srgb, currentColor 45%, transparent) 80%,
        transparent 98%);
    mask-image: linear-gradient(to bottom,
        currentColor 55%,
        color-mix(in srgb, currentColor 45%, transparent) 80%,
        transparent 98%);
}
/* hairline de verdade mesmo com o slice escalando o viewBox */
.spacetime path { vector-effect: non-scaling-stroke; }
.spacetime__ln {
    fill: none;
    stroke: var(--line);
    stroke-width: 1;
}
/* As linhas que passam pelo centro de um poço carregam um fio da marca —
   são a "energia" da deformação, bem abaixo do peso de qualquer conteúdo. */
.spacetime__ln--hot {
    stroke: color-mix(in srgb, var(--azure) 26%, transparent);
}

/* Nos presets claros a malha escura ganharia peso de pauta de caderno; meia
   força. No high-contrast, decoração não compete com o contraste que dá nome
   ao tema. */
:root[data-theme="paper"] .spacetime,
:root[data-theme="sepia"] .spacetime { opacity: 0.4; }
:root[data-theme="high-contrast"] .spacetime { opacity: 0.25; }

.grain {
    position: fixed;
    inset: 0;
    z-index: var(--z-grain);
    pointer-events: none;
    opacity: 0.05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

/* Nos temas CLAROS o grão escuro suja o papel: metade da força. */
:root[data-theme="paper"] .grain,
:root[data-theme="sepia"] .grain { opacity: 0.025; }

main,
.topbar,
.foot { position: relative; z-index: var(--z-page); }

/* ============================================================================
   MARCA
   ----------------------------------------------------------------------------
   O símbolo é uma placa com um traço em degraus subindo até o ponto de leitura
   — telemetria, não letra. Ele NÃO é o logo da Blue3: este site é a face do
   projeto ShvIA, e a porta corporativa vive em outro repositório
   (BLUE3-AI-LOGIN). Ver docs/decisoes.md → ADR-001.
   ============================================================================ */
.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: var(--tx);
    flex: 0 0 auto;
}

.mark { width: 28px; height: 28px; flex: 0 0 auto; }
.mark--sm { width: 22px; height: 22px; }

.mark__plate {
    fill: var(--bg-3);
    stroke: var(--line-2);
    stroke-width: 1.4;
}
.mark__trace {
    fill: none;
    stroke: var(--azure);
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.mark__dot { fill: var(--azure); }

.brand__word {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.02em;
}
.brand__word em {
    font-style: normal;
    color: var(--azure-strong);
}

/* ============================================================================
   TOPBAR FLUTUANTE
   ----------------------------------------------------------------------------
   Barra que não encosta no topo: a página respira atrás dela e a retícula
   continua visível. Sticky com um respiro de 12px.
   ============================================================================ */
.topbar {
    position: sticky;
    top: 12px;
    z-index: var(--z-topbar);
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 var(--gut);
}

.topbar__in {
    display: flex;
    align-items: center;
    gap: 20px;
    background: color-mix(in srgb, var(--bg-2) 88%, transparent);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: var(--hair) solid var(--line-2);
    border-radius: 14px;
    padding: 10px 16px;
    box-shadow: var(--shadow-md);
}

.nav {
    display: flex;
    gap: 2px;
    margin-left: 8px;
    min-width: 0;
    overflow-x: auto;          /* em tela média o índice ROLA — nada escondido */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.nav::-webkit-scrollbar { display: none; }

/* Tightened in 0.5.0: the index went from 9 to 11 entries (agent, routines)
   and gained the language pair beside it. It still scrolls when it has to —
   nothing is ever hidden — but at 1440px the whole index now fits. */
.nav a {
    color: var(--tx-dim);
    text-decoration: none;
    font-size: 13px;
    white-space: nowrap;
    padding: 6px 8px;
    border-radius: 8px;
    transition: color var(--dur-fast) var(--ease-out-quart),
                background var(--dur-fast) var(--ease-out-quart);
}
.nav a:hover {
    color: var(--tx);
    background: var(--bg-3);
}

.topbar__ctl {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
}

/* Controle nativo de propósito: select do sistema abre certo no toque, no
   teclado e no leitor de tela. */
.ctl {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
}
.ctl__sel {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx);
    background: var(--bg-3);
    border: var(--hair) solid var(--line-2);
    border-radius: 8px;
    padding: 6px 8px;
    cursor: pointer;
}

/* Language pair. Two links, not a <select>: with JavaScript off a select does
   nothing, and this repository already refuses controls that are dead on
   screen (see the copy button in js/motion.js — no clipboard, no button). The
   links navigate on their own; the JS only carries the fragment across and
   remembers the choice. Visible at EVERY width, unlike `.ctl` — landing on the
   wrong language is the one thing a visitor must be able to undo from the
   first screen. */
.lang {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
.lang a {
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1;
    color: var(--tx-dim);
    text-decoration: none;
    padding: 6px 7px;
    border-radius: 7px;
    transition: color var(--dur-fast) var(--ease-out-quart),
                background var(--dur-fast) var(--ease-out-quart);
}
.lang a:hover { color: var(--tx); background: var(--bg-3); }
.lang a[aria-current="page"] {
    color: var(--tx);
    background: var(--bg-3);
}

/* ============================================================================
   TRILHO LATERAL
   ----------------------------------------------------------------------------
   Substitui o "§01, §02…" que antes se repetia acima de cada título. Aqui o
   índice é um instrumento: tique + rótulo, e o tique CRESCE e acende na seção
   em que você está. Só a partir de 1280px, onde há margem sobrando; abaixo
   disso quem navega é o índice da topbar (e o rodapé).
   ============================================================================ */
.rail {
    position: fixed;
    left: max(10px, calc((100vw - var(--wrap)) / 2 - 150px));
    top: 50%;
    transform: translateY(-50%);
    z-index: var(--z-rail);
    display: none;
    flex-direction: column;
    gap: 2px;
}
@media (min-width: 1280px) { .rail { display: flex; } }

/* ...and where the rail exists, the top index steps aside. The two were saying
   the same thing at the same time — the rail with the current section lit, the
   topbar as a strip that had to scroll to show all of it. Below 1280px there is
   no rail and the top index is the only one, so it stays. Same specificity as
   the `.nav` rule above and later in the file: this one wins. */
@media (min-width: 1280px) { .nav { display: none; } }

.rail a {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    letter-spacing: 0.02em;
    color: var(--tx-dim);
    text-decoration: none;
    padding: 5px 8px;
    border-radius: 6px;
    transition: color var(--dur-fast) var(--ease-out-quart);
}
.rail a::before {
    content: "";
    width: 14px;
    height: 1px;
    background: var(--line-2);
    transition: width var(--dur) var(--ease-out-quart),
                background var(--dur) var(--ease-out-quart);
}
.rail a:hover { color: var(--tx); }
.rail a.is-on { color: var(--azure-strong); }
.rail a.is-on::before { width: 22px; background: var(--azure); }

/* ============================================================================
   BOTÕES
   ============================================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: var(--hair) solid var(--line-2);
    border-radius: 10px;
    background: var(--bg-3);
    color: var(--tx);
    font-family: var(--font-sans);
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: 0.4px;
    line-height: 1;
    padding: 12px 18px;
    text-decoration: none;
    cursor: pointer;
    transition: filter var(--dur-fast) var(--ease-out-quart),
                transform var(--dur-fast) var(--ease-out-quart),
                box-shadow var(--dur) var(--ease-out-quart);
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); }

/* Marca CHAPADA, e não o gradiente azure-deep→azure que o app usa no botão do
   login: com o texto em --on-accent, a ponta escura do gradiente fecha 3.69:1
   no dark-glass (e 4.02:1 no nebulosa) — abaixo do mínimo AA que o produto
   exige. Medido pelo harness em tests/run.mjs, par "texto do botão". Chapado dá
   7.9:1 no dark-glass e passa nos 10 presets. */
.btn--primary {
    border-color: transparent;
    background: var(--azure);
    color: var(--on-accent);
}
.btn--primary:hover {
    box-shadow: 0 6px 24px color-mix(in srgb, var(--azure) 30%, transparent);
}
.btn--lg { padding: 15px 26px; font-size: 14.5px; border-radius: 12px; }
.btn--full { width: 100%; }

.btn[disabled],
.btn[aria-busy="true"] {
    cursor: progress;
    filter: saturate(0.55);
}

.lnk {
    color: var(--azure-strong);
    text-decoration: none;
    font-size: inherit;
}
.lnk:hover { text-decoration: underline; }

/* ============================================================================
   HERO
   ============================================================================ */
.hero {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: clamp(44px, 8vh, 92px) var(--gut) clamp(40px, 6vh, 72px);
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(320px, 420px);
    gap: clamp(32px, 5vw, 72px);
    align-items: start;
}

/* ---------- Boot: a página LIGA ----------
   Cascata de 80ms. Só transform — `from { opacity: 0 }` num renderizador que
   congela animações em t=0 deixa o conteúdo invisível PARA SEMPRE (aconteceu
   no harness headless do app; está documentado no tokens.css). Deslocamento
   congelado é imperceptível: 14px fora do lugar. */
@keyframes shvia-boot {
    from { transform: translateY(14px); }
}
.boot-1 { animation: shvia-boot 600ms var(--ease-out-expo) both; }
.boot-2 { animation: shvia-boot 600ms 80ms var(--ease-out-expo) both; }
.boot-3 { animation: shvia-boot 600ms 160ms var(--ease-out-expo) both; }
.boot-4 { animation: shvia-boot 700ms 240ms var(--ease-out-expo) both; }

/* ---------- Faixa de leitura ao vivo ----------
   Saiu da borda da tela e entrou no hero: é o primeiro sinal de vida da
   página. REGRA DURA (PRODUCT.md §1): número exibido é número lido. Falha de
   rede vira "—" e o motivo escrito ao lado. Ver js/instrument.js. */
.livebar {
    display: inline-flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    margin: 0 0 clamp(22px, 3.5vh, 32px);
    padding: 8px 16px;
    font-family: var(--font-mono);
    font-size: 12px;
    background: color-mix(in srgb, var(--bg-2) 80%, transparent);
    border: var(--hair) solid var(--line);
    border-radius: var(--radius-pill);
}

.rd {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    white-space: nowrap;
}
.rd__lb { color: var(--tx-dim); }
.rd__v {
    color: var(--tx);
    font-variant-numeric: tabular-nums;
}

.livebar__src {
    color: var(--tx-dim);
    font-size: 11px;
}

/* LED: cor COM função (tokens.css → verde = online, âmbar = atenção,
   vermelho = offline). Cinza = ainda não sei, e isso também é um estado. */
.led {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--tx-dim);
    box-shadow: 0 0 0 3px var(--bg-3);
    align-self: center;
}
.led.is-ok   { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }
.led.is-warn { background: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.led.is-down { background: var(--red);   box-shadow: 0 0 0 3px var(--red-soft); }

/* O pulso só existe no estado ONLINE: é o aparelho dizendo "estou lendo". */
@keyframes shvia-led-pulse {
    50% { box-shadow: 0 0 0 7px var(--green-soft); }
}
.led.is-ok { animation: shvia-led-pulse 2.4s var(--ease-out-quart) infinite; }

/* ---------- Tese ---------- */
.hero__thesis { min-width: 0; }

.hero h1 {
    margin: 0 0 20px;
    font-family: var(--font-display);
    font-size: clamp(32px, 4.6vw, 56px);
    font-weight: 600;
    line-height: 1.04;
    letter-spacing: -0.035em;
    text-wrap: balance;
}
.hero h1 em {
    font-style: normal;
    color: var(--azure-strong);
}

/* O fio que energiza a frase: um traço da marca que "acende" da esquerda para
   a direita no fim do boot. É a única floreada da página, e ela sublinha
   exatamente a promessa do produto. */
.wire { position: relative; white-space: nowrap; }
.wire::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0.04em;
    height: 3px;
    border-radius: 2px;
    background: var(--azure);
    transform-origin: left;
    animation: shvia-wire 900ms 460ms var(--ease-out-expo) both;
}
@keyframes shvia-wire {
    from { transform: scaleX(0); }
}

.lede {
    margin: 0 0 28px;
    max-width: 58ch;
    font-size: clamp(15.5px, 1.3vw, 17.5px);
    line-height: 1.62;
    color: var(--tx-dim);
    text-wrap: pretty;
}
.lede strong { color: var(--tx); font-weight: 600; }

.facts {
    list-style: none;
    margin: 0;
    padding: 0;
    max-width: 60ch;
}
.facts li {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    gap: 14px;
    padding: 13px 0;
    border-top: var(--hair) solid var(--line);
    font-size: 14.5px;
    color: var(--tx-dim);
}
.facts li:last-child { border-bottom: var(--hair) solid var(--line); }
.facts svg {
    width: 17px;
    height: 17px;
    margin-top: 2px;
    color: var(--azure-strong);
}

/* ============================================================================
   PORTA DE ENTRADA (login)
   ----------------------------------------------------------------------------
   Fica no hero, visível sem clique: o pedido é entrar do próprio site. O
   destino real (ai.shvia.org) está escrito na moldura — a porta não finge ser
   o app, ela diz para onde leva. Fluxo em js/frontdoor.js.

   O `:focus-within` acende a moldura INTEIRA: foco é estado, e estado se
   mostra. Sem isso, um cartão escuro num fundo escuro não dá sinal nenhum de
   que está ativo.
   ============================================================================ */
.door {
    position: sticky;
    top: 86px;                 /* topbar (12 + ~56) + respiro */
    background: linear-gradient(180deg, var(--bg-3), var(--bg-2) 55%);
    border: var(--hair) solid var(--line-2);
    border-radius: 18px;
    padding: 24px;
    box-shadow: var(--shadow-xl),
                inset 0 1px 0 color-mix(in srgb, var(--tx) 6%, transparent);
    transition: border-color var(--dur-slow) var(--ease-out-quart),
                box-shadow var(--dur-slow) var(--ease-out-quart);
}
.door:focus-within {
    border-color: var(--azure-line);
    box-shadow: var(--shadow-xl),
                0 0 0 4px var(--azure-soft),
                inset 0 1px 0 color-mix(in srgb, var(--tx) 6%, transparent);
}

.door__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--tx-dim);
    padding-bottom: 14px;
    margin-bottom: 18px;
    border-bottom: var(--hair) solid var(--line);
}
.door__dest {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--azure-strong);
}
.door__dest::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: var(--radius-pill);
    background: var(--azure);
}

.door__t {
    margin: 0 0 4px;
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 600;
    letter-spacing: -0.02em;
}
.door__sub {
    margin: 0 0 18px;
    font-size: 13px;
    color: var(--tx-dim);
}

.fld { display: block; margin-bottom: 12px; }
.fld__lb {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--tx-dim);
}
.fld__in {
    width: 100%;
    background: var(--bg);
    border: var(--hair) solid var(--line-2);
    border-radius: 10px;
    padding: 12px 13px;
    color: var(--tx);
    font-family: var(--font-sans);
    font-size: 15px;
    transition: border-color var(--dur-fast) var(--ease-out-quart),
                box-shadow var(--dur-fast) var(--ease-out-quart);
}
.fld__in:focus {
    outline: none;
    border-color: var(--azure);
    box-shadow: 0 0 0 3px var(--azure-soft);
}
.fld__in[aria-invalid="true"] { border-color: var(--red); }

.door__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 6px 0 18px;
    font-size: 13px;
}

.chk {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--tx-dim);
    cursor: pointer;
}
.chk input {
    width: 15px;
    height: 15px;
    accent-color: var(--azure);
    cursor: pointer;
}

.door__msg {
    margin: 14px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--tx-dim);
}
.door__msg:empty { display: none; }
.door__msg--err {
    color: var(--tx);
    background: var(--red-soft);
    border: var(--hair) solid var(--red);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
}
.door__msg--warn {
    color: var(--tx);
    background: var(--amber-soft);
    border: var(--hair) solid var(--amber);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
}
.door__msg--ok {
    color: var(--tx);
    background: var(--green-soft);
    border: var(--hair) solid var(--green);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
}

/* 15px and full --tx, not the 13px dim it used to be: while access was
   invitation-only this line was a dead end ("ask support"), and dim was the
   right weight for it. Reopening sign-up (0.6.3) made it the only path a new
   visitor has, sitting under a form they cannot use yet. 15px is the size of
   .fld__in right above it, so the CTA reads at the same scale as the fields it
   is an alternative to, without competing with the 22px .door__t. */
.door__foot {
    margin: 16px 0 0;
    padding-top: 14px;
    border-top: var(--hair) solid var(--line);
    font-size: 15px;
    color: var(--tx);
    text-align: center;
}

/* ============================================================================
   SEÇÕES
   ============================================================================ */
.sec {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: clamp(46px, 9vh, 100px) var(--gut) 0;
}

.sec__head {
    max-width: 70ch;
    margin-bottom: clamp(24px, 4vh, 40px);
}
.sec__head h2 {
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: clamp(26px, 3vw, 38px);
    font-weight: 600;
    line-height: 1.12;
    letter-spacing: -0.025em;
    text-wrap: balance;
}
.sec__head p {
    margin: 0;
    max-width: 66ch;
    font-size: 15.5px;
    line-height: 1.66;
    color: var(--tx-dim);
    text-wrap: pretty;
}
.sec__head p + p { margin-top: 14px; }
.sec__head p strong { color: var(--tx); font-weight: 600; }

/* ---------- Folha de especificação ---------- */
.specs { margin: 0; }
.specs__row {
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr);
    gap: 8px 20px;
    padding: 14px 0;
    border-top: var(--hair) solid var(--line);
    transition: background var(--dur-fast) var(--ease-out-quart);
}
.specs__row:last-child { border-bottom: var(--hair) solid var(--line); }
.specs__row:hover { background: color-mix(in srgb, var(--bg-2) 55%, transparent); }
.specs dt {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--azure-strong);
    padding-top: 2px;
}
.specs dd {
    margin: 0;
    max-width: 75ch;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--tx-dim);
}

/* ============================================================================
   O RECIBO
   ----------------------------------------------------------------------------
   A assinatura da página. O produto é "o gateway que mostra a conta" — então a
   conta aparece como CONTA: papel térmico, serrilha, filete tracejado, total
   destacado. A serrilha é conic-gradient repetido, sem imagem e sem SVG extra.

   O bloco é EXEMPLO e está escrito que é: número inventado com cara de leitura
   ao vivo violaria o princípio nº1 do produto na primeira tela pública.

   Impressão: o DEFAULT do DOM é impresso. O JS só REIMPRIME quando a seção
   entra na tela (js/motion.js). Sem JS, com movimento reduzido ou em
   renderizador headless, o recibo já está completo — nunca gated.
   ============================================================================ */
.till {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 430px);
    gap: clamp(32px, 5vw, 72px);
    align-items: center;
}

.receipt {
    position: relative;
    max-width: 430px;
    margin: 0 auto;
    filter: drop-shadow(var(--shadow-lg));
}
/* Serrilha de papel picotado: dois conic-gradients de MÁSCARA recortando os
   dentes no topo e no pé, mais um retângulo cheio no meio. A primeira versão
   desenhava os dentes como background de pseudo-elemento e saía reta — o
   gradiente pintava, mas não recortava. Máscara recorta.
   `currentColor` e `transparent` em vez de cor cravada: em máscara só o ALFA
   conta, e assim a regra continua token-pura. */
.receipt__paper {
    --dente-l: 14px;   /* largura do dente */
    --dente-h: 9px;    /* altura do dente */

    background: var(--bg-3);
    border-inline: var(--hair) solid var(--line-2);
    /* o respiro de cima e de baixo já desconta a altura do dente */
    padding: calc(26px + var(--dente-h)) 26px calc(22px + var(--dente-h));
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 1.9;
    color: var(--tx-dim);

    -webkit-mask:
        conic-gradient(from 135deg at top, transparent, currentColor 1deg 89deg, transparent 90deg)
            top / var(--dente-l) var(--dente-h) repeat-x,
        conic-gradient(from -45deg at bottom, transparent, currentColor 1deg 89deg, transparent 90deg)
            bottom / var(--dente-l) var(--dente-h) repeat-x,
        linear-gradient(currentColor 0 0)
            center / 100% calc(100% - 2 * var(--dente-h)) no-repeat;
    mask:
        conic-gradient(from 135deg at top, transparent, currentColor 1deg 89deg, transparent 90deg)
            top / var(--dente-l) var(--dente-h) repeat-x,
        conic-gradient(from -45deg at bottom, transparent, currentColor 1deg 89deg, transparent 90deg)
            bottom / var(--dente-l) var(--dente-h) repeat-x,
        linear-gradient(currentColor 0 0)
            center / 100% calc(100% - 2 * var(--dente-h)) no-repeat;
}

.receipt table { width: 100%; border-collapse: collapse; }
.receipt td { padding: 1px 0; }
.receipt td:last-child {
    text-align: right;
    color: var(--tx);
    font-variant-numeric: tabular-nums;
}
.receipt__head td {
    color: var(--tx);
    font-weight: 600;
    letter-spacing: 0.04em;
}
.receipt__rule td {
    height: 8px;
    border-top: 1px dashed var(--line-2);
}
.receipt__total td {
    padding-top: 4px;
    font-size: 15px;
    font-weight: 600;
    color: var(--tx);
}
.receipt__total td:last-child { color: var(--azure-strong); }
.receipt__aside td {
    text-align: right;
    font-size: 11.5px;
    color: var(--tx-dim);
}
.receipt__note td {
    padding-top: 12px;
    text-align: center;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--tx-dim);
}

/* Texto em --tx e não em --amber: âmbar sobre o próprio tinto âmbar fica em
   3.46:1 no sepia e 3.73:1 no paper. Mesma decisão já tomada no auth.css do
   app para os alertas — o SINAL vem da borda e do fundo, a legibilidade vem
   do texto. */
.tag {
    display: inline-block;
    margin-bottom: 6px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tx);
    background: var(--amber-soft);
    border: var(--hair) solid var(--amber);
    border-radius: var(--radius-pill);
    padding: 2px 10px;
}

@keyframes shvia-print { from { transform: scaleY(0); } }
.receipt tr { transform-origin: top; }

/* ============================================================================
   DIAGRAMA — caminho do dado
   ----------------------------------------------------------------------------
   Desenhado com os TOKENS (classes .dg-*), então acompanha os 10 temas. Os
   pacotes (.pkt) viajam pelos fios com animateMotion (SMIL): é movimento que
   É o conteúdo — a informação atravessando o gateway. Somem em movimento
   reduzido. Alternativa textual completa no <figcaption>.
   ============================================================================ */
.dg { margin: 0; }
.dg__scroll {
    overflow-x: auto;          /* diagrama largo rola dentro da própria caixa;
                                  a PÁGINA nunca rola na horizontal */
    border: var(--hair) solid var(--line);
    border-radius: 18px;
    background:
        radial-gradient(600px 300px at 50% 0%, color-mix(in srgb, var(--azure) 6%, transparent), transparent 70%),
        var(--bg-2);
    padding: clamp(16px, 3vw, 28px);
}
.dg__svg {
    display: block;
    width: 100%;
    min-width: 700px;
}

.dg-box {
    fill: var(--bg-3);
    stroke: var(--line-2);
    stroke-width: 1.2;
}
.dg-box--hi {
    fill: var(--bg-4);
    stroke: var(--azure-line);
    stroke-width: 1.5;
}
.dg-t {
    fill: var(--tx);
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 600;
}
.dg-s {
    fill: var(--tx-dim);
    font-family: var(--font-mono);
    font-size: 12.5px;
}
.dg-lb {
    fill: var(--tx-dim);
    font-family: var(--font-mono);
    font-size: 11.5px;
}
.dg-rule { stroke: var(--line-2); stroke-width: 1; }
.dg-wire {
    fill: none;
    stroke: var(--azure);
    stroke-width: 1.5;
    opacity: 0.8;
}
.dg-wire--back {
    stroke: var(--line-2);
    stroke-dasharray: 5 5;
    opacity: 1;
}
.dg-node { fill: var(--azure); }

.pkt { fill: var(--azure-strong); }
.pkt--back { fill: var(--green); }
@media (prefers-reduced-motion: reduce) {
    .pkt { display: none; }
}

.dg__cap {
    margin: 18px 4px 0;
    font-size: 13.5px;
    color: var(--tx-dim);
}
.dg__cap ol {
    margin: 0;
    padding-left: 20px;
    display: grid;
    gap: 6px;
    max-width: 74ch;
}

/* ============================================================================
   ÍNDICE DE SUPERFÍCIES
   ============================================================================ */
.idx {
    list-style: none;
    margin: 0;
    padding: 0;
}
.idx__row {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 8px 20px;
    padding: 15px 4px;
    border-top: var(--hair) solid var(--line);
    transition: background var(--dur-fast) var(--ease-out-quart);
}
.idx__row:last-child { border-bottom: var(--hair) solid var(--line); }
.idx__row:hover { background: color-mix(in srgb, var(--bg-2) 55%, transparent); }
.idx__k {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--azure-strong);
}
.idx__d {
    font-size: 14.5px;
    color: var(--tx-dim);
}
.idx__d strong { color: var(--tx); font-weight: 600; }
.idx__s {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
    white-space: nowrap;
}
.idx__s i {
    width: 7px;
    height: 7px;
    border-radius: var(--radius-pill);
    background: var(--tx-dim);
}
.idx__s--live { color: var(--green); }
.idx__s--live i { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }
.idx__s--dev i { background: var(--amber); }

/* ============================================================================
   DOWNLOAD
   ----------------------------------------------------------------------------
   Same row vocabulary as the surfaces index above (.idx): a mono key, a
   description, a status. Only layout is declared here — every colour is a
   token already verified by the contrast suite, so this section adds no new
   pair to check.

   The rows are DRAWN BY js/download.js from the app's release manifest. Which
   is why there is no `.dl__row` in any HTML file: the page ships the frame and
   the prose, never the file list. A list in the markup would be a second
   source of truth, and the stale one.
   ============================================================================ */
.dl__group { margin-top: 30px; }
.dl__group h3 {
    font-family: var(--font-mono);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--azure-strong);
    margin: 0 0 6px;
}
.dl {
    list-style: none;
    margin: 0;
    padding: 0;
}
.dl__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: baseline;
    gap: 6px 18px;
    padding: 14px 4px;
    border-top: var(--hair) solid var(--line);
}
.dl__row:last-child { border-bottom: var(--hair) solid var(--line); }

.dl__file {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--tx);
    word-break: break-all;
}
.dl__meta,
.dl__seal {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
    white-space: nowrap;
}
/* The hash spans the row on its own line: 64 hex characters do not share a
   line with anything, and truncating the one value that exists to be compared
   would defeat the point of showing it. */
.dl__hash {
    grid-column: 1 / -1;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--tx-dim);
    word-break: break-all;
}
.dl__act {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 4px;
}
.dl__copy {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
    background: none;
    border: var(--hair) solid var(--line-2);
    border-radius: 8px;
    padding: 7px 11px;
    cursor: pointer;
    transition: color var(--dur-fast) var(--ease-out-quart),
                background var(--dur-fast) var(--ease-out-quart);
}
.dl__copy:hover { color: var(--tx); background: var(--bg-3); }

/* Inside the `.doc` layout every `li` is prose: it gets a drawn marker and a
   left inset (`.doc__body li::before`, further down). These two lists are rows
   of DATA, so they opt out — the same way `.doc__toc` already does, and by the
   same mechanism, so there is one idiom for "this list is not prose". */
.doc__body .dl li,
.doc__body .band__in li { padding-left: 0; }
.doc__body .dl li::before,
.doc__body .band__in li::before { content: none; }

/* A button inside the `.doc` layout is still a button. `.doc__body a` sets the
   prose link colour and, being the more specific rule, was repainting the
   button's own text — `--azure-strong` on `--azure`, which is a pair nobody
   declared and therefore a pair the contrast suite never measured. The suite
   checks token PAIRS, not the cascade that decides which pair is on screen;
   this is the shape of defect it cannot catch, so the rule is written down. */
.doc__body a.btn { color: var(--tx); }
.doc__body a.btn--primary { color: var(--on-accent); }
.doc__body a.btn:hover { text-decoration: none; }

/* ============================================================================
   FAQ
   ============================================================================ */
.faq { max-width: 78ch; }
.faq__it { border-top: var(--hair) solid var(--line); }
.faq__it:last-child { border-bottom: var(--hair) solid var(--line); }

.faq__it summary {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 14px;
    min-width: 0;
    padding: 16px 4px;
    cursor: pointer;
    list-style: none;
    font-family: var(--font-display);
    font-size: 16.5px;
    font-weight: 500;
    color: var(--tx);
    transition: color var(--dur-fast) var(--ease-out-quart);
}
.faq__it summary::-webkit-details-marker { display: none; }
.faq__it summary:hover { color: var(--azure-strong); }

/* O marcador é o estado: + fechado, − aberto. */
.faq__it summary::before {
    content: "+";
    font-family: var(--font-mono);
    font-size: 15px;
    color: var(--azure-strong);
    flex: 0 0 14px;
}
.faq__it[open] summary::before { content: "−"; }

.faq__a {
    padding: 0 4px 18px 32px;
    max-width: 68ch;
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--tx-dim);
}

/* ============================================================================
   CTA FINAL
   ----------------------------------------------------------------------------
   O fio da marca atravessa a página e termina aqui: um filete vertical que
   desce até o bloco e "entrega" a energia no botão.
   ============================================================================ */
.cta {
    position: relative;
    max-width: var(--wrap);
    margin: 0 auto;
    padding: clamp(56px, 10vh, 116px) var(--gut);
    text-align: center;
}
.cta::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    transform: translateX(-50%);
    width: 1px;
    height: clamp(28px, 5vh, 56px);
    background: linear-gradient(to bottom, transparent, var(--azure));
}
.cta h2 {
    margin: 0 0 10px;
    font-family: var(--font-display);
    font-size: clamp(28px, 3.4vw, 44px);
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.03em;
}
.cta p {
    margin: 0 auto 26px;
    max-width: 52ch;
    font-size: 15.5px;
    color: var(--tx-dim);
}
.cta__addr {
    margin-top: 18px;
    display: flex;
    gap: 10px;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--tx-dim);
}

/* Fileira de botões alinhada à esquerda (404 e blocos de ação dentro de seção). */
.acts {
    margin: 26px 0 0;
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
.acts--center { justify-content: center; }

/* ============================================================================
   RODAPÉ
   ============================================================================ */
.foot {
    margin-top: clamp(24px, 5vh, 48px);
    border-top: var(--hair) solid var(--line);
    background: color-mix(in srgb, var(--bg-2) 80%, transparent);
}
.foot__in {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 24px var(--gut) calc(28px + env(safe-area-inset-bottom, 0px));
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--tx-dim);
}
.foot__brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.foot__nav {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    margin-left: auto;
}
.foot__nav a {
    font-size: 12.5px;
    color: var(--tx-dim);
    text-decoration: none;
}
.foot__nav a:hover { color: var(--tx); text-decoration: underline; }

.foot__meta {
    margin: 0;
    display: flex;
    gap: 14px;
    align-items: baseline;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--tx-dim);
}
.foot__meta output { font-variant-numeric: tabular-nums; }
/* Privacidade e suporte ficam na linha da letra miúda, não na navegação de
   seções: são documentos do produto, não partes da leitura da landing — e é
   onde a Apple e o Google esperam encontrá-los. */
.foot__meta a { color: var(--tx-dim); text-decoration: none; }
.foot__meta a:hover { color: var(--tx); text-decoration: underline; }

/* ============================================================================
   FAIXA DE NÚMEROS
   ----------------------------------------------------------------------------
   Logo abaixo do hero: quatro fatos contáveis no código, não slogans — os
   provedores saem de config/providers.php do app, os dialetos de
   routes/openai.php, as superfícies da seção que as lista. Se o catálogo
   mudar, esta faixa muda junto.
   ============================================================================ */
.band {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 var(--gut);
}
.band__in {
    list-style: none;
    margin: 0;
    padding: 20px 4px;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 18px 28px;
    border-top: var(--hair) solid var(--line);
    border-bottom: var(--hair) solid var(--line);
}
.band__in li {
    display: grid;
    gap: 5px;
    align-content: start;
}
.band__in strong {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--tx);
}
.band__in span {
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--tx-dim);
}

/* ============================================================================
   COMBO — a fila com fallback
   ----------------------------------------------------------------------------
   Cadeia vertical: ordinal, identidade do modelo e estado com LED — o mesmo
   vocabulário da faixa de leitura do hero. O passo que atendeu acende a
   moldura: estado se mostra, igual à porta. O encadeamento é exemplo e leva
   a mesma etiqueta do recibo.
   ============================================================================ */
.combo {
    max-width: 680px;
    margin-bottom: clamp(24px, 4vh, 40px);
}
.combo__chain {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 10px;
}
.combo__step {
    position: relative;
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr) auto;
    align-items: center;
    gap: 8px 14px;
    padding: 13px 16px;
    background: color-mix(in srgb, var(--bg-2) 80%, transparent);
    border: var(--hair) solid var(--line);
    border-radius: 14px;
}
/* o fio que liga um passo ao próximo, alinhado ao centro do ordinal */
.combo__step + .combo__step::before {
    content: "";
    position: absolute;
    left: 29px;
    top: -11px;
    width: 1px;
    height: 11px;
    background: var(--line-2);
}
.combo__ord {
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
    background: var(--bg-3);
    border: var(--hair) solid var(--line-2);
    border-radius: var(--radius-pill);
}
.combo__id {
    font-family: var(--font-mono);
    font-size: 13.5px;
    color: var(--tx);
}
.combo__id em {
    font-style: normal;
    display: block;
    margin-top: 2px;
    font-size: 11px;
    color: var(--tx-dim);
}
.combo__st {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--tx-dim);
    white-space: nowrap;
}
.combo__step.is-hit {
    border-color: var(--azure-line);
    background: color-mix(in srgb, var(--azure-soft) 60%, var(--bg-2));
}
.combo__note {
    margin: 14px 0 0;
    max-width: 62ch;
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.7;
    color: var(--tx-dim);
}

/* ============================================================================
   ECONOMIA — antes/depois do RTK
   ----------------------------------------------------------------------------
   Duas barras e os dois números em mono tabular. A largura da barra vem no
   style do HTML, colada no número que ela representa — exemplo etiquetado,
   mesma regra do recibo. Barra não carrega texto: contraste é problema do
   rótulo, que fica fora dela.
   ============================================================================ */
.saver {
    margin: 0 0 clamp(24px, 4vh, 40px);
    max-width: 680px;
}
.saver__rows { display: grid; gap: 12px; }
.saver__row {
    display: grid;
    grid-template-columns: 176px minmax(0, 1fr) 108px;
    align-items: center;
    gap: 12px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--tx-dim);
}
.saver__bar {
    height: 10px;
    background: var(--bg-3);
    border: var(--hair) solid var(--line);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.saver__bar i {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--tx-dim) 55%, transparent);
}
.saver__row--out .saver__bar i { background: var(--azure); }
.saver__row--out .saver__lb,
.saver__row--out .saver__v { color: var(--tx); }
.saver__v {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.saver__cap {
    margin-top: 14px;
    max-width: 62ch;
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.7;
    color: var(--tx-dim);
}

/* ============================================================================
   APONTE SEU CLI — passos e terminal
   ----------------------------------------------------------------------------
   O terminal é conteúdo, não enfeite: os endereços são as rotas reais da
   fachada /v1 do app. O botão "copiar" é progressivo — quem o cria é o JS
   (js/motion.js): sem script, nenhum controle morto fica na tela.
   ============================================================================ */
.steps {
    list-style: none;
    margin: 0 0 clamp(22px, 3.5vh, 32px);
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px 24px;
}
.steps__it h3 {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 8px;
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--tx);
}
.steps__n {
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 400;
    color: var(--azure-strong);
    border: var(--hair) solid var(--azure-line);
    border-radius: var(--radius-pill);
}
.steps__it p {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.62;
    color: var(--tx-dim);
}

.term {
    position: relative;
    max-width: 760px;
    background: var(--bg-3);
    border: var(--hair) solid var(--line-2);
    border-radius: 14px;
    box-shadow: var(--shadow-md);
    overflow: hidden;
}
.term__bar {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 10px 14px;
    border-bottom: var(--hair) solid var(--line);
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--tx-dim);
}
.term__bar i {
    width: 10px;
    height: 10px;
    border-radius: var(--radius-pill);
    border: var(--hair) solid var(--line-2);
    background: var(--bg-4);
}
.term__bar span { margin-left: 8px; }
.term__body {
    margin: 0;
    padding: 16px 18px;
    overflow-x: auto;      /* linha comprida rola aqui dentro; a página, nunca */
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 1.75;
    color: var(--tx);
}
/* dentro do terminal, <code> é texto corrido — sem o chip global */
.term__body code {
    background: none;
    border: 0;
    padding: 0;
    font-size: inherit;
    color: inherit;
}
.term__ps { color: var(--azure-strong); }
.term__c { color: var(--tx-dim); }
.term__copy {
    position: absolute;
    top: 7px;
    right: 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--tx-dim);
    background: var(--bg-4);
    border: var(--hair) solid var(--line-2);
    border-radius: 8px;
    padding: 4px 10px;
    cursor: pointer;
    transition: color var(--dur-fast) var(--ease-out-quart);
}
.term__copy:hover { color: var(--tx); }
.term__foot {
    margin: 14px 0 0;
    max-width: 66ch;
    font-size: 13.5px;
    line-height: 1.62;
    color: var(--tx-dim);
}
.term__foot strong { color: var(--tx); font-weight: 600; }

/* ============================================================================
   DOCUMENTO — texto corrido longo (privacidade, suporte)
   ----------------------------------------------------------------------------
   A landing é feita de seções curtas com voz de instrumento; um documento legal
   é o oposto: parágrafo atrás de parágrafo, para ser LIDO inteiro e citado por
   trecho. Por isso ele tem bloco próprio em vez de reaproveitar `.sec__head`,
   que limita a 70ch e trata `p` como legenda.

   Medida em `ch` (não em px) porque quem manda no conforto de leitura é a
   contagem de caracteres por linha, e a fonte do usuário pode não ser a nossa.
   ============================================================================ */
.doc {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: clamp(38px, 7vh, 76px) var(--gut) 0;
}
.doc__head { max-width: 72ch; }
.doc__head h1 {
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: clamp(30px, 4vw, 46px);
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.028em;
    text-wrap: balance;
}
/* Data de vigência: um documento legal sem data não vale como compromisso —
   é a primeira coisa que um encarregado de proteção de dados procura. */
.doc__stamp {
    margin: 0 0 26px;
    font-family: var(--font-mono);
    font-size: 12.5px;
    letter-spacing: 0.02em;
    color: var(--tx-dim);
}
.doc__stamp strong { color: var(--azure-strong); font-weight: 500; }

.doc__body { max-width: 74ch; }
.doc__body h2 {
    margin: 40px 0 12px;
    font-family: var(--font-display);
    font-size: clamp(19px, 2.2vw, 24px);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.018em;
    padding-top: 24px;
    border-top: var(--hair) solid var(--line);
}
.doc__body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.doc__body h3 {
    margin: 26px 0 8px;
    font-size: 15.5px;
    font-weight: 600;
    letter-spacing: -0.005em;
}
.doc__body p {
    margin: 0 0 14px;
    font-size: 15.5px;
    line-height: 1.7;
    color: var(--tx-dim);
    text-wrap: pretty;
}
.doc__body strong { color: var(--tx); font-weight: 600; }
.doc__body a { color: var(--azure-strong); text-decoration: none; }
.doc__body a:hover { text-decoration: underline; }

.doc__body ul { margin: 0 0 16px; padding: 0; list-style: none; }
.doc__body li {
    position: relative;
    margin: 0 0 9px;
    padding-left: 20px;
    font-size: 15.5px;
    line-height: 1.66;
    color: var(--tx-dim);
}
/* Marcador desenhado em vez de `list-style`: o bullet nativo herda a cor do
   texto e não aceita token sem `::marker`, que ainda varia entre navegadores. */
.doc__body li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 10px;
    width: 5px;
    height: 5px;
    border-radius: var(--radius-pill);
    background: var(--azure);
}

/* Caixa de destaque: o que o leitor precisa levar mesmo se ler na diagonal. */
.doc__note {
    margin: 20px 0;
    padding: 16px 18px;
    border: var(--hair) solid var(--azure-line);
    border-radius: var(--radius-md);
    background: var(--bg-2);
}
.doc__note p:last-child { margin-bottom: 0; }

/* Índice do documento: âncoras para citar "seção 7" num e-mail de titular. */
.doc__toc { margin: 0 0 8px; padding: 0; list-style: none; }
.doc__toc li { margin: 0 0 7px; padding-left: 0; }
.doc__toc li::before { content: none; }
.doc__toc a {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--tx-dim);
    text-decoration: none;
}
.doc__toc a:hover { color: var(--azure-strong); }

/* ============================================================================
   RESPONSIVO
   ----------------------------------------------------------------------------
   Este bloco vem DEPOIS de todas as definições de propósito: com a mesma
   especificidade, quem vence é a ordem. Um `@media` no meio do arquivo já
   custou um `display:none` que não pegava.
   ============================================================================ */
@media (max-width: 960px) {
    .hero {
        grid-template-columns: minmax(0, 1fr);
        gap: 36px;
    }
    .door { position: static; }

    .till { grid-template-columns: minmax(0, 1fr); }
    .receipt { margin: 0; }

    .specs__row { grid-template-columns: minmax(0, 1fr); }
    .idx__row { grid-template-columns: 88px minmax(0, 1fr); }
    .idx__s { grid-column: 2; }

    .band__in { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .steps { grid-template-columns: minmax(0, 1fr); }

    .combo__step { grid-template-columns: 26px minmax(0, 1fr); }
    .combo__st { grid-column: 2; }

    .foot__nav { margin-left: 0; }
}

@media (max-width: 760px) {
    /* O índice do topo sai e a marca fica com o botão ACESSAR: em tela estreita
       os três disputam o mesmo eixo e a rolagem horizontal do índice fica a
       dois dedos do gesto de "voltar" do iOS. A informação NÃO se perde — as
       mesmas seções estão no rodapé, que aqui é a navegação real. */
    .nav { display: none; }
    .ctl { display: none; }
    /* `.lang` is deliberately NOT in the line above: the theme can wait for a
       wider screen, the language cannot. */
    .topbar__in { gap: 12px; padding: 9px 12px; }
}

@media (max-width: 620px) {
    /* iOS dá zoom automático ao focar campo com fonte < 16px (mesmo motivo
       documentado em auth.css do app). */
    .fld__in { font-size: 16px; }

    .livebar { gap: 12px; padding: 8px 14px; }
    .door { padding: 20px; }
    .receipt__paper { padding: 22px 18px 18px; font-size: 12.5px; }

    /* barras empilham: rótulo, barra, número — o número sai da coluna fixa */
    .saver__row {
        grid-template-columns: minmax(0, 1fr);
        gap: 5px;
    }
    .saver__v { text-align: left; }
}
