/* Dandelion bundle for Playground — GENERATED by tools/bundle-css.py from the vault source. Do not edit. */
@import url('https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@300;400;500;600&family=JetBrains+Mono:wght@300;400;500;700&display=swap');

/* ---- styles.css ---- */
/* ===========================================================================
   machado.group — Design System  ·  global entry
   ---------------------------------------------------------------------------
   Consumers link THIS one file. It is a manifest of @imports only — no rules
   live here. Two layers, kept separate: TOKENS (the shipped foundation) and
   COMPONENTS (vanilla class implementations on top of those tokens).
   =========================================================================== */

/* ---- fonts ------------------------------------------------------------ */

/* ---- tokens/fonts.css ---- */
/* ===========================================================================
   machado.group — Webfonts
   ---------------------------------------------------------------------------
   The canonical faces of the system (serif retired 2026-07-24 — Baskervville
   dropped from all surfaces; the display/heading face is now a geometric
   grotesk in the Aeonik family):
     - Hanken Grotesk: geometric grotesk   (display / headings / the core face,
                                           Aeonik-like — replaces the serif)
     - IBM Plex Mono: monospace          (labels, eyebrows, wordmark)
     - JetBrains Mono: technical mono     (PRIMARY body face — incl. light 300)
   Doto (dot-matrix, the "luzinha" numerals) was the fourth face and was
   REMOVED in contract 6: it earned its place on a readout that had already
   moved to JetBrains, so what it actually bought was one more webfont request
   for a flourish. Numerals are one face — see --font-numeric.
   The system uses TWO faces: grotesk (display/headings) + mono (everything
   else). Serif and sans are retired — --font-serif is aliased to the grotesk
   and --font-sans to mono, both for back-compat only.
   All three are open and self-hostable. This file loads them from Google Fonts
   for prototyping; production surfaces (or CSP-restricted artifacts) graduate
   to self-hosted woff2 @font-face rules — nothing else in the system changes,
   it all reads from the --font-* tokens in typography.css.
   =========================================================================== */



/* ---------------------------------------------------------------------------
   VCR OSD Mono — A FACE DO PAINEL  [escolhida por ele em 25-ago-2026]
   ---------------------------------------------------------------------------
   Ganhou a prova das 14 monos instaladas na máquina dele por três razões, e
   nenhuma é gosto:

     13,22 de tinta   a mais densa das 14 — 22% acima da Menlo que era o default.
                      A malha de LED escurece uma fração FIXA da área, então
                      densa não é "mais bonita": é a que SOBREVIVE à malha.
     acentos          ÁÀÂÃÉÊÍÓÔÕÚÜÇ completos, conferidos glifo a glifo. A
                      Rigidon Mono era a 3ª em tinta e caiu exactamente aqui.
     é a coisa        é uma fonte de on-screen display de vídeo. As outras 13
                      imitam o painel; esta É o painel.

   AUTO-HOSPEDADA DE PROPÓSITO. Ela está instalada no Mac dele, e é justamente
   por isso que o @font-face é obrigatório: sem ele a identidade do painel só
   existiria na máquina de quem a tem instalada, e toda superfície servida —
   flavio.machado.group, artifact, deck de cliente — cairia no fallback sem
   avisar ninguém. O .woff2 tem 18KB e vive ao lado deste arquivo.

   PENDENTE, e é decisão dele: o arquivo NÃO traz campo de licença embutido
   (nameID 13/14 ausentes). Circula há anos como gratuita, mas antes de entrar
   em superfície de CLIENTE isso precisa de confirmação escrita. Em ferramenta
   interna — dash, runbook, status — segue sem ressalva.
   --------------------------------------------------------------------------- */
@font-face {
  font-family: 'VCR OSD Mono';
  src: url("tokens/fonts/vcr-osd-mono.woff2") format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}


/* ---- tokens (foundation) ---------------------------------------------- */

/* ---- tokens/colors.css ---- */
/* ===========================================================================
   machado.group — Color
   ---------------------------------------------------------------------------
   Two layers:
     1. PALETTE  — raw, named values. Never reference these directly in UI.
     2. SEMANTIC — role aliases. DARK is the default (`:root`, applied unless
                    `data-theme="light"` is set); LIGHT is the opt-out.
                    Components reference ONLY these.
   Mood: warm paper light, near-black dark, a single WHITE accent (the one
   bold color — orange RETIRED 2026-07-24, removed 2026-07-27), a SIGNAL BLUE
   as the secondary house colour (gradient white → blue → cool cyan), and
   red / green / yellow status "luzinhas".
   =========================================================================== */

:root {
  /* ---- PALETTE : warm neutral (ink) scale ------------------------------- */
  --c-white:     #ffffff;
  --c-paper:     #f4f2ec;   /* bone — default page in light          */
  --c-paper-2:   #fcfbf8;   /* warm white — raised card               */
  --c-sand:      #edeae2;   /* cream — sunken / alt card              */
  --c-sand-2:    #e4e0d6;   /* deeper cream                           */
  --c-gray-200:  #d8d4c9;   /* hairline-on-cream                      */
  --c-gray-300:  #bcb7aa;
  --c-gray-400:  #928e83;
  --c-gray-500:  #6f6b62;
  --c-gray-600:  #524f49;
  --c-gray-700:  #3a3833;
  --c-gray-800:  #242320;
  --c-gray-900:  #141312;   /* ink                                    */
  --c-black:     #0c0c0c;   /* near-black — dark page                 */
  --c-ink-2:     #121212;   /* dark raised card                       */
  --c-ink-3:     #1e1e1e;   /* dark inset — o degrau que faltava       */
  --c-ink-0:     #080808;   /* dark sunken                            */
  /* os degraus de TOQUE e de ÂNCORA — vieram do app de treino (22-set-2026,
     ordem dele). Ficam no meio da escala de propósito: toque é um passo, não
     uma cor nova. */
  --c-ink-00:          #060606;   /* dark anchor — barra, menu            */
  --c-chip-dark:       #151515;
  --c-press-dark:      #201f1c;
  --c-press-soft-dark: #151413;
  --c-chip-light:      #e9e6dd;
  --c-press-light:     #c8c3b6;
  --c-press-soft-light:#ded9cf;

  /* ---- PALETTE : signal blue (the secondary house colour) ---------------
     Sampled from refs/index.md — uploads/ref-blue-border.png: a rim that runs
     near-white → bright blue → deep blue, with a cool cyan tail. This is the
     only chromatic family in the system besides status. */
  --c-signal-050: #eaf2ff;
  --c-signal-100: #c1dcfc;  /* light rim                              */
  --c-signal-200: #9bc0fa;
  --c-signal-300: #5992f7;
  --c-signal-500: #2f6bf5;  /* SIGNAL core                            */
  --c-signal-600: #2350b3;
  --c-signal-700: #1d459f;  /* deep                                   */
  --c-signal-cyan: #aae8fa; /* cool tail of the gradient              */

  /* ---- PALETTE : status -------------------------------------------------- */
  --c-red-100:    #fcdad8;
  --c-red-500:    #e5403b;
  --c-red-600:    #c8302c;
  --c-green-100:  #d8ecdd;
  --c-green-500:  #3fa45e;
  --c-green-600:  #2f8049;
  --c-yellow-100: #fbedc6;
  --c-yellow-500: #f5b81e;
  --c-yellow-600: #cf9606;

  /* ---- PALETTE : deck blue (dark-mode editorial accent) ----------------- */
  --c-blue-300:   #bcb4e0;  /* periwinkle                             */
  --c-blue-500:   #3b36f0;  /* electric                               */

  /* ---- PALETTE : azure (the "working" luzinha — vivid blue light) ------- */
  --c-azure-100:  #d8e8ff;
  --c-azure-300:  #bcd9fb;  /* working light border (locked default)  */
  --c-azure-400:  #3b8bff;
  --c-azure-500:  #0cc8ed;  /* working core — cyan (locked default)    */
  --c-azure-600:  #0f54e6;

  /* ---- PALETTE : voltage (amarelo sólido — a nota de sinalização) -------
     Medido em refs/index.md → uploads/…a38b1c.jpg: o cartão de voo em amarelo
     chapado com conteúdo preto. Não é status (não pisca, não avisa): é uma
     CHAPA, para o botão que tem de ser visto de longe. */
  --c-volt-500:   #f8f808;
  --c-volt-600:   #e4e400;

  /* ---- PALETTE : teal (alternate accent — calm, dark-leaning) ----------- */
  --c-teal-50:    #eaf5f3;
  --c-teal-100:   #cfe8e4;
  --c-teal-300:   #95cdc6;
  --c-teal-400:   #7cc2ba;
  --c-teal-500:   #62b3aa;  /* ALT accent                             */
  --c-teal-600:   #4f9890;  /* hover / pressed                        */
  --c-teal-700:   #3d7a73;

  /* default color-scheme is dark (form controls, scrollbars) */
  color-scheme: dark;

  /* =====================================================================
     SEMANTIC ROLES  —  DARK  (default — near-black editorial)
     ===================================================================== */
  /* surfaces */
  --surface-page:     var(--c-black);
  --surface-raised:   var(--c-ink-2);
  --surface-sunken:   var(--c-ink-0);
  --surface-inset:    var(--c-ink-3);
  --surface-inverse:  var(--c-paper);
  /* papéis do app mobile (22-set-2026). ÂNCORA inverte de DENSIDADE, não de
     cor: no escuro é o mais preto da tela, no claro o mais denso. */
  --surface-anchor:     var(--c-ink-00);
  --surface-chip:       var(--c-chip-dark);
  --surface-press:      var(--c-press-dark);
  --surface-press-soft: var(--c-press-soft-dark);

  /* ink (text / icon)
     ---------------------------------------------------------------------
     A ESCADA SUBIU EM 04-set-2026. [ele, olhando o Tolkien Desk: "as fontes
     estão com um tom de cinza muito escuro, e é difícil de ler"]

     Ele estava certo e o número diz onde. Medido sobre os quatro fundos
     escuros da casa, antes:

       --ink            1.00   17,5:1   ✓
       --ink-secondary  0.60    6,6:1   ✓
       --ink-tertiary   0.40    3,5:1   ✗  abaixo do piso de 4,5:1
       --ink-disabled   0.24    2,0:1   ✗✗

     O réu é o TERCIÁRIO, e ele é o degrau que mais trabalha: eyebrow, rótulo
     de coluna, legenda de eixo, carimbo de rodapé — tudo que diz ONDE o
     número está. Um degrau que carrega informação e mede 3,5:1 não é
     hierarquia, é dado escondido. Hierarquia se faz com a DISTÂNCIA entre os
     degraus, não empurrando o de baixo para fora da leitura.

     A escada nova mantém os quatro degraus distintos e põe os três que
     carregam informação bem acima do piso — o terciário sai de 3,5:1 e chega
     a 9,2:1, em duas passadas no mesmo dia (a segunda está explicada abaixo).

       --ink            1.00   17,5:1   #f4f2ec
       --ink-secondary  0.86   12,9:1   #d4d2cd
       --ink-tertiary   0.72    9,2:1   #b3b2ad
       --ink-disabled   0.44    4,0:1   ← de propósito: desabilitado NÃO se
                                          lê, e a WCAG isenta. Subiu só o
                                          bastante para a peça continuar
                                          visível como peça.

     SEGUNDA PASSADA no mesmo dia, ordem dele: "more close to white". A
     primeira correção tirou o terciário do vermelho (3,5 → 6,2) e ele ainda
     leu cinza. Está certo: 6,2:1 PASSA na norma e mesmo assim a letra
     aparente é #93918e — cinza médio. A norma é piso de acessibilidade, não
     régua de conforto, e quem lê 12-15h por dia opera acima do piso.
     O terciário agora aparece como #b3b2ad e o secundário como #d4d2cd —
     ambos claramente tinta clara, não cinza.

     A conta que fecha, para quem for mexer: sobre estes fundos, o alfa
     mínimo para 4,5:1 é 0,48, e para 7:1 é 0,62. Abaixo de 0,48 nenhum tom
     de tinta desta casa se lê — é aritmética, não gosto. */
  --ink:              var(--c-paper);
  --ink-secondary:    rgba(244, 242, 236, 0.86);
  --ink-tertiary:     rgba(244, 242, 236, 0.72);
  --ink-disabled:     rgba(244, 242, 236, 0.44);
  --ink-inverse:      var(--c-gray-900);
  --ink-on-accent:    var(--c-black);

  /* lines / borders (alpha so they sit on any surface) */
  --line:             rgba(244, 242, 236, 0.12);
  --line-strong:      rgba(244, 242, 236, 0.24);
  --line-faint:       rgba(244, 242, 236, 0.07);

  /* accent — WHITE (the single bold color) */
  --accent:           var(--c-white);
  --accent-hover:     rgba(255, 255, 255, 0.86);
  --accent-press:     rgba(255, 255, 255, 0.70);
  --accent-tint:      rgba(255, 255, 255, 0.12);
  --accent-tint-2:    rgba(255, 255, 255, 0.20);
  --accent-ink:       var(--c-black);

  /* signal — the secondary house colour. White stays primary; signal carries
     the live/indicator layer (dots, rims, sweeps) and never the page action. */
  --signal:           var(--c-signal-500);
  --signal-soft:      var(--c-signal-300);
  --signal-light:     var(--c-signal-100);
  --signal-deep:      var(--c-signal-700);
  --signal-cyan:      var(--c-signal-cyan);
  --signal-tint:      rgba(47, 107, 245, 0.16);
  --signal-tint-2:    rgba(47, 107, 245, 0.28);
  /* GRADIENTE É LUZ, NÃO SUPERFÍCIE [ordem dele 01-out-2026: "a gente não
     utiliza gradiente"]. Estes tokens só alimentam o EFEITO de luz que varre
     (signal, bloom, a linha do agora do gantt). Card, painel, fundo e botão
     nunca levam gradiente. */
  --gradient-signal:  linear-gradient(118deg, #ffffff 0%, var(--c-signal-100) 24%, var(--c-signal-500) 62%, var(--c-signal-cyan) 100%);
  --gradient-signal-deep: linear-gradient(118deg, var(--c-signal-100) 0%, var(--c-signal-500) 46%, var(--c-signal-700) 100%);

  /* ---- LUZ (o default) ------------------------------------------------
     O gradiente dos DETALHES — fieiras, rims, luz de timeline, glow. É branco:
     varia luminosidade e alfa, nunca hue, com o papel da casa como meio-tom
     quente para não cair em cinza morto. O azul continua guardado em
     `--gradient-signal` e volta com `data-glow="signal"` no ancestral.
     Todo detalhe decorativo aponta para `--glow-*`, nunca para signal direto. */
  --gradient-light:   linear-gradient(118deg, #ffffff 0%, rgba(255,255,255,0.26) 30%, var(--c-paper) 66%, rgba(255,255,255,0.95) 100%);
  --glow-gradient:    var(--gradient-light);
  --glow-tint:        rgba(255, 255, 255, 0.16);
  --glow-tint-2:      rgba(255, 255, 255, 0.32);

  /* status (foreground / tint background) — locked light colors */
  --status-online:     #c2e368;   /* DONE — soft house green (HBF) */
  --status-online-bg:  color-mix(in srgb, var(--status-online), transparent 80%);
  --status-ondeck:     var(--c-yellow-500);  /* ON-DECK — worked on now */
  --status-ondeck-bg:  color-mix(in srgb, var(--status-ondeck), transparent 80%);
  --status-warning:    #f5e000;
  --status-warning-bg: color-mix(in srgb, var(--status-warning), transparent 80%);
  --status-progress:   var(--c-azure-500);
  --status-progress-bg: color-mix(in srgb, var(--status-progress), transparent 80%);
  --status-offline:    #e9048b;
  --status-offline-bg: color-mix(in srgb, var(--status-offline), transparent 80%);
  /* ALERTA — o laranja voltou, e voltou como ESTADO, não como cor de marca.
     A aposentadoria de 24-jul tirou o laranja do acento; isto aqui é outra
     coisa: o tom de alarme e destrutivo-armado, que a casa já usava cru em
     `key.css` (255,77,0) sem token nenhum. Registrado em 24-ago-2026 depois
     de o Eduardo cobrar o ícone laranja na tecla em falha.
     NÃO usar como acento decorativo — só onde algo deu errado ou vai doer. */
  --status-alert:      #ff4d00;
  --status-alert-rgb:  255, 77, 0;
  --status-alert-bg:   color-mix(in srgb, var(--status-alert), transparent 80%);

  /* TOM — os três tons do painel, agora fora do selo. 28-set-2026 [vector,
     achado do harvest na auditoria do Runbook do HBF].
     O `badge.css` cravava #c2e368 / #ff3300 / #f4f2ec dentro do próprio
     arquivo. Consumidor que precisa do MESMO tom fora da pílula — texto de
     linha travada, borda de item feito, traço de gráfico — não tinha de onde
     ler e cravava o hex outra vez. Cor é DADO (00_context/tint.md): três tons
     e só três, e o nome é do PAPEL, não da cor — o valor recalibra, o papel
     não.
     ATENÇÃO: --tone-held é o LARANJA #ff3300, não o âmbar que o comentário
     antigo do badge dizia. O valor manda; a palavra "âmbar" ali é herança.
     É irmão de --status-alert (#ff4d00) e não o mesmo: alert é "deu errado",
     held é "está travado esperando". Não trocar um pelo outro. */
  --tone-done:  #c2e368;   /* lima  — terminou bem, disponível, confirmado */
  --tone-held:  #ff3300;   /* travado, esgotado, fora do que se validou */
  --tone-live:  #f4f2ec;   /* acento — está acontecendo agora */

  /* ESCALA LIMA — 31-out-2026 [vector, pedido do playground-project, ordem
     dele 27-out: "use the lime theme… get it out with the Design Lab"].
     Promovida do Mission Control do lab (--mc-lime-1…7, --mc-past-b), hexes
     copiados, não medidos. Escala de PELE (skin, glow), não tom de estado:
     --tone-done continua sendo o papel "terminou bem". Aditivo — nada que já
     está no ar lê estes nomes antes desta data.
     Pares de leitura: escuro --lime-6 sobre --lime-floor · claro --lime-2
     sobre --lime-7. */
  --lime-1:     #2f5216;
  --lime-2:     #5f8f2c;
  --lime-3:     #9ccf3c;
  --lime-4:     #aed74b;
  --lime-5:     #c8ec7a;
  --lime-6:     #d9f28c;
  --lime-7:     #e6f7b8;
  --lime-floor: #16260d;   /* o chão escuro da lima (mc-past-b) */

  /* focus */
  --focus-ring:       var(--c-white);

  /* glass (frosted, translucent — buttons/chips over any backdrop) */
  --glass-bg:         rgba(244, 242, 236, 0.12);
  --glass-bg-hover:   rgba(244, 242, 236, 0.18);
  --glass-edge:       rgba(244, 242, 236, 0.14);
}

/* =====================================================================
   SEMANTIC ROLES  —  LIGHT  (opt-out: set data-theme="light")
   ===================================================================== */
[data-theme="light"] {
  color-scheme: light;

  --surface-page:     var(--c-paper);
  --surface-raised:   var(--c-paper-2);
  --surface-sunken:   var(--c-sand);
  --surface-inset:    var(--c-sand-2);
  --surface-inverse:  var(--c-gray-900);
  --surface-anchor:     var(--c-gray-200);
  --surface-chip:       var(--c-chip-light);
  --surface-press:      var(--c-press-light);
  --surface-press-soft: var(--c-press-soft-light);

  --ink:              var(--c-gray-900);
  --ink-secondary:    var(--c-gray-500);
  --ink-tertiary:     var(--c-gray-400);
  --ink-disabled:     var(--c-gray-300);
  --ink-inverse:      var(--c-paper);
  --ink-on-accent:    var(--c-white);

  --line:             rgba(20, 19, 18, 0.10);
  --line-strong:      rgba(20, 19, 18, 0.20);
  --line-faint:       rgba(20, 19, 18, 0.06);

  /* accent — INK (white is invisible on paper; the bold color inverts to ink) */
  --accent:           var(--c-gray-900);
  --accent-hover:     var(--c-gray-800);
  --accent-press:     var(--c-gray-700);
  --accent-tint:      rgba(20, 19, 18, 0.08);
  --accent-tint-2:    rgba(20, 19, 18, 0.16);
  --accent-ink:       var(--c-white);

  /* signal keeps its hue on paper; the gradient starts deeper so it reads */
  --signal:           var(--c-signal-600);
  --signal-soft:      var(--c-signal-500);
  --signal-light:     var(--c-signal-200);
  --signal-deep:      var(--c-signal-700);
  --signal-tint:      rgba(35, 80, 179, 0.12);
  --signal-tint-2:    rgba(35, 80, 179, 0.22);
  --gradient-signal:  linear-gradient(118deg, var(--c-signal-200) 0%, var(--c-signal-500) 40%, var(--c-signal-700) 100%);

  /* luz em papel: branco é invisível, então a luz inverte para ink — a mesma
     regra do acento. Continua a variar só valor, nunca hue. */
  --gradient-light:   linear-gradient(118deg, var(--c-gray-900) 0%, rgba(20,19,18,0.20) 30%, var(--c-gray-600) 66%, var(--c-gray-900) 100%);
  --glow-gradient:    var(--gradient-light); /* obrigatório: --glow-gradient resolve onde é DECLARADO, então o :root fixaria o branco e o ink acima seria código morto */
  --glow-tint:        rgba(20, 19, 18, 0.14);
  --glow-tint-2:      rgba(20, 19, 18, 0.26);

  --status-online:     #c2e368;
  --status-online-bg:  color-mix(in srgb, var(--status-online), transparent 86%);
  --status-ondeck:     var(--c-yellow-500);
  --status-ondeck-bg:  color-mix(in srgb, var(--status-ondeck), transparent 86%);
  --status-warning:    #f5e000;
  --status-warning-bg: color-mix(in srgb, var(--status-warning), transparent 86%);
  --status-progress:   var(--c-azure-500);
  --status-progress-bg: color-mix(in srgb, var(--status-progress), transparent 86%);
  --status-offline:    #e9048b;
  --status-offline-bg: color-mix(in srgb, var(--status-offline), transparent 86%);
  /* ALERTA — o laranja voltou, e voltou como ESTADO, não como cor de marca.
     A aposentadoria de 24-jul tirou o laranja do acento; isto aqui é outra
     coisa: o tom de alarme e destrutivo-armado, que a casa já usava cru em
     `key.css` (255,77,0) sem token nenhum. Registrado em 24-ago-2026 depois
     de o Eduardo cobrar o ícone laranja na tecla em falha.
     NÃO usar como acento decorativo — só onde algo deu errado ou vai doer. */
  --status-alert:      #ff4d00;
  --status-alert-rgb:  255, 77, 0;
  --status-alert-bg:   color-mix(in srgb, var(--status-alert), transparent 86%);

  --focus-ring:       var(--c-gray-900);

  --glass-bg:         rgba(20, 19, 18, 0.07);
  --glass-bg-hover:   rgba(20, 19, 18, 0.11);
  --glass-edge:       rgba(20, 19, 18, 0.10);
}

/* =====================================================================
   GLOW VARIATION  —  SIGNAL  (opt-in via [data-glow="signal"])
   ---------------------------------------------------------------------
   O azul guardado. O default da casa para detalhes é LUZ BRANCA
   (`--gradient-light`); ponha `data-glow="signal"` em <html>, numa seção
   ou numa peça e todo o gradiente decorativo dentro dela volta ao azul.
   Repõe só os três ponteiros `--glow-*` (+ as paradas da timeline) —
   surfaces, ink e status ficam intactos, e `.signal-dot` é azul sempre.
   ===================================================================== */
[data-glow="signal"] {
  --glow-gradient: var(--gradient-signal);
  --glow-tint:     var(--signal-tint);
  --glow-tint-2:   var(--signal-tint-2);
}

/* =====================================================================
   ALT ACCENT  —  TEAL  (opt-in via [data-accent="teal"])
   ---------------------------------------------------------------------
   A calmer, dark-leaning accent (~#62b3aa). Add data-accent="teal" on
   <html> (alone, or with the light theme). Overrides only the accent
   role tokens — surfaces, ink and status are untouched.
   ===================================================================== */
[data-accent="teal"] {
  --accent:        var(--c-teal-500);
  --accent-hover:  var(--c-teal-400);
  --accent-press:  var(--c-teal-300);
  --accent-tint:   rgba(98, 179, 170, 0.16);
  --accent-tint-2: rgba(98, 179, 170, 0.24);
  --accent-ink:    #0c0c0c;
  --focus-ring:    var(--c-teal-400);
}

[data-theme="light"][data-accent="teal"] {
  --accent:        var(--c-teal-500);
  --accent-hover:  var(--c-teal-600);
  --accent-press:  var(--c-teal-700);
  --accent-tint:   var(--c-teal-50);
  --accent-tint-2: var(--c-teal-100);
  --accent-ink:    var(--c-white);
  --focus-ring:    var(--c-teal-500);
}

/* =====================================================================
   ALT ACCENT  —  SIGNAL BLUE  (opt-in via [data-accent="blue"])
   ---------------------------------------------------------------------
   Promotes the secondary house colour to the accent role for views that
   need a chromatic focal point. Same discipline: one accent per view.
   ===================================================================== */
[data-accent="blue"] {
  --accent:        var(--c-signal-500);
  --accent-hover:  var(--c-signal-300);
  --accent-press:  var(--c-signal-600);
  --accent-tint:   rgba(47, 107, 245, 0.16);
  --accent-tint-2: rgba(47, 107, 245, 0.26);
  --accent-ink:    var(--c-white);
  --focus-ring:    var(--c-signal-300);
}

[data-theme="light"][data-accent="blue"] {
  --accent:        var(--c-signal-600);
  --accent-hover:  var(--c-signal-500);
  --accent-press:  var(--c-signal-700);
  --accent-tint:   var(--c-signal-050);
  --accent-tint-2: rgba(35, 80, 179, 0.18);
  --accent-ink:    var(--c-white);
  --focus-ring:    var(--c-signal-600);
}


/* ---- tokens/typography.css ---- */
/* ===========================================================================
   machado.group — Typography
   ---------------------------------------------------------------------------
   Families, weights, and a fixed type scale. Steps pair a size with a
   line-height and tracking; consume via the .h1 / .text-body / .mono-label
   utilities in components/type.css, or read the raw tokens directly.
   =========================================================================== */

:root {
  /* ---- families --------------------------------------------------------- */
  /* The system uses TWO faces: DISPLAY GROTESK (Aeonik-like — display,
     headings AND body prose, the core brand face) and MONO (UI chrome,
     labels, numerals, console). Serif and sans are retired: --font-serif is kept as an alias
     to the grotesk so existing references resolve to the new face, and
     --font-sans is aliased to mono. Nothing new should reach for either. */
  --font-display: 'Hanken Grotesk', 'Aeonik', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif; /* geometric grotesk — display / headings / core */
  --font-serif: var(--font-display);  /* retired — aliased to the display grotesk */
  --font-mono:  'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --font-mono-tech: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace; /* technical mono — chrome, labels, data */

  /* CONSOLE — a face de terminal, e ela existe separada por medição, não por
     gosto [vector, 24-ago-2026, pedido dele via opdash: "a tipografia que vai
     dentro do terminal é uma tipografia típica de terminal… algo similar ao
     terminal atual do VS Code"].

     O `.log` do runbook JÁ era mono e ainda assim não lia como terminal: o
     --font-mono da casa começa em IBM Plex Mono, que é mono de DOCUMENTO —
     contraste alto, terminações humanistas, desenhada para texto corrido. A
     do console é de grade fechada e desenho de máquina.

     NÃO se resolve trocando --font-mono: isso arrastaria junto todo rótulo
     mono da casa — selo, tabela, legenda, número. Por isso é token próprio,
     e por isso só o terminal o usa.

     Sem webfont de propósito: é a face do sistema, a mesma que o VS Code usa
     por default neste Mac. Custo zero de carregamento, e a familiaridade é o
     ponto.

     A ORDEM É MEDIDA, não copiada de um snippet [24-ago]:
       · `ui-monospace` NÃO pode vir primeiro. No Chromium ele resolve para a
         fonte fixa padrão (Courier), não para a SF Mono — e como casa sempre,
         a lista morre nele e nunca chega no Menlo. O log sairia em Courier.
       · `SF Mono` não é acessível por nome ao browser no macOS (é de sistema,
         restrita). Fica na lista por higiene, mas não conta com ela.
       · `Menlo` é o que existe de verdade aqui e é o default do VS Code no
         macOS. Por isso vem primeiro.
     Medido no próprio pane: Menlo mede 101,14px onde a lista com ui-monospace
     à frente media 84,47 — o mesmo valor do fallback genérico, que é como se
     descobre que a face pedida nunca entrou. */
  /* CLOCK — o número do painel.  [escolha dele, 25-ago-2026, olhando sete
     candidatas lado a lado no material do painel: "let's use Monaco for
     numbers with this style of board".]

     Não é capricho de fonte: dígito de mono de CÓDIGO tem ombro redondo e zero
     oval, e num painel de LED isso lê como texto, não como mostrador. O de
     Monaco é fechado e reto — o mesmo desenho dos relógios de cabeceira, que é
     exatamente a referência que ele pediu.

     Fica SEPARADO do --font-mono de propósito: o número do painel é a única
     coisa da casa que quer este desenho. Rótulo, tabela e legenda continuam no
     mono de sempre; misturar os dois numa frase corrida seria pior que não ter
     token nenhum.

     Sem webfont: Monaco é de sistema neste Mac. Custo zero, e foi medida ao
     vivo antes da escolha — três das candidatas instaladas nem chegam ao
     browser pelo nome (Aeion, GC Robuto, GC Monoglitch), e a IBM Plex Mono do
     --font-mono também não: cai no fallback há tempos. */
  /* O RELÓGIO CONTINUA MONACO — decisão dele de 24-ago, e não foi reaberta:
     a VCR ganhou a prova do PAINEL, não a do número grande. Onde os dois se
     encontram (o número DENTRO de uma pílula), quem manda é o painel, e por
     isso `.badge__n` lê --font-console, não este token. 'Courier New' saiu da
     cauda pela mesma medida que a tirou do console. */
  --font-clock: Monaco, Menlo, ui-monospace, monospace;

  /* A FACE DO PAINEL — VCR OSD Mono na frente desde 25-ago-2026 (c9).
     A cauda perdeu a 'Courier New': ela mediu 9,01 de tinta contra 13,22 da
     VCR, a ÚLTIMA das 14 medidas, e estava justamente no último degrau da
     pilha — o dia em que caísse nela, cairia na pior. Monaco e Menlo são as
     duas mais densas depois da VCR, e são as que ficam. */
  --font-console: 'VCR OSD Mono', Monaco, Menlo, 'SF Mono', SFMono-Regular, ui-monospace, monospace;
  /* O CORPO DO CONSOLE — 12px, e é token porque 10px era o PISO sendo usado
     como alvo [vector, 10-set-2026, ordem dele olhando o Drift Ops: "painel
     retro tá defasado, com legibilidade ruim"]. retro-panel-led.md mede: a
     10px sobre malha de passo 4 o traço da VCR tem 0,8px contra uma linha
     escura de 1px — a letra não escurece, some. Todo painel de instrumento
     estava cravando 10px porque era o número que o documento cita como
     mínimo, e mínimo virou default sem ninguém decidir. 12px é onde a letra
     ganha da malha. Quem consome escreve `var(--fs-console)`, nunca o número:
     é a alavanca única para o dia em que a malha ou a face mudarem. */
  --fs-console: 12px; /* @kind font */
  --font-numeric: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace; /* ALL numerals — figures, data, stats, counters */
  --font-sans:  var(--font-mono-tech);   /* retired — aliased to mono */
  /* ZERO CONSUMIDORES NA FONTE desde 28-set-2026 [vector, ordem dele olhando os
     Cards da OpDeck: "não tenho hierarquia… parece bula de remédio"]. O alias
     mandava PROSA para mono sem ninguém pedir: .accordion-item__body, título,
     feature, input e o próprio body do base.css. Cada consumidor foi apontado
     pelo PAPEL — prosa → --font-body, rótulo/chrome → --font-mono-tech — e o
     alias fica só para não quebrar consumidor fora da fonte. Nome de papel,
     nunca de família: quem escreve --font-sans hoje está pedindo o erro. */

  /* semantic body face — GROTESK. Prosa é grotesk; a mono fica com chrome,
     rótulo, número e console. [vector, 05-set-2026, ordem dele: "por que que
     cê tá usando essa fonte? Essa fonte tá errada", olhando prosa em mono
     numa página que colou o mg-head.]
     Até hoje --font-body apontava para --font-mono-tech, e o `body` do
     mg-head aplicava isso sozinho: TODA página da casa nascia com prosa em
     mono sem ninguém pedir. Quem precisa de mono no corpo pede explícito —
     [data-body="mono"] no container, ou .text-mono num bloco. */
  --font-body:  var(--font-display);

  /* ---- weights (restrained: light→semibold, no black) ------------------- */
  --weight-light:    300; /* @kind font */
  --weight-regular:  400; /* @kind font */
  --weight-medium:   500; /* @kind font */
  --weight-semibold: 600; /* @kind font */

  /* PESO DO RÓTULO EM CAIXA ALTA — 21-ago-2026, pedido do Eduardo.
     MECÂNICA, não gosto: caixa alta pequena com tracking largo perde peso
     APARENTE — as letras afastam e o traço fino some, sobretudo no escuro.
     A correção é peso real, não corpo maior: subir o tamanho faria o rótulo
     competir com o dado, que é o que um rótulo nunca pode fazer.
     Existe como TOKEN e não como 600 espalhado por treze folhas porque a
     pergunta "quanto pesa um rótulo desta casa" tem que ter UM lugar.
     Herança era a causa raiz: 22 das 30 regras não declaravam peso nenhum e
     herdavam --weight-light (300) do body. */
  --weight-label:    500; /* @kind font — 500 desde 19-set-2026: ordem dele 08-set ("bold não excessivo, mediano"); os utilitários de type.css já estavam em 500 e o token ficou em 600 sozinho */

  /* ---- tracking --------------------------------------------------------- */
  --tracking-tight:  -0.02em;   /* @kind font */
  --tracking-snug:   -0.01em;   /* @kind font */
  --tracking-normal:  0em;      /* @kind font */
  --tracking-wide:    0.08em;   /* @kind font */
  --tracking-wider:   0.14em;   /* @kind font */
  --tracking-numeric: -2px;     /* @kind font */ /* numerals only (test) */

  /* ---- type scale : size / line-height ---------------------------------- */
  /* display — the big end. Titles live at 120px by default (`.title`); the
     4xl/mega steps are for posters, hero covers and full-bleed statements. */
  --fs-mega:        200px; --lh-mega:        0.90; /* @kind font */
  --fs-display-4xl: 160px; --lh-display-4xl: 0.92; /* @kind font */
  --fs-display-3xl: 120px; --lh-display-3xl: 0.96; /* @kind font */ /* = .title */
  --fs-display-2xl: 72px;  --lh-display-2xl: 1.04; /* @kind font */
  --fs-display-xl:  56px;  --lh-display-xl:  1.06; /* @kind font */
  --fs-display-lg:  44px;  --lh-display-lg:  1.08; /* @kind font */
  /* headings */
  --fs-h1: 34px;  --lh-h1: 1.12; /* @kind font */
  --fs-h2: 28px;  --lh-h2: 1.18; /* @kind font */
  --fs-h3: 22px;  --lh-h3: 1.25; /* @kind font */
  --fs-h4: 18px;  --lh-h4: 1.33; /* @kind font */
  /* body */
  --fs-lede:    24px;  --lh-lede:    1.45; /* @kind font */ /* standfirst / subhead */
  --fs-body-lg: 18px;  --lh-body-lg: 1.6;  /* @kind font */
  --fs-body:    16px;  --lh-body:    1.6;  /* @kind font */
  /* O PÉ DA ESCADA SUBIU EM 04-set-2026. [ele: "as fontes estão muito
     pequenas de uma forma geral"]

     O topo nunca foi o problema — ninguém reclama de um h1. A dor mora aqui
     embaixo, e por duas razões que se somam:

     1 · O PÉ ESTAVA COMPRIMIDO. body-sm 14 · caption 13 · label 12 ·
         label-sm 11: quatro degraus dentro de 3px. Um degrau de 1px não é
         hierarquia — o olho não separa 13 de 12, então a tela inteira lê
         como um bloco só de letra miúda. Era escada no papel e rampa na tela.

     2 · ELES CARREGAM O TRABALHO. Rótulo, legenda, carimbo e eyebrow são
         justamente o que se lê em ferramenta de operação — e é a camada que
         estava mais apertada, no degrau de tinta mais fraco (ver a escada de
         `--ink` em colors.css, corrigida no mesmo dia). Letra pequena com
         pouco contraste não soma: multiplica.

     A escada nova abre 1px real entre cada degrau e sobe o piso de 11 para
     12. O topo (lede, body-lg, body) não se move: ele estava certo. */
  --fs-body-sm: 15px;  --lh-body-sm: 1.55; /* @kind font */
  --fs-caption: 14px;  --lh-caption: 1.45; /* @kind font */
  /* labels (mono) */
  --fs-label:    13px;  --lh-label:    1.2; /* @kind font */
  /* 12px é o PISO da tipografia da casa — e não confundir com o piso de 10px
     do RETRO PANEL LED, que é outra conta: lá o limite é a malha comendo o
     traço da VCR; aqui é leitura de rótulo em tela de trabalho. */
  --fs-label-sm: 12px;  --lh-label-sm: 1.2; /* @kind font */
  /* data (pixel) */
  --fs-data-lg: 48px;  --lh-data-lg: 1.0; /* @kind font */
  --fs-data:    28px;  --lh-data:    1.0; /* @kind font */
}


/* ---- tokens/spacing.css ---- */
/* ===========================================================================
   machado.group — Spacing
   ---------------------------------------------------------------------------
   One scale, 4px base. Negative space is a deliberate element — reach for the
   larger steps generously. Use for padding, margin, and gap.
   =========================================================================== */

:root {
  --space-0:   0;
  --space-1:   4px;
  --space-2:   8px;
  --space-3:   12px;
  --space-4:   16px;
  --space-5:   20px;
  --space-6:   24px;
  --space-8:   32px;
  --space-10:  40px;
  --space-12:  48px;
  --space-16:  64px;
  --space-20:  80px;
  --space-24:  96px;
  --space-32:  128px;

  /* layout */
  --container-max: 1200px;
  --gutter:        var(--space-6);

  /* RITMO DE SECÇÃO — 21-set-2026, do rascunho "Dandelion" (DesignSystem
     #spacers) e do dandelion-site, onde vivia como token local. As secções
     alternam page / raised / sunken; a profundidade é só tom, e o vão entre
     elas é um destes degraus: hero 0→x2 · intro xl→x3 · sticky x2 (x3 na
     home) · carrossel x2 · painel, newsletter, fecho e rodapé 0→x2. */
  --pad-x: clamp(20px, 2.78vw, 40px);
  --sy-xs: clamp(1.25rem, 1.0714rem + .8929vw, 1.875rem);
  --sy-sm: clamp(1.875rem, 1.6964rem + .8929vw, 2.5rem);
  --sy-md: clamp(2.5rem, 2.2857rem + 1.0714vw, 3.25rem);
  --sy-lg: clamp(3.25rem, 2.75rem + 2.5vw, 5rem);
  --sy-xl: clamp(5rem, 4.6429rem + 1.7857vw, 6.25rem);
  --sy-x2: clamp(6.25rem, 5.3571rem + 4.4643vw, 9.375rem);
  --sy-x3: clamp(9.375rem, 8.4821rem + 4.4643vw, 12.5rem);
}


/* ---- tokens/radius.css ---- */
/* ===========================================================================
   machado.group — Radius
   ---------------------------------------------------------------------------
   Tightened, uniform scale: containers read RECTANGULAR. Every surface caps at
   15px, the smallest detail is 4px — nothing in between drifts soft. Pills and
   status lights stay fully round. No "rounded-everything".
   **30-jul-2026:** os três passos de container subiram 5px (10 → 15) por decisão
   do Eduardo. Controlos (input, botão) e o detalhe mínimo não mexeram — a
   distância entre um card e um botão passou a ser legível.
   **08-out-2026 18:4x:** os três passos de container subiram de novo, 15 → 24, ordem dele (via opdeck, verbatim):
   "adotar 24px como padrão… até para as tools da casa… precisamos de um padrão… mudou em um, muda em todos". É o
   canto dos cards da Crew na OpDeck, e a ESCADA INTEIRA sobe junto no mesmo fator 1,6, como ele mandou na OpDeck
   ("container e botão… a proporção mantenha a mesma. O que é quadrado permanece quadrado"): 4→6 · 6→10 · 8→12 · 12→20 ·
   15→24. O fio (hair 2) e a pílula (999) não mudam. A OpDeck fazia isso por cima (RAIO_OPDECK, cliente/build.py);
   agora é a fonte, e o override dela fica redundante. Ajuste fino daqui pra frente: SÓ NESTE ARQUIVO.
   =========================================================================== */

:root {
  /* O FIO DE CABELO — só na camada de INSTRUMENTO (Retro Panel LED). Não é um
     degrau novo da escala de container: é a resposta à MALHA. O canto reto
     absoluto deixa o pixel do vértice ligado sozinho contra a trama de LED, e
     2px é o menor raio que apaga esse pixel sem o mostrador voltar a ler como
     etiqueta. Site de cliente, deck, proposta e social não usam — lá não há
     malha, e sem malha isto é só um canto arredondado sem razão.
     [09-set-2026 · escolha dele: "2px só na camada de instrumento, como token"] */
  --radius-hair: 2px;    /* painel de LED — pílula, aviso, chip de instrumento */
  --radius-xs:   6px;    /* tags, tiny chips, smallest detail (4 → 6, 08-out-2026) */
  --radius-sm:   10px;   /* inputs, buttons, segmented cells (6 → 10) */
  --radius-md:   12px;   /* compact cards, menus (8 → 12) */
  --radius-ml:   20px;   /* (12 → 20, 08-out-2026) card em grade, mídia em card — o degrau que faltava entre 8 e 15 (Dandelion, 10-set-2026; com fallback, não sobe contrato) */
  --radius-lg:   24px;   /* cards — the container maximum (15 → 24, 08-out-2026) */
  --radius-xl:   24px;   /* large surfaces / panels              */
  --radius-2xl:  24px;   /* hero panels                          */
  --radius-pill: 999px;  /* pills, badges, status dots          */
}


/* ---- tokens/shadows.css ---- */
/* ===========================================================================
   machado.group — Elevation & Glow
   ---------------------------------------------------------------------------
   Shadows are soft, low, and diffuse — never "shadow soup". The signature is
   the status GLOW ("luzinha"): a colored bloom behind a live status light,
   used sparingly to draw the eye.
   =========================================================================== */

:root {
  /* soft neutral elevation (dark default) */
  --shadow-xs:  0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-sm:  0 1px 2px rgba(0, 0, 0, 0.40),
                0 2px 6px rgba(0, 0, 0, 0.40);
  --shadow-md:  0 2px 4px rgba(0, 0, 0, 0.40),
                0 8px 24px rgba(0, 0, 0, 0.50);
  --shadow-lg:  0 4px 8px rgba(0, 0, 0, 0.45),
                0 18px 48px rgba(0, 0, 0, 0.60);

  /* inner hairline that reads as a crisp edge on raised cards */
  --shadow-edge: inset 0 0 0 1px var(--line);

  /* focus ring (offset halo) — MORTO NA BASE desde 21-set-2026 (ordem dele: foco
     é branco, glow só na fonte, sem sombra). Fica só pra instrumento legado. */
  --shadow-focus: 0 0 0 3px var(--accent-tint),
                  0 0 0 1px var(--accent);

  /* status glows — the "luzinha" bloom */
  --glow-online:  0 0 0 3px var(--status-online-bg),  0 0 12px 1px rgba(63, 164, 94, 0.45);
  --glow-warning: 0 0 0 3px var(--status-warning-bg), 0 0 12px 1px rgba(245, 184, 30, 0.45);
  --glow-offline: 0 0 0 3px var(--status-offline-bg), 0 0 12px 1px rgba(229, 64, 59, 0.55);
  /* progress ("working") — FLAT core + thick lighter-blue soft border + a faint
     displacement shadow behind. No gloss. */
  --glow-progress: 0 0 0 2px var(--c-azure-300),
                   0 0 5px 2px color-mix(in srgb, var(--c-azure-300), transparent 40%),
                   0 0 13px 4px color-mix(in srgb, var(--c-azure-300), transparent 72%);
}

[data-theme="light"] {
  /* soft neutral elevation (light) */
  --shadow-xs:  0 1px 2px rgba(20, 19, 18, 0.05);
  --shadow-sm:  0 1px 2px rgba(20, 19, 18, 0.05),
                0 2px 6px rgba(20, 19, 18, 0.05);
  --shadow-md:  0 2px 4px rgba(20, 19, 18, 0.05),
                0 8px 24px rgba(20, 19, 18, 0.07);
  --shadow-lg:  0 4px 8px rgba(20, 19, 18, 0.05),
                0 18px 48px rgba(20, 19, 18, 0.10);
}

/* ===========================================================================
   O HALO — uma lei, três corpos                             (21-ago-2026)
   ---------------------------------------------------------------------------
   A casa acende o que responde, e só quando a mão chega. Em repouso nada
   pisca: a tinta é morna e pinta tudo sem um ponto de luz. O hover é o único
   momento em que a casa acende COR PLENA — e é por isso que ele lê como
   energia, e não como mais um degrau da escada de tons.

   POR QUE ESTE BLOCO EXISTE. A lei do brilho do botão foi escrita em 14-ago
   dentro de `guidelines/control-glow.card.html` — numa CARTA, não no sistema.
   Quando o campo (`.fld`) precisou de halo em 21-ago, nasceu um segundo
   vocabulário para a mesma ideia, porque o primeiro não estava onde se procura.
   Duas leis para o mesmo gesto é como um sistema começa a mentir. Aqui elas
   viram uma; a carta e o componente passam a LER daqui.

   O TOM É DE QUEM ACENDE. `--glow-tone` é um TRIPLETO R,G,B — os corpos
   compõem-no com o seu próprio alfa. O default é branco pleno (#fff, o
   `--accent`), NUNCA o osso `#f4f2ec`: é a cor plena que faz a luz ler como
   luz. Um botão com tom próprio troca o triplo e herda tempo e forma.

   OS TRÊS CORPOS, e a diferença entre eles é medida, não gosto:
     ARESTA  o botão acende o CONTORNO. Duas camadas: um anel curto e um bloom
             largo e fraco. É o que faz uma pastilha escura parecer ligada.
     CORPO   a peça sólida que a mão agarra — barrinha do slider, botão do
             interruptor, amostra de cor. Halo CURTO e quase cheio: largo
             espalha e some no fundo escuro; curto lê como FILAMENTO.
             A coisa está acesa, não iluminada. LED, não abajur.
     TEXTO   valor e rótulo. Mais fraco que o corpo porque halo em tipografia
             miúda vira borrão antes de virar brilho. E acende SEMPRE por
             `text-shadow`: mudar o peso no hover faz a linha saltar.
   =========================================================================== */
:root {
  --glow-tone: 255, 255, 255; /* @kind other */

  --glow-edge: 0 0 12.6px 0 rgba(var(--glow-tone), .392),
               0 0 30.8px 7px rgba(var(--glow-tone), .14); /* @kind shadow */
  /* o LIGADO tem uma terceira camada — um bloom muito largo e fraco. É ele
     que faz o estado ligado ler à distância sem clarear a pastilha. */
  --glow-edge-on: 0 0 12.6px 0 rgba(var(--glow-tone), .56),
                  0 0 30.8px 7px rgba(var(--glow-tone), .28),
                  0 0 64.4px 14px rgba(var(--glow-tone), .14); /* @kind shadow */
  --glow-body: 0 0 6px 0 rgba(var(--glow-tone), .95); /* @kind shadow */
  --glow-text: 0 0 5px rgba(var(--glow-tone), .85); /* @kind shadow */
  --glow-text-soft: 0 0 4px rgba(var(--glow-tone), .55); /* @kind shadow */
  /* CORPO PEQUENO (≤ 12px) — duas camadas, não uma. [03-set-2026, palavra dele
     sobre o OPS de um cliente: "esfumaçado, sem contraste"]

     Uma camada de 5px a .85 lê como fósforo num corpo grande. Num traço de
     0,8px ela é NÉVOA em volta da letra: o halo cobre mais área que o glifo e
     a peça borra em vez de acender. A separação em duas resolve pela função —
     o NÚCLEO curto e quase opaco é o que faz a letra parecer acesa, e o HALO
     largo e fraco é o que a solta do fundo. Uma camada só tenta fazer as duas
     coisas e não faz nenhuma.

     Em currentColor de propósito: quem usa isto (badge, readout, campo) já
     pinta o próprio tom, e um --glow-tone fixo obrigaria a repintar o par nos
     nove lugares que hoje o repetem à mão. */
  --glow-text-sm: 0 0 2px color-mix(in srgb, currentColor 85%, transparent),
                  0 0 6px color-mix(in srgb, currentColor 28%, transparent); /* @kind shadow */
}



/* ---- tokens/motion.css ---- */
/* ===========================================================================
   machado.group — Motion
   ---------------------------------------------------------------------------
   Restrained and quick. Mostly opacity + small translate, ease-out. No bounce,
   no spring, no decorative loops (the one exception: a slow status pulse).
   =========================================================================== */

:root {
  /* durations */
  --dur-instant: 80ms; /* @kind other */
  --dur-fast: 120ms; /* @kind other */
  --dur-base: 200ms; /* @kind other */
  --dur-slow: 320ms; /* @kind other */
  --dur-slower: 480ms; /* @kind other */
  --dur-snap:   1000ms; /* @kind other */ /* carrossel assenta no slide — Dandelion, 10-set-2026 */
  --dur-reveal: 1800ms; /* @kind other */ /* mídia revela por clip-path — Dandelion, 10-set-2026 */
  --dur-enter:  800ms;  /* @kind other */ /* texto entra: título gigante, painel de aba, reveal de texto — Dandelion, 11-set-2026 */

  /* easing */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);     /* @kind other */
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);  /* @kind other */
  --ease-in:       cubic-bezier(0.4, 0, 1, 1);     /* @kind other */
  --ease-linear:   linear;                         /* @kind other */
  /* EASE DAS PEÇAS DE SCROLL — decisão dele, 10-set-2026, contra a recomendação
     do vector (que era o --ease-out expo). power3.out do GSAP = 1 − (1−t)³ =
     easeOutCubic; em CSS é cubic-bezier(.215,.61,.355,1). É a curva das 18
     páginas do bundle Dandelion e da gramática de movimento (regra 2, "one
     ease"). Vale para stack, pinned, sticky-rule, text-fill, carousel snap.
     Hover e transição curta continuam em --ease-standard / --ease-out. */
  --ease-scroll:   cubic-bezier(.215, .61, .355, 1); /* @kind other */

  /* common composed transitions */
  --transition-colors: color var(--dur-fast) var(--ease-standard),
                       background-color var(--dur-fast) var(--ease-standard),
                       border-color var(--dur-fast) var(--ease-standard),
                       box-shadow var(--dur-fast) var(--ease-standard);
  --transition-transform: transform var(--dur-base) var(--ease-standard);
}

/* signature slow pulse for live status lights */
@keyframes mg-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* first-tick blink for empty tick-bars (TickBar .is-zero) */
@keyframes tick-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.15; }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 0ms; /* @kind other */
    --dur-fast: 0ms; /* @kind other */
    --dur-base: 0ms; /* @kind other */
    --dur-slow: 0ms; /* @kind other */
    --dur-slower: 0ms; /* @kind other */
    --dur-snap: 0ms; /* @kind other */
    --dur-reveal: 0ms; /* @kind other */
    --dur-enter: 0ms; /* @kind other */
  }
}


/* ---- tokens/led.css ---- */
/* ===========================================================================
   machado.group — A RESOLUÇÃO DA MALHA DE LED
   ---------------------------------------------------------------------------
   Retro Panel LED é a linguagem de instrumento da casa (retro-panel-led.md):
   caixa preta, canto reto, fósforo com glow, e uma MALHA por cima que faz o
   texto parecer um mostrador em vez de uma etiqueta.

   Até 02-set-2026 essa malha era código repetido: 40+ gradientes espalhados
   por 12 componentes e 6 páginas, cada um com o passo cravado (3px, 4px, 5px)
   e a linha escura cravada em 1px. Não havia o que calibrar sem editar 40
   lugares, e por isso ela nunca foi calibrada — ficou no primeiro chute.

   A MECÂNICA, e ela contraria a intuição
   ---------------------------------------------------------------------------
   A malha ESCURECE O VÃO entre os LEDs. Ela não pinta o ponto aceso — pintar
   o ponto exigiria alinhar a grade ao glifo, e a grade quebra a cada troca de
   fonte, corpo ou zoom.

   Consequência: a 10px a haste da VCR OSD Mono mede ~0,8px e a linha escura
   media 1px. A linha era MAIS GROSSA que a letra. O texto pequeno não ficava
   escuro — ficava CORTADO, e nenhuma dose de contraste resolvia, porque não
   era falta de contraste, era subtração de traço.

   E diminuir a célula sozinho PIORA: no passo 3 a linha ocupa 33% da área,
   no passo 4 ocupa 25%. Célula menor com a mesma linha = mais preto.

   Por isso a alavanca principal é o TRAÇO, não o passo.

   OS TRÊS TOKENS
   ---------------------------------------------------------------------------
     --led-traco   px      a espessura da linha escura. É ela que corta.
     --led-k       fator   multiplica o passo de cada peça. Multiplicador, e
                           não valor absoluto, de propósito: a calibragem
                           RELATIVA entre as peças (3px no campo, 4px na
                           pílula, 5px no aviso) foi comprada com leitura e
                           fica de pé. O knob move todas na mesma proporção.
     --led-malha   fator   multiplica a opacidade .9 da grade.

   A CALIBRAGEM, e de onde ela vem
   ---------------------------------------------------------------------------
   Ele achou o número na tela, com os três knobs provisórios do masthead da
   Opdash, em 02-set-2026 — e mandou fixar. Não é um valor derivado de conta:
   é MEDIÇÃO na superfície, que é a única prova que vale para composição.

     --led-traco: .30px    ⅓ da linha antiga. Some sob a haste em vez de
                           comê-la, e a textura continua legível.
     --led-k:     .50      célula na metade — 4px→2px, 3px→1,5px. Só funciona
                           porque o traço caiu junto; sozinha, dobraria o
                           preto.
     --led-malha: 1.30     a grade mais forte. Com a linha fina, a malha podia
                           subir sem cobrar leitura — e é ela que segura a
                           matéria de painel que o traço fino quase apagou.

   Os três se compram juntos: um sozinho quebra os outros dois.

   COMO SE MEXE NISTO
   ---------------------------------------------------------------------------
   Aqui, e só aqui. Nenhum componente volta a cravar 1px ou um passo em px sem
   passar por estes tokens — foi o que custou os 40 lugares. Peça que precise
   de um passo próprio declara `--panel-passo` no seu escopo; o multiplicador
   continua valendo por cima.

   Ver também: 00_context/tint.md (a lei do rótulo) e
   machado.group/design-system/retro-panel-led.md (a linguagem).
   =========================================================================== */

:root {
  --led-traco: .30px; /* @kind other */
  --led-k:     .50;   /* @kind other */
  --led-malha: 1.30;  /* @kind other */
}
      /* a resolução da malha de LED — calibrada na tela em 02-set */

/* ---- tokens/version.css ---- */
/* ===========================================================================
   machado.group — Selo de versão
   ---------------------------------------------------------------------------
   Um projeto consumidor carrega uma CÓPIA deste sistema (a pasta `_ds/`), não
   um link vivo. Sem selo, não há como olhar um projeto e saber que versão ele
   tem — só arqueologia no código. Estes dois tokens respondem isso.

   `--ds-contract` é o número que importa: sobe UMA vez por mudança que quebra
   contrato (classe renomeada, componente removido, markup obrigatório novo).
   Se o número do consumidor é menor que o daqui, há trabalho a fazer, e o
   `sync.md` diz exactamente qual. `--ds-version` é a data do último toque.

   Regra: quem mexer em contrato sobe o número AQUI e escreve a linha no
   `sync.md`. Sem isso o selo mente, e um selo que mente é pior que nenhum.
   =========================================================================== */

:root {
  --ds-version: "2026-09-09"; /* @kind other */
  --ds-contract: 11; /* @kind other */
}


/* ---- components (vanilla HTML + CSS, token-driven) -------------------- */

/* ---- components/base.css ---- */
/* ===========================================================================
   machado.group — Base
   ---------------------------------------------------------------------------
   Minimal reset + document defaults wired to tokens. Sets the warm paper
   surface, ink color, and the sans family as the document baseline.
   =========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "ss01", "cv01";
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6, p, figure { margin: 0; }

a { color: inherit; text-decoration: none; }

::selection { background: var(--accent); color: var(--accent-ink); }

/* @kit:foco:inicio — o gerar-mg-kit.py copia daqui até o fim do marcador pro mg-kit.
   Sem isto, página montada com os blocos ganhava o anel AZUL do navegador
   (29-set-2026, ele no visualizador de imagens: "remova esses elementos azuis"). */
/* FOCO DA CASA: BRANCO, GLOW SÓ NA FONTE, SEM SOMBRA — ordem dele 21-set-2026
   ("a cor de foco vai ser branco, com um pouquinho de glow só na fonte. Não
   quero nenhum efeito de acessível, shadow, sombra"). O halo de acento saiu;
   o que acende é o texto do elemento focado. Peça com foco próprio (nav, input,
   pager) declara o seu; instrumento LED continua com a régua do painel. */
:focus-visible {
  outline: none;
  box-shadow: none;
  text-shadow: var(--glow-text-sm);
}

/* O ÍCONE ACENDE JUNTO — 28-set-2026 [vector, achado do harvest na auditoria
   do Runbook do HBF: botão SÓ COM ÍCONE ficava sem foco nenhum, porque o glow
   da casa é `text-shadow` e ali não há texto para acender].
   A ordem dele de 21-set fica INTEIRA — branco, glow só na fonte, sem efeito
   de acessível, sem sombra. Isto é a mesma matéria aplicada ao traço:
   `drop-shadow` de deslocamento ZERO na cor do próprio ícone é GLOW, não
   sombra projetada. Sem outline, sem halo, sem offset, sem cor nova.
   Vale também em botão com texto: o ícone acende junto com a letra, que é o
   que a peça já parecia prometer. */
:focus-visible svg { filter: drop-shadow(0 0 2px currentColor); }
/* @kit:foco:fim */

/* tabular figures everywhere numbers matter by default */
.tnum { font-variant-numeric: tabular-nums; }

/* ===========================================================================
   VÍDEO DECORATIVO — contrato (2026-07-27)
   ---------------------------------------------------------------------------
   Vídeo decorativo NUNCA depende de mix-blend-mode para esconder o próprio
   fundo. A composição entra ASSADA no arquivo, UM ARQUIVO POR TEMA, com o
   fundo do arquivo batendo com o do container (desvio ≤ 1/255). Em CSS o clip
   fica neutro: filter:none · opacity:1 · mix-blend-mode:normal.

   Por quê (medido): webm VP9 não carrega canal alpha no Safari, e o WebKit de
   iOS compõe vídeo numa camada de GPU que IGNORA o blend — o retângulo opaco
   aparece no aparelho. Não reproduz em Chromium nem em WebKit headless (esses
   compõem por software e aplicam o blend): defeito visual de Safari/iOS só se
   valida no APARELHO. Receita de bake e teto de peso em readme.md → Media.

   Marcação: data-decor="light|dark" no <video>; o tema ativo mostra o seu.
   O componente dá o display do clip visível via --decor-display (default block).
   =========================================================================== */
video[data-decor] { filter: none; opacity: 1; mix-blend-mode: normal; background: transparent; }
video[data-decor="light"] { display: none; }
[data-theme="light"] video[data-decor="light"] { display: var(--decor-display, block); }
[data-theme="light"] video[data-decor="dark"] { display: none; }

/* LEGADO — NÃO USAR EM NADA NOVO. Clips "*-screen.*" (traço claro sobre preto)
   escondiam o próprio fundo por blend. Viola o contrato acima e mostra
   retângulo opaco no Safari/iOS. Mantido só para os assets legados de media/
   ainda não reassados; migre para o par por tema + data-decor. */
video[src*="-screen."], video[data-legacy-blend] { mix-blend-mode: screen; filter: brightness(.94) contrast(1.14); }
[data-theme="light"] video[src*="-screen."], [data-theme="light"] video[data-legacy-blend] { filter: brightness(.94) contrast(1.14) invert(1); mix-blend-mode: multiply; }




    /* o carimbo — o Dandelion parado, dentro de outra peça, 26-ago */

/* ---- components/type.css ---- */
/* ===========================================================================
   machado.group — Type utilities
   ---------------------------------------------------------------------------
   Role classes for every step in the scale. Headings/display use the sans at
   medium weight + tight tracking; body is regular; labels are mono caps with
   wide tracking; data uses the pixel face. All read from typography.css tokens.
   =========================================================================== */

/* ---- display (grotesk) ------------------------------------------------
   The big end of the ladder. `.title` is the house default title step (120px);
   `.display-4xl` / `.mega` are poster / full-bleed statements. */
.mega, .display-4xl, .display-3xl, .title, .display-2xl, .display-xl, .display-lg {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
.mega        { font-size: var(--fs-mega);        line-height: var(--lh-mega); }
.display-4xl { font-size: var(--fs-display-4xl); line-height: var(--lh-display-4xl); }
.display-3xl,
.title       { font-size: var(--fs-display-3xl); line-height: var(--lh-display-3xl); }
.display-2xl { font-size: var(--fs-display-2xl); line-height: var(--lh-display-2xl); }
.display-xl  { font-size: var(--fs-display-xl);  line-height: var(--lh-display-xl); }
.display-lg  { font-size: var(--fs-display-lg);  line-height: var(--lh-display-lg); }

/* ---- headings (grotesk) ------------------------------------------------ */
.h1, .h2, .h3, .h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-snug);
  text-wrap: balance;
}
.h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); }
.h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); }
.h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); }
.h4 { font-size: var(--fs-h4); line-height: var(--lh-h4); letter-spacing: var(--tracking-normal); }

/* ---- lede / standfirst -------------------------------------------------
   The line that sits under a title: bigger than body, quieter than a heading. */
.lede {
  font-family: var(--font-body);
  font-weight: var(--weight-light);
  font-size: var(--fs-lede);
  line-height: var(--lh-lede);
  letter-spacing: var(--tracking-snug);
  color: var(--ink-secondary);
  text-wrap: pretty;
}

/* ---- pull quote --------------------------------------------------------- */
.quote {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--fs-display-lg);
  line-height: 1.16;
  letter-spacing: var(--tracking-snug);
  color: var(--ink);
  text-wrap: balance;
}

/* ---- body (grotesk-led) ----------------------------------------------- */
/* Body copy defaults to the display grotesk (Hanken Grotesk) since 05-set-2026.
   Mono as body was the old default and it read as terminal, not as prose.
   [data-body="mono"] still forces mono where a surface wants it. */
.text-body-lg, .text-body, .text-body-sm, .text-caption {
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-snug);
  text-wrap: pretty;
}
.text-body-lg { font-size: var(--fs-body-lg); line-height: 1.65; }
.text-body    { font-size: var(--fs-body);    line-height: 1.65; }
.text-body-sm { font-size: var(--fs-body-sm); line-height: 1.6; font-weight: var(--weight-medium); }
.text-caption { font-size: var(--fs-caption); line-height: var(--lh-caption); font-weight: var(--weight-medium); color: var(--ink-secondary); }

/* ---- editorial serif title (Baskervville) ----------------------------- */
/* The underlined question-headline treatment from the references. Pair with
   --underline for the thin rule under each line. */
.title-serif, .title-serif-lg, .title-serif-sm {
  font-family: var(--font-serif);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-snug);
  color: var(--ink);
  text-wrap: balance;
}
.title-serif-lg { font-size: var(--fs-display-lg); line-height: 1.1; }
.title-serif    { font-size: var(--fs-h1);         line-height: 1.18; }
.title-serif-sm { font-size: var(--fs-h3);         line-height: 1.3; }
.title-serif--italic { font-style: italic; }
.title-serif--underline {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: currentColor;
}

/* serif body — for longer editorial reading passages */
.text-serif {
  font-family: var(--font-serif);
  font-weight: var(--weight-regular);
  font-size: var(--fs-body-lg);
  line-height: 1.55;
  color: var(--ink);
  text-wrap: pretty;
}

/* ---- mono labels (caps, tracked) -------------------------------------- */
.mono-label, .mono-label-sm {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-secondary);
}
.mono-label    { font-size: var(--fs-label);    line-height: var(--lh-label); }
.mono-label-sm { font-size: var(--fs-label-sm); line-height: var(--lh-label-sm); letter-spacing: var(--tracking-wider); }

/* an editorial bracketed index, e.g. [004] */
.index {
  font-family: var(--font-numeric);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-numeric);
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink);
}

/* ---- numerals --------------------------------------------------------
   The house rule: every figure in our content is JetBrains Mono. Wrap any
   number that isn't already inside a numeric component (badge, index, data)
   in .num — inline figures in sans/serif copy, table cells, stats, counters,
   timestamps, prices. .num--tabular locks equal-width columns for alignment. */
.num {
  font-family: var(--font-numeric);
  letter-spacing: var(--tracking-numeric);
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}
.num--tabular {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* ---- data (LCD numerals) ---------------------------------------------- */
.data-lg, .data {
  font-family: var(--font-numeric);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: var(--tracking-numeric);
  color: var(--ink);
}
.data-lg { font-size: var(--fs-data-lg); line-height: var(--lh-data-lg); }
.data    { font-size: var(--fs-data);    line-height: var(--lh-data); }

/* ---- helpers ---------------------------------------------------------- */
.ink-secondary { color: var(--ink-secondary); }
.ink-tertiary  { color: var(--ink-tertiary); }
.ink-accent    { color: var(--accent); }

/* ---- wordmark --------------------------------------------------------
   The house mark, ONE style across every material: MACHADO.GROUP set in
   mono CAPS, muted ink, no colored dot, no background. Size it from context
   (font-size on the parent); the mark itself inherits em. */
.wordmark {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  white-space: nowrap;
}

/* ---- body face overrides ---------------------------------------------
   Grotesk is the body face. [data-body="mono"] flips a whole container back
   to mono — that is the escape hatch for instrument surfaces (dash, runbook,
   console); the legacy [data-body="sans"] hook resolves to mono too (sans
   retired). `.text-mono` / `.text-light` are one-off utilities for a single
   block. */
[data-body="sans"],
[data-body="mono"] {
  --font-body: var(--font-mono-tech);
}

/* one-off utility for a single block */
.text-mono {
  font-family: var(--font-mono-tech);
  font-weight: var(--weight-regular);
  font-size: var(--fs-body);
  line-height: 1.65;
  letter-spacing: var(--tracking-snug);
  color: var(--ink);
}
/* JetBrains Mono in its light (300) cut — the airy editorial register */
.text-light {
  font-family: var(--font-mono-tech);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-snug);
}


/* ---- components/icon.css ---- */
/* ===========================================================================
   machado.group — Icon
   ---------------------------------------------------------------------------
   Tamanho e alinhamento do set de traço. O glifo é um SVG inline que herda
   `currentColor` (a geometria mora em `icon/Icon.jsx`); aqui fica só a métrica.

   `--icon-sw` é a espessura — 1,75 na grelha de 24, o mesmo traço do
   BridgeButton. Subir para 2 em superfície muito escura; nunca abaixo de 1,5,
   que é onde o glifo desaparece a 16px.
   =========================================================================== */

:root{--icon-sw:1.75 /* @kind other */}

/* NÃO declarar width/height aqui. O componente escreve-os como atributo
   (default `1em`), e CSS vence atributo de apresentação: uma linha
   `width:1em` nesta regra torna o `size` inerte em todo o parque — foi o bug de
   31-jul. As classes de escala mexem em `font-size`, que é o que dá valor ao
   `1em` do atributo. */
.icon{display:inline-block;flex:none;vertical-align:-0.125em}
.icon--lg{font-size:20px}
.icon--xl{font-size:28px}

/* ícone + texto na mesma linha, com o vão da casa */
.icon-row{display:inline-flex;align-items:center;gap:var(--space-2)}



/* DUAS CAIXAS DE REFERÊNCIA, e a diferença foi medida, não suposta:
   `fill-box` faz cada parte transformar em torno de SI (o dedo encolhe no
   próprio eixo, a onda abre do próprio centro) — é o que press, pulse e sway
   precisam. `view-box` faz a parte girar em torno do CENTRO DO GLIFO, que é o
   que spin precisa: com fill-box, a seta e o arco de `tap-rotate` giravam cada
   um no próprio centro e o glifo lia como duas peças a tombar em separado. */

/* o CORPO — a mão. press: recua e volta, como quem encosta. */
/* pulse — a onda do toque: nasce, abre, some.
   SÓ para marca que É onda. Nunca para traço que faz parte da forma: um
   contorno com opacidade a zero pisca, e o glifo deixa de se ler. */
/* travel — a marca de direção viaja no próprio eixo */
/* spin — a seta dá a volta em torno do CENTRO DO GLIFO, não do próprio */
/* sway — o aceno, com origem no punho */
/* draw — o traço que nasce (o trim path do Lottie, em CSS) */


/* Uma linha, e ela vale por todas as seis. */
@media (prefers-reduced-motion:reduce){
}

/* ===========================================================================
   ÍCONE DENTRO DO PAINEL — o traço engorda, a geometria não muda
   ---------------------------------------------------------------------------
   [25-ago-2026, medido na prova de fonte do RETRO PANEL LED]

   A ARITMÉTICA. O glifo da casa é viewBox 24 com traço 1,75. Num ícone de
   14px isso rende 14/24 × 1,75 = **1,02px** na tela. A linha escura da malha
   de LED mede **1px**. O traço tem o tamanho da linha que o corta: o ícone
   não escurece — ele se PARTE. É a mesma conta que já travava o texto do
   painel em corpo 10.

   POR QUE ISTO NÃO REABRE A LEI DOS ÍCONES. `00_context/icons.md` fixa traço
   1,75 como gramática única do set, e ela continua inteira: o 1,75 é da
   GEOMETRIA, do desenho do glifo. `stroke-width` é ATRIBUTO — quem consome
   decide com que peso pinta. Nenhum SVG do set muda; muda o consumo dentro
   do painel, e só ali.

   Medido: 14px/1,75 parte · 16px/2,00 melhora · 18px/2,25 sobrevive inteiro.
   =========================================================================== */
:root { --icon-sw-panel: 2.25 }

.readout :where(svg),
.ticker  :where(svg),
.badge   :where(svg),
.notice  :where(svg) { stroke-width: var(--icon-sw-panel) }


/* ---- components/button.css ---- */
/* ===========================================================================
   machado.group — Button
   ---------------------------------------------------------------------------
   Variants: primary (ink fill) · accent (the one bold colour) · secondary (outline) ·
             ghost (text). Sizes: sm / md / lg. States: hover/active/disabled.
   Quiet by default — fills are ink, not color; the accent is reserved for the one
   primary action that should be loud.
   =========================================================================== */

/* APOSENTADO 09-out-2026 — ele marcou SAI na bancada de defaults (B5–B8). Nada novo nasce com .btn;
   o que está no ar (~1.700 usos em 41 projetos) migra pra .pill-btn quando a tela for tocada. Não se
   apaga daqui antes da varredura: apagar quebra as telas vivas. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-mono-tech);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-snug);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  border-radius: var(--radius-sm);
  transition: var(--transition-colors), transform var(--dur-fast) var(--ease-standard);
  user-select: none;
}
.btn:active { transform: translateY(0.5px) scale(0.99); }
.btn:disabled, .btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.45;
  transform: none;
}

/* ---- sizes ------------------------------------------------------------ */
.btn--sm { height: 28px; padding: 0 7px; font-size: var(--fs-body-sm); }
.btn--md { height: 34px; padding: 0 11px; font-size: var(--fs-body-sm); }
.btn--lg { height: 42px; padding: 0 19px; font-size: var(--fs-body); }

/* ---- variants --------------------------------------------------------- */
.btn--primary   { background: var(--ink); color: var(--ink-inverse); }
.btn--primary:hover:not(:disabled)   { background: var(--c-gray-700); }
[data-theme="light"] .btn--primary    { background: var(--ink); color: var(--ink-inverse); }
:root:not([data-theme="light"]) .btn--primary    { background: var(--c-paper); color: var(--c-gray-900); }
:root:not([data-theme="light"]) .btn--primary:hover:not(:disabled) { background: var(--c-sand-2); }

.btn--accent    { background: var(--accent); color: var(--accent-ink); }
.btn--accent:hover:not(:disabled)    { background: var(--accent-hover); }
.btn--accent:active:not(:disabled)   { background: var(--accent-press); }

.btn--secondary { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn--secondary:hover:not(:disabled) { background: var(--surface-sunken); border-color: var(--line-strong); }

.btn--ghost     { background: transparent; color: var(--ink); }
.btn--ghost:hover:not(:disabled)     { background: var(--surface-sunken); }

/* icon-only square button */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition-colors), transform var(--dur-fast) var(--ease-standard);
}
.icon-btn:active { transform: scale(0.94); }
.icon-btn:hover  { background: var(--surface-sunken); }
.icon-btn--sm { width: 32px; height: 32px; }
.icon-btn--md { width: 40px; height: 40px; }
.icon-btn--bordered { border-color: var(--line-strong); }
.icon-btn :where(svg) { width: 1.15em; height: 1.15em; }
/* .icon-btn--round — o CÍRCULO ESCURO da casa (02-out-2026). Ele pediu os comandos "completamente
   circulares" no visor, no Drop e no Fieldcraft; o mesmo círculo nasceu três vezes local (.ag-ico,
   .fc-ico, .fc-ver__ico) e sobe pra fonte aqui. Fundo ink-0, hover ink-3, ícone branco, 36px. */
.icon-btn--round { width: 36px; height: 36px; padding: 0; border-radius: 50%; aspect-ratio: 1; background: var(--c-ink-0); color: var(--c-white); text-decoration: none; }
/* SEM CINZA NO GESTO (19-out, ele: "não quero cinza… uma temática mais dark"): o hover não clareia o círculo — acende o anel, como o P9b */
/* ANEL MAIS ESCURO (31-out, ele: "this borders when on hover must be darker. this serve for all similar cases"): o anel
   do hover vem de um token só, --icon-btn-ring (era branco a 22%); todo círculo/anel parecido usa este token */
:root { --icon-btn-ring: color-mix(in srgb, var(--c-white) 9%, transparent); }
.icon-btn--round:hover { background: var(--c-ink-0); color: var(--c-white); box-shadow: inset 0 0 0 2px var(--icon-btn-ring); }
.icon-btn--round :where(svg) { width: 16px; height: 16px; }
.icon-btn--round[disabled] { opacity: .3; cursor: default; }
/* MARCADO (14-out-2026, pedido do atlas-doula pro Manter/Tirar da curadoria do Meu Aconchego): o círculo que é
   escolha usa aria-pressed. Marcado = papel cheio, glifo escuro — a mesma inversão do .chip--filter aceso. */
.icon-btn--round[aria-pressed="true"] { background: var(--c-paper); color: var(--c-ink-0); }
.icon-btn--round[aria-pressed="true"]:hover { background: var(--c-white); color: var(--c-ink-0); }
/* ACESO (26-out-2026, pedido do playground-project pro ditado): o círculo que está ESCUTANDO não é escolha —
   é estado vivo, e o disco branco do MARCADO grita. --lit troca por chão on-accent, glifo accent e brilho
   suave do acento. Segue a skin: na "playground" sai verde sobre verde-fundo. */
.icon-btn--round.icon-btn--lit[aria-pressed="true"],
.icon-btn--round.icon-btn--lit[aria-pressed="true"]:hover { background: var(--ink-on-accent); color: var(--accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent), 0 0 18px color-mix(in srgb, var(--accent) 25%, transparent); }

/* leading/trailing icons inside .btn */
.btn :where(svg) { width: 1.05em; height: 1.05em; flex: none; }

/* ===========================================================================
   Pill button — tall, fully-rounded ink pill with mono caps + trailing dot,
   and an 8-bit "decode" scramble on the label at hover (driven by the
   PillButton component; pure CSS fallback is a clean static label).
   =========================================================================== */
.pill-btn {
  display: inline-flex;
  /* PÍLULA = TAMANHO DO CONTEÚDO, ENCOSTADA À ESQUERDA — ordem dele 09-out (Mind Reader):
     "pills são sempre justificados a esquerda com tamanho relativo ao content".
     inline-flex já mede pelo conteúdo; max-width segura texto longo dentro da coluna.
     antes: sem teto. reverter: .bak-*-pill-conteudo */
  max-width: 100%;
  align-items: center;
  gap: 10px;
  /* O BOTÃO BASE DA CASA — ordem dele 21-set 21:1x–21:3x, olhando "send me a
     link" no login do Deck e depois os botões da OpDash: "reduz
     consideravelmente o espaço entre letras… aumente em 2 px o tamanho da
     fonte… passa para o Vector para ser aplicado como botão base do nosso
     design system, porque a gente não fica replicando vários botões com
     estilo diferente". Os números são os que ele escolheu no painel de
     knobs do preview (era 36px · 13px · 0.14em).
     B1 DEFAULT DA CASA — ordem dele 09-out-2026 13:0x, colando o CSS da bancada
     de defaults (_check-defaults.html): display 900, caixa Abc, letras e
     palavras apertadas. Ele mediu 34px · 15px com scale .785; o vector ASSOU a
     escala nos números (27 · 11.75 · 12 · 8) — scale num componente base
     desenha menor que a caixa que ocupa e desalinha o vizinho. Era 45px ·
     16.5px · mono 600 · −0.02em · lowercase (backup .bak-2026-10-09-b1-defaults). */
  gap: 8px;
  height: 27px;
  padding: 0 12px;
  background: var(--ink);
  color: var(--ink-inverse);
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 12px;   /* B1 da bancada, 19-out (era 11.75) */
  line-height: 1;
  letter-spacing: -0.105em;
  /* ENTRE PALAVRAS no texto CORRIDO (pílula escrita direto no HTML, sem as células do PillButton).
     Era −0.74em — o número do knob, que media a CÉLULA do espaço — e no texto corrido as palavras
     encavalavam ("Resetltem", print dele 09-out 14:0x). O equivalente é 0.79 + (−0.74) = 0.05em:
     o mesmo vão da célula de 0.205em, medido com o espaço da Hanken (0.26em). */
  word-spacing: 0.05em;
  /* LOWERCASE E MAIS PESO — ordem dele 21-set 17:3x, na tela Rail: "as pills,
     tudo em lowercase" · "more weight". Caixa alta é do painel LED (badge),
     não da pílula de base; o peso 600 é o que a mono tem de verdade. */
  font-weight: 900;
  text-transform: capitalize;
  transition: background var(--dur-base) var(--ease-standard), transform var(--dur-fast) var(--ease-standard);
  user-select: none;
}
.pill-btn:hover { background: #000; }
/* ALVO DE TOQUE DE 44px NO TELEFONE (09-out-2026, CHECK do dude ao pôr a B1 no Polaris): a B1 desenha 27px e
   a Apple pede 44 de toque. A área invisível cresce 8.5px pra cima e pra baixo só onde o ponteiro é dedo;
   o desenho não muda. */
@media (pointer: coarse) {
  .pill-btn { position: relative; }
  .pill-btn::before { content: ""; position: absolute; inset: -8.5px -4px; }
}
.pill-btn:active { transform: scale(0.98); }
.pill-btn--square { border-radius: 0; }
.pill-btn--rounded { border-radius: var(--radius-md); }

/* PESOS — a pílula base é TINTA (a ação que chama). Duas pesos a menos, ambas
   nascidas na barra de ação dos cards do Fieldcraft (17-set-2026, pedido do
   fieldcraft) e promovidas por regra do intake: dois usos, um componente.
   · ghost   a secundária ao lado da tinta — vidro (--glass-bg + --glass-edge),
             mesma tinta do texto. É o par da .btn--ghost deste ficheiro.
   · dashed  o gesto "+ adicionar": contorno tracejado, tinta terciária; no
             hover a tinta sobe e o traço fecha. Slot vazio, não botão cheio.
   O terceiro peso pedido (`--held`, chapa âmbar) NÃO entrou: cor é DADO
   (tint.md) — estado se sinaliza no crachá ao lado, nunca pintando a ação. */
.pill-btn--ghost {
  background: var(--surface-raised); /* 31-out ds-guard: was --glass-bg (grey); buttons dark */
  color: var(--ink);
  border: 1px solid var(--glass-edge);
}
.pill-btn--ghost:hover { background: var(--glass-bg-hover); }
/* DASHED NA LINHA DO P9b (19-out, ele: "aplica o estilo que a gente puxou do P9B para o B3… gosto do conceito do dash,
   mas tem que ser mais alguma variação. Aproxima os estilos"): mesma altura (32), mesmo anel de 2 px, mesmo tipo
   (display 500, 13 px, sem a célula apertada do B1) e a mesma tinta no gesto. A variação é o próprio traço: em repouso
   o anel é TRACEJADO (o lugar vazio, o "adicionar"); no hover ele FECHA em linha cheia e o fundo tinge, como a pílula
   ligada do P9b. --dash-tone muda a cor do gesto (padrão: a tinta). Duas classes: vence o tamanho (--sm/--lg). */
.pill-btn.pill-btn--dashed {
  --dash-tone: var(--ink);
  --bot-ease: cubic-bezier(.22, 1, .36, 1);
  height: 32px; padding: 0 14px; gap: 6px;
  background: transparent;
  color: color-mix(in srgb, var(--ink) 70%, transparent);
  border: 2px dashed var(--line-strong);
  border-radius: 999px;
  font-family: var(--font-display); font-size: 13px; font-weight: var(--weight-medium); letter-spacing: 0; text-transform: none;
  transition: background .3s var(--bot-ease), color .3s var(--bot-ease), border-color .3s var(--bot-ease);
}
.pill-btn.pill-btn--dashed .pill-btn__char { letter-spacing: 0; }
.pill-btn.pill-btn--dashed:hover {
  border-style: solid;
  border-color: color-mix(in srgb, var(--dash-tone) 55%, #000);
  /* sem cinza (19-out): o fundo fica no preto; só tinge quando --dash-tone é uma cor de agente (--dash-tint) */
  background: color-mix(in srgb, var(--dash-tone) var(--dash-tint, 0%), #050505);
  color: var(--dash-tone);
}
.pill-btn--dashed:active { transform: translateY(.5px); }

/* A RÉGUA DAS ESCALAS (vector, 21-set 21:5x) — a base subiu de 36 para 45px e
   os degraus seguem a mesma proporção: padding ≈ altura/3, corpo ≈ altura×0.37,
   tracking o mesmo em todos (o -0.02em da base — o --lg tinha 0.2em próprio e
   perdeu; um botão, não vários). Escada: xs 30 · sm 36 · base 45 · lg 56.
   Antes: xs 26/11px · sm 32/13px · md 42/14px · lg 56/14px. */

/* md — era "o default anterior, um degrau acima da base compacta". Com a base
   em 45px o degrau sumiu: --md é a BASE, mantido como classe para quem já a
   escreve não quebrar. */
.pill-btn--md {
  gap: 8px;
  height: 27px;
  padding: 0 12px;
  font-size: 11.75px;
}
.pill-btn--md .pill-btn__dot { width: 5px; height: 5px; }

/* sm — compact footprint (HBF), label stays legible */
/* APOSENTADA 09-out-2026 — a escada (B1s) saiu na bancada: tela nova usa só a .pill-btn, sem modificador de
   tamanho. As classes ficam iguais à B1 para quem já as escreve. */
/* UMA ALTURA + LG — decisão dele em cartão, 09-out-2026 13:1x. Com a B1 em 27px
   a escada de baixo não cabe: abaixo de 27 a letra cai sob o piso de 10px. sm, xs
   e md passam a SER a B1 (classes mantidas para quem já as escreve não quebrar);
   só o lg sobe, na proporção antiga (56/45): 34px · corpo 14. */
.pill-btn--sm {
  height: 27px;
  padding: 0 12px;
  gap: 8px;
  font-size: 11.75px;
}
.pill-btn--sm .pill-btn__dot { width: 5px; height: 5px; }

/* xs — a menor pílula da fonte. Nasceu no sino do Deck (10-set-2026): ele viu o
   "Mark all read" ao lado de itens de 13.5px numa janela de 420px e disse
   "reduz o tamanho, tá gigantesco" — e quando o Deck trocou pelo ghost, "não
   foi para tirar a cor". A ação continua BRANCA (é a que chama); só o corpo
   encolhe. Nasceu com os números medidos pelo OpDeck (26px/11px); em 21-set
   subiu com a base, pela régua acima. */
.pill-btn--xs {
  height: 27px;
  padding: 0 12px;
  gap: 8px;
  font-size: 11.75px;
}
.pill-btn--xs .pill-btn__dot { width: 5px; height: 5px; }

/* lg — the original tall, generous pill (opt-in) */
.pill-btn--lg {
  gap: 10px;
  height: 34px;
  padding: 0 15px;
  font-size: 14px;
}
/* APOSENTADA 09-out-2026 — SAI na bancada (B4). A B1 nova absorveu o pedido do Deck; não usar em tela nova. */
/* O BOTÃO DA CASA, PELE TECH — vector, 30-set-2026, promovido do Deck.
   A base desta folha é a pílula de 21-set (mono, 600, -0.02em, 45px). Em 29-set
   ele mediu outro ajuste nos knobs do Deck e mandou aplicar "em todos os botões
   do deck": mesma forma, tipo TÉCNICO, muito mais peso, mais baixa e apertada.
   Entra como PELE opt-in e NÃO troca a base — a base já está no ar em HBF,
   OpDash, lobby e decks, e trocá-la é mão única: ele validou os números numa
   superfície, não nas oito. Os números são os do SAVE dele (36 · 15 · 16.5 ·
   900 · -0.1em · mono-tech), vindos de machado-deck/cliente/build.py,
   BOTAO_CASA (l.2826), que nasceu override local esperando esta promoção. */
.pill-btn--tech {
  height: 36px;
  padding: 0 15px;
  font-family: var(--font-mono-tech);
  font-size: 16.5px;
  font-weight: 900;
  letter-spacing: -0.1em;
  border: none;
}
/* tech-sm — a pílula de BANDEJA: a fila de tags dentro de um cartão, onde 36px
   empurra o conteúdo. O corpo NÃO encolhe (a escada de altura×0.37 daria 10px,
   e a tag é lida de relance); encolhe só a caixa. Nasceu no hertz (.hz-pill,
   app/static/app.css l.91) e é o segundo uso que promove a peça — régua do
   intake: dois usos, um componente. */
.pill-btn--tech-sm { height: 28px; }

.pill-btn:disabled, .pill-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; }
/* No escuro a pílula de TINTA vira papel. Os pesos ghost/dashed ficam de fora:
   achado do lobby, 19-set-2026 — a regra do tema vencia a variante por
   especificidade e o ghost morria no dark. */
:root:not([data-theme="light"]) .pill-btn:not(.pill-btn--ghost):not(.pill-btn--dashed) { background: var(--c-paper); color: var(--c-gray-900); }
:root:not([data-theme="light"]) .pill-btn:not(.pill-btn--ghost):not(.pill-btn--dashed):hover { background: #fff; }

/* label is a row of fixed-width char cells so font swaps never shift layout */
.pill-btn__label {
  display: inline-block;
  /* o tracking mora no .pill-btn (-0.02em, dele, 21-set) e chega aqui por
     herança — era 0.14em cravado aqui e 0.2em no --lg. */
  white-space: nowrap;
}
/* A CÉLULA TEM A LARGURA DO GLIFO (09-out-2026, ordem dele com print: "Cance l").
   Era célula fixa de 0.62em, feita pra mono; com a B1 em display (proporcional) o
   "l" ficava solto numa caixa larga. Agora a célula é auto e o tracking da B1
   (−0.105em, herdado do .pill-btn) corre por letter-spacing; o PillButton congela
   a largura medida só enquanto embaralha, então o rótulo continua sem pular.
   O espaço segue fixo: ENTRE PALAVRAS da bancada (1.05 − 0.105 − 0.74). */
.pill-btn__char {
  display: inline-block;
  text-align: center;
}
.pill-btn__char[data-space="1"] { width: 0.205em; }
/* Abc com células: cada célula é uma "palavra" pro navegador e capitalize
   subiria TODAS — a célula desce e só a primeira de cada palavra sobe. */
.pill-btn__char { text-transform: lowercase; }
.pill-btn__char:first-child,
.pill-btn__char[data-space="1"] + .pill-btn__char { text-transform: uppercase; }
/* Durante o scramble os glifos passam à mono de rótulo — era a face pixel
   (Doto) até contract 6. A célula continua de largura fixa, que é o que impede
   o layout de saltar; o efeito é o embaralhado, nunca foi a face. */
.pill-btn__label.is-scrambling { font-family: var(--font-mono); }

.pill-btn__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
  transition: transform var(--dur-base) var(--ease-out-back, var(--ease-standard));
}
.pill-btn:hover .pill-btn__dot { transform: scale(1.35); }
.pill-btn--lg .pill-btn__dot { width: 6px; height: 6px; }

@media (prefers-reduced-motion: reduce) {
  .pill-btn__label.is-scrambling { font-family: var(--font-mono); }
}

/* ---------------------------------------------------------------------------
   GlassButton — two blocks (label + icon) read as ONE silhouette, joined by a
   concave tangent fillet in the gap. THE HOUSE BASE BUTTON.

   A junta é CALCULADA, não filtrada (contract 6). Até aqui a peça corria blocos
   sólidos por um filtro metaball (#mg-goo: blur + contraste de alfa) e a forma
   que saía não era a que se desenhava — o blur infla cada bloco, o corte de
   alfa endurece-o maior, e a junta sai convexa: dois lóbulos a estufar, não um
   pescoço cavado. A nav largou o mesmo filtro no contract 2; este botão ficou
   atrás dois contratos, e era por isso que a mesma peça tinha duas silhuetas no
   mesmo ecrã. Agora a silhueta é GlassBandPath (a matemática da nav) num
   clip-path: path() — o filtro #mg-goo saiu, e a forma depende de JS.
   --------------------------------------------------------------------------- */
.glass-btn{--gb-icon:44px;--gb-gap:14px;--gb-shift:10px;position:relative;display:inline-flex;align-items:stretch;gap:var(--gb-gap);height:44px;padding:0;border:none;background:transparent;color:var(--ink);font-family:var(--font-mono);font-size:13px;font-weight:var(--weight-medium);letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;text-decoration:none;cursor:pointer;user-select:none;transition:transform var(--dur-fast) var(--ease-standard)}
/* shape layer — uma camada só, recortada pelo path medido. Sem o clip-path a
   camada é um retângulo cheio, então o JS entrega inset(100%) até medir: nada
   pinta antes de a forma existir. */
/* VIDRO ESCURO (19-out, ele: "aplique o efeito blur dele… mais dark… não quero cinza"): o véu era tinta clara a 15% (cinza); agora é preto translúcido com desfoque do que está atrás e um fio de luz */
.glass-btn__glass{position:absolute;inset:0;z-index:0;pointer-events:none;background:rgba(5,5,5,.55);-webkit-backdrop-filter:blur(16px) saturate(140%);backdrop-filter:blur(16px) saturate(140%);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);opacity:1;transition:background var(--dur-base) var(--ease-standard)}
[data-theme="light"] .glass-btn__glass{opacity:.1}
.glass-btn:hover:not(:disabled) .glass-btn__glass{background:rgba(5,5,5,.72);box-shadow:inset 0 0 0 1px var(--icon-btn-ring)}   /* 31-out: the house hover ring token */
[data-theme="light"] .glass-btn:hover:not(:disabled) .glass-btn__glass{opacity:.14}
/* content — sits above the glass, transparent itself */
.glass-btn__seg{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center}
.glass-btn__label{padding:0 18px}
.glass-btn__icon{width:var(--gb-icon);flex:none;font-family:var(--font-mono);font-weight:var(--weight-regular);font-size:1.25em;line-height:1;transform:translateX(calc(-1 * var(--gb-shift)));transition:transform var(--dur-base) var(--ease-out)}
.glass-btn__icon :where(svg){width:1.1em;height:1.1em;display:block}
/* repouso = blocos CONECTADOS (o pescoço cavado); hover afasta o bastante pra
   ponte QUEBRAR — o path passa a dois subpaths, não a dois elementos. */
.glass-btn:hover:not(:disabled) .glass-btn__icon{transform:translateX(0)}
.glass-btn:active:not(:disabled){transform:scale(.98)}
.glass-btn:disabled,.glass-btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
/* As escalas só mexem em altura, tipo, folga e no bloco do ícone — a largura
   dos blocos é MEDIDA, então não há mais um `right:` por escala a repetir a
   soma à mão (era a linha que desalinhava quando o rótulo mudava de corpo).
   Raio e pescoço DERIVAM da altura no JS: knob de componente é entrada, não
   default declarado — `--gb-r` e `--gb-neck` existem para quem quiser mandar,
   e não se declaram aqui (readme → Knob de componente). */
.glass-btn--sm{height:34px;font-size:12px;gap:11px}
.glass-btn--sm .glass-btn__icon{width:34px;transform:translateX(-8px)}
.glass-btn--sm:hover:not(:disabled) .glass-btn__icon{transform:translateX(0)}
.glass-btn--sm .glass-btn__label{padding:0 13px}
.glass-btn--lg{height:52px;font-size:14px;gap:16px}
.glass-btn--lg .glass-btn__icon{width:52px;transform:translateX(-11px)}
.glass-btn--lg:hover:not(:disabled) .glass-btn__icon{transform:translateX(0)}
.glass-btn--lg .glass-btn__label{padding:0 21px}
@media (prefers-reduced-motion: reduce){.glass-btn__icon{transition:none}}

/* ---------------------------------------------------------------------------
   LinkButton — outlined "link-out" button: mono-caps label + a filled square
   holding a pixel arrow-up-right. For external links / socials / contact.
   Hover inverts the whole button (fill ink), the box flips with it.
   --------------------------------------------------------------------------- */
/* A BOLA NO CENTRO (16-out, ele: "a bolinha perfeitamente centralizada… a mesma distância top, bottom, right"): o recuo
   da direita DERIVA da altura, da caixa e da borda — muda um, a bola continua equidistante. Nada se mexe no hover. */
.link-btn {
  /* B11 da bancada (ele, 19-out): 26 px, bola de 15 px, borda 1,5 — a pílula de saída redonda */
  --lb-h: 26px; --lb-box: 15px; --lb-bw: 1.5px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: var(--lb-h);
  padding: 0 calc((var(--lb-h) - var(--lb-box)) / 2 - var(--lb-bw)) 0 11px;
  border: var(--lb-bw) solid var(--ink);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard);
}
.link-btn__label { display: inline-block; }
.link-btn__box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--lb-box);
  height: var(--lb-box);
  flex: none;
  border-radius: 3px;
  background: var(--ink);
  color: var(--ink-inverse);
  transition: background var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard), transform var(--dur-base) var(--ease-standard);
}
.link-btn__box svg { width: 14px; height: auto; display: block; }
.link-btn:hover { background: var(--ink); color: var(--ink-inverse); }
.link-btn:hover .link-btn__box { background: var(--ink-inverse); color: var(--ink); }
.link-btn:active { transform: translateY(0.5px); }

/* sm — tighter footprint */
.link-btn--sm { --lb-h: 30px; --lb-box: 22px; font-size: 12px; padding-left: 8px; gap: 7px; }
.link-btn--sm .link-btn__box svg { width: 12px; }

/* B1 e B11 DA BANCADA (ele, 19-out, colando o CSS da página Defaults) */
.pill-btn:not(.pill-btn--ghost):not(.pill-btn--dashed):hover { box-shadow: inset 0 0 0 1px var(--icon-btn-ring); }   /* 31-out: the house hover ring token */
.link-btn { gap: 7px; padding-left: 11px; border-radius: var(--radius-pill); font-family: var(--font-display); font-size: 13px; font-weight: 600;
  letter-spacing: .01em; text-transform: capitalize; line-height: 1.05; }
.link-btn__box { border-radius: 50%; }
.link-btn__box svg { width: 12px; }
.link-btn__box svg * { stroke-width: 2.9; }
.link-btn:hover .link-btn__box svg * { stroke-width: 2.4; }
.link-btn--sm { --lb-h: 29px; --lb-box: 15px; gap: 4px; }




/* ---- components/input.css ---- */
/* ===========================================================================
   machado.group — Input & Field
   ---------------------------------------------------------------------------
   Borderless text input. Separation comes from surface tonality (the field
   sits on a sunken well, distinct from page/card); white accent ring on focus
   only.
   **PRECONDIÇÃO do mecanismo tonal:** ele exige um CARD atrás. No dark não há
   degrau para baixo — `--surface-sunken` é #080808 e `--surface-page` é #0c0c0c,
   quatro de 255, medido em 1,02:1 num consumidor: o campo fica invisível e os
   rótulos flutuam sobre nada. Campo que assenta DIRETO na página usa
   `.input--on-page`, que sobe o tom em vez de baixar.
   Optional field wrapper with mono-caps label and helper / error text.
   =========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: var(--weight-medium);
  color: var(--ink-secondary);
}

.input {
  width: 100%;
  height: 44px;
  padding: 0 var(--space-4);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1;
  color: var(--ink);
  background: var(--surface-anchor);   /* DEEP WELL (01-nov-2026, ele escolheu a opção A): o campo desce abaixo da página */
  border: none;
  border-radius: var(--radius-sm);
  transition: var(--transition-colors), box-shadow var(--dur-fast) var(--ease-standard);
  appearance: none;
}
.input::placeholder { color: var(--ink-tertiary); }
.input:hover:not(:disabled) { background: var(--surface-anchor); }   /* 01-nov: sem subir para o cinza no hover */
/* FOCO É BRANCO, COM GLOW SÓ NA FONTE — ordem dele, 21-set-2026 17:2x, olhando
   o login do Deck: "a cor de foco vai ser branco, com um pouquinho de glow só
   na fonte. Não quero nenhum efeito de acessível, shadow, sombra." O anel
   `--shadow-focus` (halo de acento) sai da base; o campo sobe um tom e o texto
   acende. */
.input:focus-visible {
  outline: none;
  background: var(--surface-anchor);   /* 01-nov (ele: "this color at the input bg is not good"): o foco não sobe ao cinza --surface-raised; só o texto acende */
  box-shadow: none;
  caret-color: var(--ink);
  text-shadow: var(--glow-text-sm);
}
.input:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------------------------------------------------------------------------
   --on-page: o campo assenta na página, sem card atrás. Sobe o tom em vez de
   baixar — 1,65:1 contra a página, onde o default dava 1,02:1. O anel de foco
   do sistema fica intacto. Medido no consumidor `machado.group` (landing).
   APOSENTADO EM 22-set-2026 — substituído por `.input--filete`. Continua vivo
   só porque dois consumidores publicados ainda o usam (landing machado.group,
   hbf-proposal-demo); migrar o que está no ar é decisão do Eduardo. Nada novo
   pega esta variante.
   --------------------------------------------------------------------------- */
.input--on-page { background: color-mix(in srgb, var(--surface-inset), var(--ink) 12%); }
.input--on-page:hover:not(:disabled) { background: color-mix(in srgb, var(--surface-inset), var(--ink) 20%); }
.input--on-page:focus-visible { background: color-mix(in srgb, var(--surface-inset), var(--ink) 20%); }

/* mono variant for codes / data entry */
.input--mono { font-family: var(--font-mono); letter-spacing: var(--tracking-snug); }

/* sizes */
.input--sm { height: 36px; padding: 0 var(--space-3); font-size: var(--fs-body-sm); }
.input--lg { height: 52px; padding: 0 var(--space-5); }

/* ---------------------------------------------------------------------------
   FILETE  .input--filete       [vector, 22-set-2026]
   ---------------------------------------------------------------------------
   Campo que assenta DIRETO na página e não vira caixa. Fundo transparente,
   um filete de 1px embaixo, o texto na tinta da casa. Foco acende o filete e
   a fonte — a mesma lei de 21-set ("branco, com um pouquinho de glow só na
   fonte; nenhum efeito de acessível, shadow, sombra").

   POR QUE ELE NASCE, ordem dele em 22-set 16:5x olhando o campo de busca do
   Atlas: "nem esse elemento nem essa cor fazem parte do nosso design system.
   Corrija." Os dois defeitos que ele viu num só campo:
     a COR    `--on-page` pinta o fundo com color-mix(--surface-inset + ink
              12%) — mistura CALCULADA, não token. Rendia ~#383735 sobre a
              página #0c0c0c: uma caixa cinzenta preenchida, que a base quiet
              luxury não tem.
     a FORMA  caixa cheia de 52px onde a casa resolve com um filete.
   O filete dispensa o degrau tonal, que era a razão inteira do `--on-page`:
   sem fundo não há contraste de superfície a defender.

   A FONTE É O DISPLAY, E DECLARADA. `.input` pede `var(--font-body)`, e
   --font-sans está APOSENTADO e aliasado ao MONO em tokens/typography.css —
   por isso o placeholder do Atlas saía em mono sem ninguém ter pedido mono.
   Aqui a face vem explícita. Corrigir o `.input` base é mudança de família
   em consumidor publicado: está na mesa do Eduardo, não se faz por dentro.

   POR QUE ESTE BLOCO MORA DEPOIS DOS TAMANHOS: o `padding` do `--lg` é
   shorthand e tem a mesma especificidade. Quem vem depois ganha. A saída
   óbvia — `.input.input--filete` — ganharia por especificidade e ficaria
   INVISÍVEL no CATALOGO.md, cujo leitor só lê classe única no início da
   linha. Classe que o catálogo não vê é classe que a próxima tela reinventa.
   --------------------------------------------------------------------------- */
.input--filete {
  background: none;
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
  font-family: var(--font-display);
  box-shadow: inset 0 -1px 0 0 var(--line);
}
.input--filete:hover:not(:disabled) { background: none; box-shadow: inset 0 -1px 0 0 var(--line-strong); }
.input--filete:focus-visible {
  background: none;
  box-shadow: inset 0 -1px 0 0 var(--ink);
  text-shadow: var(--glow-text-sm);
}
.input--filete::placeholder { color: var(--ink-tertiary); }

/* ---------------------------------------------------------------------------
   TRACE  .field--trace          [vector, 22-set-2026 19:1x]
   ---------------------------------------------------------------------------
   O filete que ENCHE da esquerda no foco. Promovido do `.fin-campo` do Deck
   (Developer/machado-deck/cliente/build.py), onde nasceu por ordem dele em
   22-set 18:2x: "padronizados… apenas a borda… com animação da esquerda para
   a direita… não precisa ter a tag no topo, apenas o placeholder". Sobe pra
   fonte porque é MECÂNICA, não decoração de uma tela: duas fieiras empilhadas
   no MESMO lugar — a de repouso (`::after`, `--line-strong`) e a de tinta
   (`::before`) que cresce em scaleX a partir da esquerda quando algo dentro
   recebe foco. Sem caixa, sem fundo, sem mudança de altura.

   MORA NO WRAPPER, não no controle: `::before`/`::after` no `.input` não
   existem (input é elemento vazio). Por isso é `.field--trace` e não
   `.input--*` — e por isso ele veste input, textarea e select com uma regra
   só. O `.input--filete` continua sendo o campo de UMA linha sem animação;
   quem quer o enchimento envolve com `.field--trace`.

   O RÓTULO SAI DA VISTA, NÃO DO LEITOR: `.field--trace .field__label` fica
   clipado (ordem dele: só o placeholder à vista). O texto do rótulo tem de
   ser repetido no `placeholder` do controle — o clip não faz isso sozinho.

   OS DOIS NÚMEROS SÃO DELE, medidos no par do Deck e por isso nomeados em vez
   de cravados: a espessura (3px → +2px → 2px, 18:4x) e o tempo (520ms, entre
   --dur-slower e --dur-snap; fica declarado para não virar número anônimo).

   SEM GLOW AQUI — ordem dele, 22-set 18:4x: "remove esse glow… no claro está
   estranho". Só nesta variante: o `.input:focus-visible` e o `.input--filete`
   da base continuam a acender a fonte pela lei de 21-set 17:2x. Duas ordens
   dele, de dias diferentes, sobre a mesma coisa — unificar mexe em consumidor
   publicado e é decisão DELE, não minha. Está na caixa.
   --------------------------------------------------------------------------- */
.field--trace {
  --field-trace-w: 2px;
  --field-trace-dur: 520ms;
  position: relative;
  gap: 0;
  padding-bottom: var(--space-2);
  min-width: 0;
}
.field--trace > .field__label {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.field--trace > :is(.input, textarea.input, select.input) {
  background: none;
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
  font-family: var(--font-display);
  box-shadow: none;
  text-shadow: none;
}
.field--trace > :is(.input, textarea.input, select.input):is(:hover, :focus-visible):not(:disabled) {
  background: none;
  box-shadow: none;
  text-shadow: none;
}
.field--trace::after,
.field--trace::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--field-trace-w);
}
.field--trace::after  { background: var(--line-strong); }
.field--trace::before {
  background: var(--ink); z-index: 1;
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--field-trace-dur) var(--ease-standard);
}
.field--trace:focus-within::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .field--trace::before { transition: none; }
}


/* textarea */
textarea.input { height: auto; min-height: 96px; padding: var(--space-3) var(--space-4); line-height: var(--lh-body); resize: vertical; }

/* helper / error */
.field__help  { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--ink-secondary); }
/* AVISO EM BRANCO — mesma ordem: "essa cor amarela não quero que fique. Tem que
   ser branco." Na base o erro é tinta com glow na fonte; tom só onde o painel
   (tint.md) manda. A moldura do campo em erro é o filete de tinta, não sombra. */
.field__error { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--ink); text-shadow: var(--glow-text-sm); }

.field--error .input { box-shadow: inset 0 0 0 1px var(--ink); }
.field--error .input:focus-visible { box-shadow: inset 0 0 0 1px var(--ink); }



   /* a gota — vidro sobre foto, 03-out */
   /* a pena da casa — o traço de esboço, 03-out */
      /* o aparelho — tecla com relevo + visor de LED, 26-ago */
      /* a tecla do canto — estava órfã do barril até 24-ago */

/* ---- components/tooltip.css ---- */
/* ===========================================================================
   machado.group — Tooltip ("o sussurro")
   ---------------------------------------------------------------------------
   O rótulo curto que aparece ao lado de um controle sem rótulo — a tecla, um
   ícone solto, um número sem legenda. Nasceu em 24-ago-2026 no runbook da HBF,
   onde as teclas de ping usavam `title=""` e o browser desenhava a sua própria
   caixa: fonte do sistema, cantos do sistema, cinza do sistema. Mesma classe
   de falha do range nativo — a página estava vestindo o browser, não a casa.

   Anatomia
     [data-tip]                  — o próprio controle. o texto vem do atributo.
     [data-tip-side="below"]     — desce em vez de ir para a esquerda.

   Não tem seta e não tem borda: é uma superfície flutuando, separada por tom,
   como todo o resto da casa.

   ARMADILHA MEDIDA, 24-ago: o container que hospeda a tecla costuma ter
   `overflow: clip` (o .accordion-item tem). Um balão que desce é DECEPADO
   quando o card está fechado, porque aí o card mede só a altura do header.
   Por isso o default é ir para a ESQUERDA, alinhado ao centro do controle:
   um balão de ~22px cabe dentro de uma linha de header de 60px, sempre.
   O `--baixo` existe para quem hospeda em container sem clip, e é opt-in
   justamente para a escolha ser consciente.

   E TIRE o `title` do elemento: se os dois ficam, o browser desenha a caixa
   dele por cima da nossa depois de ~1s.
   =========================================================================== */

[data-tip] {
  position: relative;
}

[data-tip]::after {
  content: attr(data-tip);

  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%) translateX(4px);

  padding: 5px 10px;
  background: var(--surface-inset);
  color: var(--ink);
  border-radius: var(--radius-sm);

  font-family: var(--font-mono-tech);
  font-size: 11px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.02em;
  line-height: 1.2;
  white-space: nowrap;
  text-transform: none;

  opacity: 0;
  pointer-events: none;
  z-index: 3;
  transition:
    opacity   var(--dur-base) var(--ease-standard),
    transform var(--dur-base) var(--ease-standard);
  /* o atraso é o que separa "passei o mouse indo para outro lugar" de
     "parei aqui porque não sei o que isto faz". */
  transition-delay: 0s;
}

[data-tip]:hover::after,
[data-tip]:focus-visible::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  transition-delay: 0.32s;
}

/* segundo encaixe — desce. só em container SEM overflow clip (ver acima). */
[data-tip][data-tip-side="below"]::after {
  right: auto;
  left: 50%;
  top: calc(100% + 8px);
  transform: translateX(-50%) translateY(-4px);
}
[data-tip][data-tip-side="below"]:hover::after,
[data-tip][data-tip-side="below"]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  [data-tip]::after { transition: opacity var(--dur-fast) linear; transform: translateY(-50%); }
  [data-tip]:hover::after,
  [data-tip]:focus-visible::after { transform: translateY(-50%); }
  [data-tip][data-tip-side="below"]::after,
  [data-tip][data-tip-side="below"]:hover::after { transform: translateX(-50%); }
}

/* O BALÃO FIXO (16-out-2026, tooltip.js): com o script na página, um balão só, preso ao body, mostra o rótulo de TODO
   botão — data-tip, title ou aria-label — por cima do botão. O ::after acima vira reserva de página sem JS. */
html.tip-js [data-tip]::after { display: none; }
.tip-float {
  position: fixed;
  z-index: 2147483600;
  max-width: 260px;
  padding: 5px 10px;
  background: var(--surface-inset, #161616);
  color: var(--ink, #f2f2ee);
  border-radius: var(--radius-sm, 6px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .35);
  font-family: var(--font-mono-tech, ui-monospace, monospace);
  font-size: 11px;
  font-weight: var(--weight-medium, 500);
  letter-spacing: 0.02em;
  line-height: 1.25;
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity var(--dur-base, .16s) var(--ease-standard, ease), transform var(--dur-base, .16s) var(--ease-standard, ease);
}
.tip-float.is-on { opacity: 1; transform: none; }
  /* o sussurro — nasceu 24-ago, mata o title nativo */
  /* o rumo — escolha + as duas consequências, 24-ago */
    /* o bichinho — assinatura de agente, 24-ago */
   /* o aviso — o único com borda, e por quê, 24-ago */
   /* a barra — uma linha que acende, 24-ago */
    /* o mostrador — mata a bolinha de status, 24-ago */
     /* a peça — o texto pronto pra pegar, 24-ago */
   /* o traçante — a scrollbar da casa, 24-ago */
  /* o mostrador — painel de LED, 24-ago */
    /* a contagem — o cartão de UM número, 26-ago */
        /* o terminal — a superfície de log, 05-set */
  /* a tecla do painel — os 4 botões do dash, 06-set */
   /* o arsenal — o menu de ferramentas da casa, 24-ago */


    /* a saída — a tela da travessia, 26-ago */








   /* a travessia — sequência sobre N trilhos, 06-set */
    /* o instrumento — série no tempo dentro do painel, 08-set */
    /* o que está guardado atrás do número — dialog nativo, 08-set */


/* ---- components/chip.css ---- */
/* ===========================================================================
   machado.group — Chip ("a etiqueta") · Dandelion, 10-set-2026
   ---------------------------------------------------------------------------
   O QUE É: o rótulo de BASE — tag de categoria, chip de tipo, breadcrumb e
   paginação. Camada quiet luxury: sem malha, sem glow, sem caixa preta.
   O QUE NÃO É: o .badge. O badge é INSTRUMENTO (Retro Panel LED, tint.md) e
   só vive em dash, runbook e ferramenta. Em site, deck e proposta o rótulo é
   este. Veredito do vector sobre dn.chips: "nasce como .chip, NUNCA como .badge".
   DE ONDE VEIO: bundle "075 T Dandelion" (#chips), medido: tag 36px / 0 16px,
   chip de tipo 32px / 0 12px, tinta a 12% no fundo, corpo 13px; breadcrumb
   mono 12 caps separado por "/"; paginação 44px redonda.

   Anatomia
     .chip                 a tag (36px, pílula, só filete — sem tom desde 19-set)
     .chip--sm             o chip de tipo (32px) · --xs 26 · --2xs 22
     .chip--tonal          o fundo a 12% (era o default até 19-set)
     .chip--filter         o chip de filtro, com [aria-pressed="true"] cheio
     .chip--outline        alias da base (só filete)
     .chip--on             aceso, igual a [aria-pressed="true"]
     .crumbs               o breadcrumb (mono, caps)
       .crumbs__item       um degrau; o último é a página atual
     .pager                a paginação
       .pager__page        um número (44px, disco); [aria-current="page"] cheio
       .pager__arrow       ← → nas pontas

   ARMADILHA MEDIDA: a tinta a 12% (`--line`) é fundo, e sobre foto some. Em
   chip sobre mídia usa `.chip--outline` — o filete sobrevive à foto, o tom não.
   =========================================================================== */
.chip {
  display: inline-flex;
  /* PÍLULA = TAMANHO DO CONTEÚDO, ENCOSTADA À ESQUERDA — ordem dele 09-out (Mind Reader):
     "pills são sempre justificados a esquerda com tamanho relativo ao content".
     inline-flex já mede pelo conteúdo; max-width segura texto longo dentro da coluna.
     antes: sem teto. reverter: .bak-*-pill-conteudo */
  max-width: 100%;
  align-items: center;
  gap: var(--space-2);
  height: 36px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-pill);
  background: transparent; /* 31-out ds-guard: was --line (grey), always overridden below */
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--weight-regular);
  line-height: 1;
  letter-spacing: var(--tracking-normal);
  white-space: nowrap;
  text-decoration: none;
  border: 0;
  cursor: default;
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}
.chip--sm { height: 32px; padding: 0 var(--space-3); font-size: var(--fs-label-sm); }
/* DEGRAUS PEQUENOS — 19-set-2026, ordem dele no Deck (18-set): "tire 5px do top
   e 5px do bottom". 36→26 e 32→22, os números medidos por ele na fila de
   reuniões; entram como degraus, não como override de consumidor. */
.chip--xs  { height: 26px; padding: 0 var(--space-3); font-size: var(--fs-label-sm); }
/* 21-set-2026: o --2xs lia --fs-caption (14px) — a pílula MENOR saía com a letra
   MAIOR que a do --xs (12px). Achado do opdeck no sync c11. 12px é o piso da
   casa (typography.css), então os dois degraus pequenos dividem o mesmo corpo;
   o que os separa é a altura e o padding. */
.chip--2xs { height: 22px; padding: 0 var(--space-2); font-size: var(--fs-label-sm); }
/* A BASE É SEM TOM — veto de cor dele, 18-set-2026, olhando os chips do Deck:
   "fundo transparente nos pills… não quero essa cor de cinza… os selecionados
   ou com status diferenciado podem ser branco". Rejeição de cor feita na
   revisão alimenta o Dandelion (regra de 16-set, log.md): o fundo a 12% deixa
   de ser o default e vira opt-in `.chip--tonal`. `.chip--outline` fica como
   alias do que agora é a base. */
.chip { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); }
/* SEM CINZA (31-out, ele: "#282827 this btns with this colours are not right… I've be fighting this long time"): botão é
   escuro, como o Mission Control (30-out, "darker btns"): --surface-raised, hover --surface-inset. Nunca --line (#282827). */
.chip--tonal { background: var(--surface-raised); box-shadow: none; }
.chip--outline { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); }
/* RING (16-out, da referência que ele trouxe — "Project Admin" lima · "Stakeholder" rosa): pílula vazada com o anel e o
   texto na MESMA cor, o papel de uma pessoa ou de uma conta. A cor é dado: --chip-tone. Em trabalho na página Defaults. */
.chip--ring { background: transparent; color: var(--chip-tone, var(--ink)); box-shadow: inset 0 0 0 1.5px currentColor; font-weight: var(--weight-medium); }
/* P8 da bancada (ele, 19-out): 26 px, 12/500, 9 px de lado — o padrão de pílula da casa junto do P9b */
.chip--ring.chip--xs, .chip--ring { padding: 0 9px; font-size: 12px; letter-spacing: 0; }
.chip--filter { cursor: pointer; font-weight: var(--weight-medium); } /* a pílula de filtro pesa um grau acima do corpo [ele, 02-out: "mais peso na fonte… pills"] */
.chip--filter:hover { background: var(--surface-inset); }
.chip--tonal.chip--filter:hover { background: var(--surface-inset); }
.chip--filter[aria-pressed="true"], .chip--on { background: var(--ink); color: var(--ink-inverse); box-shadow: none; }
/* 31-out (ele: print do Tuner, o "Design System" escolhido sumia): o hover do tonal (--surface-inset) vencia a pílula escolhida e deixava texto escuro em fundo escuro. A escolhida fica cheia no hover, um grau abaixo. */
.chip--filter[aria-pressed="true"]:hover, .chip--tonal.chip--filter[aria-pressed="true"]:hover, .chip--on:hover { background: color-mix(in srgb, var(--ink) 88%, var(--surface-page)); color: var(--ink-inverse); }

/* breadcrumb --------------------------------------------------------------- */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0; padding: 0; list-style: none;
  font-family: var(--font-mono);
  font-size: var(--fs-label-sm);
  line-height: var(--lh-label-sm);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
.crumbs__item { display: inline-flex; align-items: center; gap: var(--space-2); }
.crumbs__item + .crumbs__item::before { content: "/"; color: var(--ink-disabled); }
.crumbs__item a { color: inherit; text-decoration: none; }
.crumbs__item a:hover { color: var(--ink); }
.crumbs__item[aria-current="page"] { color: var(--ink); }

/* paginação ---------------------------------------------------------------- */
.pager {
  display: flex;
  flex-wrap: wrap;            /* a fila que não cabe QUEBRA — nunca espreme o disco */
  align-items: center;
  gap: var(--space-2);
  margin: 0; padding: 0; list-style: none;
}
/* ARMADILHA MEDIDA (lobby, 19-set-2026): 11 discos numa coluna de 504px e o
   flex-shrink default encolhia cada um pra 38×44 — oval ("china"). O disco é
   disco: não encolhe; a fila quebra. */
.pager__page, .pager__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-secondary);
  font-family: var(--font-numeric);
  font-size: var(--fs-label);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}
.pager__page:hover, .pager__arrow:hover { background: var(--line); color: var(--ink); }
.pager__page[aria-current="page"] { background: var(--ink); color: var(--ink-inverse); }
.pager__arrow[disabled] { opacity: .35; cursor: not-allowed; }

/* BOT (19-out, clone do mecanismo do x.ai/bot "Give each Bot a job"; ele: "a borda com pelo menos 1 px a mais"):
   pílula de escolha única. Ligada, o rosto do agente NASCE à esquerda (largura 0→28, escala 0→1, ~350 ms sem rebote),
   o fundo tinge na cor do agente, o texto ganha a cor e o anel engrossa. A cor é dado: --bot-fg por pílula.
   O rosto é NOSSO (cabeça + dois olhos a 28°, o ângulo dos braços da marca), não a marca do Grok. JS: chip-bot.js. */
.chip--bot {
  --bot-fg: var(--ink);
  --bot-ring: 2px;
  --bot-ease: cubic-bezier(.22, 1, .36, 1);
  height: 32px; padding: 0 12px; gap: 0; cursor: pointer;
  font-weight: var(--weight-medium); color: color-mix(in srgb, var(--ink) 70%, transparent);
  background: transparent; box-shadow: inset 0 0 0 var(--bot-ring) var(--line-strong);
  transition: background .3s var(--bot-ease), color .3s var(--bot-ease), box-shadow .3s var(--bot-ease), padding .3s var(--bot-ease);
}
.chip--bot:hover:not([aria-pressed="true"]) { color: var(--ink); }
.chip--bot[aria-pressed="true"] {
  padding-left: 5px;
  background: color-mix(in srgb, var(--bot-fg) 18%, transparent);
  /* 19-out, ele: o texto ligado na MESMA cor do rosto; o anel, a mesma cor um pouco mais escura */
  color: var(--bot-fg);
  box-shadow: inset 0 0 0 var(--bot-ring) color-mix(in srgb, var(--bot-fg) 55%, #000);
}
.chip__bot { display: flex; flex-shrink: 0; width: 0; overflow: hidden; transition: width .35s var(--bot-ease); }
.chip--bot[aria-pressed="true"] .chip__bot { width: 28px; }
.chip__face { width: 22px; height: 22px; flex: none; transform: scale(0); opacity: 0;
  transition: transform .35s var(--bot-ease), opacity .2s linear; }
.chip--bot[aria-pressed="true"] .chip__face { transform: scale(1); opacity: 1; }
.chip__face svg { display: block; width: 100%; height: 100%; overflow: visible; }
.chip__face .bot-head { fill: var(--bot-fg); }
.chip__face .bot-eye { fill: color-mix(in srgb, var(--bot-fg) 22%, #0b0b0b); transform-box: fill-box; transform-origin: center;
  transition: translate .25s var(--bot-ease); translate: var(--bot-look, 0 0); }
/* nasce piscando: os olhos fecham e abrem uma vez quando a pílula liga */
.chip--bot[aria-pressed="true"] .bot-eye { animation: bot-pisca .5s .32s 1 both; }
@keyframes bot-pisca { 0%, 100% { scale: 1 1; } 45% { scale: 1 .12; } }
@media (prefers-reduced-motion: reduce) { .chip--bot, .chip__bot, .chip__face { transition: none; } .chip--bot .bot-eye { animation: none; } }

/* SELETOR COM ROSTO (19-out, ele: "uma versão do P9B… um iconezinho interagindo… como o seletor de tema light/dark…
   faz disso um botão, um selector"). Uma trilha só; o rosto é UM e ESCORREGA até a opção escolhida, olhando para onde
   vai; a opção ligada abre espaço à esquerda e ganha a cor dela. Mesma matéria da .chip--bot. JS: chip-bot.js. */
.botseg { --bot-ease: cubic-bezier(.22, 1, .36, 1); position: relative; display: inline-flex; align-items: center; gap: 2px;
  height: 36px; padding: 2px; border-radius: 999px; box-shadow: inset 0 0 0 2px var(--line-strong); }
.botseg__opt { --bot-fg: var(--ink); position: relative; z-index: 1; height: 32px; padding: 0 12px; border: 0; border-radius: 999px;
  background: transparent; color: color-mix(in srgb, var(--ink) 60%, transparent); cursor: pointer;
  font: var(--weight-medium) 13px/1 var(--font-display); white-space: nowrap;
  transition: padding .35s var(--bot-ease), color .3s var(--bot-ease), background .3s var(--bot-ease); }
.botseg__opt:hover { color: var(--ink); }
.botseg__opt[aria-pressed="true"] { padding-left: 33px; color: var(--bot-fg); background: color-mix(in srgb, var(--bot-fg) 18%, transparent);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--bot-fg) 55%, #000); }
.botseg__face { --bot-fg: var(--ink); position: absolute; z-index: 2; left: 0; top: 7px; width: 22px; height: 22px; pointer-events: none;
  transition: translate .45s var(--bot-ease); }
.botseg__face svg { display: block; width: 100%; height: 100%; overflow: visible; }
.botseg__face .bot-head { fill: var(--bot-fg); transition: fill .4s var(--bot-ease); }
.botseg__face .bot-eye { fill: color-mix(in srgb, var(--bot-fg) 22%, #0b0b0b); transform-box: fill-box; transform-origin: center;
  translate: var(--bot-look, 0 0); transition: translate .25s var(--bot-ease), fill .4s var(--bot-ease); }
.botseg__face.is-blink .bot-eye { animation: bot-pisca .45s 1 both; }
@media (prefers-reduced-motion: reduce) { .botseg__opt, .botseg__face { transition: none; } }


/* ── .chip--paper — the white pill of Mission Control (Dandelion, 28-out-2026) ──────────────────────────────────────────
   The status pill and the view filters: white paper with a light grain, dark text, the sheep (sheep.js) on the left. As a
   toggle (aria-pressed), only the pressed one keeps the sheep and the others are text alone, a step back. No ring, no border.
   <button class="chip chip--paper" aria-pressed="true"><span class="chip__sheep" data-sheep data-mood="work"></span>Focus</button>
   Tokens: --chip-paper-h 29px · --chip-paper-pad 8px (right) / 4px (left with sheep) · --chip-paper-gap 3px · --chip-paper-radius 25px ·
   --chip-paper-text 13px · --chip-paper-sheep 18px · --chip-paper-bg #fff · --chip-paper-ink #0b0b0b */
.chip--paper{--chip-paper-grain:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='80'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .13 0'/></filter><rect width='100%' height='100%' filter='url("components/%23n")'/></svg>");display:inline-flex;align-items:center;gap:var(--chip-paper-gap,3px);height:var(--chip-paper-h,29px);box-sizing:border-box;
 padding:0 var(--chip-paper-pad,8px) 0 var(--chip-paper-pad-l,4px);border:0;border-radius:var(--chip-paper-radius,25px);background-color:var(--chip-paper-bg,#fff);
 background-image:var(--chip-paper-grain);background-size:80px;color:var(--chip-paper-ink,#0b0b0b);font:400 var(--chip-paper-text,13px)/1 var(--font-display);box-shadow:none;outline:none}
.chip--paper .chip__sheep{display:inline-flex;width:var(--chip-paper-sheep,18px);height:var(--chip-paper-sheep,18px);flex:none}
.chip--paper[aria-pressed="false"]{padding-left:var(--chip-paper-pad,8px);color:color-mix(in srgb,var(--chip-paper-ink,#0b0b0b) 55%,transparent)}
.chip--paper[aria-pressed="false"] .chip__sheep{display:none}
.chip--paper:focus-visible{outline:none;filter:brightness(.94)}
      /* o chip — tag, breadcrumb, paginação de BASE (nunca LED), Dandelion 10-set */
   /* a linha com filete — título · sub · seta, Dandelion 10-set */
 /* a tabela de spec — dl em grade, zebra tonal, Dandelion 10-set */
  /* o carrossel — arrasta, setas, filete de progresso, sem dots, Dandelion 10-set */

/* ---- components/tabs.css ---- */
/* ===========================================================================
   machado.group — Tabs ("as abas") · Dandelion, 11-set-2026
   ---------------------------------------------------------------------------
   O QUE É: botões que trocam painéis; a variante HOTSPOTS é a mesma peça com
   a lista à esquerda e a mídia à direita (o ponto aceso na foto).
   O QUE NÃO É: o .segnav / .dc-aba dos consumidores (que vão morrer para
   consumir esta) nem o .bearing (escolha com consequência).
   DE ONDE VEIO: bundle "075 T Dandelion" (dn.tabs-hotspots, initTabs):
   [data-tab=k] mostra [data-panel=k]; o painel entra opacity 0→1 e y 12→0 em
   .8s. Veredito do vector: LEVA. tabs.js escreve aria-selected e hidden;
   a forma está aqui.

   Anatomia
     .tabs  [data-tabs]                 a peça
       .tabs__list                      a fila de abas (role=tablist)
         .tabs__tab [data-tab] [aria-selected]   uma aba (button)
       .tabs__panel [data-panel] [hidden]        um painel
     .tabs--pill                        abas em pílula (fundo --surface-raised quando ativa)
     .tabs--seg                         FILTRO / SEGMENTO: o botão da casa em 28 px
                                        (ver o bloco no fim; é o padrão para filtro)
     .tabs--hotspots                    lista vertical à esquerda, painel à direita
       .tabs__hot                       a lista (grid 1fr 2fr)

   ARMADILHA MEDIDA: `[hidden]` + transição de opacidade não animam juntos —
   o display:none corta. O painel tira o hidden e SÓ DEPOIS (rAF) ganha
   .is-in; sem o quadro de intervalo a entrada não acontece.
   =========================================================================== */
.tabs { display: flex; flex-direction: column; gap: var(--space-6); }
.tabs__list { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.tabs__tab {
  height: 40px;
  padding: 0 var(--space-4);
  border: 0; border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-disabled);
  font-family: var(--font-display);
  font-size: var(--fs-body-sm);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard), background var(--dur-fast) var(--ease-standard);
}
.tabs__tab:hover { color: var(--ink-secondary); }
.tabs__tab[aria-selected="true"] { color: var(--ink); }
.tabs--pill .tabs__tab[aria-selected="true"] { background: var(--surface-raised); } /* 31-out ds-guard: was --line (grey) */
.tabs__panel { opacity: 0; transform: translateY(12px); transition: opacity var(--dur-enter, .8s) var(--ease-scroll), transform var(--dur-enter, .8s) var(--ease-scroll); }
.tabs__panel.is-in { opacity: 1; transform: translateY(0); }
.tabs__panel[hidden] { display: none; }

/* hotspots: a lista à esquerda, a mídia à direita */
.tabs--hotspots .tabs__hot { display: grid; grid-template-columns: minmax(220px, 1fr) 2fr; gap: var(--space-8); align-items: start; }
.tabs--hotspots .tabs__list { flex-direction: column; gap: 0; }
.tabs--hotspots .tabs__tab { height: auto; padding: var(--space-4) 0; border-radius: 0; border-top: 1px solid var(--line); text-align: left; width: 100%; font-size: var(--fs-body-lg); }
.tabs--hotspots .tabs__tab:last-child { border-bottom: 1px solid var(--line); }
@media (max-width: 760px) { .tabs--hotspots .tabs__hot { grid-template-columns: 1fr; } }

/* ===========================================================================
   .tabs--seg — FILTRO / SEGMENTO · 29-set-2026 [vector]
   É o BOTÃO DA CASA aprovado na OpDeck (BOTAO_CASA, machado-deck/cliente/build.py
   l.2826: JetBrains Mono / mono-tech, 900, -0.1em, minúscula, sem borda), com as
   CORES dele e o tamanho reduzido na proporção da altura:
     36 px e 16.5 px no botão → 28 px e 13 px no filtro
     ativa     chapa --c-ink-3 (o hover do primário da OpDeck), tinta --c-white
     inativa   a do secundário: sem fundo, tinta --c-white
     hover     chapa --c-ink-2, um degrau abaixo da ativa. NUNCA o azul.
   Por que ink-3 e não o ink-0 do primário: na página (#0c0c0c) o #080808 some e o
   ativo não se lê [medido no Atlas, 29-set]. Escolha dele em cartão, 23:09.
   2ª versão, 29-set 23:1x, ordem dele ao ver a 1ª: *"essa tonalidade de cor azul
   aí não [...] uma cor escura, a mesma que a gente tratou lá nos botões do
   OpDeck [...] o tamanho também está muito grande do texto"*. A 1ª tinha 16.5 px
   e a ativa em --c-azure-300. O cinza --line das abas também não volta aqui.
   =========================================================================== */
/* 3ª versão, 29-set 23:14, ordem dele olhando o Supply: *"reduz a 30% o tamanho
   dessas pilas [...] Tá gigante [...] A gente só usa tonalidade de preto, dark e
   branco [...] Utilize a cor do background nessas pilas aí [...] dentro desse
   container com uma cor mais clara."* 28 → 20 px de altura, 13 → 10 px de texto
   (10 px é o piso de corpo da casa). A ATIVA é a chapa que CONTRASTA com o chão:
   na página, --c-ink-3; dentro de card (chão mais claro), a cor da página. */
.tabs--seg { --seg-on: var(--c-ink-3); --seg-hover: var(--c-ink-2); }
.card .tabs--seg { --seg-on: var(--surface-page); --seg-hover: var(--c-ink-3); }
.tabs--seg .tabs__list { gap: var(--space-1); }
.tabs--seg .tabs__tab {
  height: 20px;
  padding: 0 var(--space-2);
  display: inline-flex; align-items: center;
  background: transparent;
  color: var(--c-white);
  font-family: var(--font-mono-tech);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: -0.1em;
  line-height: 1;
  text-transform: lowercase;
}
.tabs--seg .tabs__tab:hover { background: var(--seg-hover); color: var(--c-white); }
.tabs--seg .tabs__tab[aria-selected="true"],
.tabs--seg .tabs__tab[aria-selected="true"]:hover { background: var(--seg-on); color: var(--c-white); }
.tabs--seg .tabs__tab:focus-visible { outline: 2px solid var(--line-strong); outline-offset: 2px; }
      /* as abas e os hotspots — Dandelion 11-set */
  /* a faixa de anúncio acima da nav — Dandelion 11-set */
  /* o menu grande de desktop, 3 colunas com foto — Dandelion 11-set */
/* o painel de assinatura — Dandelion 11-set */
     /* o título gigante que sangra e deriva — Dandelion 11-set */
    /* o título que fica + filete de progresso — Dandelion 11-set */
     /* a pilha — quadros que se cobrem no scroll — Dandelion 11-set */
    /* o fecho — o card que cresce até sangrar — Dandelion 11-set */

/* ---- components/badge.css ---- */
/* ===========================================================================
   machado.group — Badge ("a pílula")  ·  RETRO PANEL LED
   ---------------------------------------------------------------------------
   A ETIQUETA DA CASA, e desde 25-ago-2026 ela é FEITA DA MESMA MATÉRIA que o
   mostrador: caixa preta, texto em fósforo, malha de LED por cima, canto reto.

   *"Eu quero que a gente passe a adotar o padrão do painel de LED. Isso que
    você está me mostrando já não atende. Faz a transferência pro novo estilo."*
                                                          — Eduardo, 25-ago-2026

   ── O QUE MUDOU, E O QUE SE PERDEU DE PROPÓSITO ──────────────────────────
   De manhã a pílula era TINTA (fundo tingido a 10%, texto no tom). A tinta
   separava dois papéis pela matéria: etiqueta era tingida, instrumento era
   preto. Ele fechou essa distinção: **a casa inteira é painel.**

   O custo é real e fica escrito aqui para ninguém o redescobrir: `EM ESTOQUE`
   e `LIVE` passam a ter a mesma cara. O que os separa agora é só o TOM e a
   presença do LED — não mais a matéria. Quem escrever uma tela nova precisa
   ser mais disciplinado com o tom do que precisava ontem.

   ── A MATÉRIA — a mesma de panel.css, e é uma família só ──────────────────
       caixa   #0a0a0a (o tom escurece o fundo junto)
       texto   fósforo, com glow da própria cor a 40%
       malha   grade de LED em multiply — escurece o VÃO, nunca o ponto aceso
       canto   RETO. painel de instrumento não tem raio.
       letra   VCR OSD Mono, caixa alta, tracking .14em (--font-console)

   ── TRÊS TONS, E SÓ TRÊS ─────────────────────────────────────────────────
       (default)  cinza   informação, spec, rótulo
       --done     lima    terminou bem, disponível, confirmado
       --held     âmbar   travado, esgotado, fora do que se validou
       --live     acento  está acontecendo agora — e é o único que ganha LED

   ── O CORPO MÍNIMO É 10px, E ISSO É ARITMÉTICA ───────────────────────────
   A 9px o traço da mono mede 0,81px e a linha escura da malha mede 1px: a
   linha é MAIS GROSSA que a letra, e a letra não escurece — SOME. Por isso
   `.badge--sm` não desce de 10px; ele encolhe o PADDING, não a letra.

   Anatomia
     .badge                a peça
     .badge--done / --held / --live
     .badge--bezel         moldura de fósforo — para O item escolhido
     .badge--sm / --lg     padding. a letra só cresce.
     .badge__led           o ponto que pisca (só faz sentido no --live)
     .badge__n             número em Monaco, tabular
   =========================================================================== */

.badge {
  --panel-bg:    #0a0a0a;
  --panel-tone:  138, 138, 132;
  --panel-grade: rgba(0, 0, 0, .55);
  --panel-passo: 4px;

  position: relative;
  overflow: hidden;
  contain: paint;
  display: inline-flex;
  /* PÍLULA = TAMANHO DO CONTEÚDO, ENCOSTADA À ESQUERDA — ordem dele 09-out (Mind Reader):
     "pills são sempre justificados a esquerda com tamanho relativo ao content".
     inline-flex já mede pelo conteúdo; max-width segura texto longo dentro da coluna.
     antes: sem teto. reverter: .bak-*-pill-conteudo */
  max-width: 100%;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border: 0;
  /* 2px, não 0. [09-set-2026, escolha dele] O canto reto absoluto deixa o pixel
     do vértice aceso sozinho contra a trama, e a 10px isso lê como sujeira, não
     como aresta. `--radius-hair` apaga esse pixel e para aí: o raio de PÍLULA
     (999px) e o de CARD (15px) continuam proibidos aqui, e é por eles que a
     lei do canto existe. O `50%` do dot e do status__dot não muda — luz redonda
     é forma de luz, não de caixa. */
  border-radius: var(--radius-hair);

  font-family: var(--font-console);
  font-size: 10px;
  /* PESO 400, E `font-synthesis: none`. [26-ago-2026, ele: "a leitura tá muito
     difícil… tira um pouquinho do peso da fonte"]

     A VCR OSD Mono tem UM arquivo e ele é declarado `font-weight: 400`
     (tokens/fonts.css). Pedir 700 não carrega um bold — o browser SINTETIZA:
     dilata o glifo pra fora. A 10px sobre a malha de LED isso é fatal, porque
     o traço engorda pros lados e encosta na linha escura de 1px em vez de
     ficar dentro do vão. O que se lia como "fonte pesada demais" era
     borrão sintético, não peso.

     `font-synthesis: none` é o cinto: mesmo que alguém peça 700 numa variante,
     o browser desenha o glifo REAL em vez de fabricar um. Sem essa linha, o
     peso volta pela porta dos fundos na primeira sobrescrita. */
  font-weight: 400;
  font-synthesis: none;
  line-height: 1;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;

  /* LITERAIS, e não rgb(var(--panel-tone)). Medido em 24-ago: a regra base
     resolvida por var() vence a variante quando vem depois na folha, e as
     três variantes saíam idênticas. Cada tom repinta os dois valores. */
  background: #0a0a0a;
  color: #8a8a84;
  /* O GLOW SAIU DA MÃO E VIROU TOKEN [03-set-2026]. Era `0 0 6px rgba(tone,.4)`
     repetido em cada tom — uma camada, e a 10px ela é névoa, não fósforo: o
     halo cobre mais área que o traço de 0,8px. `--glow-text-sm` são duas
     camadas (núcleo curto quase opaco + halo largo fraco) em currentColor, o
     que apaga de uma vez a repetição por tom: cada variante já pinta o próprio
     `color`, e o glow o segue sozinho. Ver tokens/shadows.css. */
  text-shadow: var(--glow-text-sm);
}

/* a malha. multiply escurece o VÃO entre os pontos e nunca pinta o ponto
   aceso — pintar o ponto exigiria alinhar a grade ao glifo, e a grade muda
   com a fonte, o corpo e o zoom. Assim funciona sobre qualquer texto. */
.badge::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: multiply;
  opacity:calc(.9 * var(--led-malha, 1.30));
  background-image:
    repeating-linear-gradient(to right,  var(--panel-grade) 0 var(--led-traco, .30px), transparent var(--led-traco, .30px) calc(var(--panel-passo) * var(--led-k, .50))),
    repeating-linear-gradient(to bottom, var(--panel-grade) 0 var(--led-traco, .30px), transparent var(--led-traco, .30px) calc(var(--panel-passo) * var(--led-k, .50)));
}

/* O TOM VEM DO TOKEN desde 28-set-2026 [vector, achado do harvest na auditoria
   do Runbook]. Os hex eram cravados aqui e o selo era o ÚNICO lugar da casa
   com esses três tons — quem precisava do mesmo tom fora da pílula cravava o
   hex de novo. Agora moram em tokens/colors.css (--tone-done/held/live).
   O `--panel-tone` (rgb solto, para a malha) fica cravado: a malha precisa dos
   componentes separados e CSS não desmonta um hex. Mudou um, muda o outro. */
.badge--done {
  --panel-tone: 194, 227, 104;
  background: #060a06; color: var(--tone-done);
  text-shadow: var(--glow-text-sm);
}
.badge--held {
  --panel-tone: 255, 51, 0;
  background: #0a0605; color: var(--tone-held);
  text-shadow: var(--glow-text-sm);
}
.badge--live {
  --panel-tone: 244, 242, 236;
  background: #0c0c0c; color: var(--tone-live);
  text-shadow: var(--glow-text-sm);
}

/* ALIASES dos nomes antigos — apagá-los deixaria pílulas sem estilo pelo
   parque, e isso é falha silenciosa. Peça nova usa os três tons acima. */
.badge--accent { --panel-tone: 244, 242, 236; background: #0c0c0c; color: #f4f2ec; text-shadow: var(--glow-text-sm) }
/* EXFIL / o não-declarado — o PISO. Ele é o mais apagado dos quatro, e por um
   tempo foi apagado DEMAIS: #67645e sobre #090909 dá 3,38:1, contra 13,74:1 do
   lima e 7,06:1 do âmbar ao lado. Quatro vezes mais fraco que o vizinho, num
   corpo de 10-13px com a malha por cima — ele apontou "ilegível" em 02-set e
   estava certo: sob a linha escura da malha o tom caía para 1,45:1.

   Agora ele usa o tom-base do painel (138,138,132 = 5,74:1). Continua sendo o
   MAIS APAGADO do vocabulário, e o que o mantém quieto deixou de ser a
   escuridão: é a AUSÊNCIA DE GLOW. Mesma lógica que este arquivo já aplica ao
   `--live`, onde o que separa não é a cor, é o LED que pisca.

   A régua que fica: tom que vive sob a malha nunca desce de ~5,5:1. A malha
   escurece 36% da área do glifo, e esse é o orçamento que ela cobra. */
.badge--quiet  { --panel-tone: 138, 138, 132; background: #090909; color: #8a8a84; text-shadow: none }

/* CALLSIGN — o quarto EIXO, não um quarto tom [10-set-2026, ordem dele na dash:
   "agent OpDash (in blue. apply same principle to all agents)"].
   Os três tons medem ESTADO (terminou · travou · acontece). O callsign mede
   IDENTIDADE: responde QUEM, nunca COMO VAI. As duas perguntas nunca disputam a
   mesma pílula, por isso não é um quarto tom — é outro eixo, e o LED continua
   exclusivo do vivo. Azul = --c-azure-400 (a "luzinha de trabalho" da paleta).
   Contraste medido: 6,1:1 sobre #06090f, acima do piso de 5,5 da malha. */
.badge--callsign {
  --panel-tone: 59, 139, 255;
  background: #06090f; color: #3b8bff;
  text-shadow: var(--glow-text-sm);
}

/* .led-callsign — o CALLSIGN COMO TOM, sem caixa [11-set-2026, pedido do OpDash
   com a ordem DELE de 10-set, verbatim: "mantenha o mesmo estilo de fonte dos
   demais… A ÚNICA coisa que eu quero que você aplique diferente para os agentes
   do CREW é a COR."]. O `.badge--callsign` acima é a pílula (caixa + malha);
   esta é a irmã do `.led-prose`: aplica-se a texto que JÁ tem a tipografia do
   sítio e só troca a tinta e o halo. Nome de agente numa linha de prosa,
   numa faixa, num rótulo que não é pílula — é aqui. Mesmo eixo, mesma cor. */
.led-callsign {
  --panel-tone: 59, 139, 255;
  color: #3b8bff;
  text-shadow: var(--glow-text-sm);
}

/* a moldura: um filete do próprio fósforo, como o bezel de um mostrador.
   É o "A ESCOLHA" — UM item entre iguais, nunca um segundo estilo à solta. */
.badge--bezel { box-shadow: inset 0 0 0 1px rgba(var(--panel-tone), .55) }

/* o corpo NÃO encolhe abaixo de 10px — ver a aritmética no cabeçalho.
   O que muda é o padding. */
.badge--sm { padding: 4px 8px; letter-spacing: .12em }
.badge--lg { padding: 8px 14px; font-size: 11px }

.badge :where(svg) { width: 1em; height: 1em; flex: none; position: relative; z-index: 1 }

/* o LED. Corpo aceso em currentColor, halo da mesma cor — luz e halo
   pertencem ao mesmo instrumento. Pisca SÓ no vivo: cinza é histórico e
   âmbar é travado, e nenhum dos dois está acontecendo neste segundo.
   Piscar neles seria mentir com movimento. */
.badge__led {
  width: 5px; height: 5px; flex: none;
  border-radius: 50%;
  position: relative; z-index: 1;
  background: currentColor;
  box-shadow: 0 0 5px 0 currentColor;
}
.badge--live .badge__led { animation: badge-pisca 2.4s cubic-bezier(.4,0,.6,1) infinite }
/* não apaga de vez: diodo respira entre 100% e 35%. Apagar lê como falha de
   contato, e falha é o que o âmbar diz. */
@keyframes badge-pisca { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
@media (prefers-reduced-motion: reduce) { .badge--live .badge__led { animation: none } }

/* NÚMERO DENTRO DA PÍLULA = --font-console, e NÃO --font-clock [25-ago].
   O relógio da casa é Monaco e continua sendo, mas uma pílula é UM painel: se
   a palavra sai em VCR e o número ao lado sai em Monaco, a peça tem duas
   faces e lê como duas peças coladas. --font-clock manda no número GRANDE,
   fora do painel; aqui manda o painel.
   tabular-nums é obrigatório: sem ele "1.254" e "1.111" têm larguras
   diferentes e a lista treme a cada atualização. */
.badge__n { font-family: var(--font-console); font-variant-numeric: tabular-nums; position: relative; z-index: 1 }

/* ---- tag — DEPRECIADA (25-ago). Herda a matéria para não haver duas
   gramáticas na mesma tela. Peça nova usa `.badge`. ---------------------- */
.tag {
  --panel-bg: #090909; --panel-grade: rgba(0,0,0,.5); --panel-passo: 4px;
  position: relative; overflow: hidden; contain: paint;
  display: inline-flex; align-items: center;
  padding: 4px 8px; border: 0; border-radius: var(--radius-hair);
  font-family: var(--font-console); font-size: 10px; font-weight: 700;
  line-height: 1; letter-spacing: .12em; text-transform: uppercase;
  background: #090909; color: #8a8a84;
}
.tag::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  mix-blend-mode: multiply; opacity:calc(.9 * var(--led-malha, 1.30));
  background-image:
    repeating-linear-gradient(to right,  var(--panel-grade) 0 var(--led-traco, .30px), transparent var(--led-traco, .30px) calc(var(--panel-passo) * var(--led-k, .50))),
    repeating-linear-gradient(to bottom, var(--panel-grade) 0 var(--led-traco, .30px), transparent var(--led-traco, .30px) calc(var(--panel-passo) * var(--led-k, .50)));
}

/* ---- status ("luzinha") — DEPRECIADA desde 24-ago. Estado se diz pelo
   MATERIAL: use `readout` (parado) ou `ticker` (rolando). Sobrevive só para
   superfícies antigas; nada novo nasce com isto. --------------------------- */
.status { display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-console); font-size: var(--fs-body-sm); color: var(--ink) }
.status__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--ink-tertiary) }
.status__pill { display: inline-flex; align-items: center; padding: 4px 8px;
  border-radius: var(--radius-hair); font-family: var(--font-console); font-size: 10px;
  font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  background: #0a0a0a; color: #8a8a84 }
.status--online  .status__dot { background: #c2e368 }
.status--ondeck  .status__dot { background: var(--status-ondeck) }
.status--progress .status__dot { background: var(--status-progress) }
.status--warning .status__dot { background: var(--status-warning) }
.status--offline .status__dot { background: #ff3300 }
.status--online  .status__pill { background: #060a06; color: #c2e368 }
.status--offline .status__pill { background: #0a0605; color: #ff3300 }



      /* o trilho — nav lateral de app + palco com canto, Dandelion 21-set */
      /* o controle — a linha de ajuste do Dandelion (rótulo · tinta · valor com glow), 21-set */
      /* a bancada — a caixa flutuante que carrega os Knobs numa tela em revisão, 23-set */
     /* o seletor de cor — a faixa (Color · Tone · Opacity · House · Recent) que substitui o do sistema, 09-out */
      /* a pilha de miniaturas — conjunto recolhido numa linha, abre a grade (14-out; nome provisório) */
   /* a chamada — o menu de tela cheia, 26-ago */











/* ---- components/aura.css ---- */
/* ===========================================================================
   machado.group — Aura
   ---------------------------------------------------------------------------
   A soft, defocused bloom of the project's essence-color. It is the moving,
   living translation of the brand's "one color, lots of negative space" idea:
   a quiet glow that breathes behind content. Use it as a full-page backdrop or
   inside any container — it is a non-interactive layer that sits BEHIND content.

   The bloom is an ELLIPSE you size and place freely:
     • width  (--aura-w) and height (--aura-h) are INDEPENDENT — make it a wide
       short band, a tall column, or a circle. Sizing width no longer inflates
       height.
     • position (--aura-x / --aura-y) places the bloom's CENTER anywhere in the
       layer, measured from the top-left. Values can go negative or past 100%
       so the bloom bleeds off any edge and only the part on-screen shows.

   Color comes from --aura-color (defaults to the accent); override per
   instance:  style="--aura-color: var(--c-teal-500)"

   Usage:
     <div class="surface" style="position:relative">
       <div class="aura" data-aura-pos="bottom"></div>   <- the bloom layer
       <div style="position:relative; z-index:1"> ...content... </div>
     </div>

   API:
     position (attr)    data-aura-pos="bottom (default) | top | center | left |
                        right | top-left | top-right | bottom-left | bottom-right"
                        — presets for --aura-x / --aura-y. Override either inline.
     shape    (attr)    data-aura-shape="band | column | circle | tight | wide | full"
                        — presets for --aura-w / --aura-h.
     extra blob (class) .aura--duet   adds a second, offset bloom for a subtle mesh
     multi-element      drop <div class="aura__blob"> children (1–N), each with its
                        OWN tokens inline; auto-hides the default pseudo bloom
     grain (child)      add <span class="aura__grain"></span>, then set the
                        --aura-grain token (opacity, e.g. point-one-five)
     intensity (attr)   data-aura-intensity="soft | bold"
     motion    (attr)   data-aura-motion="calm | alive | still"

   Place it exactly, inline:
     style="--aura-w: 140%; --aura-h: 38%; --aura-x: 50%; --aura-y: -8%"
            (a wide band hugging the top edge, half bled off the top)
   =========================================================================== */

/* ---- tokens (component-local knobs, registered globally) --------------- */
:root {
  --aura-color:    var(--accent); /* @kind color */
  --aura-w:        86%;  /* bloom width  @kind spacing */
  --aura-h:        58%;  /* bloom height @kind spacing */
  --aura-x:        50%;  /* center X in layer @kind spacing */
  --aura-y:        100%; /* center Y in layer @kind spacing */
  --aura-w2:       60%;  /* duet blob width  @kind spacing */
  --aura-h2:       46%;  /* duet blob height @kind spacing */
  --aura-x2:       90%;  /* duet center X @kind spacing */
  --aura-y2:       4%;   /* duet center Y @kind spacing */
  --aura-strength: 0.85; /* @kind other */
  --aura-blur:     44px; /* @kind spacing */
  --aura-dur:      16s;  /* @kind other */
  --aura-vibrancy: 165%; /* @kind other */
  --aura-grain:    0;    /* @kind other */
}

.aura {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
}

.aura::before,
.aura--duet::after {
  content: "";
  position: absolute;
  background: radial-gradient(50% 50% at 50% 50%,
              var(--aura-color)                                      0%,
              color-mix(in srgb, var(--aura-color), transparent 10%) 34%,
              color-mix(in srgb, var(--aura-color), transparent 52%) 58%,
              transparent 78%);
  filter: blur(var(--aura-blur)) saturate(var(--aura-vibrancy));
  opacity: var(--aura-strength);
  will-change: transform;
}

/* main bloom — centered on (--aura-x, --aura-y) via the `translate` property;
   `transform` is left free for the drift/scale animation so the two compose. */
.aura::before {
  width: var(--aura-w);
  height: var(--aura-h);
  left: var(--aura-x);
  top: var(--aura-y);
  translate: -50% -50%;
  animation: aura-drift-x var(--aura-dur) ease-in-out infinite alternate;
}

/* second blob (mesh) */
.aura--duet::after {
  width: var(--aura-w2);
  height: var(--aura-h2);
  left: var(--aura-x2);
  top: var(--aura-y2);
  translate: -50% -50%;
  opacity: calc(var(--aura-strength) * 0.6);
  animation: aura-breathe calc(var(--aura-dur) * 1.35) ease-in-out infinite alternate;
}

/* ---- explicit blobs (multi-element mode) ------------------------------
   For 1–N fully independent blooms, drop <div class="aura__blob"> children and
   give each its OWN tokens inline (color, geometry, blur, strength, vibrancy).
   Adding any explicit blob auto-suppresses the default pseudo bloom (:has). */
.aura:has(.aura__blob)::before,
.aura:has(.aura__blob)::after { content: none; }

.aura__blob {
  position: absolute;
  width: var(--aura-w);
  height: var(--aura-h);
  left: var(--aura-x);
  top: var(--aura-y);
  translate: -50% -50%;
  background: radial-gradient(50% 50% at 50% 50%,
              var(--aura-color)                                      0%,
              color-mix(in srgb, var(--aura-color), transparent 10%) 34%,
              color-mix(in srgb, var(--aura-color), transparent 52%) 58%,
              transparent 78%);
  filter: blur(var(--aura-blur)) saturate(var(--aura-vibrancy));
  opacity: var(--aura-strength);
  will-change: transform;
  animation: aura-drift-x var(--aura-dur) ease-in-out infinite alternate;
}
.aura__blob:nth-of-type(2) { animation-name: aura-breathe; }
.aura__blob:nth-of-type(3) { animation-name: aura-drift-x; animation-direction: alternate-reverse; }
.aura[data-aura-motion="still"] .aura__blob { animation: none; }

/* ---- grain / noise overlay -------------------------------------------
   A fine film of monochrome noise laid OVER the bloom (z above both blobs).
   Add the child <span class="aura__grain"></span> and dial --aura-grain. */
.aura__grain {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: var(--aura-grain);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url("components/%23n")'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* ---- position presets (data-attribute scopes) -------------------------
   Each just sets the center point; the bloom's own size decides how much
   bleeds past the edge. Override --aura-x / --aura-y inline for anything else. */
[data-aura-pos="bottom"]       { --aura-x: 50%;  --aura-y: 100%; }
[data-aura-pos="top"]          { --aura-x: 50%;  --aura-y: 0%;   }
[data-aura-pos="center"]       { --aura-x: 50%;  --aura-y: 50%;  }
[data-aura-pos="left"]         { --aura-x: 0%;   --aura-y: 50%;  }
[data-aura-pos="right"]        { --aura-x: 100%; --aura-y: 50%;  }
[data-aura-pos="top-left"]     { --aura-x: 0%;   --aura-y: 0%;   }
[data-aura-pos="top-right"]    { --aura-x: 100%; --aura-y: 0%;   }
[data-aura-pos="bottom-left"]  { --aura-x: 0%;   --aura-y: 100%; }
[data-aura-pos="bottom-right"] { --aura-x: 100%; --aura-y: 100%; }

/* ---- shape presets (data-attribute scopes) ---------------------------- */
[data-aura-shape="band"]   { --aura-w: 130%; --aura-h: 42%; }   /* wide & short */
[data-aura-shape="column"] { --aura-w: 46%;  --aura-h: 120%; }  /* tall & narrow */
[data-aura-shape="circle"] { --aura-w: 70%;  --aura-h: 70%; }   /* equal */
[data-aura-shape="tight"]  { --aura-w: 50%;  --aura-h: 40%; --aura-w2: 38%; --aura-h2: 32%; }
[data-aura-shape="wide"]   { --aura-w: 124%; --aura-h: 60%; --aura-w2: 80%; --aura-h2: 50%; --aura-blur: 60px; }
[data-aura-shape="full"]   { --aura-w: 170%; --aura-h: 150%; --aura-w2: 130%; --aura-h2: 120%; --aura-blur: 80px; }

/* ---- intensity (data-attribute scopes) -------------------------------- */
[data-aura-intensity="soft"] { --aura-strength: 0.5; /* @kind other */ --aura-blur: 56px; }
[data-aura-intensity="bold"] { --aura-strength: 1;   /* @kind other */ --aura-blur: 36px; }

/* ---- motion (data-attribute scopes) ----------------------------------- */
[data-aura-motion="calm"]  { --aura-dur: 26s; /* @kind other */ }
[data-aura-motion="alive"] { --aura-dur: 9s;  /* @kind other */ }
[data-aura-motion="still"]::before,
[data-aura-motion="still"]::after { animation: none; }

@keyframes aura-drift-x {
  from { transform: translateX(-7%) scale(0.96); }
  to   { transform: translateX(7%)  scale(1.06); }
}
@keyframes aura-breathe {
  from { transform: scale(0.93); }
  to   { transform: scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .aura::before, .aura--duet::after { animation: none; }
}




/* ---- components/noise.css ---- */
/* ===========================================================================
   machado.group — Grain
   ---------------------------------------------------------------------------
   A fine film-grain / noise texture for a tactile, analog feel over flat light
   (or dark) surfaces. Two ways to call it:

   1) ONE CLASS on any box — grains that box's own background, content stays on
      top automatically. The easiest "apply to a section" call:

        <section class="grained"> ...content... </section>
        <div class="card grained"> ... </div>

   2) OVERLAY LAYER — a standalone <div class="grain"> you stack yourself, e.g.
      over an .aura gradient, between the backdrop and the z-index:1 content:

        <div style="position:relative; overflow:hidden">
          <div class="aura"><div class="aura__blob" style="…"></div></div>
          <div class="grain"></div>
          <div style="position:relative; z-index:1"> ...content... </div>
        </div>

   Intensity:  data-grain="subtle | strong"  (or set --grain-opacity inline)
   Tune:       --grain-opacity (0–1) · --grain-scale (tile px) · --grain-blend
   =========================================================================== */

:root {
  --grain-opacity: 0.22;  /* @kind other */
  --grain-scale:   150px; /* tile size of the noise field  @kind spacing */
}

/* shared visual definition ------------------------------------------------
   The noise is contrast-stretched (feComponentTransfer widens the values to a
   near full black→white range) so the blend actually has something to push.
   `overlay` is the universal default: it lightens-and-darkens around the
   backdrop, so the grain reads on BOTH light paper and near-black. */
.grain,
.grained::after,
body::before {
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend, overlay);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.4' intercept='-0.7'/%3E%3CfeFuncG type='linear' slope='2.4' intercept='-0.7'/%3E%3CfeFuncB type='linear' slope='2.4' intercept='-0.7'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url("components/%23n")'/%3E%3C/svg%3E");
  background-size: var(--grain-scale) var(--grain-scale);
}

/* 1) overlay layer -------------------------------------------------------- */
.grain {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
}

/* 2) one-class convenience ------------------------------------------------ */
/* Grains the element's OWN background; direct children are lifted above the
   grain so text/content is untouched. `isolation` keeps the blend local. */
.grained { position: relative; isolation: isolate; }
.grained > * { position: relative; z-index: 1; }
.grained::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
}

/* 3) page default --------------------------------------------------------
   Every page rendered with this system ships with grain: a fixed, full-
   viewport noise layer pinned above the paper but below content. It never
   intercepts clicks. Opt out per page with <body data-grain="off"> or
   <html data-grain="off">. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
}
body { position: relative; }
body > * { position: relative; z-index: 1; }
[data-grain="off"]::before,
[data-grain="off"] body::before { content: none; }

/* intensity presets ------------------------------------------------------- */
[data-grain="subtle"] { --grain-opacity: 0.12; /* @kind other */ }
[data-grain="strong"] { --grain-opacity: 0.4;  /* @kind other */ }

/* For an even grittier, fully film-like look on LIGHT surfaces, use multiply
   (dark specks bite into the paper). Opt in with .grain--ground. */
.grain--ground { mix-blend-mode: multiply; }

     /* a moldura de mídia (Dandelion, 21-set) */
   /* o aviso de cookie (Dandelion, 21-set) */
  /* o anel de prata em movimento (app de treino, 22-set) */
       /* o orbe de navegação mobile (app de treino, 22-set) */
 /* a roda de números (app de treino, 22-set) */
 /* a lista com foco (app de treino, 22-set) */

/* ---- skins (camada de cor opt-in) --------------------------------------
   POR ÚLTIMO de propósito: um seletor de skin tem a mesma especificidade de
   `:root` e de `[data-theme="light"]`, e precisa vencer quando é chamado.
   Não pinta nada sozinho — só sob `data-skin="<nome>"`. */

/* ---- tokens/skins.css ---- */
/* ===========================================================================
   machado.group — SKIN  ·  camada de cor opt-in
   ---------------------------------------------------------------------------
   Uma SKIN é um pacote de COR e nada mais — não mexe em tipo, espaço, raio nem
   movimento. Ela não existe em lado nenhum até ser CHAMADA pelo nome:

       <section data-skin="pop"> … </section>

   e vale em qualquer escopo: <html>, uma seção, um card, um botão só. Fora
   dele o sistema continua sendo o sistema.

   O CONTRATO: uma skin são SETE hexes, e nada mais. Os papéis (surface, ink,
   accent, line…) são DERIVADOS desses sete por uma lei única, escrita uma vez
   no bloco [data-skin]. Quem cria uma skin escreve só os sete.

     --skin-1  base        a superfície da página
     --skin-2  surface     a superfície levantada (card)
     --skin-3  ink         a tinta
     --skin-4  accent      a única cor forte
     --skin-5  on-accent   a tinta por cima do acento
     --skin-6  muted       a tinta secundária / o detalhe quieto
     --skin-7  detail      a segunda nota — press, line-strong, glow

   POSIÇÃO É PAPEL. O slot 1 é sempre a base. Trocar a ordem é trocar o papel —
   é essa a operação do laboratório (`pages/skin-lab.html`).

   Este arquivo é importado por ÚLTIMO em `styles.css`, de propósito: um
   seletor de skin tem a mesma especificidade de `:root` e de
   `[data-theme="light"]`, então quem chega depois vence. Skin é opt-in
   explícito — quando está posta, manda.

   O que a skin NÃO toca: as luzinhas de status. Estado é estado, não estilo.
   Um `data-skin` com nome que não existe não pinta nada — herda a casa.
   =========================================================================== */

/* ---- a lei da derivação  (escrita uma vez, vale para toda skin) --------- */
[data-skin] {
  /* papéis dos slots — uma skin pode remapear redeclarando estes */
  --skin-base:      var(--skin-1);
  --skin-surface:   var(--skin-2);
  --skin-ink:       var(--skin-3);
  --skin-accent:    var(--skin-4);
  --skin-on-accent: var(--skin-5);
  --skin-muted:     var(--skin-6);
  --skin-detail:    var(--skin-7);

  /* surfaces */
  --surface-page:    var(--skin-base);
  --surface-raised:  var(--skin-surface);
  --surface-sunken:  color-mix(in srgb, var(--skin-base), var(--skin-ink) 7%);
  --surface-inset:   color-mix(in srgb, var(--skin-base), var(--skin-ink) 13%);
  --surface-inverse: var(--skin-ink);

  /* ink */
  --ink:           var(--skin-ink);
  --ink-secondary: var(--skin-muted);
  --ink-tertiary:  color-mix(in srgb, var(--skin-muted), transparent 38%);
  --ink-disabled:  color-mix(in srgb, var(--skin-muted), transparent 66%);
  --ink-inverse:   var(--skin-base);
  --ink-on-accent: var(--skin-on-accent);

  /* linhas — sempre derivadas da tinta, para caírem em qualquer base */
  --line:        color-mix(in srgb, var(--skin-ink), transparent 86%);
  --line-strong: color-mix(in srgb, var(--skin-detail), transparent 60%);
  --line-faint:  color-mix(in srgb, var(--skin-ink), transparent 93%);

  /* acento — a única cor forte da vista */
  --accent:        var(--skin-accent);
  --accent-hover:  color-mix(in srgb, var(--skin-accent), var(--skin-on-accent) 16%);
  --accent-press:  var(--skin-detail);
  --accent-tint:   color-mix(in srgb, var(--skin-accent), transparent 84%);
  --accent-tint-2: color-mix(in srgb, var(--skin-accent), transparent 72%);
  --accent-ink:    var(--skin-on-accent);
  --focus-ring:    var(--skin-accent);

  /* luz — o detalhe decorativo segue a segunda nota da skin */
  --glow-tint:     color-mix(in srgb, var(--skin-detail), transparent 84%);
  --glow-tint-2:   color-mix(in srgb, var(--skin-detail), transparent 66%);
  --glow-gradient: linear-gradient(118deg, var(--skin-on-accent) 0%, var(--skin-accent) 52%, var(--skin-detail) 100%);

  /* vidro */
  --glass-bg:       color-mix(in srgb, var(--skin-ink), transparent 92%);
  --glass-bg-hover: color-mix(in srgb, var(--skin-ink), transparent 87%);
  --glass-edge:     color-mix(in srgb, var(--skin-ink), transparent 88%);
}

/* o esquema dos controles nativos não se calcula em CSS — a skin declara */
[data-skin][data-skin-scheme="light"] { color-scheme: light; }
[data-skin][data-skin-scheme="dark"]  { color-scheme: dark; }

/* ---- remendos: as duas peças que furam a camada de papéis ---------------
   `.btn--primary` e `.pill-btn` fixam `--c-paper` / `--c-gray-700` direto da
   paleta sob `:root:not([data-theme="light"])` — vieram de antes da regra.
   Dentro de uma skin isso saía branco-papel sobre a base da skin. Aqui elas
   voltam a ler papel: mesma especificidade (0,2,1), este arquivo chega depois.
   Fora da skin nada muda. */
[data-skin] .btn--primary { background: var(--ink); color: var(--ink-inverse); }
[data-skin] .btn--primary:hover:not(:disabled) { background: color-mix(in srgb, var(--ink), var(--skin-base) 18%); }
[data-skin] .pill-btn { background: var(--ink); color: var(--ink-inverse); }
[data-skin] .pill-btn:hover { background: color-mix(in srgb, var(--ink), var(--skin-base) 14%); }

/* ===========================================================================
   AS SKINS
   =========================================================================== */

/* ---- pop · beta ---------------------------------------------------------
   Da referência `refs/index.md` → uploads/…a6a950.jpg. Os três hexes medidos
   no arquivo (amostragem de pixel, 06-ago-2026): lima **#cef866** (71,6% da
   imagem), magenta **#ec1d91** (13,6%) e **#000000** (5,5%). A ref tem TRÊS
   cores e nada mais — os outros quatro slots são degraus de VALOR desses
   mesmos hues, nenhum hue novo. O `on-accent` é preto porque é isso que a ref
   faz: rótulo preto por cima do bloco magenta. */
[data-skin="pop"] {
  --skin-1: #cef866;  /* base       — lima ácida          · medido  */
  --skin-2: #dffa9c;  /* surface    — a lima levantada    · +11 L   */
  --skin-3: #000000;  /* ink        — o preto da sombra   · medido  */
  --skin-4: #ec1d91;  /* accent     — magenta             · medido  */
  --skin-5: #000000;  /* on-accent  — a ref rotula em preto        */
  --skin-6: #567409;  /* muted      — a lima em sombra    · −44 L   */
  --skin-7: #ab0c65;  /* detail     — o magenta fundo     · −16 L   */
  color-scheme: light;
}

/* ═══ INSTRUMENTO ═══════════════════════════════════════════════════════════
   A cor do gravador de campo — os dois prints que o Eduardo trouxe em
   20-ago-2026. Anda em par com o material de mesmo nome; sozinha ela troca a
   paleta e a peça continua macia.

   O QUE A REFERÊNCIA ENSINA, e casa com a lei que já tínhamos:
   o corpo NÃO é preto — é um cinza morno, quase oliva, de plástico moldado.
   O visor é que é quase preto. E há UMA cor quente, que é sempre COMANDO:
   gravar, o botão que dispara. Nunca decoração. É a mesma regra do --block,
   noutra matéria.

   ⚠ Estes sete saíram da imagem A OLHO, não de medição. A bancada
   (reference/design/color-bench/) existe exatamente para afinar isto contra
   a referência — `extrair.py <imagem>` monta a escada em OKLab. Enquanto não
   for medido, é aproximação declarada. */
[data-skin="instrumento"] {
  --skin-1: #2e302c;   /* base       corpo do aparelho, cinza-oliva fosco   */
  --skin-2: #3a3d38;   /* surface    o painel levantado                     */
  --skin-3: #eceae4;   /* ink        serigrafia clara                       */
  --skin-4: #e8622a;   /* accent     o laranja de COMANDO — rec, disparo    */
  --skin-5: #171814;   /* on-accent  tinta sobre o laranja                  */
  --skin-6: #9a9c95;   /* muted      rótulo gravado, segunda leitura        */
  --skin-7: #c4441f;   /* detail     o laranja pressionado / o filete quente*/
}
[data-skin="instrumento"] { color-scheme: dark; }


/* ═══ PLAYGROUND ════════════════════════════════════════════════════════════
   O tema do Obsidian dele (Journal/.obsidian/snippets/obsidian-custom-theme.css),
   promovido do playground-app em 26-out-2026 a pedido do playground-project.
   Hexes copiados do tema, não medidos. Só os sete slots sobem: os ajustes de
   peça (.day, .chip--bot, ::selection) continuam no app — são da tela, não da
   paleta. */
[data-skin="playground"] {
  --skin-1: #0d0d0d;  /* base       background-primary dele      */
  --skin-2: #121212;  /* surface    background-secondary         */
  --skin-3: #f4f2ec;  /* ink        o papel da casa              */
  /* 31-out: 4/5 passam a apontar a escala lima de colors.css (era #c2e368 /
     #141a06). Pedido do playground-project; o override local do app.css sai. */
  --skin-4: var(--lime-6);      /* accent     #d9f28c                    */
  --skin-5: var(--lime-floor);  /* on-accent  #16260d                    */
  --skin-6: #93938b;  /* muted      text-normal dele             */
  --skin-7: #f19bd7;  /* detail     a tag violeta                */
  color-scheme: dark;
}
/* tema claro do playground: o par claro da escala. Só 4/5 — o resto é do app. */
[data-theme="light"] [data-skin="playground"],
[data-theme="light"][data-skin="playground"] {
  --skin-4: var(--lime-2);      /* #5f8f2c */
  --skin-5: var(--lime-7);      /* #e6f7b8 */
}


/* ---- material (camada de MATÉRIA opt-in) --------------------------------
   DEPOIS da skin, e por uma razão de papel: a skin decide a COR, o material
   decide a ARESTA, o RAIO, a PROFUNDIDADE e a FOLGA. Onde os dois falam do
   mesmo token (as linhas, que a skin deriva da tinta), quem manda é o
   material — é ele que sabe se a peça tem filete. */

/* ---- tokens/materials.css ---- */
/* ===========================================================================
   machado.group — MATERIAL  ·  camada de MATÉRIA opt-in
   ---------------------------------------------------------------------------
   Uma SKIN é cor. Um MATERIAL é tudo o que faz a mesma cor parecer outra
   coisa: aresta, raio, profundidade, densidade e serigrafia.

       <div data-skin="instrumento" data-material="instrumento"> … </div>

   As duas são independentes de propósito. Cor sem matéria é o que já
   tínhamos; matéria sem cor deixa testar o relevo sem mexer na paleta.

   O CONTRATO: um material são SEIS números, e nada mais. Os papéis (raio,
   filete, sombra, folga, tick) são DERIVADOS desses seis por uma lei única,
   escrita uma vez no bloco [data-material]. Quem cria um material escreve só
   os seis.

     --mat-1  radius     o raio do container, em px
     --mat-2  edge       presença da aresta        0 = sem filete · 1 = duro
     --mat-3  depth      profundidade da sombra    0 = plano · 1 = objeto
     --mat-4  density    multiplicador de folga    1 = a casa · <1 = apertado
     --mat-5  tick       presença da serigrafia    0 = nenhuma · 1 = régua
     --mat-6  bevel      o relevo                  0 = chapado · 1 = moldado
     --mat-7  grain      a textura                 0 = liso · 1 = granulado

   O slot 7 não desenha nada sozinho: ele regula o `components/noise.css`, que
   já existia. Foi a única peça da referência que o sistema JÁ tinha — o corpo
   moldado daqueles aparelhos é superfície com grão, e a casa tem grão desde
   sempre. Reaproveitar em vez de inventar é o que mantém uma camada nova
   pequena.

   O QUE O MATERIAL NUNCA TOCA — e as três razões são diferentes:

     TIPOGRAFIA   a face é a marca. Regra do Eduardo, 20-ago-2026: muda o
                  material, mantém a tipografia da casa.
     ESTADO       luzinha de status é ESTADO, não estilo. Mesma lei da skin.
     GEOMETRIA    de peça — o goo do GlassNav, o anel do StepButton. Isso é
                  desenho do componente, não da matéria em que ele é feito.

   ⚠ O SLOT PERIGOSO É O 4. `density` reescreve a escala de espaço, e escala
     de espaço é layout. Abaixo de 0.8 as peças começam a se tocar; acima de
     1.2 a grade quebra em telas baixas. O intervalo é conselho, não trava:
     material é opt-in e quem o chama assume o que vê.
   =========================================================================== */

/* ---- a lei da derivação  (escrita uma vez, vale para todo material) ------ */
[data-material] {
  /* RAIO. O container manda; os degraus menores saem dele por proporção, e
     não por tabela — assim um material duro (raio 2) não precisa declarar
     cinco números para ficar duro em toda parte. */
  --radius-xs:   calc(var(--mat-1) * 0.25);
  --radius-sm:   calc(var(--mat-1) * 0.4);
  --radius-md:   calc(var(--mat-1) * 0.6);
  --radius-lg:   var(--mat-1);
  --radius-xl:   var(--mat-1);
  /* a pílula continua pílula: 999px não é um raio, é uma FORMA */

  /* ARESTA. Derivada da tinta para cair em qualquer base — mesma lei da skin.
     A casa não usa borda por default; um material com edge alto está a
     DECLARAR que quer o filete, e é a única forma de o ter sem pedir. */
  --line:        color-mix(in srgb, var(--ink), transparent calc(100% - var(--mat-2) * 22%));
  --line-strong: color-mix(in srgb, var(--ink), transparent calc(100% - var(--mat-2) * 42%));
  --line-faint:  color-mix(in srgb, var(--ink), transparent calc(100% - var(--mat-2) * 11%));

  /* PROFUNDIDADE. Sombra de verdade tem duas partes: o contacto (curto e
     escuro, que cola a peça na superfície) e a queda (longa e difusa, que diz
     a que altura ela está). Uma só das duas lê como adesivo. */
  --shadow-xs: 0 1px 1px rgba(0,0,0,calc(var(--mat-3) * .34));
  --shadow-sm: 0 1px 2px rgba(0,0,0,calc(var(--mat-3) * .40)),
               0 2px 6px rgba(0,0,0,calc(var(--mat-3) * .22));
  --shadow-md: 0 2px 3px rgba(0,0,0,calc(var(--mat-3) * .46)),
               0 6px 16px rgba(0,0,0,calc(var(--mat-3) * .30));
  --shadow-lg: 0 3px 5px rgba(0,0,0,calc(var(--mat-3) * .50)),
               0 14px 34px rgba(0,0,0,calc(var(--mat-3) * .38));

  /* RELEVO. É o que separa "retângulo mais claro" de PEÇA: uma luz fina em
     cima e uma sombra fina em baixo, por dentro. Duas linhas de 1px fazem o
     olho ver volume — é como o plástico moldado devolve a luz. */
  --bevel: inset 0 1px 0 rgba(255,255,255,calc(var(--mat-6) * .09)),
           inset 0 -1px 0 rgba(0,0,0,calc(var(--mat-6) * .45));
  --bevel-press: inset 0 1px 2px rgba(0,0,0,calc(var(--mat-6) * .55));

  /* DENSIDADE. O slot perigoso — ver o aviso no topo. */
  --space-1: calc(4px  * var(--mat-4));
  --space-2: calc(8px  * var(--mat-4));
  --space-3: calc(12px * var(--mat-4));
  --space-4: calc(16px * var(--mat-4));
  --space-5: calc(20px * var(--mat-4));
  --space-6: calc(24px * var(--mat-4));
  --space-8: calc(32px * var(--mat-4));

  /* SERIGRAFIA. A régua de ticks e o rótulo gravado do equipamento. Não pinta
     nada sozinha: é vocabulário que o componente chama quando quer. */
  --tick-color:  color-mix(in srgb, var(--ink), transparent calc(100% - var(--mat-5) * 34%));
  --tick-major:  color-mix(in srgb, var(--ink), transparent calc(100% - var(--mat-5) * 62%));
  --tick-size:   calc(var(--mat-5) * 6px);
  --tick-gap:    8px;

  /* TEXTURA. Só regula o que o `noise.css` já faz — não redesenha grão
     nenhum. Quem quer a textura chama `class="grained"`; o material decide
     QUANTA. Material sem grão põe 0 e a classe fica inerte. */
  --grain-opacity: calc(var(--mat-7) * .26);
}

/* ═══ INSTRUMENTO ═══════════════════════════════════════════════════════════
   O gravador de campo: painel de equipamento, aresta dura, peça moldada,
   régua à mostra. Referência trazida pelo Eduardo em 20-ago-2026 (dois prints
   de field recorder). A cor vive na skin de mesmo nome; aqui é só a matéria. */
[data-material="instrumento"] {
  --mat-1: 4px;    /* quase reto — equipamento não tem canto macio      */
  --mat-2: 1;      /* a aresta aparece, e é ela que desenha o painel    */
  --mat-3: 1;      /* objeto, não folha                                 */
  --mat-4: .85;    /* apertado: instrumento não desperdiça painel       */
  --mat-5: 1;      /* régua e ticks à mostra                            */
  --mat-6: 1;      /* moldado                                           */
  --mat-7: 1;      /* grão de plástico injetado                         */
}

/* ═══ CASA ══════════════════════════════════════════════════════════════════
   O material que o sistema já é, escrito por extenso. Serve para VOLTAR sem
   recarregar, e para o laboratório comparar lado a lado. */
[data-material="casa"] {
  --mat-1: 24px; --mat-2: .55; --mat-3: .8; --mat-4: 1; --mat-5: 0; --mat-6: 0;
  --mat-7: 0;
}



