/* ============================================================================
   ATT — tokens do sistema de design da plataforma
   Servido em /portal-static/att-tokens.css · consumido pelas 6 superfícies
   (portal, /status, /kafka, terminal FND, terminal CHP, Demandas).

   Fonte única de verdade de cor. Antes disto havia quatro: portal.css,
   o CSS do CHP, o <style> inline do FND e strings hardcoded no switcher.js.

   PALETA DE MARCA (compromisso fixo, ver PRODUCT.md):
     azul #017CC2 · amarelo #F5C300 · navy #073F5A e #081F33

   REGRA DE OURO DO AMARELO: #F5C300 tem contraste ~1.6:1 sobre branco.
   No tema claro ele é SEMPRE preenchimento com texto navy por cima, nunca
   texto sobre fundo claro. Por isso os estados são triplas (bg/fg/border)
   e não cores soltas — nenhuma superfície precisa improvisar.
   ========================================================================== */

/* ---------------------------------------------------------------- fontes -- */
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ------------------------------------------------------ marca (fixa) -- */
  --att-blue: #017CC2;
  --att-yellow: #F5C300;
  --att-navy: #073F5A;
  --att-navy-deep: #081F33;

  /* ----------------------------------------------------------- tipos --- */
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* Escala fixa em rem, razão ~1.2 (Operate: nada de tipografia fluida).
     O -3xs existe porque o vocabulário de micro-caps em mono dos terminais
     depende dele; abaixo de 11px o mono deixa de ser legível. */
  --fs-3xs: 0.6875rem;  /* 11px — micro-caps em mono */
  --fs-2xs: 0.75rem;    /* 12px */
  --fs-xs:  0.8125rem;  /* 13px */
  --fs-sm:  0.875rem;   /* 14px */
  --fs-base: 1rem;      /* 16px */
  --fs-lg:  1.125rem;   /* 18px */
  --fs-xl:  1.375rem;   /* 22px */
  --fs-2xl: 1.75rem;    /* 28px */
  --fs-3xl: 2.25rem;    /* 36px */
  --fs-4xl: 3rem;       /* 48px — números-herói (saldo do FND) */

  --lh-tight: 1.15;   /* @kind other */
  --lh-snug: 1.35;    /* @kind other */
  --lh-base: 1.55;    /* @kind other */

  --ls-caps: 0.12em;   /* micro-caps em mono */
  --ls-caps-wide: 0.22em;
  --ls-tight: -0.02em; /* números e títulos grandes */

  /* --------------------------------------------------------- espaço ---- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.25rem;  --sp-6: 1.5rem;   --sp-8: 2rem;     --sp-10: 2.5rem;
  --sp-12: 3rem;    --sp-16: 4rem;

  /* ---------------------------------------------------------- forma ---- */
  --r-sm: 6px; --r-md: 9px; --r-lg: 12px; --r-xl: 16px; --r-pill: 999px;

  /* Alvo de toque mínimo. Campo, no celular, com luva. */
  --touch-min: 44px;

  /* --------------------------------------------------------- movimento -- */
  --t-fast: 120ms;    /* @kind other */
  --t-base: 180ms;    /* @kind other */
  --t-slow: 260ms;    /* @kind other */
  --ease: cubic-bezier(.4, 0, .2, 1);   /* @kind other */

  /* @kind other */
  --z-sticky: 20; --z-overlay: 60; --z-panel: 70; --z-toast: 90;
}

/* ============================================================== DARK ====== */
/* Cena: sala de controle, turno noturno, celular no pátio de madrugada.
   Herda a escala dos terminais, que é a mais forte que já existia. */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  --bg:            #06182a;
  --bg-gradient-a: rgba(1, 124, 194, .18);
  --bg-gradient-b: rgba(245, 195, 0, .06);
  --surface:       #0c2840;
  --surface-raised:#11324f;
  --surface-sunken: #041220;

  /* Ver "REGRA DAS BORDAS" no fim do arquivo. */
  --border:        #1d486e;
  --border-strong: #2e5e8a;
  --border-interactive: #6b93b8;  /* >=4.07:1 sobre bg/surface/raised */

  --text:       #eaf2f9;
  --text-muted: #a3b9cd;
  /* faint carrega os micro-caps de 11px (eyebrow, metric__sub, live), então
     precisa de 4.5:1 — não do piso de texto grande. Aferido contra bg,
     surface E raised: 6.14 / 5.16 / 4.51. */
  --text-faint: #829aaf;
  --text-on-accent: #ffffff;
  --text-on-warm:   #06182a;

  /* Azul de interação. O #017CC2 puro rende só ~2.6:1 sobre o --bg escuro,
     então o interativo usa a variante clara e o puro fica para preenchimento. */
  --accent:       #37a8e6;
  --accent-hover: #5cbdf0;
  --accent-fill:  #017CC2;
  --accent-soft:  rgba(55, 168, 230, .14);

  --warm:      #F5C300;
  --warm-soft: rgba(245, 195, 0, .14);

  /* Semânticos */
  --ok:      #34d399;  --ok-soft:     rgba(52, 211, 153, .13);
  --warn:    #fbbf24;  --warn-soft:   rgba(251, 191, 36, .13);
  --danger:  #f87171;  --danger-soft: rgba(248, 113, 113, .14);
  --info:    #37a8e6;  --info-soft:   rgba(55, 168, 230, .13);

  /* Texto dentro de pill/badge soft: no escuro a própria cor já contrasta. */
  --ok-fg: #6ee7b7; --warn-fg: #fcd34d; --danger-fg: #fca5a5; --info-fg: #7dd3fc;

  /* Fluxos do terminal (recepção/expedição) — informação, não decoração.
     Eram verde e laranja: duas famílias de fora da marca, e no mapa do CHP
     brigavam com --ok/--danger (que são ESTADO) e com a foto de satélite. Agora
     são as DUAS cores da marca — azul e amarelo — que se separam por matiz E por
     luminância, deixando verde e vermelho livres para significar estado. */
  --fluxo-recep: #4aa8f0;
  --fluxo-exped: #F5C300;

  /* Produto movimentado. Açúcar é branco, e essa leitura é informação — por isso
     é token próprio e não uma superfície genérica. Grãos usa o amarelo da marca. */
  --produto-acucar:    #e9eef3;   /* 12.91:1 sobre o card; texto navy dá 14.34:1 */
  --produto-acucar-fg: #081F33;
  --produto-graos:     var(--warm);
  --produto-graos-fg:  var(--text-on-warm);

  /* Tinta SOBRE FOTO (mapa do CHP). NÃO muda com o tema, porque o substrato é a
     imagem de satélite e a imagem não tem tema. São os únicos valores do sistema
     deliberadamente iguais nos dois modos — está declarado aqui uma vez só, em
     vez de repetido no bloco claro, exatamente para não ser "esquecido" e virar
     texto navy com halo escuro em cima de uma foto clara. */
  --map-ink:      #eaf2f9;
  --map-ink-dim:  #a3b9cd;
  --map-halo:     rgba(3, 14, 26, .9);
  /* Não existe mais --map-ink-warm. Dado sobre o mapa era escrito em amarelo, e o
     amarelo passou a SIGNIFICAR expedição (ver --map-exped): número dourado sobre
     correia dourada desaparece. Todo dado no mapa é --map-ink com halo escuro. */

  /* Mesma doutrina, aplicada às FORMAS do mapa e não só ao texto. O mapa colore o
     CAMINHO DO PRODUTO (recepção/expedição) e nada mais: elevador, moega, bica,
     tulha e caixa auxiliar ficam neutros e se distinguem pela SILHUETA. Antes eram
     sete famílias de cor literais no app.js (rosa elevador, ciano auxiliar…) e o
     mapa lia como confete sobre a foto.
     --map-casing é o contorno escuro que descola o equipamento da imagem: sem ele
     qualquer cor cai para ~2:1 em cima do trecho claro do telhado. */
  /* Tinta FOSCA, não cor de saturação cheia. O azul #4aa8f0 e o amarelo puro da
     marca #F5C300 sobre a foto liam como desenho animado; painel industrial usa
     pigmento dessaturado, que continua se separando da imagem sem gritar.
     São DEFAULTS: o editor do mapa sobrescreve cor e opacidade por família e
     grava no layout.json. */
  --map-recep:  #5b95bf;
  --map-exped:  #c9a227;
  --map-neutro: #8a97a3;
  /* Estado no mapa. Verde só ficou disponível para "operando" PORQUE saiu de
     recepção: enquanto fluxo era verde/laranja, operando tinha de se anunciar em
     branco a 35% e não se via. Agora verde no mapa significa uma coisa só. */
  --map-live:   #4fb286;
  --map-alarme: #d9615c;
  --map-edge:   rgba(233, 242, 249, .30);
  --map-casing: rgba(3, 14, 26, .6);
  /* Estruturas (armazém, células, silos, moinhos): contorno translúcido de propósito
     — a foto embaixo mostra o prédio real. Preservados como estavam. */
  --map-estru-fill: rgba(11, 36, 61, .22);
  --map-estru-line: #5b93c4;

  /* Série categórica de gráfico — ver "REGRA DE GRÁFICO" no fim do arquivo.
     Ordem fixa, nunca ciclada. Validada contra a superfície #0c2840. */
  --viz-1: #3987e5;  --viz-2: #d95926;  --viz-3: #199e70;
  --viz-4: #c98500;  --viz-5: #d55181;  --viz-6: #9085e9;
  --viz-grid: rgba(255, 255, 255, .07);
  --viz-axis: #2e5e8a;

  --shadow-sm: 0 2px 8px rgba(0, 0, 0, .3);
  --shadow:    0 6px 28px rgba(0, 0, 0, .38);
  --shadow-lg: 0 16px 44px rgba(0, 0, 0, .5);

  --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);
}

/* ============================================================== LIGHT ===== */
/* Cena: celular no pátio sob sol, e tela grande em sala iluminada.
   Derivado, não invertido: fundo levemente frio da família navy, texto
   navy em vez de preto puro, e contraste alto para leitura sob sol. */
[data-theme="light"] {
  color-scheme: light;

  --bg:            #eef3f8;
  --bg-gradient-a: rgba(1, 124, 194, .07);
  --bg-gradient-b: rgba(245, 195, 0, .05);
  --surface:       #ffffff;
  /* raised precisa ser MAIS ESCURO que surface no claro, senão card dentro de
     card não se distingue. #f6f9fc dava 1.057 sobre branco — invisível. Este
     valor dá 1.140, o mesmo degrau que o escuro tem (#11324f sobre #0c2840 =
     1.143), então o aninhamento lê igual nos dois temas. */
  --surface-raised:#eaf1f7;
  --surface-sunken: #e2eaf3;

  --border:        #cbd9e6;
  --border-strong: #96afc7;
  --border-interactive: #6d8ba6;  /* >=3.19:1 sobre surface/raised/bg */

  --text:       #08243a;  /* navy, não preto — 15.9:1 sobre --surface */
  --text-muted: #3d6180;  /* 6.5:1 */
  /* Aferido contra os TRÊS fundos (surface 5.18, bg 4.64, raised 4.54). O valor
     anterior (#55718a) caía a 4.48 sobre raised depois que raised escureceu. */
  --text-faint: #547089;
  --text-on-accent: #ffffff;
  --text-on-warm:   #081F33;

  /* No claro o azul precisa escurecer para servir de texto/ícone. */
  --accent:       #0166a2;  /* 5.4:1 sobre branco */
  --accent-hover: #014f7f;
  --accent-fill:  #017CC2;
  --accent-soft:  rgba(1, 102, 162, .10);

  /* Amarelo permanece o da marca, mas só como preenchimento. */
  --warm:      #F5C300;
  --warm-soft: rgba(245, 195, 0, .22);

  --ok:      #0f7a4f;  --ok-soft:     rgba(15, 122, 79, .11);
  --warn:    #8a5a00;  --warn-soft:   rgba(245, 195, 0, .24);
  --danger:  #c0322c;  --danger-soft: rgba(192, 50, 44, .10);
  --info:    #0166a2;  --info-soft:   rgba(1, 102, 162, .10);

  /* Em pill soft no claro, o texto é a própria cor escura (já contrastada). */
  --ok-fg: #0b5c3b; --warn-fg: #6d4700; --danger-fg: #a3211c; --info-fg: #014f7f;

  /* Azul e amarelo da marca, calibrados para o tema claro. O amarelo é sempre
     PREENCHIMENTO (chip, amostra de legenda) com --text-on-warm por cima — como
     tinta sobre branco dá ~1,6:1 e reprovaria. Ver regra 2 no fim do arquivo.
     ATENÇÃO: estes valem em SUPERFÍCIE DE CARD (chip, legenda). As formas do mapa
     usam --map-recep/--map-exped, que não seguem tema porque ficam sobre a foto. */
  --fluxo-recep: #0166a2;   /* 5,4:1 sobre branco */
  --fluxo-exped: #F5C300;

  /* No claro um chip branco desapareceria no fundo branco, então açúcar assume
     um slate. Perde a literalidade do branco e mantém o que importa: continuar
     distinguível de grãos (amarelo) e legível. 5.15:1 com texto branco. */
  --produto-acucar:    #5b7080;
  --produto-acucar-fg: #ffffff;
  --produto-graos:     var(--warm);
  --produto-graos-fg:  var(--text-on-warm);

  /* Série categórica — passos próprios para a superfície clara, não inversão.
     Slot 1 é o azul da marca (#017CC2), que valida em claro.
     viz-2 foi escurecido de #eb6834 para #e26432: o original passava sobre
     branco mas caía a 2.81 sobre --surface-raised, e as barras do histórico do
     FND ficam justamente dentro de um card raised. Revalidado no validador da
     skill dataviz depois da troca (CVD adjacente ΔE 8.7, all-pairs 1↔2 ΔE 21.3). */
  --viz-1: #017CC2;  --viz-2: #e26432;  --viz-3: #1baf7a;
  --viz-4: #b0740a;  --viz-5: #e87ba4;  --viz-6: #4a3aa7;
  --viz-grid: rgba(8, 36, 58, .09);
  --viz-axis: #96afc7;

  --shadow-sm: 0 1px 3px rgba(8, 36, 58, .10);
  --shadow:    0 4px 16px rgba(8, 36, 58, .12);
  --shadow-lg: 0 12px 32px rgba(8, 36, 58, .16);

  --focus-ring: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
}

/* ============================================================================
   REGRA DAS BORDAS — três tokens porque são três trabalhos diferentes.

   --border              hairline estrutural: linha de tabela, contorno de card,
                         divisor. É DE PROPÓSITO discreto (~1.5:1) e não precisa
                         de 3:1: a WCAG 1.4.11 exige 3:1 de quem *identifica um
                         componente*, não de decoração. Escurecer isto deixaria
                         card e tabela pesados e ruidosos.
   --border-strong       hairline de ênfase: aresta de painel, superfície elevada.
                         Também decorativo.
   --border-interactive  fronteira de CONTROLE — input, select, textarea, botão
                         com contorno, tile focável. Garantido >=3:1 contra
                         bg/surface/raised nos dois temas. Todo controle usa este.

   Era exatamente aqui que o portal errava: input em #0a1d2b sobre card #0f2536
   com borda #1c3a50 dava ~1.3:1, e os campos liam como buracos na tela.

   REGRA DO AMARELO — #F5C300 rende ~1.6:1 sobre branco. Nunca é texto sobre
   fundo claro. É preenchimento com --text-on-warm por cima, ou hairline/ícone
   sobre fundo escuro. No tema claro, "aviso" como TEXTO usa --warn (#8a5a00),
   não o amarelo da marca.

   ---------------------------------------------------------------------------
   REGRA DE GRÁFICO

   --viz-1..6 são IDENTIDADE de série (categórica), em ordem fixa e NUNCA
   cicladas: uma 7ª série vira "Outros", múltiplos pequenos ou facetas. Cor
   segue a entidade, nunca a posição no ranking — filtrar séries não pode
   repintar as que sobraram.

   --ok/--warn/--danger são ESTADO e são reservados: não servem de "série 4".
   Estado sempre vem com rótulo, nunca só com cor (é o caso do /kafka, onde
   RUNNING/PAUSED/FAILED são estado e por isso usam esta paleta, com legenda).

   Validado com o validador da skill dataviz contra as duas superfícies reais
   (#0c2840 escuro, #ffffff claro): banda de luminosidade, piso de croma,
   separação para daltonismo (pior par adjacente ΔE 8.4 protan no escuro),
   piso de visão normal (ΔE 19.3) e contraste — todos passam.

   RESSALVA no tema claro: --viz-3 (2.82:1) e --viz-5 (2.69:1) ficam abaixo de
   3:1 sobre branco. Vale a regra de alívio — quem usar esses dois slots no
   claro precisa de rótulo direto visível ou visão de tabela. Os gráficos
   atuais usam só os slots 1 e 2, que passam com folga.

   NUNCA dois eixos Y. Duas medidas de escala diferente = dois gráficos.
   ========================================================================== */

/* ============================================================================
   ESCOPO DE TEMA — por elemento, nao so na raiz.

   Os blocos de token acima usam `[data-theme="..."]`, e nao
   `:root[data-theme="..."]`. Duas consequencias, as duas desejadas:

   1. um tema pode valer numa SUBARVORE (`<div data-theme="dark">` dentro de uma
      pagina clara), o que antes era impossivel — os tokens so existiam na raiz;
   2. a especificidade dos blocos de tema cai de (0,2,0) para (0,1,0), empatando
      com `:root`. O claro continua vencendo porque vem DEPOIS no arquivo.

   NAO existe mais o bloco `@media (prefers-color-scheme: light)` com
   `:root:not([data-theme])`. Ele duplicava o conjunto claro inteiro — a segunda
   fonte de verdade que este arquivo nasceu para eliminar — e definia tokens sob
   um seletor que nao nomeia tema. Removido em 18/08/2026.

   Consequencia: sem `data-theme` estampado, a pagina abre no ESCURO, que e o
   `:root` base. Quem estampa e o `att-theme.js` (sincrono no `<head>`, antes do
   primeiro paint) e, no portal, o proprio Jinja no servidor. Com JavaScript
   desligado nas superficies estaticas o resultado e escuro em vez de seguir a
   preferencia do sistema — degradacao aceitavel e legivel, porque o escuro e a
   escala primaria do dominio.
   ========================================================================== */
