/* iEntrega — Módulos · só o que é desta página.
   Tokens, primitivas, cabeçalho, rodapé, CTA com filme, ilustrações e a escada
   responsiva vêm de css/site.css, carregado antes. Aqui entra apenas o que não
   existe em nenhuma outra tela. */

/* ---------- índice de módulos no hero ----------
   VOLTOU A SER PÍLULA, e a volta tem motivo registrado: por um dia isto foi
   cartão, com número, seta e descritor. Ganhava em informação e perdia no que
   importa mais AQUI: o hero é a única seção da página que não precisa de
   densidade. Ele já carrega um h1 de 58px, uma subida de três linhas e o halo
   índigo; somar seis cartões com três linhas cada empurra o primeiro módulo
   para fora da dobra e faz a entrada da página competir consigo mesma.

   O que se perdeu foi o descritor ("prioriza o dia"), e a perda é aceitável
   porque a TRILHA no fim da página faz esse trabalho melhor, com o fluxo
   inteiro à vista. O índice do topo só precisa dizer "são estes seis".

   O que se GANHOU na ida e ficou: o realce índigo no ponteiro, que a fileira
   antiga não tinha. */
.mod-chips {
  margin-top: 38px;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
}
.mod-chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 15px 9px 11px;
  border: 1px solid var(--bd); background: var(--sf); border-radius: 999px;
  font-size: 14px; font-weight: 500; color: var(--mu);
}
.mod-chip__ico { display: inline-flex; width: 18px; height: 18px; color: var(--ac); }
.mod-chip__ico svg { width: 18px; height: 18px; }
.mod-chip:focus-visible { outline: 2px solid var(--ac); outline-offset: 3px; }

/* --- o realce no ponteiro: o tratamento do handoff ---
   Borda índigo, sobe 3px e ganha brilho índigo por baixo. A pílula antiga
   subia 1px e só trocava a borda para `--hl`, que é cinza: o toque acontecia
   e não se via.

   O brilho aqui É por fora, ao contrário do que eu tinha argumentado quando
   isto era cartão. O argumento valia lá e não vale aqui: seis cartões de
   150x80 acesos por fora somavam uma mancha índigo do tamanho da fileira, ao
   lado do halo do hero. Uma pílula de 40px de altura acende uma área pequena,
   e só uma por vez. É a diferença entre gastar a cor e usá-la. */
.mod-chip { transition: transform .25s var(--e-casa), border-color .25s, background .25s, color .25s, box-shadow .25s; }
@media (hover: hover) {
  .mod-chip:hover {
    border-color: var(--ac); color: var(--tx); background: var(--card);
    transform: translateY(-3px);
    box-shadow: 0 14px 28px -16px rgba(99,102,241,.85);
  }
}
@media (prefers-reduced-motion: reduce) {
  .mod-chip { transition: none; }
  .mod-chip:hover { transform: none; }
}

/* ---------- bloco de módulo ----------
   Alterna o lado da arte. A referência usa sempre o mesmo lado e o resultado
   é um metrônomo: seis blocos idênticos descendo. Inverter dá ritmo sem
   inventar um layout novo por módulo. */
.mod__grid {
  display: grid; grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
  gap: clamp(32px, 4.5vw, 72px); align-items: center;
  padding-top: 88px; padding-bottom: 88px;
}
.mod--inverso .mod__texto { order: 2; }
.mod--inverso .mod__arte { order: 1; }
/* Inverter o LADO exige inverter o PESO junto. Sem esta linha a arte dos
   módulos 02/04/06 cai na coluna de .92fr — a menor — e o mesmo mock que a
   home dá 484,6px passa a rodar em 413,8px, 15% mais estreito. O texto não
   ganha nada com a folga (tem max-width: 46ch), mas o mock perde: em 1024px
   de janela o chip "EM ESTOQUE" (nowrap, 80,6px) trava mais largura que o
   nome do produto (51,9px), e "Cimento CP-II 50 kg" quebra em três linhas —
   o painel chamado "Consolidado por produto" deixa de ler como tabela justo
   na coluna do produto. */
.mod--inverso .mod__grid { grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); }

.mod__n {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--mu); margin-bottom: 12px;
}
.mod__texto h2 {
  margin-top: 14px;
  font-size: clamp(28px, 3.2vw, 40px); line-height: 1.08;
  max-width: 18ch; text-wrap: balance;
}
.mod__texto .lede { margin: 18px 0 0; max-width: 46ch; font-size: 17px; line-height: 1.62; color: var(--mu); }
.mod__texto .bullets { margin-top: 26px; gap: 13px; }
/* fecho do bloco: a ressalva ou a regra que governa o módulo. Fica em cima de
   um fio para não se confundir com mais um bullet de recurso. */
.mod__pe {
  margin: 26px 0 0; padding-top: 18px;
  border-top: 1px solid var(--bd);
  max-width: 46ch; font-size: 14.5px; line-height: 1.6; color: var(--tx);
}
.mod__texto .link-accent { display: inline-flex; margin-top: 22px; }

/* O `.mod__arte` é só o lugar: quem carrega borda, fundo e sombra é o `.mock`
   que mora dentro dele. Enquadrar os dois daria moldura dupla. */
.mod__arte { min-width: 0; }

/* ============================================================
   A TRILHA — "Como se encaixam"
   ============================================================
   Substitui uma grade `repeat(3, 1fr)` com gap de 1px, que era a "três
   colunas iguais" mais genérica que existe. Ela tinha três defeitos somados,
   e o terceiro é o que condenava: os numerais 01 a 06 colidiam com os
   `Módulo 01-06` logo acima e NÃO CORRESPONDIAM (a corrente 03 "A central
   despacha" é o Módulo 01, e o Copiloto não aparecia em lugar nenhum); o
   conteúdo resumia o que os seis blocos acabaram de explicar; e a leitura
   3x2 quebrava a corrente exatamente no elo 03→04.

   No lugar: um fio de 1px atravessa a seção, com seis estações penduradas
   nele, alternando acima e abaixo. E entre cada par, SOBRE o fio, o
   substantivo do que é entregue de um módulo ao próximo. São CINCO entregas,
   não seis passos: é a frase "o que um grava, o próximo usa" desenhada, e é
   a diferença entre seis módulos e seis sistemas dita sem texto.

   Sem números de etapa. A posição no fio é o número e o horário é a ordem;
   rótulo `01`..`06` é o padrão mais banido que existe.

   Cada estação é uma grade de quatro linhas — [texto acima] [nó] [texto
   abaixo] [haste] — com a linha do nó de altura fixa. É isso que mantém os
   seis nós no MESMO eixo sem nenhuma conta de altura: quem alterna é a linha
   que recebe o texto, não a posição do nó. A haste da quarta linha desce
   para o Copiloto e fica alinhada de graça. */
.trilha { margin-top: 52px; }
.tri__linha { position: relative; display: flex; align-items: stretch; }

/* o fio, atrás de tudo, exatamente no eixo dos nós */
.tri__fio {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
  pointer-events: none; display: grid; grid-template-rows: 1fr 12px 1fr auto;
}
/* `--hl`, não `--bd`: o fio é o objeto principal da seção e precisa ser visto.
   Em `--bd` (#37374B sobre #16161F) ele existe e some, que é o pior dos dois
   mundos — parece defeito de renderização, não desenho. */
.tri__fio i {
  grid-row: 2; align-self: center; height: 1px; background: var(--hl);
  transform-origin: left;
}

.tri__est {
  flex: 1 1 0; min-width: 0;
  display: grid; grid-template-rows: 1fr 12px 1fr auto;
  justify-items: center; text-align: center;
  padding: 0 8px;
}
.tri__no {
  position: relative;
  grid-row: 2; align-self: center;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--ac); box-shadow: 0 0 0 4px var(--bg);
}
/* a primeira estação não é módulo nenhum: o pedido entra por integração.
   Nó OCO, porque a diferença é a informação. */
.tri__no--oco { background: var(--bg); box-shadow: 0 0 0 1px var(--hl), 0 0 0 4px var(--bg); }
/* O texto é MAIS LARGO que a fatia da estação, e transborda de propósito.
   Só os NÓS precisam estar igualmente espaçados; o texto vive nas linhas 1 e
   3, e os chips na linha 2, então um não alcança o outro. E como as estações
   alternam, vizinha nenhuma divide linha com vizinha: quem divide são as de
   duas em duas, que estão longe. Sem isto, os chips comem a largura e
   "O pedido entra pela integração" quebra em três linhas num vão de 119px. */
.tri__txt { display: flex; flex-direction: column; gap: 5px; width: 176px; }
.tri__est--cima .tri__txt { grid-row: 1; align-self: end; padding-bottom: 14px; }
.tri__est--baixo .tri__txt { grid-row: 3; align-self: start; padding-top: 14px; }
.tri__h { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--ac-tx); font-variant-numeric: tabular-nums; }
.tri__o { font-size: 15.5px; font-weight: 600; line-height: 1.25; letter-spacing: -.01em; text-wrap: balance; }
.tri__m { font-size: 11px; line-height: 1.35; color: var(--ft); }
/* a haste que desce para o Copiloto */
.tri__haste { grid-row: 4; width: 1px; height: 30px; background: linear-gradient(180deg, var(--bd), transparent); }

/* o que passa de um para o outro, SOBRE o fio */
.tri__passa {
  flex: 0 0 auto; display: grid; grid-template-rows: 1fr 12px 1fr auto;
  align-items: center; padding: 0 2px;
}
/* `position: relative` NÃO é enfeite: o fio é `position: absolute`, e elemento
   posicionado pinta ACIMA de elemento em fluxo normal, por mais fundo que este
   tenha. O resultado era o fio riscando o texto dos chips de ponta a ponta,
   com cara de tachado. Posicionando o chip, ele entra na mesma camada do fio e
   ganha por vir depois no documento. Vale para o nó pelo mesmo motivo. */
.tri__passa span {
  position: relative;
  grid-row: 2; align-self: center;
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .04em;
  color: var(--mu); background: var(--bg); border: 1px solid var(--bds);
  border-radius: 999px; padding: 4px 9px; white-space: nowrap;
  transition: color .25s, border-color .25s;
}
.section--tint .tri__passa span { background: var(--sf); }

/* o Copiloto NÃO fica no fio: ele lê as seis e não produz nenhuma, e é por
   isso que não é um passo. O desenho explica isso sem uma linha de texto. */
.tri__base { display: grid; justify-items: center; }
.tri__base::before {
  content: ""; width: 100%; height: 1px;
  background: repeating-linear-gradient(90deg, var(--bd) 0 5px, transparent 5px 10px);
}
.tri__copiloto {
  margin-top: -1px; display: block; text-align: center; max-width: 60ch;
  border: 1px solid var(--bd); background: var(--sf); border-radius: 11px;
  padding: 15px 24px; transform: translateY(22px);
}
.section--tint .tri__copiloto { background: var(--bg); }
.tri__copiloto b { display: block; font-size: 15px; font-weight: 600; }
.tri__copiloto span { display: block; margin-top: 5px; font-size: 13.5px; line-height: 1.5; color: var(--mu); }

.tri__mais { margin-top: 68px; padding-top: 30px; border-top: 1px solid var(--bd); }
.tri__mais-t { margin: 0; font-size: 15px; color: var(--mu); }
.tri__mais-t strong { color: var(--tx); font-weight: 600; }

/* miudinho de procedência, uma vez só na página inteira */
.tri__miudo {
  margin: 30px 0 0; font-family: 'JetBrains Mono', monospace;
  font-size: 11px; line-height: 1.6; color: var(--ft);
}

/* a nuvem cortada: "e mais 400" desenhado, onde o corte é a informação
   (ientrega.css:1204-1215) */
.ftodas {
  margin-top: 18px; display: flex; flex-wrap: wrap; gap: 7px;
  max-height: 96px; overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 58%, transparent);
          mask-image: linear-gradient(180deg, #000 58%, transparent);
}
.ftodas span {
  font-family: 'JetBrains Mono', monospace; font-size: 10.5px; line-height: normal;
  color: var(--mu); background: var(--bds); border-radius: 5px; padding: 5px 8px;
}
/* [iE] a landing tem um `[data-theme="light"] .ftodas span { background: var(--bg) }`
   que NÃO porta: lá a nuvem mora numa seção `--sf`, então `--bg` contrasta.
   Aqui a seção já é `--bg`, e a regra pintaria as pastilhas exatamente da cor
   do fundo — quinze chips invisíveis, sem nada quebrado para investigar.
   `--bds` funciona nos dois temas porque em ambos ele é um degrau do fundo. */

/* --- movimento: o fio se desenha e as estações acendem quando ele passa --- */
@keyframes tri-fio   { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes tri-fio-v { from { transform: scaleY(0); } to { transform: scaleY(1); } }
.rv .tri__fio i { transform: scaleX(0); }
.rv-in .tri__fio i { animation: tri-fio 1.1s var(--e-traco) both; }
.rv .tri__est, .rv .tri__passa span, .rv .tri__base { opacity: 0; }
/* 1100 / 6 ≈ 183; 170 faz a estação pousar um instante ANTES de o fio chegar,
   que é o que parece certo — o fio alcança algo que já está lá. */
.rv-in .tri__est { animation: mod-entra .46s var(--e-casa) both; animation-delay: calc(var(--i, 0) * 170ms); }
.rv-in .tri__passa span { animation: mod-entra .46s var(--e-casa) both; animation-delay: calc(var(--i, 0) * 170ms + 90ms); }
.rv-in .tri__base { animation: mod-entra .5s var(--e-casa) 1.15s both; }
@media (hover: hover) {
  .tri__est { transition: transform .3s var(--e-casa); }
  .tri__est:hover { transform: translateY(-3px); }
  /* passar o ponteiro numa estação acende o que ELA entrega ao próximo:
     é o gesto mínimo de "eu passo isto adiante" */
  .tri__est:hover + .tri__passa span { color: var(--tx); border-color: var(--ac); }
}

/* --- escada responsiva: o fio gira para vertical ---
   Uma corrente vertical continua sendo uma corrente. O que não funcionava
   era a grade de duas colunas, que quebrava o encadeamento três vezes. */
@media (max-width: 900px) {
  .tri__linha { flex-direction: column; align-items: stretch; }
  .tri__fio { display: block; }
  /* `height: 100%` explícito, não `top:0; bottom:0` com altura automática: a
     regra base deixa `align-self: center` no elemento e o par offset+auto
     resolvia para zero — o fio existia, com 1px de largura e 0 de altura. */
  .tri__fio i { position: absolute; left: 4px; top: 0; width: 1px; height: 100%; transform-origin: top; align-self: stretch; }
  /* na vertical quem se desenha é a altura */
  .rv .tri__fio i { transform: scaleY(0); }
  .rv-in .tri__fio i { animation-name: tri-fio-v; }
  .tri__est, .tri__passa { display: block; padding: 0 0 0 26px; position: relative; }
  .tri__est { padding-top: 4px; padding-bottom: 18px; text-align: left; justify-items: start; }
  .tri__est .tri__txt { max-width: none; padding: 0; }
  .tri__no { position: absolute; left: 0; top: 8px; }
  .tri__haste { display: none; }
  .tri__passa { padding-bottom: 18px; }
  .tri__passa span { display: inline-block; }
  .tri__base::before { display: none; }
  .tri__copiloto { transform: none; margin-top: 10px; margin-left: 26px; }
  .tri__base { justify-items: start; }
}
@media (prefers-reduced-motion: reduce) {
  .rv .tri__fio i { transform: scaleX(1); }
  .rv .tri__est, .rv .tri__passa span, .rv .tri__base { opacity: 1; }
  .rv-in .trilha *, .rv-in .trilha *::before { animation: none !important; }
  .tri__est { transition: none; }
}

/* ---------- escada responsiva (mesmos degraus do site) ---------- */
@media (max-width: 1000px) {
  .mod__grid { grid-template-columns: 1fr; gap: 36px; padding-top: 64px; padding-bottom: 64px; }
  /* empilhado, a arte vai SEMPRE para baixo do texto: alternar na vertical não
     dá ritmo nenhum, só faz metade dos blocos abrirem por uma imagem sem
     contexto. */
  .mod--inverso .mod__texto { order: 0; }
  .mod--inverso .mod__arte { order: 0; }
  .mod__texto .lede, .mod__pe { max-width: 60ch; }
}
@media (max-width: 620px) {
  .mod__grid { padding-top: 52px; padding-bottom: 52px; }
  /* a fileira já é flex-wrap: em telas estreitas ela quebra sozinha em duas ou
     três linhas de pílula, sem precisar de grade. */
  .mod-chips { gap: 8px; margin-top: 30px; }
  .mod-chip { font-size: 13px; padding: 8px 13px 8px 10px; }
}


/* ============================================================
   MOCK DE PRODUTO — levantado de css/ientrega.css
   ============================================================
   A arte desta página deixou de ser ilustração desenhada e passou a ser a
   MESMA representação de tela que a home usa na seção #modulos. Os seis mocks
   são HTML+CSS puro (não dependem de app.js nem de <canvas>), então só o CSS
   precisou vir junto. Copiado sem reescrever, exceto o que está marcado [iE].

   Uma renomeação obrigatória: `.tl` da landing (linha do tempo do rastreio,
   ientrega.css:206) COLIDE com `.tl` do site.css:149 (a Trajetória da página
   Sobre). Mesmo nome, dois componentes — e a vítima seria ESTA página, não a
   Sobre: quem carrega site.css aqui somos nós, e ele vem ANTES, então o
   `max-width:820px; display:flex; flex-direction:column` da Trajetória
   capturaria o container da linha do tempo do mock 05 e desmontaria o
   empilhamento dele. (A Sobre é justamente a única que não pode ser atingida:
   modulos.css não é carregado lá.) Por isso o container virou `.rtl`; os
   filhos (.tli/.tt/.td) não colidem com nada. */

/* [iE] RÓTULO DE PROCEDÊNCIA — fora da moldura, acima da arte.
   Numa página cuja tese é prova verificável, dizer o que é diagrama e o que é
   evidência é o argumento mais barato e mais difícil de copiar que existe.
   Toda superfície DESENHADA leva `· EXEMPLO`. Quando entrarem as capturas
   reais, elas levam `CAPTURA · SEM RETOQUE` com a data, e a diferença entre as
   duas passa a estar escrita na página em vez de subentendida.

   O rótulo fica FORA do quadro de propósito: dentro, ele vira parte do
   desenho e a pessoa lê como se fosse mais um elemento da tela fingida. */
.rot {
  font-family: 'JetBrains Mono', monospace; font-size: 10.5px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--ft); margin: 0 0 10px 2px;
}

/* moldura */
.mock { border: 1px solid var(--bd); background: var(--sf); border-radius: 16px; overflow: hidden; }
/* [iE] A faixa do topo era uma BARRA DE TÍTULO: nome do módulo à esquerda,
   métrica à direita. Barra de título é o que faz uma maquete ser lida como
   captura de tela falsa, e era o mesmo desenho seis vezes seguidas — o
   metrônomo não estava só no tamanho dos cartões, estava aqui.

   O nome saiu para o rótulo de procedência, acima da moldura. Ficou a métrica,
   que é dado do exemplo e não enfeite de janela, agora alinhada à esquerda:
   um span só, encostado num canto, lê como faixa de indicador, não como
   cabeçalho de aplicativo. */
.mock-h { display: flex; align-items: center; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--bds); font-family: 'JetBrains Mono', monospace; font-size: 11px; letter-spacing: .08em; color: var(--mu); }
.mock-b { padding: 18px; }
.split2 { display: grid; grid-template-columns: 1.4fr 1fr; gap: 14px; }
@media (max-width: 560px) { .split2 { grid-template-columns: 1fr; } }
.pane { background: var(--bg); border: 1px solid var(--bds); border-radius: 12px; padding: 15px; }
.pane h5 { margin: 0 0 11px; font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase; color: var(--mu); }

/* Sombra de três camadas — contato, meia distância e ambiente. Uma sombra só,
   por mais borrada que seja, lê como mancha; são as três que o olho lê como
   volume (ientrega.css:390-415). */
.mock, .phone {
  box-shadow: 0 2px 3px rgba(0,0,0,.13), 0 10px 20px -6px rgba(0,0,0,.20), 0 34px 64px -18px rgba(0,0,0,.45);
}
[data-theme="light"] .mock, [data-theme="light"] .phone {
  box-shadow: 0 2px 3px rgba(20,19,23,.05), 0 10px 20px -6px rgba(20,19,23,.08), 0 34px 64px -18px rgba(20,19,23,.16);
}
.phone.small { box-shadow: 0 2px 3px rgba(0,0,0,.10), 0 8px 16px -6px rgba(0,0,0,.16), 0 24px 44px -16px rgba(0,0,0,.34); }

/* 01 — lista de entregas + entregadores */
.lrow { display: grid; grid-template-columns: 3px 62px 1fr auto; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--bds); font-size: 13px; }
.lrow:last-child { border-bottom: 0; }
.lrow .stripe { width: 3px; height: 20px; border-radius: 2px; }
.lrow .id { font-family: 'JetBrains Mono', monospace; font-size: 11.5px; color: var(--ft); }
.lrow .stt { font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; text-align: right; white-space: nowrap; }
@media (max-width: 480px) { .lrow { grid-template-columns: 3px 1fr auto; } .lrow .id { display: none; } }
.drv { display: flex; align-items: center; gap: 10px; padding: 9px 0; font-size: 13px; }
.drv .av { width: 25px; height: 25px; border-radius: 50%; display: grid; place-items: center; font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700; color: #0B0A0C; flex: none; }
.drv .dp { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 11.5px; color: var(--mu); }
.minibar { height: 4px; border-radius: 99px; background: var(--bds); overflow: hidden; margin: 2px 0 9px; }
.minibar i { display: block; height: 100%; border-radius: 99px; }

/* 02 — consolidado por produto */
.prd { display: grid; grid-template-columns: 1fr auto auto; gap: 11px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--bds); font-size: 13px; }
.prd:last-child { border-bottom: 0; }
.prd .q { font-family: 'JetBrains Mono', monospace; font-size: 12.5px; }
.pt { font-family: 'JetBrains Mono', monospace; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; padding: 3px 8px; border-radius: 5px; white-space: nowrap; }
.pt.ok { background: rgba(52,211,153,.12); color: var(--ok); }
.pt.warn { background: rgba(251,191,36,.12); color: var(--warn); }
.pt.bad { background: rgba(248,113,113,.12); color: var(--bad); }
[data-theme="light"] .pt.ok { background: rgba(31,138,99,.12); }
[data-theme="light"] .pt.warn { background: rgba(154,106,11,.12); }
[data-theme="light"] .pt.bad { background: rgba(194,69,61,.12); }

/* 03 — celulares */
.phones { display: flex; justify-content: center; gap: 20px; padding: 22px 16px; }
.phone { width: 236px; border: 1px solid var(--bd); background: var(--sf2); border-radius: 24px; padding: 15px; }
.phone.small { width: 196px; align-self: flex-end; }
@media (max-width: 560px) { .phones { flex-direction: column; align-items: center; } .phone.small { align-self: center; } }
.ph-top { display: flex; justify-content: space-between; font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--ft); padding: 2px 4px 12px; }
.chk { display: flex; align-items: center; gap: 10px; padding: 8px 0; font-size: 12.5px; }
.chk .cb { width: 16px; height: 16px; border-radius: 5px; border: 1.5px solid var(--hl); display: grid; place-items: center; font-size: 9px; color: transparent; flex: none; }
.chk.done .cb { background: var(--ok); border-color: var(--ok); color: #0B0A0C; }
.chk.done > span:nth-child(2) { color: var(--mu); }
.qbadge { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 9.5px; letter-spacing: .09em; color: var(--warn); }
.chk.done .qbadge { color: var(--ok); }
/* [iE] o botão do celular: em site.css `.btn` é inline-block, e o mock traz
   `justify-content:center` inline — que só resolve em flex. Sem isto o rótulo
   "Concluir entrega" cola à esquerda (na landing o ientrega.css:274 já fazia
   `.btn` virar inline-flex; aqui, não). */
.phone .btn { display: flex; align-items: center; justify-content: center; }

/* 04 — o `.minisheet` (comprovante em miniatura) saiu junto com a maquete que
   ele vestia: são 9 regras sem um só uso no HTML depois que o módulo passou a
   mostrar o papel em tamanho de leitura. CSS órfão não quebra nada e é
   exatamente por isso que fica: some agora, no mesmo commit que o tornou
   órfão, enquanto ainda está claro por quê. O componente vivo é `.receipt`,
   no fim deste arquivo. */

/* 05 — linha do tempo do rastreio (.tl renomeada, ver nota acima) + balões */
.rtl { position: relative; padding-left: 20px; }
.rtl::before { content: ""; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 1px; background: var(--bd); }
.tli { position: relative; padding: 8px 0; font-size: 13px; }
.tli::before { content: ""; position: absolute; left: -19px; top: 13px; width: 9px; height: 9px; border-radius: 50%; background: var(--sf2); border: 1px solid var(--bd); }
.tli.did::before { background: var(--ok); border-color: var(--ok); }
.tli.now::before { background: var(--ac); border-color: var(--ac); box-shadow: 0 0 0 4px rgba(99,102,241,.2); }
.tli .tt { color: var(--tx); }
.tli .td { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--ft); }
.bub { background: var(--sf2); border: 1px solid var(--bds); border-radius: 11px; padding: 10px 13px; font-size: 12.5px; line-height: 1.5; color: var(--tx); }
.bub .bt { display: block; font-family: 'JetBrains Mono', monospace; font-size: 9.5px; color: var(--ft); margin-top: 6px; letter-spacing: .05em; }
.bub.me { align-self: flex-end; border-color: rgba(99,102,241,.32); background: rgba(99,102,241,.09); }

/* 06 — conversa do copiloto */
.chat { display: flex; flex-direction: column; gap: 10px; padding: 22px; }
.chat .msg { padding: 11px 14px; border-radius: 11px; font-size: 13.5px; line-height: 1.55; max-width: 88%; }
.chat .msg--user { align-self: flex-end; background: rgba(99,102,241,.12); border: 1px solid rgba(99,102,241,.3); color: var(--tx); }
.chat .msg--bot { background: var(--bg); border: 1px solid var(--bd); color: var(--mu); }
.chat .msg--bot strong { color: var(--tx); font-weight: 600; }
.chat .tool { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; letter-spacing: .05em; color: var(--mu); opacity: .75; padding-left: 3px; }

@media (max-width: 620px) { .mock-b { padding: 14px; } .chat { padding: 16px; } }


/* ============================================================
   MOVIMENTO — no sotaque do site, não inventado
   ============================================================
   Tudo pendurado nas classes que o reveal JÁ escreve: `.rv` no estado inicial
   e `.rv-in` quando a seção entra na tela. É exatamente como a landing dispara
   o traço da assinatura (ientrega.css:100) — sem observer novo e sem JS a mais.

   O estado escondido mora SÓ dentro de `.rv`, que é escrita por JavaScript.
   Se o JS não rodar, nada fica invisível: o conteúdo aparece parado, que é a
   degradação correta. Pendurar o `opacity:0` no elemento cru seria apostar a
   legibilidade da página no sucesso de um script.

   As curvas e durações saem da escada do site: .2,.7,.3,1 é a curva da casa;
   as durações ficam entre .3s e .9s; e o escalonamento entre irmãos é o
   "atraso em cascata dentro de uma peça" que o alternador de tema e a
   atribuição dos depoimentos já usam. */

@keyframes mod-entra { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
@keyframes mod-entra-tool { from { opacity: 0; transform: translateY(9px); } to { opacity: .75; transform: none; } }
@keyframes mod-enche { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes mod-tica  { to { background: var(--ok); border-color: var(--ok); color: #0B0A0C; } }

/* --- as linhas do mock entram em cascata --- */
.rv .mod__arte .lrow,
.rv .mod__arte .prd,
.rv .mod__arte .tli,
.rv .mod__arte .bub,
.rv .mod__arte .chat > .msg { opacity: 0; }
/* o rótulo de ferramenta do copiloto nasce a 75% de propósito (é sussurro, não
   fala): sai do conjunto genérico para não voltar em 100% no fim da animação */
.rv .mod__arte .chat > .tool { opacity: 0; }

.rv-in .mod__arte .lrow,
.rv-in .mod__arte .prd,
.rv-in .mod__arte .tli,
.rv-in .mod__arte .bub,
.rv-in .mod__arte .chat > .msg { animation: mod-entra .46s var(--e-casa) both; }
.rv-in .mod__arte .chat > .tool { animation: mod-entra-tool .46s var(--e-casa) both; }

/* O JS mantém `.rv` junto com `.rv-in`, então as regras de opacidade 0 acima
   continuam casando depois da revelação: sem isto, a página inteira depende do
   `animation-fill-mode: both` ter rodado. O próprio site.css:94 se protege
   assim (`.rv.rv-in { opacity: 1 }`) em vez de confiar na transição — é uma
   linha para tirar a legibilidade da página das mãos de um fill-mode. */
.rv-in .mod__arte .lrow,
.rv-in .mod__arte .prd,
.rv-in .mod__arte .tli,
.rv-in .mod__arte .bub,
.rv-in .mod__arte .chat > .msg { opacity: 1; }
.rv-in .mod__arte .chat > .tool { opacity: .75; }

/* [iE] O escalonamento passa a vir de `--i`, escrito no próprio elemento.
   Estava em `:nth-of-type`, e o comentário que ele trazia defendia uma robustez
   que ele não tem: `:nth-of-type` conta por TAG, não por classe. Qualquer <div>
   não animado inserido no meio de um painel desloca todos os atrasos seguintes
   sem quebrar nada e sem avisar, que é o tipo de defeito que só aparece três
   edições depois e nunca é atribuído a esta linha. Com o índice no elemento, o
   que anda junto é o que está escrito que anda junto.

   Dezoito regras viraram uma, e a cascata deixou de ter teto em seis. */
.rv-in .mod__arte :is(.lrow, .prd, .tli, .bub, .msg, .tool) {
  animation-delay: calc(60ms + var(--i, 0) * 70ms);
}

/* --- 01: as barras de progresso dos entregadores enchem ---
   Mesma peça do rodízio de abas: scaleX(0→1) com transform-origin à esquerda.
   As três enchem juntas, depois das linhas — lê como "o painel acordou". */
.rv .mod__arte .minibar i { transform: scaleX(0); transform-origin: left; }
.rv-in .mod__arte .minibar i { animation: mod-enche .9s var(--e-casa) .3s both; }

/* --- 03: o checklist tica em sequência --- */
.rv .mod__arte .chk.done .cb { background: transparent; border-color: var(--hl); color: transparent; }
.rv-in .mod__arte .chk.done .cb { animation: mod-tica .3s var(--e-casa) both; }
/* mesmo motivo do bloco acima: o índice mora no elemento. Aqui a cascata sai
   de 300ms porque o ✓ tica DEPOIS de a linha ter chegado. */
.rv-in .mod__arte .chk .cb { animation-delay: calc(300ms + var(--i, 0) * 80ms); }

/* --- 05: a parada "agora" pulsa ---
   O pulso é o primitivo que o site reserva para dado AO VIVO (o ponto do
   badge, a pílula "em operação", os pinos do mapa). "Em rota agora" é
   exatamente isso. Duração 2.4s, fora de fase com os 2.2s do `.dot` do hero,
   para os dois não baterem juntos — que é a regra que a landing segue. */
.rv-in .mod__arte .tli.now::before { animation: livedot 2.4s ease-in-out infinite; }

/* --- levantar no ponteiro ---
   O mock ganha o mesmo lift dos cartões da landing (translateY(-3px), curva da
   casa) com a sombra de três camadas se aprofundando. */
@media (hover: hover) {
  .mod__arte .mock { transition: transform .3s var(--e-casa), border-color .25s, box-shadow .25s; }
  .mod__arte .mock:hover { transform: translateY(-3px); border-color: var(--hl);
    box-shadow: 0 3px 4px rgba(0,0,0,.16), 0 14px 26px -6px rgba(0,0,0,.24), 0 44px 78px -18px rgba(0,0,0,.52); }
  [data-theme="light"] .mod__arte .mock:hover {
    box-shadow: 0 3px 4px rgba(20,19,23,.07), 0 14px 26px -6px rgba(20,19,23,.10), 0 44px 78px -18px rgba(20,19,23,.20); }
}

/* --- respeitar quem pediu menos movimento ---
   Não basta desligar a animação: o estado inicial de cada efeito ESCONDE
   alguma coisa (opacidade 0, barra em scaleX(0), ✓ transparente). Desligar só
   o `animation` deixaria a página pela metade — pior que não ter movimento. */
@media (prefers-reduced-motion: reduce) {
  .rv .mod__arte .lrow,
  .rv .mod__arte .prd,
  .rv .mod__arte .tli,
  .rv .mod__arte .bub,
  .rv .mod__arte .chat > .msg { opacity: 1; }
  .rv .mod__arte .chat > .tool { opacity: .75; }
  .rv .mod__arte .minibar i { transform: none; }
  .rv .mod__arte .chk.done .cb { background: var(--ok); border-color: var(--ok); color: #0B0A0C; }
  /* `!important` aqui não é preguiça: `.rv-in .mod__arte *` é (0,2,1) e perde
     para TODA regra de animação acima, que são (0,3,0) ou mais. Sem ele a
     declaração é morta em 100% dos casos — a preferência do usuário ficaria
     escrita e ignorada, que é pior do que não ter escrito. Override de
     acessibilidade é o uso canônico do !important. */
  .rv-in .mod__arte *,
  .rv-in .mod__arte *::before { animation: none !important; }
  .mod__arte .mock { transition: none; }
}


/* O BLOCO DE PROVA (`.pcap`) saiu inteiro daqui. Ver a nota longa em
   modulos.html, onde a seção morava: em resumo, o assunto daquelas capturas
   era ausência de dado, então a seção era vazia por construção. Volta quando
   o app tiver dado real. O CSS sai junto com a marcação, no mesmo commit,
   porque regra órfã não quebra nada e é justamente por isso que fica.

   Cai junto a restrição que ela impunha: com as capturas fora, "um componente
   aparece OU desenhado OU capturado" deixa de valer, e o módulo 01 volta a
   poder desenhar o anel de Health Score. */


/* ============================================================
   04 · O PAR DE COMPROVANTES
   ============================================================
   O módulo 04 é o único em LARGURA TOTAL, e é de propósito: seis maquetes do
   mesmo tamanho na mesma moldura descendo em zigue-zague continuam sendo
   metrônomo, por mais densas que sejam. Quebrar a silhueta de um bloco custa
   menos do que redesenhar seis.

   E o par é o argumento. À esquerda o comprovante selado; à direita, menor,
   tracejado e parado, o MESMO comprovante quando não houve prova na rua. O
   contraste não custa uma alegação nova, é literal do CAPACIDADES ("preserva
   o valor do selo verdadeiro") e nenhum concorrente mostra.

   O papel imprime `Documento autêntico`, NÃO `Íntegro`. Íntegro é o veredito
   do verificador público, de quem cola o hash em /verificar. Carimbar a
   palavra do verificador no papel colapsa justamente a distinção que o módulo
   vende: o papel afirma, o terceiro sem login julga. */

.mod--largo .mod__cabeca { padding-top: 88px; }
.mod--largo .mod__cabeca .mod__texto {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(32px, 5vw, 88px); align-items: end;
}
.mod--largo .mod__cabeca .bullets { margin-top: 0; }
.rec-par {
  display: flex; align-items: flex-start; justify-content: center;
  gap: clamp(28px, 4vw, 72px);
  padding: 62px 32px 118px;   /* o rodapé é maior: a sombra do chão precisa de chão */
}
.rec-col { margin: 0; }
.rec-col--selado { flex: 0 1 520px; }
.rec-col--adm    { flex: 0 1 366px; padding-top: 26px; }
.rec-legenda {
  margin: 22px 2px 0; max-width: 40ch;
  font-size: 13.5px; line-height: 1.6; color: var(--mu);
}

/* --- o papel, portado de styles.css:356-371 + ientrega.css:417-479 --- */
.receipt-wrap { position: relative; }
.receipt-float { transform: translateY(var(--float, 0px)); will-change: transform; }
.receipt {
  position: relative; z-index: 1;
  background: var(--paper); color: var(--ink);
  border-radius: 6px;              /* papel não compartilha raio com UI */
  padding: 28px;
  transform: rotate(-.6deg);
  box-shadow:
    0 2px 3px rgba(0,0,0,.14),
    0 10px 20px -6px rgba(0,0,0,.22),
    0 34px 64px -18px rgba(0,0,0,.50),
    0 0 0 1px var(--rim);
  animation: flutua 7s ease-in-out .7s infinite backwards;
  will-change: transform;
}
[data-theme="light"] .receipt {
  box-shadow:
    0 2px 3px rgba(20,19,23,.07),
    0 10px 20px -6px rgba(20,19,23,.10),
    0 34px 64px -18px rgba(20,19,23,.22),
    0 0 0 1px var(--paper-bd);
  /* o aro aqui NÃO é enfeite: --paper é #FAF8F5, um branco QUENTE, e no tema claro
     --sf já valeu esse mesmo valor — o papel evaporava no fundo. Desde 18/ago --sf é
     #FFFFFF (branco frio), então os dois se separam por conta própria e o fio virou
     cinto e suspensório. Mantido: a diferença entre os dois é de poucos pontos e
     depende do monitor. Foi exatamente o defeito que a arte antiga deste módulo tinha. */
}
@keyframes flutua {
  0%, 100% { transform: rotate(-.9deg) translateY(-8px); }
  50%      { transform: rotate(-.3deg) translateY(8px); }
}

/* sombra projetada no chão: é ela que mais vende o "está no ar".
   [iE] TERCEIRA CALIBRAGEM. A da landing é preta e existe porque lá o papel
   só aparece sobre índigo; há um segundo bloco (ientrega.css:1612) só para
   isso. Aqui o fundo é --sf (#24242F no escuro), e preto a 42% sobre quase
   preto some — junto com a razão inteira de portar a peça. Vai a 78%, que
   sobre #24242F ainda escurece o suficiente para o olho ler chão.
   (O 78% foi calibrado contra o #111118 de antes; com o fundo clareado a
   sombra só ganhou, porque preto sobre chão mais claro contrasta mais.) */
.receipt-wrap::after {
  content: ""; position: absolute; left: 8%; right: 8%; bottom: -30px; height: 46px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(0,0,0,.78), transparent 72%);
  pointer-events: none; z-index: 0;
  animation: flutuaSombra 7s ease-in-out .7s infinite backwards;
}
[data-theme="light"] .receipt-wrap::after {
  background: radial-gradient(ellipse at center, rgba(20,19,23,.30), transparent 72%);
}
/* respira ao contrário: papel em cima = sombra maior, mais clara e mais
   difusa; em baixo = menor e mais densa. É o comportamento físico real. */
@keyframes flutuaSombra {
  0%, 100% { transform: scale(1.07); opacity: .58; filter: blur(18px); }
  50%      { transform: scale(.90);  opacity: .96; filter: blur(11px); }
}
/* pausa no ponteiro: dá para ler o comprovante parado */
.receipt-wrap:hover .receipt,
.receipt-wrap:hover::after { animation-play-state: paused; }

/* --- miolo do papel --- */
.receipt__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--paper-bd); }
.receipt .paper-label { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--paper-mu); }
.receipt__head .id { margin-top: 7px; font-size: 19px; font-weight: 600; letter-spacing: -.02em; }
.receipt__stamp {
  flex: none; font-family: 'JetBrains Mono', monospace; font-size: 9.5px;
  letter-spacing: .09em; text-transform: uppercase; padding: 6px 10px; border-radius: 4px;
  /* hex cravados: é tinta em papel, não pode seguir o tema da interface */
  background: #DFF3E9; color: #0F7A52;
}
.receipt__stamp--adm { background: #ECE8E1; color: #6B665E; }
.receipt__meta { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 16px 0; border-bottom: 1px solid var(--paper-bd); }
.receipt__meta .cap { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--paper-mu); }
.receipt__meta .val { margin-top: 5px; font-size: 15px; font-weight: 500; }
.receipt__meta .val--mono { font-family: 'JetBrains Mono', monospace; font-weight: 400; font-variant-numeric: tabular-nums; }
.receipt__proofs { display: grid; grid-template-columns: 1.15fr .85fr; gap: 16px; padding-top: 16px; }
.rec-cap { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--paper-mu); }
.receipt__sign { margin-top: 8px; height: 96px; border: 1px dashed #D8D3CA; border-radius: 6px; display: flex; align-items: center; justify-content: center; background: #FFFDFA; }
.rec-gps { margin-top: 8px; height: 96px; border: 1px solid var(--paper-bd); border-radius: 6px; background: #F3EFE8; display: grid; place-items: center; }
.rec-gps svg { display: block; }

/* as duas molduras de foto ficam VAZIAS e ROTULADAS, sobre hachura.
   A página não tem foto real de entrega e não vai inventar uma: numa página
   que vende prova, foto falsa é a contradição mais cara possível. A hachura
   diz "aqui existe uma imagem que não é sua para ver". */
.rec-fotos { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px; }
.rec-foto {
  height: 74px; border-radius: 6px; border: 1px solid var(--paper-bd);
  display: grid; place-items: center; text-align: center;
  background:
    repeating-linear-gradient(-45deg, #EDE8E0 0 6px, #F4F0EA 6px 12px);
}
.rec-foto span { font-family: 'JetBrains Mono', monospace; font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--paper-mu); }
.receipt__foot { margin-top: 16px; padding-top: 13px; border-top: 1px solid var(--paper-bd); display: flex; justify-content: space-between; gap: 12px; font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--paper-mu); }
.receipt__hash { margin-top: 10px; font-family: 'JetBrains Mono', monospace; font-size: 9.5px; line-height: 1.7; color: var(--paper-mu); word-break: break-all; font-variant-ligatures: none; }
.receipt__hash b { display: block; color: var(--ink); font-weight: 600; margin-bottom: 2px; }

/* --- o comprovante administrativo: MESMO PAPEL, parado e sem flutuar ---
   Ele é papel branco nos dois temas, igual ao selado, e isso não é detalhe de
   gosto: o argumento da seção é que os DOIS são o mesmo documento, um com
   prova de campo e outro sem. Na primeira versão ele era um esqueleto
   tracejado transparente — aquilo comparava MATERIAIS diferentes, o que
   enfraquece a comparação, e ainda custava legibilidade no tema escuro.

   O que separa os dois passa a ser COMPORTAMENTO, não material: este não
   flutua, não recebe [data-float], e tem sombra rasa de objeto pousado na
   mesa, contra as três camadas do que está no ar. */
.receipt--adm {
  padding: 22px; rotate: 2deg; transform: none;
  animation: none; will-change: auto;
  background: var(--paper); color: var(--ink); border: 0;
  box-shadow: 0 1px 2px rgba(0,0,0,.18), 0 8px 18px -12px rgba(0,0,0,.38), 0 0 0 1px var(--paper-bd);
}
[data-theme="light"] .receipt--adm {
  box-shadow: 0 1px 2px rgba(20,19,23,.05), 0 8px 18px -12px rgba(20,19,23,.14), 0 0 0 1px var(--paper-bd);
}
/* numa coluna de 366px o cabeçalho em linha esmagava os dois lados: o rótulo
   quebrava em três linhas e o número do pedido em duas. Aqui ele empilha, e a
   diferença de arranjo entre os dois papéis ajuda a leitura — o de baixo não é
   uma cópia menor do de cima, é outro documento. */
.receipt--adm .receipt__head { flex-direction: column; align-items: flex-start; gap: 13px; }
.receipt--adm .receipt__head .id { margin-top: 0; font-size: 17px; }
/* o carimbo neutro continua neutro, agora em tinta de papel */
.receipt--adm .receipt__stamp { background: #ECE8E1; color: var(--paper-mu); }
/* A LINHA QUE FALTA FICA EM TINTA, NÃO EM VERMELHO. O documento é legítimo: o
   CAPACIDADES diz que a conclusão administrativa existe para PRESERVAR o valor
   do selo verdadeiro. Vermelho aqui dentro faria o papel parecer inválido, e a
   página perderia justamente o argumento de que aquilo É um comprovante, só
   que mais fraco. Quem sinaliza é o rótulo de FORA do papel. */
.rec-semprova {
  margin-top: 16px; padding: 15px 0 3px;
  font-size: 13.5px; color: var(--paper-mu);
}

/* OS DOIS RÓTULOS SÃO O PLACAR DA SEÇÃO: verde no que tem prova, vermelho no
   que não tem. Eles não descrevem os documentos, comentam o que cada um tem e
   o que falta — sinal editorial mora na página, nunca dentro do artefato, que
   é por isso que nenhum dos dois papéis muda de cor por dentro.

   Verde e vermelho juntos são o par que mais falha em daltonismo, e aqui isso
   está coberto: a cor REFORÇA um texto que já diz "Comprovante selado" e "Sem
   prova de campo". Quem não distingue as duas cores lê exatamente a mesma
   informação nas palavras. Cor sozinha nunca carrega o significado. */
.rec-col--selado .rot { color: var(--ok); }
.rec-col--adm .rot { color: var(--bad); }

/* --- assinatura que se desenha (ientrega.css:99-101, portado) --- */
.receipt__sign svg path { stroke-dasharray: 340; stroke-dashoffset: 340; }
.rv-in .receipt__sign svg path { animation: sign-draw 1.6s .35s var(--e-traco) forwards; }
@keyframes sign-draw { to { stroke-dashoffset: 0; } }

/* --- a cena: ~2,4s, uma passada, e só então o loop --- */
@keyframes rec-pousa   { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes rec-carimbo { from { opacity: 0; transform: scale(1.06); }      to { opacity: 1; transform: none; } }
@keyframes rec-adm     { from { opacity: 0; } to { opacity: 1; } }

.rv .rec-col--selado .receipt-wrap { opacity: 0; }
.rv-in .rec-col--selado .receipt-wrap { animation: rec-pousa .7s var(--e-casa) both; }
.rv .rec-col--selado .receipt__stamp { opacity: 0; }
.rv-in .rec-col--selado .receipt__stamp { animation: rec-carimbo .26s var(--e-casa) .9s both; }
.rv .rec-col--adm { opacity: 0; }
.rv-in .rec-col--adm { animation: rec-adm .46s var(--e-casa) 1.3s both; }

/* --- escada responsiva --- */
@media (max-width: 1000px) {
  .mod--largo .mod__cabeca { padding-top: 64px; }
  .mod--largo .mod__cabeca .mod__texto { grid-template-columns: 1fr; gap: 28px; }
  .mod--largo .mod__cabeca .bullets { margin-top: 4px; }
  .rec-par { flex-direction: column; align-items: center; gap: 46px; padding: 48px 32px 96px; }
  .rec-col--selado, .rec-col--adm { flex: 0 1 auto; width: min(100%, 520px); }
  .rec-col--adm { padding-top: 0; }
}
@media (max-width: 620px) {
  .receipt { padding: 20px; }
  .receipt--adm { padding: 18px; }
  .receipt__proofs { grid-template-columns: 1fr; }
  .rec-par { padding: 40px 20px 84px; }
  /* no celular o carimbo em linha rouba metade da largura e o nome do cliente
     quebra em três. Empilhado, o cabeçalho devolve a linha inteira aos dois. */
  .receipt__head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .receipt__head .id { margin-top: 0; font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  /* de novo o estado FINAL, nominalmente: o papel parado no ângulo de repouso,
     o carimbo aceso, a assinatura desenhada e o administrativo visível. */
  .receipt { animation: none; transform: rotate(-.6deg); }
  .receipt-wrap::after { animation: none; transform: none; opacity: .8; }
  .receipt-float { transform: none; }
  .receipt__sign svg path { stroke-dashoffset: 0; }
  .rv .rec-col--selado .receipt-wrap,
  .rv .rec-col--selado .receipt__stamp,
  .rv .rec-col--adm { opacity: 1; }
  .rv-in .rec-par *,
  .rv-in .rec-par *::before,
  .rv-in .rec-par *::after { animation: none !important; }
}
