/* ==========================================================================
   Portogoia — Base: tokens, reset e primitivos
   --------------------------------------------------------------------------
   DIREÇÃO: CONTRASTE.

   A premissa é onde isto vai ser aberto: um celular barato, com a tela cheia
   de digital, no meio de uma cozinha quente e com sol batendo na janela.
   Nenhum cinza sutil sobrevive a isso.

   Daí as regras, e todas elas são deliberadas:

     · preto puro sobre creme, sem meio-tom decorativo;
     · borda de 2px, sempre visível — nada de hairline de 1px que some;
     · sombra dura (deslocada, sem desfoque). Sombra borrada é uma sugestão
       de profundidade; sombra dura é um fato, e sobrevive a tela ruim;
     · zero gradiente. Além de brutalista, é o que renderiza instantâneo em
       aparelho fraco;
     · vermelho da marca só em ação e em alerta. Se tudo é vermelho, nada é
       urgente;
     · alvo de toque de 48px, porque quem usa está com a mão ocupada.

   O modo escuro não é um tema diferente: é a mesma linguagem invertida —
   preto vira o fundo, branco vira a borda.

   --------------------------------------------------------------------------
   O QUE FOI ACRESCENTADO SEM SAIR DA DIREÇÃO

   Três primitivos novos, todos escritos na linguagem acima:

     · a LOMBADA (`[data-rail]`) — 8px de cor chapada na borda esquerda de
       qualquer linha com situação. É a etiqueta da prateleira, e existe para
       não repetir a mesma regra em cada componente;
     · o TRILHO (`.fluxo`) — o desenho de produção → CD → unidade;
     · o ESQUELETO (`.skel`) — silhueta do conteúdo enquanto ele não chega,
       em chapa lisa e pulso de opacidade, nunca em degradê.

   E duas escalas em token, para o tamanho parar de ser decidido caso a caso:
   `--fs-*` (tipografia) e `--s1…--s10` (espaço).
   ========================================================================== */

:root {
  color-scheme: light;

  /* Superfícies — creme em vez de branco puro: descansa o olho sob luz forte
     e faz o branco dos cartões virar hierarquia em vez de ruído. */
  --bg:            #fffdf5;
  --surface:       #ffffff;
  --surface-2:     #fffdf5;
  --surface-3:     #f0f0ee;
  --overlay:       rgba(0, 0, 0, 0.55);

  /* Tinta — preto puro. Contraste 21:1, o máximo possível. */
  --ink:           #000000;
  --ink-2:         #2b2a27;
  --muted:         #55534d;
  --line:          #000000;
  --line-2:        #000000;
  --line-strong:   #000000;
  --borda:         2px;

  /* Marca */
  --brand:         #e01b16;
  --brand-strong:  #b31410;
  --brand-ink:     #ffffff;
  --brand-soft:    #ffe4e3;
  --brand-soft-2:  #ffc9c7;

  /* Faixas escuras (sidebar, rodapé, login) — preto, não grafite. */
  /* PAINEL INVERTIDO — a faixa preta que aparece na landing, no rodapé e na
     lateral do login. Ela é escura nos DOIS temas, e por isso não pode sair de
     `--ink`: no tema escuro `--ink` é branco, e o painel virava branco com o
     texto branco que estava fixo em cima. Era o "site todo bugado no escuro".

     No claro é preto cheio. No escuro é um degrau acima do fundo — preto sobre
     preto não teria borda visível de painel nenhum. */
  --painel:        #000000;
  --painel-ink:    #ffffff;
  --painel-suave:  rgba(255, 255, 255, 0.68);
  --painel-linha:  rgba(255, 255, 255, 0.16);

  --slate:         #000000;
  --slate-2:       #1a1a18;
  --slate-line:    rgba(255, 255, 255, 0.14);
  --slate-ink:     rgba(255, 255, 255, 0.72);

  /* Dados — preto para a série, vermelho só na semana corrente. */
  --series:        #000000;
  --series-accent: #e01b16;
  --series-soft:   rgba(0, 0, 0, 0.10);
  --grid:          #d8d6cf;
  --axis:          #000000;

  /* Status — cores chapadas, sem transparência, sempre com ícone + rótulo. */
  --ok:            #00994d;
  --ok-bg:         #d7f2e4;
  --ok-ink:        #00593c;
  --warn:          #ffc800;
  --warn-bg:       #fff1c2;
  --warn-ink:      #4a3800;
  --serious:       #ff6a00;
  --serious-bg:    #ffe3cc;
  --serious-ink:   #5c2800;
  --crit:          #e01b16;
  --crit-bg:       #ffe0de;
  --crit-ink:      #8f100c;
  --info:          #0055d4;
  --info-bg:       #dde9ff;
  --info-ink:      #002f78;

  /* Elevação: deslocamento sem desfoque. É a assinatura da direção. */
  --shadow-sm:  2px 2px 0 var(--ink);
  --shadow-md:  4px 4px 0 var(--ink);
  --shadow-lg:  6px 6px 0 var(--ink);
  --stamp:      2px 2px 0 var(--ink);
  --stamp-lg:   3px 3px 0 var(--ink);
  /* Foco em amarelo: o vermelho já é ação e alerta, e sobrepor os três
     significados na mesma cor apagaria a diferença entre eles. */
  --ring:       0 0 0 3px #ffc800;

  /* Forma: canto reto. O raio zero é o que faz borda de 2px parecer traço
     de carimbo em vez de cartão arredondado. */
  --r-sm: 0;
  --r-md: 0;
  --r-lg: 0;
  --r-full: 0;
  --container: 1180px;

  /* Alturas do cabeçalho fixo e do rodapé. São token porque a seção de
     contato cresce até `100dvh − topo − rodapé`: se qualquer um dos dois
     mudar e o número aqui não acompanhar, sobra uma folga no fim da página
     ou o topo da chamada some atrás do cabeçalho.
     MEDIDO, não estimado: o rodapé quebra em duas linhas de link em todas as
     larguras de desktop, e são 84px. Mexeu nos links do rodapé, confira. */
  --h-topo:   68px;
  --h-rodape: 84px;

  /* Espaço em token: o tamanho para de ser decidido caso a caso. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 20px;
  --s6: 24px; --s7: 32px; --s8: 40px; --s9: 56px; --s10: 80px;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Escala tipográfica. Os nomes dizem a função, não o tamanho — é o que
     impede "só aumentar um pouquinho" caso a caso. */
  --fs-micro: 11.5px;
  --fs-mini:  12.5px;
  --fs-sm:    13.5px;
  --fs-body:  15px;
  --fs-lead:  17px;
  --fs-h4:    15px;
  --fs-h3:    18px;
  --fs-h2:    23px;
  --fs-h1:    30px;
  --fs-num:   34px;
  --fs-num-lg: 46px;

  --tight:  -0.025em;
  --tighter: -0.045em;
}

/* A mesma linguagem invertida: o papel vira tinta e a tinta vira papel.
   Só vale quando o visitante PEDE o escuro. O padrão é claro em qualquer
   sistema: quem abre o site no celular à noite não pediu tema escuro, e
   `theme.js` escreve data-theme="light" antes da primeira pintura — este
   bloco existe apenas para quem chegar sem JavaScript. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;

    --bg:            #0a0a09;
    --surface:       #141412;
    --surface-2:     #0a0a09;
    --surface-3:     #24241f;
    --overlay:       rgba(0, 0, 0, 0.72);

    --ink:           #ffffff;
    --ink-2:         #e2e0d8;
    --muted:         #a8a59b;
    --line:          #ffffff;
    --line-2:        #ffffff;
    --line-strong:   #ffffff;

    --brand:         #ff4a44;
    --brand-strong:  #ff6f6a;
    --brand-ink:     #1a0000;
    --brand-soft:    #3d100e;
    --brand-soft-2:  #571714;

    --painel:        #141412;
    --painel-ink:    #ffffff;
    --painel-suave:  rgba(255, 255, 255, 0.68);
    --painel-linha:  rgba(255, 255, 255, 0.16);

    --slate:         #000000;
    --slate-2:       #141412;
    --slate-line:    rgba(255, 255, 255, 0.16);
    --slate-ink:     rgba(255, 255, 255, 0.72);

    --series:        #ffffff;
    --series-accent: #ff4a44;
    --series-soft:   rgba(255, 255, 255, 0.14);
    --grid:          #2e2e28;
    --axis:          #ffffff;

    --ok:            #2ee08a;
    --ok-bg:         #08331f;
    --ok-ink:        #6df0b2;
    --warn:          #ffc800;
    --warn-bg:       #3a2d00;
    --warn-ink:      #ffd84d;
    --serious:       #ff8c3d;
    --serious-bg:    #3d1f00;
    --serious-ink:   #ffb37a;
    --crit:          #ff4a44;
    --crit-bg:       #3d0f0d;
    --crit-ink:      #ff8b86;
    --info:          #5b9bff;
    --info-bg:       #0a1f47;
    --info-ink:      #9dc2ff;

    --shadow-sm:  2px 2px 0 var(--ink);
    --shadow-md:  4px 4px 0 var(--ink);
    --shadow-lg:  6px 6px 0 var(--ink);
    --stamp:      2px 2px 0 var(--ink);
    --stamp-lg:   3px 3px 0 var(--ink);
    --ring:       0 0 0 3px #ffc800;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:            #0a0a09;
  --surface:       #141412;
  --surface-2:     #0a0a09;
  --surface-3:     #24241f;
  --overlay:       rgba(0, 0, 0, 0.72);

  --ink:           #ffffff;
  --ink-2:         #e2e0d8;
  --muted:         #a8a59b;
  --line:          #ffffff;
  --line-2:        #ffffff;
  --line-strong:   #ffffff;

  --brand:         #ff4a44;
  --brand-strong:  #ff6f6a;
  --brand-ink:     #1a0000;
  --brand-soft:    #3d100e;
  --brand-soft-2:  #571714;

  --painel:        #141412;
  --painel-ink:    #ffffff;
  --painel-suave:  rgba(255, 255, 255, 0.68);
  --painel-linha:  rgba(255, 255, 255, 0.16);

  --slate:         #000000;
  --slate-2:       #141412;
  --slate-line:    rgba(255, 255, 255, 0.16);
  --slate-ink:     rgba(255, 255, 255, 0.72);

  --series:        #ffffff;
  --series-accent: #ff4a44;
  --series-soft:   rgba(255, 255, 255, 0.14);
  --grid:          #2e2e28;
  --axis:          #ffffff;

  --ok:            #2ee08a;
  --ok-bg:         #08331f;
  --ok-ink:        #6df0b2;
  --warn:          #ffc800;
  --warn-bg:       #3a2d00;
  --warn-ink:      #ffd84d;
  --serious:       #ff8c3d;
  --serious-bg:    #3d1f00;
  --serious-ink:   #ffb37a;
  --crit:          #ff4a44;
  --crit-bg:       #3d0f0d;
  --crit-ink:      #ff8b86;
  --info:          #5b9bff;
  --info-bg:       #0a1f47;
  --info-ink:      #9dc2ff;

  --shadow-sm:  2px 2px 0 var(--ink);
  --shadow-md:  4px 4px 0 var(--ink);
  --shadow-lg:  6px 6px 0 var(--ink);
  --stamp:      2px 2px 0 var(--ink);
  --stamp-lg:   3px 3px 0 var(--ink);
  --ring:       0 0 0 3px #ffc800;
}

/* =============================================================== reset ==== */

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

/* O atributo hidden tem a mesma especificidade de uma classe — sem isto,
   qualquer classe com "display" definido (.field, .count, etc.) vence a
   ordem de cascata e o elemento "escondido" continua aparecendo. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 {
  margin: 0; font-weight: 800; line-height: 1.08; letter-spacing: -0.035em; color: var(--ink);
}
/* Caixa alta só nos dois níveis de maior peso: aplicada a tudo, vira grito e
   deixa de destacar o que importa. */
h1, h2 { text-transform: uppercase; font-weight: 900; letter-spacing: -0.045em; }
p { margin: 0; }
img, svg { max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
table { border-collapse: collapse; width: 100%; }

/* Foco em amarelo e grosso: é o que se enxerga numa tela lavada de sol, e
   não se confunde com o vermelho de ação nem com o de alerta. */
:focus-visible { outline: 3px solid #ffc800; outline-offset: 2px; border-radius: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 999;
  background: var(--brand); color: var(--brand-ink);
  padding: 10px 16px; border: var(--borda) solid var(--ink); font-weight: 800;
  text-transform: uppercase;
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* ========================================================= utilitários ==== */

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 24px; }
@media (max-width: 640px) { .container { padding-inline: 18px; } }

/* Fita: retângulo chapado, sem borda e sem raio. Substitui o traço fino de
   antes, que sumia em tela ruim. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px; background: var(--brand); color: var(--brand-ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.eyebrow-plain { background: transparent; color: var(--muted); padding-inline: 0; }

.lede { color: var(--ink-2); font-size: 17.5px; line-height: 1.65; }
.muted { color: var(--muted); }
.tnum { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); font-size: .92em; }

/* Número de painel: num produto de estoque, o número é lido antes da palavra. */
.big {
  font-size: var(--fs-num); font-weight: 900;
  letter-spacing: -0.05em; line-height: 1; font-variant-numeric: tabular-nums;
}
.big small { font-size: var(--fs-sm); font-weight: 700; letter-spacing: 0; color: var(--muted); margin-left: 5px; }
.bigger { font-size: var(--fs-num-lg); }

/* =============================================================== marca ==== */

/* AQUI, E NÃO EM `site.css`: o painel interno e o do cliente não carregam
   aquela folha. Ver a nota lá. */
.logo { display: inline-flex; align-items: center; }
.logo-slot { display: inline-flex; align-items: center; }
/* 40px e não 32: com o logotipo de verdade a altura passou a carregar a
   palavra "EMBALAGENS", que a 32px virava textura. Cabe nos dois lugares que
   o hospedam — o cabeçalho do site e a marca da barra lateral, ambos de 64px
   de altura, com 130px de largura numa coluna de 260px. */
.logo-img { display: block; height: 40px; width: auto; }
/* O wordmark é REDE, não a marca. Ele existiu como substituto enquanto o
   logotipo oficial não tinha sido fornecido; agora que a arte está em
   `assets/img/logo-portogoia.svg`, ele só aparece se o arquivo falhar ao
   carregar — e aí é melhor um texto do que um espaço vazio onde a empresa
   deveria estar. */
.logo-slot .wordmark { display: none; }
.logo-slot.sem-arquivo .wordmark { display: inline-flex; }

.wordmark {
  font-size: 20px; font-weight: 800; letter-spacing: -0.045em;
  text-transform: uppercase; color: var(--ink); line-height: 1;
}
.wordmark em { font-style: normal; color: var(--brand); }

/* ============================================================== botões ==== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 48px; padding: 12px 22px;
  font-size: 15px; font-weight: 800; letter-spacing: 0.01em; text-transform: uppercase;
  border: var(--borda) solid var(--ink); cursor: pointer; white-space: nowrap;
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-sm);
  transition: transform .08s ease, box-shadow .08s ease, background-color .12s ease;
}
/* O botão afunda para dentro da própria sombra. É o feedback de clique mais
   barato que existe e não depende de cor nenhuma para ser percebido. */
.btn:active { transform: translate(2px, 2px); box-shadow: none; }
.btn svg { width: 17px; height: 17px; flex: none; }

.btn-primary { background: var(--brand); color: var(--brand-ink); }
.btn-primary:hover { background: var(--brand-strong); }

.btn-ghost { background: var(--surface); color: var(--ink); }
.btn-ghost:hover { background: var(--surface-3); }

/* Preto cheio: ação de gravar e de criar. Vermelho fica reservado à ação de
   negócio da tela (cotar, fechar pedido, pagar) — vermelho repetido em botão
   de salvar deixa de significar urgência. */
.btn-slate { background: var(--slate); color: #fff; border-color: var(--ink); }
.btn-slate:hover { background: var(--slate-2); }

/* Único botão sem moldura: para ação secundária dentro de linha de tabela,
   onde uma borda por linha viraria grade dentro da grade. */
.btn-quiet {
  background: transparent; color: var(--ink); border-color: transparent;
  box-shadow: none; min-height: 40px; padding-inline: 12px;
  text-decoration: underline; text-underline-offset: 3px;
}
.btn-quiet:hover { background: var(--surface-3); }
.btn-quiet:active { transform: none; }

.btn-danger { color: var(--crit-ink); }
.btn-danger:hover { background: var(--crit-bg); }

.btn-sm { min-height: 38px; padding: 7px 14px; font-size: var(--fs-mini); box-shadow: 2px 2px 0 var(--ink); }
.btn-sm svg { width: 15px; height: 15px; }
.btn-lg { min-height: 56px; padding: 16px 28px; font-size: 16.5px; box-shadow: var(--shadow-md); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; }

/* Estado de espera: o rótulo FICA. Trocar por "Aguarde…" muda a largura do
   botão e a tela pula debaixo do dedo de quem acabou de clicar. */
.btn.is-busy { pointer-events: none; opacity: .75; }
.btn.is-busy::after {
  content: ""; width: 13px; height: 13px; flex: none;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: 50%; animation: girar .6s linear infinite;
}

/* =============================================================== chips ==== */

/* Etiqueta chapada com moldura: em Contraste a cor sozinha nunca carrega o
   significado, porque cor chapada em tela ruim vira mancha. A borda garante
   a leitura da forma mesmo quando a cor falha. */
.chip, .stamp {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border: 1.5px solid currentColor;
  font-size: var(--fs-mini); font-weight: 800; line-height: 1.4; white-space: nowrap;
  text-transform: uppercase; letter-spacing: .02em;
  background: var(--surface-3); color: var(--ink);
}
.chip .dot, .stamp .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.chip svg, .stamp svg { width: 14px; height: 14px; flex: none; }

.chip-ok,      .stamp-ok      { background: var(--ok-bg);      color: var(--ok-ink); }
.chip-warn,    .stamp-warn    { background: var(--warn-bg);    color: var(--warn-ink); }
.chip-serious, .stamp-serious { background: var(--serious-bg); color: var(--serious-ink); }
.chip-crit,    .stamp-crit    { background: var(--crit-bg);    color: var(--crit-ink); }
.chip-info,    .stamp-info    { background: var(--info-bg);    color: var(--info-ink); }
.chip-brand,   .stamp-brand   { background: var(--brand-soft); color: var(--brand); }
.chip-slate,   .stamp-slate   { background: var(--surface-3);  color: var(--ink-2); }
/* Carimbo cheio, para a afordância que precisa vencer a tela toda. */
.stamp-ink { background: var(--ink); color: var(--bg); border-color: var(--ink); }

/* ============================================================= lombada ==== */

/* A lombada: 8px de cor chapada colados na borda esquerda de qualquer linha
   ou cartão que tenha situação. Fica sempre no mesmo lugar, em todas as
   telas, e por isso deixa de precisar de legenda. É a mesma faixa grossa que
   o cartão de item já usava — promovida a utilitário para não ser reescrita
   em cada componente. */
[data-rail] { position: relative; }
[data-rail]::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px;
  background: var(--ink);
}
[data-rail="ok"]::before      { background: var(--ok); }
[data-rail="warn"]::before    { background: var(--warn); }
[data-rail="serious"]::before { background: var(--serious); }
[data-rail="crit"]::before    { background: var(--crit); }
[data-rail="info"]::before    { background: var(--info); }
[data-rail="ink"]::before     { background: var(--ink); }
[data-rail="none"]::before    { display: none; }

/* =============================================================== cartão === */

.card {
  background: var(--surface);
  border: var(--borda) solid var(--ink);
  box-shadow: var(--shadow-md);
}

/* ========================================================= formulários ==== */

.field { display: flex; flex-direction: column; gap: 6px; }
/* `.rotulo` existe para o campo que NÃO é um input: um grupo de botões, por
   exemplo. `<label>` sem `for` e sem input dentro não rotula coisa nenhuma —
   é marcação que parece acessível e não é. O grupo se rotula por
   `aria-labelledby` apontando para este span, e a aparência é a mesma. */
.field > label, .field > .rotulo {
  font-size: var(--fs-mini); font-weight: 800; color: var(--ink);
  text-transform: uppercase; letter-spacing: .04em;
}

.input, .select, .textarea {
  width: 100%; min-height: 46px; padding: 11px 13px;
  background: var(--surface);
  border: var(--borda) solid var(--ink);
  font-size: 15px;
  transition: box-shadow .12s ease;
}
.input::placeholder, .textarea::placeholder { color: var(--muted); }
.input:focus, .select:focus, .textarea:focus { outline: none; box-shadow: var(--ring); }
.input:disabled, .textarea:disabled, .select:disabled {
  background: var(--surface-3); color: var(--muted); cursor: not-allowed; border-style: dashed;
}
.textarea { resize: vertical; min-height: 96px; }
.select {
  appearance: none; padding-right: 36px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2355534d' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 12px center;
}
.field-error { font-size: var(--fs-mini); color: var(--crit-ink); }
.field-error:not(:empty) { font-weight: 700; }
.input.is-invalid, .textarea.is-invalid, .select.is-invalid {
  border-color: var(--crit); box-shadow: 3px 3px 0 var(--crit);
}

.checkline { display: flex; align-items: center; gap: 9px; font-size: 14.5px; color: var(--ink-2); cursor: pointer; }
.checkline input { width: 17px; height: 17px; accent-color: var(--brand); cursor: pointer; flex: none; }

/* ========================================================== alternador ==== */

/* Interruptor quadrado, com moldura: a posição do bloco diz o estado mesmo
   para quem não distingue as cores. */
.switch { position: relative; display: inline-block; width: 46px; height: 26px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; cursor: pointer;
  border: var(--borda) solid var(--ink); background: var(--surface-3);
  transition: background-color .15s ease;
}
.switch .track::before {
  content: ""; position: absolute; height: 16px; width: 16px; left: 3px; top: 3px;
  background: var(--ink); transition: transform .15s ease;
}
.switch input:checked + .track { background: var(--brand); }
.switch input:checked + .track::before { background: var(--brand-ink); transform: translateX(20px); }
.switch input:focus-visible + .track { box-shadow: var(--ring); }
.switch input:disabled + .track { opacity: .45; cursor: not-allowed; }

/* ======================================================== botão de tema === */

/* `flex: none` porque 40px declarado não é 40px entregue: dentro de um flex
   apertado — o cabeçalho de um celular de 360 — o botão encolhia para 31px de
   largura e virava um alvo que o dedo erra. Altura ninguém espreme; largura,
   sim, e era o que acontecia. */
.theme-toggle {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  background: var(--surface); border: var(--borda) solid var(--ink); color: var(--ink);
  cursor: pointer; transition: background-color .15s ease;
}
.theme-toggle:hover { background: var(--surface-3); color: var(--ink); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: none; }
}

/* =============================================================== aviso ==== */

.toast-stack {
  position: fixed; right: 20px; bottom: 20px; z-index: 200;
  display: flex; flex-direction: column; gap: 10px; max-width: min(380px, calc(100vw - 40px));
}
.toast {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 13px 15px;
  background: var(--surface); border: var(--borda) solid var(--ink);
  box-shadow: var(--shadow-md); font-size: 14px; color: var(--ink);
  animation: toast-in .22s cubic-bezier(.2,.8,.3,1);
}
/* Faixa de cor na lateral: diz o tipo do aviso antes de qualquer leitura. */
.toast-ok   { border-left: 8px solid var(--ok); }
.toast-info { border-left: 8px solid var(--info); }
.toast-crit { border-left: 8px solid var(--crit); }
.toast svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.toast-ok svg { color: var(--ok); }
.toast-info svg { color: var(--info); }
.toast-crit svg { color: var(--crit); }
.toast strong { display: block; font-weight: 800; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ============================================================ esqueleto === */

/* Enquanto o instantâneo não chega: a forma do conteúdo, não um disco girando
   no meio de uma tela vazia. Chapa lisa com pulso de opacidade — o brilho
   deslizante que se costuma usar aqui é um degradê, e degradê não sobrevive a
   tela lavada de sol. */
.skel {
  background: var(--surface-3);
  border: var(--borda) solid var(--ink);
  animation: skel 1.4s ease-in-out infinite;
}
@keyframes skel { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

@keyframes girar { to { transform: rotate(360deg); } }

/* ============================================================= o fluxo ==== */

/* O trilho: produção → CD Portogoia → sua unidade. É o desenho do negócio
   inteiro, e por isso reaparece na landing e nos estados vazios — sempre
   igual, para virar reconhecimento e não decoração. */
.fluxo { display: flex; align-items: stretch; }
.fluxo-no {
  flex: 1; min-width: 0; position: relative;
  padding: var(--s4) var(--s4) var(--s4) var(--s5);
  border: var(--borda) solid var(--ink); border-right: 0; background: var(--surface);
}
.fluxo-no:last-child { border-right: var(--borda) solid var(--ink); }
.fluxo-no .n {
  font-family: var(--font-mono); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.fluxo-no .t { display: block; font-size: var(--fs-body); font-weight: 800; margin-top: 3px; text-transform: uppercase; letter-spacing: var(--tight); }
.fluxo-no .d { display: block; font-size: var(--fs-sm); color: var(--muted); margin-top: 4px; line-height: 1.5; }
/* O nó da Portogoia é preto cheio: é onde o serviço acontece. */
.fluxo-no.is-nosso { background: var(--painel); border-color: var(--ink); }
.fluxo-no.is-nosso .n { color: var(--painel-suave); }
.fluxo-no.is-nosso .t { color: var(--painel-ink); }
.fluxo-no.is-nosso .d { color: var(--painel-suave); }
@media (max-width: 720px) {
  .fluxo { flex-direction: column; }
  .fluxo-no { border-right: var(--borda) solid var(--ink); border-bottom: 0; }
  .fluxo-no:last-child { border-bottom: var(--borda) solid var(--ink); }
}

/* ======================================================== barra medidor === */

/* Medidor de saldo com marca do ponto de reposição. Moldura preta e barra
   chapada: sem a moldura, a barra vazia some no fundo creme. */
.meter {
  display: block; position: relative; height: 10px;
  background: var(--surface-3); border: var(--borda) solid var(--ink); overflow: hidden;
}
.meter i {
  position: absolute; inset: 0 auto 0 0;
  background: var(--ink); transition: width .5s cubic-bezier(.2,.8,.3,1);
}
.meter .mark { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--ink); }
.meter[data-s="ok"] i   { background: var(--ok); }
.meter[data-s="warn"] i { background: var(--warn); }
.meter[data-s="crit"] i { background: var(--crit); }

/* ==================================================== botões no celular === */

/* Caixa alta e peso 800 alongaram os rótulos, e `white-space: nowrap` fazia o
   botão do herói passar da largura da tela em 390px. Em tela estreita o
   rótulo pode quebrar — texto cortado é pior que texto em duas linhas. */
@media (max-width: 520px) {
  .btn { white-space: normal; text-wrap: balance; padding-inline: 16px; }
  .btn-lg { font-size: 15px; padding-inline: 18px; }
}
