/* ===== TOKENS ===== */
/* ==========================================================================
   Four Cloud Design System — TOKENS (scale + palette).
   The provider-neutral foundation: one --density knob scales type+spacing
   together; one slate accent carries structure; colour is rationed to meaning
   (red = money leaving, green = small positive deltas). Ported from the tested
   statement mockup (bi/static/bi/demo/statement.{scale,tokens}.css).

   This is the TOKENS section — first in custom.css, everything below depends on it.
   ========================================================================== */

:root{
  /* Reto. Sem exceção (dono, 11/09/2026: "quero tudo reto e sóbrio").
     A pílula de 999px vivia em 28 lugares e cada tela a usava com um
     sotaque. Um knob só: mudar aqui muda o sistema inteiro. */
  --raio-chip: 0;
  /* ── scale (no colour) ─────────────────────────────────────────────── */
  --density:1;                 /* THE knob — >1 comfortable, <1 compact */
  /* Batch6 note: --card-pad-* / --tile-pad-* are SUPERSEDED by the unified card
     contract (header 8/16/8, body 8/16/16 — docs/planos/batch6-card-contract.md §1).
     They are NOT re-pointed to --bi-space-* here because they are density-scaled px
     and re-pointing would strip the --density knob (kept per Batch5 §3) and risk
     reflow on the FCDS faturamento components. The unified padding is applied at the
     component layer (custom.css, owned by Impl-3); these remain the px base
     the --density knob multiplies until that layer re-points them. */
  --card-pad-y:calc(14px*var(--density));  --card-pad-x:calc(18px*var(--density));
  --tile-pad-y:calc(12px*var(--density));  --tile-pad-x:calc(14px*var(--density));  --tile-pad-b:calc(10px*var(--density));
  --gap:calc(0.5rem*var(--density));
  --content-pad-y:calc(16px*var(--density)); --content-pad-x:calc(20px*var(--density));
  --content-pad-b:calc(36px*var(--density));
  --card-hd-mb:calc(10px*var(--density));
  /* component pixel dims — static (NOT density-scaled, to avoid chart reflow) */
  --doughnut:168px; --spark-h:40px; --flow-min:248px;
  --r:var(--bs-border-radius-lg); --r-sm:var(--bs-border-radius); --r-xs:var(--bs-border-radius-sm); --r-full:var(--bs-border-radius-pill);

  /* ── palette ───────────────────────────────────────────────────────── */
  --surface-app:#ffffff;       /* the canvas — BRANCO em todas as telas (dono,
                                  28/09/2026: "Deixa todas com fundo branco"; era
                                  #edf0f4). --bi-bg-base re-points here. */
  --bg:#f6f7f9;
  --surf:#ffffff; --surf-2:#f3f4f7; --surf-3:#eceef2;
  --line:#e6e8ec; --line-2:#eef0f3; --line-3:#d8dbe1;
  --ink:#191c22; --ink-2:#5a6171; --ink-3:#6b7280; --ink-4:#aab0bb;  /* ink-3 #8b93a1→#6b7280: was 3.09:1 (fail AA), now ~4.7:1 */
  /* ACENTO DE COMPONENTE — o azul DE FÁBRICA do Bootstrap, sem cor autoral
     nenhuma: os degraus APONTAM para as variáveis do próprio Bootstrap. Quem
     pinta seleção, foco, chip ligado, dia/mês escolhido e página ativa da
     paginação lê daqui. Se um dia o tema do Bootstrap mudar, isto muda junto —
     é esse o objetivo. Cinza só no SHELL, em --shell-acc-* logo abaixo. */
  --acc:var(--bs-primary); --acc-d:var(--bs-link-hover-color); --acc-ink:var(--bs-link-hover-color);
  /* únicos hex: a dupla *-bg-subtle/*-border-subtle nasceu no 5.3 e o bundle é
     5.2.3 — valores de fábrica do upstream, não cor autoral. */
  --acc-soft:#cfe2ff; --acc-line:#9ec5fe;
  /* ACENTO DO SHELL — o cinza DO BOOTSTRAP (secondary + escada gray), a única
     exceção ao azul, por diretiva do usuário. Consumido SÓ pela sidebar e pela
     topbar (§2/§3): item de menu ativo, trilho da esquerda, avatar e botão de
     menu. Não usar em conteúdo de página. */
  --shell-acc:var(--bs-secondary); --shell-acc-ink:var(--bs-gray-700);
  --shell-acc-soft:var(--bs-gray-200); --shell-acc-line:var(--bs-gray-300);

  /* Escada de tinta do Bootstrap com os VALORES DE FÁBRICA do 5.3 (rgba do corpo a
     75% e a 50%), e não com a tinta FCDS: por diretiva do usuário, nenhuma paleta
     de cor de texto é repontada aqui. Os dois tokens continuam declarados só porque
     o bundle vendorizado é 5.2.3 e não os traz — os utilitários que os consomem
     estão portados mais abaixo. NÃO apontar para --ink-*. */
  --bs-secondary-color: rgba(33, 37, 41, 0.75);
  --bs-tertiary-color: rgba(33, 37, 41, 0.5);
  /* Os utilitários que consomem estes dois tokens só nasceram no Bootstrap 5.3 e o
     build vendorizado é 5.2.3 — por isso eles estão portados logo abaixo de
     .num--* neste arquivo. Quando o Bootstrap subir para 5.3, apagar o port: os
     tokens acima já alimentam a versão upstream, sem tocar em nenhum consumidor. */

  /* CANONICAL COLOR SYSTEM — single source of truth for color meaning.
     Reuse everywhere; never hardcode hex. Ref: docs/planos/batch2-semantic-color-contract.md
     Structure tokens (text/surface/border) are above: --ink/--surf/--line/--acc.
     PRIMARY = brand slate for non-semantic UI emphasis. */
  /* AÇÃO — era o azul Four #006BB5. Passa a apontar para o acento de componente,
     ou seja, o azul de fábrica do Bootstrap: os botões sólidos desta família
     (Buscar, .tb-btn--solid) vivem lado a lado com a paginação e
     com os .btn-primary do Bootstrap, e dois azuis quase iguais na mesma tela
     leem como defeito. Um azul só. Os quatro nomes ficam porque 35 regras os
     consomem — repontar aqui alinha todas de uma vez. */
  --brand: var(--acc);
  --brand-strong: var(--acc-d);
  --brand-soft: var(--acc-soft);
  --brand-ink: var(--acc-ink);
  --command: #2b3038;        /* near-black ink for DATA magnitude where charcoal is wanted (sparklines). NOT an action color. */

  /* ── DIRECTION (value valence) ────────────────────────────────────────────
     Two tiers + a bg tint, per direction:
       --x        vivid FILL  — bars, chart datasets, icons, rules, dots.
       --x-text   AA-safe     — small text / numbers on white (≥4.5:1).
                                --warning-text é o laranja de texto #FA4B00
                                (dono, 05/10/2026; 3,5:1, sempre em negrito).
       --x-subtle BACKGROUND-ONLY tint — badges/chips; never text.
     Color encodes DIRECTION only — never category/type/entity (use --cat-* for that). */
  --positive:#22c55e;  --positive-text:#15803d;  --positive-subtle:color-mix(in srgb, var(--positive-text) 10%, var(--surf));
  --negative:#ef4444;  --negative-text:#ca2a26;  --negative-subtle:#fcecea;
  /* Atenção (#229): o laranja vivo #FF7B00 (--ds-atencao / --chart-alerta)
     pinta ÁREA — ponto, faixa, arco; como texto dá 2,6:1 sobre branco. O
     TEXTO de atenção é #FA4B00 (escolha do dono, 05/10/2026: 3,5:1, por isso
     em negrito), nunca o marrom aposentado. Alimenta .badge--warning,
     .text-warning e ~40 regras de tela. --warning (o âmbar de preenchimento)
     fica fora do #229. */
  --warning:#f59e0b;   --warning-text:#FA4B00;   --warning-subtle:color-mix(in srgb, var(--warning) 14%, var(--surf));
  --neutral:#94a3b8;   --neutral-subtle:color-mix(in srgb, var(--ink-2) 9%, var(--surf));
  --info:#1f9bcf;      --info-text:#15709c;      --info-subtle:color-mix(in srgb, var(--info) 12%, var(--surf));

  /* ── INDICATOR ALIASES (semantic, AA-safe small text) ─────────────────────
     cores.md prescribes these names for inline notices. Alias de --warning-text
     (a TINTA desde o #229): repontar aqui alinha as chamadas que o consomem. */
  --color-indicator-warning-text: var(--warning-text);

  /* ── RANGE (ordered scale, good→bad) ──────────────────────────────────────
     For 3-stop ramps / conditional thresholds. *-normal-1 = best (green),
     *-inverted reverses valence (when high = bad, e.g. cost/aging). */
  --range-normal-1:var(--positive);   --range-normal-2:var(--warning);   --range-normal-3:var(--negative);
  --range-inverted-1:var(--negative); --range-inverted-2:var(--warning); --range-inverted-3:var(--positive);

  /* ── CATEGORY (qualitative identity — NO valence) ─────────────────────────
     Identidade por matiz SÓ FORA DE GRÁFICO (dot do mapa do tracking, cor de
     sala): em gráfico, categorizar é a rampa do azul — paleta de matizes foi
     testada e rejeitada pelo dono em 2026-08-06 (DESIGN.md §2). Charts read
     these via getComputedStyle onde a exceção vale (tracking/salas). */
  --cat-1:#2563eb; --cat-2:#f97316; --cat-3:#16a34a; --cat-4:#9333ea;
  --cat-5:#db2777; --cat-6:#0e7490; --cat-7:#ca8a04; --cat-8:#dc2626;

  /* ── PALETA DE GRÁFICOS ───────────────────────────────────────────────────
     Regras completas em docs/globais/componentes.md §Gráficos e no design
     aprovado em docs/superpowers/specs/2026-07-27-sistema-cor-graficos-design.md.

     São QUATRO cores, e só. Cada uma responde a uma pergunta:
       --chart-azul    QUANTO      magnitude sem sinal (receita, volume, saldo, contagem)
       --positive      POSITIVO    entrada, ganho, acima da meta
       --negative      NEGATIVO    saída, perda, abaixo do mínimo
       --chart-alerta  ATENÇÃO     a faixa antes do vermelho, onde existe limiar

     CATEGORIZAR = opacidade do azul, em quantos passos a série pedir (não há
     teto e não há agregação em "Outros"): biChartConfig.rampaAzul(n). Dois tons
     vizinhos de uma rampa longa são perceptualmente iguais — quem devolve a
     leitura é o SEPARADOR na cor da superfície (3px em fatia de donut, 1,5px
     entre segmentos empilhados) somado ao rótulo. Sem separador, rampa longa é
     ilegível: ele é requisito, não enfeite.

     CINZA não é cor de dado. Sobrevive só em tick, rótulo e borda (--ink-*).

     --chart-alerta é o laranja vivo do design system (#FF7B00, --figure-attention;
     #229: um laranja só). Dá 2,6:1 sobre o branco, ABAIXO do piso de 3:1 de
     elemento gráfico: só pinta ÁREA que tem contorno ou rótulo junto (o ponto
     do Acompanhamento de Produção tem a borda da linha; o arco do gauge tem o
     número no centro). Nunca número, nunca texto: texto de atenção é tinta. */
  --chart-azul:#2563eb;
  --chart-alerta:#FF7B00;

  /* Fonte ÚNICA do projeto: Neue Haas Display (maquete A/C do #220, padrão da casa pelo #454).
     --mono existe só p/ os números tabulares (mesma fonte + tabular-nums) — não há 2ª fonte. */
  --sans:'Neue Haas Display','Helvetica Neue',Helvetica,Arial,sans-serif;
  --bs-body-font-family: var(--sans);
  --mono: var(--sans);
  /* --bs-font-monospace REMAPEADO para --sans por diretiva do usuário: uma fonte
     só no projeto. Sem este remap a primitiva do Bootstrap ficava de
     fábrica e a utility `.font-monospace`, <code> e <pre> caíam no stack
     SFMono/Menlo/Consolas — uma 2ª fonte, viva em 8 arquivos (importar-of,
     matriz-acesso, faturamento-fcds, diagnostico-preenchimento, pedidos,
     forecast-comex, catalogo). Como TODO o vazamento passava por esta
     variável, o remap resolve os 8 de uma vez; não há font-family mono
     hardcoded em lugar nenhum deste arquivo. */
  --bs-font-monospace: var(--sans);
  /* all resting shadows removed app-wide (user directive). Only --ring (keyboard
     focus, a11y) survives. Every surface is flat: hairline border + surface ladder. */
  --sh1:none;
  --sh2:none;
  /* anel de foco do Bootstrap (rgba do --bs-primary a 25%) — era o cinza
     rgba(100,107,120,.22), do tempo em que o acento era o slate da marca. */
  --ring:0 0 0 3px rgba(13,110,253,.25);
  /* glass — now OPAQUE. backdrop-filter was removed from card/topbar surfaces
     (per-frame blur was the scroll-jank source); opaque fills preserve the look
     without compositing cost. Over the --bg (#f6f7f9) page the old translucent
     whites already read as near-white, so this is visually ~identical. */
  --glass:#ffffff;                 /* was rgba(255,255,255,.64) */
  --glass-2:#f6f7fa;               /* was rgba(255,255,255,.54) — keeps the lower tier */
  --glass-bd:var(--line);          /* white edge only read against blur; neutral hairline now */
  --blur:saturate(150%) blur(18px);/* retained for any remaining frosted accent; off the scroll path */
  /* fully flat: glass sheen AND drop shadow removed. The soft drop lift read as a
     grey halo around every card — stacked, those halos looked like a "visual effect
     between each component." Cards are now delineated by their 1px hairline border
     and the surface ladder alone (no shadow, no glass). */
  --sh-glass:none;

  /* ═══════════════════════════════════════════════════════════════════════════
     APP (bi/) TOKENS — merged here so EVERY token lives in one file.
     Scale/typography/surface/border/shadow + grayscale ramp. No color *meaning*
     here (that's the canonical block above); these are structure + chart chrome.
     ═══════════════════════════════════════════════════════════════════════════ */

  /* grayscale ramp (neutral structure, no valence) */
  --bi-color-white: #ffffff;

  /* typography — single family via --sans (Neue Haas Display, @font-face neste arquivo). */
  --bi-font-display:   var(--sans);
  --bi-font-mono:      var(--mono);
  /* Escala única de fonte (#476): seis degraus, pesos 400 e 500. Corpo 14px no próprio Bootstrap; o html
     fica em 16px, então todo rem do Bootstrap segue valendo. Rótulo de 11px só em texto versal. */
  --bs-body-font-size: .875rem;
  --fonte-rotulo:   .6875rem;
  --fonte-pequena:  .75rem;
  --fonte-corpo:    var(--bs-body-font-size);
  --fonte-destaque: 1rem;
  --fonte-titulo:   1.25rem;
  --fonte-heroi:    2rem;
  /* Tokens antigos apontados para a escala. Os que sobram servem só a exceções do canário
     (grade, DataTables cru, outras panes, o <style> das Salas) e a JS de gráfico/tabela (#476, onda 5). */
  --bi-fs-body:    var(--fonte-corpo);
  --bi-fs-label:   var(--fonte-pequena);
  --bi-fs-compact: var(--fonte-corpo);
  --bi-fs-micro:   var(--fonte-pequena);
  --bi-fw-regular:  400;
  --bi-fw-medium:   500;
  --bi-fw-semibold: 500;
  --bi-fw-bold:     500;
  --bi-lh-normal: 1.5;

  /* spacing */
  --bi-space-3xs: 0.25rem;
  --bi-space-2xs: 0.25rem;
  --bi-space-xs2: 0.5rem;
  --bi-space-xs:  0.25rem;
  --bi-space-sm:  0.5rem;
  --bi-space-md:  1rem;
  --bi-space-lg:  1.5rem;
  --bi-space-xl:  1.5rem;
  --bi-space-2xl: 3rem;
  --bi-space-3xl: 3rem;

  /* radius, borders, shadows — alias dos primitivos --r* (fonte única) */
  --bi-radius-sm:   var(--r-xs);
  --bi-radius-md:   var(--r-sm);
  --bi-radius-lg:   var(--r);
  --bi-radius-full: var(--r-full);

  /* scroll cap — standard max-height for in-card scroll bodies (ranked lists,
     analysis tables) so side-by-side cards read at one height instead of one
     stretching the page. Responsive: floor 320px, ~46vh, ceiling 460px.
     Applied via the .card-scroll utility (custom.css). */
  --bi-scroll-cap: clamp(320px, 46vh, 460px);
  /* table tier (.tbl-scroll, sticky-header tables) and datatable tier
     (.datatable-scroll, full DataTables grids) — larger caps, distinct from the
     compact card-list tier above. Per-instance override stays via
     --bi-table-scroll-max / --bi-dt-scroll-max. */
  /* O TETO EM PIXEL MORREU (decisão do dono, 08/09/2026: "exclua essa maldita
     restrição e faça sempre ocupar"). Os dois tetos abaixo tinham um limite
     absoluto — 520px e 560px — que parava a grade no meio da janela e deixava
     faixa de chão embaixo em TODA tela de tabela: medido em 900px de janela, a
     grade terminava aos 560 e sobravam ~300px vazios. Dez lugares já haviam
     furado esse teto na mão, sempre com o mesmo `flex:1 1 auto; min-height:0;
     max-height:none` — o padrão real já era ocupar, e o teto é que era a
     exceção mal colocada.
     O limite RELATIVO fica: é ele que impede a grade de estourar a tela num
     celular deitado, mantendo o cabeçalho grudado e a rolagem por dentro. */
  --bi-table-scroll-cap: 82dvh;
  --bi-dt-scroll-cap: 82dvh;
  --bi-border-color:        #e6e8ec;
  --bi-border-color-subtle: #eef0f3;
  --bi-border-color-heavy:  #d8dbe1;
  --bi-border:        1px solid var(--bi-border-color);
  --bi-border-subtle: 1px solid var(--bi-border-color-subtle);
  --bi-border-heavy:  1px solid var(--bi-border-color-heavy);
  --bi-shadow-xs: none;
  --bi-shadow-sm: none;
  --bi-shadow-md: none;
  --bi-shadow-lg: none;

  /* surfaces + text */
  --bi-bg-surface: #ffffff;
  --bi-bg-command: #ffffff;
  --bi-bg-elevated: #ffffff;
  --bi-bg-hover:   #f3f4f7;
  --bi-bg-active:  #eceef2;
  --bi-text-primary:   #191c22;
  --bi-text-secondary: #5a6171;
  --bi-text-muted:     #6b7280;
  --bi-text-on-dark:   #F9FAFB;
  --bi-text-on-accent: #FFFFFF;

  /* transitions + z-index */
  --bi-transition-fast:   150ms ease;
  --bi-transition-normal: 250ms ease;
  --bi-transition-slow:   400ms ease;
  --bi-z-dropdown: 100;
  --bi-z-sticky:   200;
  --bi-z-fixed:    300;
  --bi-z-overlay:  400;
  --bi-z-modal:    500;

  /* ===== ESCALA CANÔNICA DE CAMADAS (chrome + modais do app) =====
     A escala --bi-z-* acima é LEGADA/interna (usada por dropdowns e overlays de
     página); não repointar em massa. A escala --z-* abaixo é a canônica de CHROME
     e MODAL, interleavada com as bandas de VENDOR que NÃO dá pra mover:
       Leaflet:   panes 200–700, controls 1000
       Bootstrap: dropdown 1000 · sticky-top 1020 · fixed-top 1030 · offcanvas 1040/1045
                  · modal-backdrop 1050 · modal 1055 · popover 1070 · tooltip 1080 · toast 1090
     Regra: conteúdo de página < 1000; chrome do app (topbar) acima do conteúdo e
     abaixo do band de modais BS; modais do app >= 1100 (acima do BS modal 1055). */
  --z-scrim:       800;    /* backdrop do drawer mobile — dim do conteúdo, não da topbar */
  --z-topbar:      900;    /* topbar sticky + seus popovers (.pop 60 é ordem interna) */
  --z-drawer:      950;    /* .side mobile aberto — cobre a topbar por design */
  --z-modal:      1100;    /* modalboxes / drawers app / mapa fullscreen (acima do BS modal 1055) */
  --z-modal-inner:1150;    /* select2 / controle aninhado DENTRO de um modal app */
  --z-boot:      13000;    /* splash / #page-loading-overlay — acima de tudo, incl. vendor */

  /* skeleton + loader */
  --bi-skeleton-base:  #E5E7EB;
  --bi-skeleton-shine: #F3F4F6;
  --bi-loader-base: #BFC3C8;
  --bi-loader-bg:   transparent;

  /* chart overlays (read by JS via getComputedStyle) */
  --bi-tooltip-bg:        #191c22;
  --bi-tooltip-fg-title:  #E2E8F0;
  --bi-tooltip-fg-body:   #CBD5E1;
  --bi-chart-datalabel:   #5a6171;
  --bi-chart-axis-tick:   #6b7280;
  --bi-chart-bar-border:  #FFFFFF;
  --bi-chart-axis-border: rgba(0, 0, 0, 0.08);

  /* ─────────────────────────────────────────────────────────────────────────
     PAGE PALETTES — per-page design languages kept distinct from the canonical
     system on purpose (warm Comex theme; metas editor). Defined here so EVERY
     token lives in one file; only consumed by their own pages.
     ───────────────────────────────────────────────────────────────────────── */

  /* Comex — Forecast (same warm language, fuller ramp) */
  /* RE-SKINNED to slate FCDS (Batch F): colours/fonts/shadow repointed to the
     canonical palette; the dense forecast radii/transition kept (tight grid). */
  --fc-page-bg:       var(--surface-app);
  --fc-border:        var(--line);
  --fc-urgent-fg:     var(--negative-text);
  --fc-urgent-border: color-mix(in srgb, var(--negative) 18%, var(--surf));
  --fc-soon-border:   color-mix(in srgb, var(--warning) 18%, var(--surf));
  --fc-ok-border:     color-mix(in srgb, var(--positive) 18%, var(--surf));
  --fc-neutral-bg:    var(--surf-2);
  --fc-radius-sm:     2px;
  --fc-radius:        4px;
  --fc-radius-md:     6px;
  --fc-transition:    0.15s ease;
}

/* ==========================================================================
   BOOTSTRAP PALETTE — REMOVIDA (diretiva do usuário)
   Aqui morava o remap da paleta do Bootstrap para o FCDS: --bs-primary,
   --bs-secondary, --bs-success, --bs-info, --bs-warning, --bs-danger (com os
   pares -rgb), --bs-body-color, --bs-body-bg e --bs-border-color, mais o
   .text-bg-primary. Tudo removido: botão, link, fonte, borda e utilitário de cor
   passam a usar os valores DE FÁBRICA do Bootstrap. O visual de marca sobrevive
   só no SHELL (.stm-shell/.app/.topbar/sidebar) e nos componentes FCDS, que têm
   cor própria e não dependem desta paleta. NÃO reintroduzir nenhum destes.

   O único token --bs-* de cor que resta aqui é o `-bg-subtle` de warning, e não
   por causa da marca: o bundle vendorizado é 5.2.3 e não tem a família *-subtle
   do 5.3. Fica com o VALOR DE FÁBRICA do 5.3, para o utilitário portado logo
   abaixo continuar existindo.
   ========================================================================== */
:root{ --bs-warning-bg-subtle:#fff3cd; }
/* Utility do Bootstrap 5.3 que falta no bundle vendorizado (só a de warning é
   usada hoje; as demais entram quando alguém precisar). */
.bg-warning-subtle{ background-color:var(--bs-warning-bg-subtle)!important; }
/* O bundle vendorizado saiu com o primary do SB-Admin (vermelho #b42735); aqui volta o azul de fábrica do 5.2.3. */
.text-bg-primary{ background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important; }

/* ===== SHELL ===== */
/* ==========================================================================
   Four Cloud Design System — SHELL.
   The app frame only: gradient body · slim glass topbar · hover-expand glass
   sidebar · content surface · mobile drawer + scrim. Ported 1:1 from the tested
   statement mockup (bi/static/bi/demo/statement.css, shell sections).

   Requires custom.css loaded first. Does NOT style filters or page content
   (page-owned) nor the .stm-* components (custom.css).

     §1 reset + display primitives   §2 app frame + sidebar
     §3 topbar   §4 content surface   §5 scrim + responsive
   ========================================================================== */

/* ── §1 RESET + display primitives ───────────────────────────────────────── */
.stm-shell *{box-sizing:border-box}
/* `body` com altura MÍNIMA, nunca fixa (reporte #134): offcanvas e modal do
   Bootstrap põem `overflow:hidden` no `body` para travar a rolagem; com
   `height:100%` ele encolhia para a altura da janela, cortava a página e a
   rolagem ia a zero — abrir a ficha jogava a lista de volta ao topo. O
   `height:auto` é explícito porque o `styles.css` vendorizado (SB-Admin) também
   declara `html, body{height:100%}`. */
html{height:100%}
html,body{margin:0;overflow-x:clip}
body{height:auto;min-height:100%}
/* A Neue Haas Display tem o espaço estreito (0,159em; o do Roboto era 0,25em): a 14px as palavras colavam
   ("Pedidos eNotasFiscais"). +0,1em devolve o vão; os controles entram junto porque o navegador zera o
   word-spacing deles (#454). */
body, button, input, select, textarea { word-spacing: .1em; }
body.stm-shell{color:var(--ink);font-family:var(--sans);font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased;
  /* plain flat page bg — the three radial glows were the "effect" on the
     background; removed for a flat surface (user directive). */
  background:var(--surface-app)}
.stm-shell .tnum{font-family:var(--mono);font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
/* Button baseline reset — wrapped in :where() so it carries ZERO specificity and
   any component class (.buscar, .fdrop, .filtbtn…) overrides
   it. Without :where() this selector (0,2,1) silently clobbered the background of
   every toolbar button, leaving chips/Buscar transparent. */
:where(.stm-shell .app button){font:inherit;color:inherit;background:none;border:none;cursor:pointer}
.stm-shell .metric--sig{font-size:var(--fonte-heroi);font-weight:500;line-height:40px;letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin:0.5rem 0 0.25rem}

/* ── §2 APP FRAME + SIDEBAR ──────────────────────────────────────────────── */
/* Largura da sidebar ABERTA (hover, foco ou `body.pinned`). Era 14.75rem (236px)
   repetida em dois lugares, e cortava três rótulos do menu em silêncio — a
   `.side` tem overflow:hidden e o texto não tem reticências, então sumia sem
   aviso ("Acompanhamento Inadimplência" terminava em 263px). 17.25rem era o
   mínimo para não cortar; 20rem (320px) é a escolha do dono (14/08/2026), com
   folga de ~57px depois do maior rótulo — respiro, não aperto.

   No hover não custa área de conteúdo: a sidebar aberta COBRE a página (o
   `.main` fica com o margin-left do trilho, 3rem). TRAVADA ela empurra — ver
   `body.pinned .main` abaixo. O piso é ~16,5rem —
   abaixo disso os três rótulos longos voltam a ser cortados em silêncio. */
:root{--side-w-aberta: 20rem}
.app{min-height:100vh}
/* near-opaque so animating width stays smooth (backdrop-filter + width = jank) */
.side{position:fixed;top:var(--topbar-h, 52px);left:0;height:calc(100vh - var(--topbar-h, 52px));width: 4rem;z-index:30;overflow:hidden; /* < --z-topbar: sidebar desktop fica sob a topbar */
  display:flex;flex-direction:column;border-right:1px solid var(--line);
  background:var(--surf);will-change:width;
  transition:width .26s cubic-bezier(.22,1,.36,1),box-shadow .26s cubic-bezier(.22,1,.36,1)}
.side:hover,.side:focus-within{width:var(--side-w-aberta)}
.main{margin-left:3rem;min-width:0;min-height:calc(100vh - 52px);
  will-change:margin-left;transition:margin-left .26s cubic-bezier(.22,1,.36,1)}
body.pinned .side{width:var(--side-w-aberta);box-shadow:none}
/* Travada, a sidebar deixa de COBRIR a página e passa a EMPURRAR: o conteúdo
   ganha a margem da barra aberta. É a diferença entre travar e só passar o
   mouse — no hover a barra sobrepõe (nada mexe de lugar), travada ela ocupa
   espaço de verdade. Transição já está no `.main`. */
body.pinned .main{margin-left:var(--side-w-aberta)}
/* Loading da casca (#671, dono 28/10/2026: "o loading deveria esconder todo o conteúdo da página, deixar só
   sidebar/topbar e a logo"). O `#page-loading-overlay` nasce no `splash-critical.css` (congelado) cobrindo a
   janela inteira com branco a 85% — a página vazava por trás. Aqui ele cobre só a área da página, opaco:
   abaixo da topbar, à direita do trilho da sidebar (a barra aberta quando travada). Só na casca do app
   (`body.stm-shell`): login e portal de representantes não têm topbar nem sidebar e seguem com a janela toda. */
.stm-shell #page-loading-overlay{top:var(--topbar-h, 52px);left:4rem;background:var(--surf)}
.stm-shell.pinned #page-loading-overlay{left:var(--side-w-aberta)}
/* collapsed rail (desktop ≥761): true icon-only — labels/headers/chevrons/subs
   LEAVE the layout so nothing is left half-cropped. */
.side .nav a span,.side .navgrp span,.side .nav__g{white-space:nowrap}
@media(min-width:768px){
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav a,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .navgrp{justify-content:center;gap:0;padding-left:0;padding-right:0}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav a span,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .navgrp span,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav a .cnt,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .navgrp .chev,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav__g,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user div{display:none}
  /* Recolhida, a barra tem 64px: o Sair espremia o avatar contra a borda e o
     deixava oval. Sai o Sair (ele volta assim que a barra abre) e o avatar
     fica redondo, sozinho e centrado — é ele que abre "Minha conta". */
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user form{display:none}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user__eu{
    flex:0 0 auto;justify-content:center}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user .av{flex:0 0 auto}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user .av__ini{display:block}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .user .av__cfg{display:none}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .subnav{max-height:0!important}
  body:not(.pinned) .side:not(:hover):not(:focus-within) .side__foot .user{justify-content:center;padding:0.25rem 0}
}
/* display:flex+column is explicit so it wins over the legacy styles.css `.nav`
   (SB-Admin/Bootstrap) rule `display:flex;flex-wrap:wrap`, which otherwise lays
   the items out as a wrapping row (collapsed rail → two icons per line). */
/* display:block neutralises the legacy styles.css `.nav` (SB-Admin/Bootstrap)
   `display:flex;flex-wrap:wrap`, which otherwise lays the items out as a wrapping
   row (collapsed rail → two icons per line). Block flow keeps them stacked AND
   lets the nav scroll naturally — a flex column would instead shrink the items to
   fit and clip the lower groups. min-height:0 lets this flex child (of .side)
   shrink below its content so overflow-y:auto can scroll. */
/* Scoped to the sidebar (#nav) — a bare `.nav{display:block}` leaked to every
   Bootstrap `.nav-tabs` (modals), overriding `.nav{display:flex}` and stacking
   tabs vertically. Sidebar keeps block flow; modal tabs get Bootstrap's row. */
#nav{flex:1;min-height:0;display:block;overflow-y:auto;overflow-x:hidden;padding:1rem 0.5rem 0.5rem}
.nav__g{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);
  padding:1rem 0.5rem 0.25rem}
.nav a{display:flex;align-items:center;gap:0.5rem;padding:0.5rem 0.5rem;border-radius:var(--r-sm);color:var(--ink-2);
  font-weight:500;text-decoration:none;margin-bottom:0;transition:background .12s,color .12s}
.nav a svg{width: 1.0625rem;height: 1.0625rem;color:var(--ink-3);flex:0 0 auto}
.nav a i{width: 1.0625rem;font-size:1rem;color:var(--ink-3);flex:0 0 auto;text-align:center}
.nav a:hover{background:var(--surf-2);color:var(--ink)}
.nav a.on,.nav a.active{background:var(--shell-acc-soft);color:var(--shell-acc-ink);position:relative}
.nav a.on svg,.nav a.active svg,.nav a.on i,.nav a.active i{color:var(--shell-acc)}
.nav a.on::before,.nav a.active::before{content:"";position:absolute;left:-12px;top:7px;bottom:7px;width: 0.1875rem;border-radius: 0 var(--bs-border-radius-sm) var(--bs-border-radius-sm) 0;background:var(--shell-acc)}
.nav a .cnt{margin-left:auto;font-family:var(--mono);font-size:var(--fonte-pequena);color:var(--ink-3);background:var(--surf-2);
  border-radius:var(--raio-chip);padding:0 0.5rem}
.nav a.on .cnt{background:var(--surf);color:var(--shell-acc-ink)}
.navgrp{display:flex;align-items:center;gap:0.5rem;width:100%;padding:0.5rem 0.5rem;border-radius:var(--r-sm);
  color:var(--ink-2);font-weight:500;text-align:left;margin-bottom:0;transition:background .12s,color .12s}
.navgrp svg.gi,.navgrp i.gi{width: 1.0625rem;height: 1.0625rem;font-size:1rem;color:var(--ink-3);flex:0 0 auto;text-align:center}
.navgrp:hover{background:var(--surf-2);color:var(--ink)}
.navgrp.has-on{color:var(--ink)} .navgrp.has-on svg.gi,.navgrp.has-on i.gi{color:var(--shell-acc)}
.navgrp .chev{width: 0.8125rem;height: 0.8125rem;font-size:0.875rem;color:var(--ink-3);margin-left:auto;transition:transform .18s}
.navgrp.open .chev{transform:rotate(180deg)}
.subnav{overflow:hidden;max-height:0;transition:max-height .24s ease}
.subnav a{padding-left:1.5rem;color:var(--ink-3)}
.subnav a i{width: 1rem;font-size:0.875rem;color:var(--ink-4);flex:0 0 auto;text-align:center}
.subnav a:hover i{color:var(--ink-3)}
.subnav a.on,.subnav a.active{color:var(--shell-acc-ink)}
/* `_menu_fcds.html` prefixa TODO ícone de item com `fas` (Solid) — um ícone de
   marca (WhatsApp) precisa de `fa-brands`, e as duas classes juntas colidem
   em font-family/weight. Especificidade igual, a ordem do all.min.css decide
   quem vence — não é pra confiar nisso. Este seletor força a família certa
   sempre que alguém combina `fas` com `fa-brands` no menu. */
.subnav a i.fa-brands, .gi.fa-brands { font-family: "Font Awesome 6 Brands"; font-weight: 400; }
.subnav a.on i,.subnav a.active i{color:var(--shell-acc)}
.subnav a.on::before,.subnav a.active::before{display:none}
/* 3º nível do menu (#220): o grupo dentro de um .subnav tem a tipografia e o recuo do item de
   2º nível, e os filhos dele descem um passo (1rem) a mais. Níveis 1 e 2 não mudam. */
.subnav .navgrp{padding-left:1.5rem;color:var(--ink-3)}
.subnav .navgrp i.gi{width: 1rem;font-size:0.875rem;color:var(--ink-4)}
.subnav .navgrp:hover,.subnav .navgrp.has-on{color:var(--ink)}
.subnav .navgrp.has-on i.gi{color:var(--shell-acc)}
.subnav .subnav a{padding-left:2.5rem}
/* 4º nível (#630): Sidora › segmento › seção com filhos › tela — cada nível recua mais 1rem. */
.subnav .subnav .navgrp{padding-left:2.5rem}
.subnav .subnav .subnav a{padding-left:3.5rem}
/* Menu lateral — favoritos e busca (reporte #210). Campo do Bootstrap de fábrica (#454);
   a estrela aparece no hover, no foco e quando marcada; na barra recolhida busca, estrela
   e dica saem (o rail é só ícone); no celular a estrela fica sempre à vista (não há hover). */
.nav__busca{padding:0 0 0.5rem}
.nav__dica{font-size:var(--fonte-pequena);color:var(--ink-3);padding:0.25rem 0.5rem;margin:0}
.navitem{display:flex;align-items:center}
.navitem > a{flex:1 1 auto;min-width:0}
.navfav{flex:0 0 auto;display:grid;place-items:center;width:1.5rem;height:1.5rem;padding:0;border:0;
  background:none;border-radius:var(--r-sm);color:var(--ink-4);font-size:var(--fonte-pequena);opacity:0;cursor:pointer}
.navitem:hover .navfav,.navfav:focus-visible,.navfav[aria-pressed="true"]{opacity:1}
.navfav:hover,.navfav[aria-pressed="true"]{color:var(--ds-acao)}
.navfav:focus-visible{outline:2px solid var(--shell-acc-ink);outline-offset:-2px}
/* A busca abre todo grupo (vence o max-height inline do fcds.shell.js só enquanto há termo)
   e o `hidden` vence o display:flex da linha. */
.nav--busca .subnav{max-height:none!important}
.nav--busca .navgrp .chev{visibility:hidden}  /* com termo todo grupo está aberto; a seta mentiria */
#nav [hidden]{display:none!important}
@media(min-width:768px){
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav__busca,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .nav__dica,
  body:not(.pinned) .side:not(:hover):not(:focus-within) .navfav{display:none}
}
@media(max-width:767.98px),(max-height:540px){
  .navfav{opacity:1}
}
.side__foot{border-top:1px solid var(--line-2);padding:0.5rem}
.user{display:flex;align-items:center;gap:0.5rem;padding:0.25rem;border-radius:var(--r-sm)}
.user:hover{background:var(--surf-2)}
.user .av{width: 1.875rem;height: 1.875rem;border-radius:50%;background:var(--shell-acc-soft);color:var(--shell-acc-ink);
  display:grid;place-items:center;font-weight:500;border:var(--bs-border-width) solid var(--shell-acc-line)}
.user b{font-weight:500;display:block}.user small{color:var(--ink-3)}
/* O bloco do usuário virou BOTÃO (abre "Minha conta"): mesma aparência de
   antes, com o alvo e o foco que um botão precisa ter. Com a barra recolhida
   sobra só o avatar — a regra do rail esconde o `div` do nome. */
.user__eu{display:flex;align-items:center;gap:0.5rem;flex:1 1 auto;min-width:0;
  background:none;border:0;padding:0;text-align:left;color:inherit;cursor:pointer}
.user__eu:focus-visible{outline:2px solid var(--shell-acc-ink);outline-offset:2px;border-radius:var(--r-sm)}
.user__id{min-width:0}
/* Aberta a barra, o círculo vira engrenagem: o nome já está escrito ao lado,
   então o ícone pode dizer o que o clique faz (abrir a conta) em vez de
   repetir as iniciais. Recolhida, volta a ser o avatar. */
.user .av__ini{display:none}
/* Rótulo miúdo do painel da conta — o mesmo tom dos rótulos do shell. */
.conta-rotulo{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3)}
.user form{margin:0;margin-left:auto;flex:0 0 auto}
.user .logout{color:var(--ink-3);display:grid;place-items:center;width: 1.75rem;height: 1.75rem;
  border-radius:var(--r-xs);transition:background .12s,color .12s}
.user .logout:hover{background:var(--negative-subtle);color:var(--negative-text)}
.user .logout i,.user .logout svg{width: 0.9375rem;height: 0.9375rem;font-size:1rem}

/* ── §3 TOPBAR (slim glass, sticky) ──────────────────────────────────────── */
/* opaque (was rgba(.7)+backdrop-filter): a sticky element re-blurs its backdrop
   on every scroll frame as content passes behind it — opaque kills that cost. */
.topbar{height: 3.25rem;display:flex;align-items:center;gap:0.5rem;padding:0 1rem;
  background:var(--surf);
  border-bottom:1px solid var(--ds-filete);position:sticky;top:0;z-index:var(--z-topbar)}
.topbar .logo{flex:0 0 auto;display:flex;color:var(--ink)}
.topbar .logo svg{width: 1.4375rem;height: 1.4375rem;display:block}
/* ☰ = `btn btn-sm` de fábrica, da altura dos outros controles da barra (#454). Hover e
   travado na tinta de ação; travado com ícone azul (dono, D4). */
.topbar .menu{margin-left:-0.25rem;flex:0 0 auto}
.topbar .menu:hover,.topbar .menu[aria-pressed="true"]{background:var(--ds-acao-tinta)}
.topbar .menu[aria-pressed="true"]{color:var(--ds-acao)}
.crumb{display:flex;align-items:baseline;gap:0.5rem;white-space:nowrap}
.crumb b{font-size:var(--fonte-destaque);font-weight:500;letter-spacing:-.01em;color:var(--ds-tinta)}
.crumb span{color:var(--ink-3)}
.topbar .sp{flex:1}
/* Botão da barra com ícone: o vão entre ícone e palavra (layout, a pele é a do Bootstrap; #454). */
.topbar .btn:has(> i){display:inline-flex;align-items:center;gap:.25rem}
.topbar .btn{white-space:nowrap}  /* o .btn do Bootstrap 5.2 quebra linha: apertado, virava botão de duas linhas (53px) em vez de deixar a busca ceder */
.topbar .btn > i{line-height:inherit}
/* Lupa e ← da busca: só no celular (bloco abaixo). `.btn.` vence o `inline-flex` de cima. */
.topbar .btn.fcds-lupa,.topbar .btn.fcds-busca-voltar{display:none}  /* senão o botão só de ícone (☰, sino) fica mais baixo que os -sm ao lado */

/* ── §4 CONTENT SURFACE ──────────────────────────────────────────────────── */
.content{padding:var(--content-pad-y) var(--content-pad-x) var(--content-pad-b);min-width:0}
/* Grade única esticada (`biUtils.esticarGradeUnica`): o recuo de baixo do
   `.content` (36px) e o do `.page` (24px) caem ABAIXO da paginação, onde não
   separam nada de nada — viram 60px de faixa cinza entre o card e o fim da
   janela, e saem da altura que a lista poderia ocupar. Enquanto a classe está
   posta, quem dá o respiro do rodapé é o próprio cálculo da grade. O
   `!important` só empata com o `!important` de `.page`. */
.content.grade-esticada{padding-bottom:0}
.content.grade-esticada > .page{padding-bottom:0 !important}

/* ── §5 SCRIM + RESPONSIVE ───────────────────────────────────────────────── */
.scrim{position:fixed;inset:var(--topbar-h, 52px) 0 0 0;background:rgba(22,24,32,.42);opacity:0;pointer-events:none;
  transition:opacity .22s;z-index:var(--z-scrim)}
body.navopen .scrim,body.filtopen .scrim{opacity:1;pointer-events:auto}

/* PAINEL LATERAL ABAIXO DA TOPBAR — reporte #84 (21/09/2026).
   O offcanvas do Bootstrap nasce em `top:0` com z 1045, e o backdrop cobre a
   viewport inteira em 1040; a topbar é 900 (--z-topbar). Resultado: todo
   painel lateral tapava a topbar — o Reportar, o sino e a busca do CRM
   sumiam enquanto o painel estava aberto. Não era só no CRM: são 26
   templates em 5 apps, mais a "Minha conta" (`_conta.html`), que está em
   todas as telas. Por isso a regra é do SHELL (`body.stm-shell` = toda tela
   com topbar) e não por `[data-pagina]`.
   Mesmo recuo de `.side`, `.scrim` e `.fcds-lateral`: 52px = `.topbar`
   (3.25rem). O `bottom:0` do Bootstrap continua, então o painel encolhe
   pela altura da topbar. `.offcanvas-end` (e não `.offcanvas.offcanvas-end`)
   também pega o `.offcanvas-lg` da Matriz de Acesso abaixo de 992px; acima
   disso ele é estático e `top` não age.
   Com painel fechado nada muda: o backdrop só existe com painel aberto. */
body.stm-shell .offcanvas-end { top: var(--topbar-h, 52px); }
body.stm-shell .offcanvas-backdrop { inset: var(--topbar-h, 52px) 0 0 0; width: auto; height: auto; }
/* Com painel aberto a topbar fica à vista e clicável — mas os balões DELA
   (sino z 1050, lista da busca do CRM) moram no contexto de empilhamento da
   topbar (900) e abririam por trás do painel. Só enquanto há painel aberto
   ela sobe um degrau acima do offcanvas (1045), ainda abaixo do modal do
   Bootstrap (1050/1055) — o modal do Reportar continua por cima de tudo. */
body.stm-shell:has(.offcanvas-end.show) .topbar { z-index: 1046; }

/* Mobile chrome: narrow portrait (≤760px) OR short landscape (≤540px tall — a
   landscape phone is ~844px wide so it would otherwise miss the width breakpoint and
   render the desktop rail). Both get the off-canvas drawer + full-width content. */
@media(max-width:767.98px),(max-height:540px){
  .side{transform:translateX(-100%);width:min(20rem, 88vw);z-index:var(--z-drawer);border-right:1px solid var(--line);
    transition:transform .26s cubic-bezier(.22,1,.36,1)}
  .side:hover,.side:focus-within{width:min(20rem, 88vw)}
  body.navopen .side{transform:none}
  .main,body.pinned .main{margin-left:0}
  .stm-shell #page-loading-overlay,.stm-shell.pinned #page-loading-overlay{left:0}
  /* `pinned` é conceito de desktop e não é restaurado no celular, mas quem
     encolhe a janela (ou gira o tablet) já com a barra travada chega aqui com a
     classe no body — e `body.pinned .side` (0,2,1) ganha de `.side` (0,1,1),
     media query não soma especificidade. Sem esta linha a gaveta abriria com
     a largura do desktop em vez da do celular. */
  body.pinned .side{width:min(20rem, 88vw)}
  .side .nav a span,.side .navgrp span,.side .nav__g{white-space:normal}  /* rótulo longo quebra linha, nunca "…" (#476) */
  .side .nav a span,.side .nav a .cnt,.side .nav__g,.side .user div,.side .navgrp span{opacity:1!important;display:initial}
  /* iOS notch / home-indicator (landscape especially): viewport-fit=cover lets content
     use the whole screen, env() insets keep it off the camera + home bar. max() so a
     non-notched device (env=0) keeps the normal value. */
  /* Goteira lateral própria da superfície: o card não sai mais da caixa por conta
     própria (a antiga quebra de 100vw foi removida), então é o .content que dá o
     respiro das bordas — e o env() mantém tudo fora do notch em paisagem. */
  .content{padding-block:0.5rem max(1.5rem, env(safe-area-inset-bottom));
    padding-inline:max(0.5rem, env(safe-area-inset-left)) max(0.5rem, env(safe-area-inset-right))}
  .side{padding-left:env(safe-area-inset-left)}
  /* #476: barra de app nativo — ☰ · título (até 2 linhas, nunca "…") · ícones. Logo sai; o ☰ é o
     #menuToggle (abre a gaveta no celular). Título que não cabe em 2 linhas ao lado das ações da
     tela: o fcds.shell.js põe `topbar--duas-linhas` e as ações descem para `.topbar__acoes`, a 2ª linha da
     barra, que rola de lado.
     Gaveta, scrim e painéis laterais nascem abaixo da barra por --topbar-h. */
  /* `.stm-shell`: o bloco de tokens do CRM põe `min-height:0` na `.topbar` (0,1,0), mais abaixo no arquivo. */
  .stm-shell .topbar{height:auto;min-height:3.25rem;padding-left:max(0.5rem, env(safe-area-inset-left));padding-right:max(0.5rem, env(safe-area-inset-right));gap:0.5rem}
  .topbar .logo{display:none}
  .crumb{flex:1 1 auto;min-width:0;white-space:normal}
  .topbar .sp{display:none}  /* o título já cresce até os ícones; o espaçador dividiria a sobra com ele */
  .crumb b{display:block;line-height:1.2}
  /* `.stm-shell #topbar`: telas que fixam a altura da própria barra (`#topbar:has(.pcx-trilho){height:46px}`, 1,1,0)
     sobreporiam a 2ª linha à 1ª. */
  .stm-shell #topbar.topbar--duas-linhas{height:auto;flex-wrap:wrap;row-gap:.25rem;padding-block:.375rem}
  .topbar--duas-linhas > .crumb{flex-basis:0}  /* com wrap, a base natural do título quebraria a linha 1 */
  .topbar__acoes{order:2;flex:1 0 100%;min-width:0;display:flex;align-items:center;gap:.5rem;overflow-x:auto}
  .topbar__acoes > *{flex-shrink:0}
  /* Busca: a lupa abre o campo na barra inteira, com ← para voltar (fcds.shell.js, `topbar--buscando`). */
  .topbar .btn.fcds-lupa{display:inline-flex}
  .topbar > .crm-busca-topbar{display:none}
  .topbar--buscando{flex-wrap:nowrap}
  .topbar--buscando > :not(.crm-busca-topbar,.fcds-busca-voltar){display:none!important}
  .topbar--buscando > .crm-busca-topbar{display:block;flex:1 1 auto;min-width:0}
  .topbar--buscando > .btn.fcds-busca-voltar{display:inline-flex}
  /* #110 — mudança de SHELL (todas as telas no celular): 2+ ações do `topbar_actions` empurravam crumb, Reportar e sino para fora da tela; ação com ícone vira só ícone (o texto segue no DOM como nome acessível) e Reportar/sino não encolhem. */
  .stm-shell :is(.topbar, .topbar__acoes) > .btn:not(.btn-link):has(> i){font-size:0;gap:0;width:2rem;padding:0;justify-content:center;flex:0 0 auto}
  .stm-shell :is(.topbar, .topbar__acoes) > .btn:not(.btn-link):has(> i) > i{font-size:.875rem}
  .topbar > .fcds-reportar,.topbar > .fcds-sino{flex-shrink:0}
}

/* ===== COMPONENTS ===== */
/* ==========================================================================
   Four Cloud Design System — COMPONENTS.
   The composable card/metric library. Ported 1:1 from the design source
   (bi/static/bi/demo/statement.css component sections). Pages compose FROM
   these — never restyle ad hoc. Depends on the TOKENS + SHELL sections above
   (.metric primitives).

     §1 grid + card/glass   §2 hero+ring   §3 kpi spark tiles
     §4 margin flow cascade  §5 cost doughnut   §6 signals   §7 units ABC table
   ========================================================================== */

/* ── §1 GRID + CARD/GLASS ────────────────────────────────────────────────── */
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--gap)}
/* Grade FLUIDA — o nº de colunas segue a largura, sem breakpoint escrito à mão.
   A `.grid` de 12 colunas exige que cada filho declare seu span, então o layout
   fica congelado: 2 cartões lado a lado continuam 2 num monitor de 27", só mais
   largos. Aqui os cartões vão encaixando conforme cabem — 4 numa tela larga, 3
   ao estreitar, 2 no notebook, 1 no celular — e cada um tem uma largura MÍNIMA
   digna em vez de uma fração fixa da tela.
   O `--min-card` é o botão de calibragem: é ele que decide em que largura o
   layout troca de nº de colunas. Uma tela pode sobrescrevê-lo inline. */
.grid-fluido{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(min(var(--min-card, 34rem), 100%), 1fr));
  gap:var(--gap);
  align-items:stretch;
}
/* Cada cartão tem a altura que o SEU conteúdo pede — não a do vizinho mais alto.
   Com `stretch` (o padrão), um cartão de gráfico numa faixa de três forçava os
   dois de texto, de ~120px de conteúdo, a herdarem a caixa dele: era exatamente
   o vão morto que motivou o redesenho. `start` desiste do rodapé alinhado e
   entrega a altura de volta. */
.grid-fluido{ align-items:start; }
/* Faixa em que os cartões DEVEM alinhar rodapé — quando uma das colunas é uma
   pilha de cartões, `stretch` é o que faz a pilha ocupar a altura da coluna e o
   `flex-fill` de cada cartão dividir esse espaço. Sem isto a pilha encolhe para
   o conteúdo e a coluna fica curta ao lado dos gráficos. */
.grid-fluido.align-items-stretch{ align-items:stretch; }

/* Ranking como cartão de faixa: acompanha a altura do gráfico ao lado e rola por
   dentro. A lista é posicionada em ABSOLUTO de propósito — assim ela não
   contribui altura nenhuma para o grid, e quem dita a altura da faixa passa a
   ser o cartão do gráfico. Sem isto, os 14 portadores ditavam a altura e sobrava
   ~650px de vão embaixo do gráfico; capar com `max-height` em rem resolveria
   pela metade, porque o número seria um chute desacoplado da altura real do
   gráfico (que o JS deriva do nº de categorias). */
#cr-board{ position:relative; overflow:hidden; }
#cr-board > .cr-board{ position:absolute; inset:0; overflow-y:auto; }
/* surface recipe — shared by every .card, .tile, and any .glass element.
   backdrop-filter removed: it forced a per-frame blur pass behind every one of
   ~39 cards during scroll (the dominant scroll-jank source). --glass is opaque
   now, so the frosted look is preserved without the compositing cost. */
.glass{
  border:var(--bs-border-width) solid var(--line);border-radius:var(--r);box-shadow:var(--sh-glass)}
/* STANDARDIZED CARD (FCDS canonical) — solid surface, neutral hairline, no shadow.
   Glass is retired: this references the semantic tokens directly (--surf/--line) instead
   of the legacy --glass* aliases (same resolved values, no "glass" naming). Layout props
   (flex column / position) are declared here so the card no longer silently borrows them
   from Bootstrap's .card — load order is now irrelevant. Body pad 8/16/16; header→body
   rhythm via .card-hd margin-bottom (8px). .cardbox (main.css) shares this visual standard. */
.card{
  display:flex;flex-direction:column;position:relative;
  background:var(--surf);border:var(--bs-border-width) solid var(--line);border-radius:var(--r);box-shadow:none;
  padding:var(--bi-space-sm,0.5rem) var(--bi-space-md,1rem) var(--bi-space-md,1rem)}
/* Cartão no modelo estruturado do Bootstrap (.card > .card-header/.card-body): quem
   dá o padding é o filho, então o .card zera o seu — senão o conteúdo recebe o
   padding duas vezes (16px do .card + 16px do .card-body = 32px de recuo). */
.card:has(> .card-body), .card:has(> .card-header){ padding:0; }
.lab{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.card-hd{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:var(--bi-space-sm,0.5rem)}
.card-hd .n{font-size:var(--fonte-pequena);color:var(--ink-3)}
.card.empty{display:grid;place-items:center;min-height: 7.5rem;color:var(--ink-3)}
/* scroll-capped card body: ranked lists / analysis tables scroll inside the card
   at a shared max-height (--bi-scroll-cap) so neighboring cards stay equal-height
   instead of one growing unbounded. min-height:0 lets it shrink inside flex/grid. */
.card-scroll{max-height:var(--bi-scroll-cap);overflow-y:auto;min-height:0}

/* skeleton loading */
/* .skb mirrors the canonical .skeleton recipe (B9) — same base/shine tokens, radius
   and timing — but stays self-contained (own keyframes) so it works on pages that load
   fcds.* without bi/main.css (e.g. tracking-comex). */
/* .skb + @keyframes shimmer removidos — skeleton unificado no Bootstrap .placeholder (utils.js). */

/* ── §3 KPI SPARK TILES ──────────────────────────────────────────────────── */
.kpi{grid-column:span 7;display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
/* unified card padding (Batch6 Agent B): tile body pad 8/16/16 (was 12/14/10) */
.tile{background:var(--glass-2);padding:var(--bi-space-sm,0.5rem) var(--bi-space-md,1rem) var(--bi-space-md,1rem);
  display:flex;flex-direction:column;position:relative;overflow:hidden}
.md{font-family:var(--mono);font-weight:500;white-space:nowrap}.md.pos{color:var(--positive-text)}.md.neg{color:var(--negative-text)}
/* margin-left, não um espaço no markup: os dois spans são irmãos colados na
   string de HTML (saía "−37,1%vs mês ant.") e um espaço solto ali se perde na
   primeira reformatação do template. */
.md__ref{font-family:var(--sans);color:var(--ink-3);white-space:nowrap;
  margin-left:0.25rem}
/* full-bleed area band at the card's bottom edge (negative margins cancel the tile's x/bottom pad) */
.spark{display:block;position:relative;width:auto;height:var(--spark-h);
  margin:var(--bi-space-sm,0.5rem) calc(-1*var(--bi-space-md,1rem)) calc(-1*var(--bi-space-md,1rem))}
.spark canvas{display:block}

/* ── §4 MARGIN FLOW CASCADE ──────────────────────────────────────────────── */
.flow{grid-column:span 8;display:flex;flex-direction:column}
.flow-cv{position:relative;flex:1;min-height:var(--flow-min);margin-top:var(--bi-space-xs2,0.25rem)}

/* ── §6 OPERATIONAL SIGNALS ──────────────────────────────────────────────── */
/* No left-stripe accent (banned >1px colored border): the cards use the standard
   .card hairline. Direction on Inadimplência is carried by the red value + label,
   not a decorative rule. The signals stack in a span-4 column beside the cascade. */
.sigcol{grid-column:span 4;display:flex;flex-direction:column;gap:var(--gap)}
.sigcol .sig{flex:1;display:flex;flex-direction:column}
.sig__v .u{font-size:var(--fonte-destaque);color:var(--ink-3);font-weight:500;margin-left:0.25rem}
.sig.neg .sig__v{color:var(--negative-text)}
/* warning glyph = non-colour backup for the negative (inadimplência) card */
.sig__mark{font-size:.62em;vertical-align:.12em;margin-right:0}
.sig__s{font-size:var(--fonte-pequena);line-height:16px;color:var(--ink-2);margin-top:auto}
/* pin the detail link flush-left across all three signal cards (consistency) */
.sigcol .sig .fcds-siglink{align-self:flex-start}

/* ── §8 FILTERS — topbar chips · glass popovers · month picker · sheet ─────── */
/* Reusable FCDS filter primitives (ported from the statement mockup). A page
   houses its live filter controls inside these; chip labels reflect state. */
.filters{display:flex;align-items:center;gap:var(--bi-space-sm,0.5rem)}
.vr{width:1px;height: 1.25rem;background:var(--line);flex:0 0 auto}
.topbar>.vr{background:var(--ds-filete)}
.fdwrap{position:relative;flex:0 0 auto}
/* Chip da barra de filtros = a caixa de seleção de fábrica (`form-select form-select-sm`, #454/#675):
   `.fdrop`/`.tb-btn` ficam só de gancho do JS. O valor aparece inteiro. */
/* Régua de toggles no topbar (diagnóstico-preenchimento, permanência-no-porto).
   Sem isto o inline-flex não encolhe: com 9 filtros a régua media 2250px,
   empurrava o botão de ação pra fora e o overflow-x:clip do body escondia
   tudo sem scroll — 4 filtros e o Atualizar ficavam INALCANÇÁVEIS (medido
   em 1536px). flex+min-width:0 deixa encolher; o trilho rola sozinho. */
.pp-topbar-toggles{flex:1 1 auto;min-width:0;overflow-x:auto;scrollbar-width:thin}
/* Permanência (#492): Reportar vira ícone, como na Despesas e na Processos Comex — a caixa do topo
   precisa da largura para mostrar a dica inteira, e os recortes não podem cortar. */
#topbar:has([data-pp-recorte]) .fcds-reportar{width:2rem;padding-inline:0;justify-content:center}
#topbar:has([data-pp-recorte]) .fcds-reportar span{display:none !important}
/* glass popover */
.pop{position:absolute;top:calc(100% + 8px);left:0;z-index:60;min-width: 14.75rem;max-height:min(70vh,520px);overflow:auto;
  background:var(--surf);border:var(--bs-border-width) solid var(--line);border-radius:var(--r-sm);box-shadow:var(--sh2);padding:0.25rem}
.pop[hidden]{display:none}
.pop--right{left:auto;right:0}
.pop__hd{display:flex;flex-wrap:wrap;align-items:center;gap:var(--bi-space-2xs,0.25rem) var(--bi-space-sm,0.5rem);padding:var(--bi-space-2xs,0.25rem) var(--bi-space-sm,0.5rem) var(--bi-space-sm,0.5rem);
  font-size:var(--fonte-corpo);font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.pop__hd button{font-size:var(--fonte-corpo);font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;white-space:nowrap;
  text-decoration:underline;text-underline-offset:2px;text-decoration-color:var(--line-3);background:none;border:0;cursor:pointer}
.pop__hd button:hover{color:var(--negative-text);text-decoration-color:currentColor}
/* Cabeçalho com DUAS ações (Selecionar todos | Limpar seleção): o rótulo empurra as duas para a
   direita e elas ficam lado a lado. Só com `space-between` cada ação ia para uma
   ponta e "todos" lia como se pertencesse ao rótulo. No popover estreito (folha de filtros a 900px) elas quebram de linha, nunca cortadas. */
.pop__hd > span:first-child{margin-right:auto;white-space:nowrap}
/* Vermelho no hover é de destruição — fica só no "Limpar seleção". "Selecionar todos" é aditivo. */
.pop__hd button[data-allpop]:hover{color:var(--ink)}
.popftog{border-top:var(--bs-border-width) solid var(--line-2);margin-top:0.25rem;padding:0.5rem 0.5rem 0}
/* option rows (used for segmento/sub/empresa lists) */
.optrow{display:flex;align-items:center;gap:0.5rem;width:100%;padding:0.5rem 0.5rem;border-radius:var(--r-xs);
  font-size:var(--fonte-corpo);color:var(--ink-2);text-align:left;cursor:pointer;background:none;border:0}
.optrow:hover{background:var(--surf-2)}
.optrow .ck{width: 1.0625rem;height: 1.0625rem;border-radius:var(--bs-border-radius);border:1.5px solid var(--line-3);flex:0 0 auto;
  display:grid;place-items:center;color:var(--bi-text-on-accent);transition:all .12s}
.optrow .ck svg,.optrow .ck i{width: 0.6875rem;height: 0.6875rem;font-size:0.875rem;opacity:0}
.optrow.on .ck{background:var(--acc);border-color:var(--acc)}
.optrow.on .ck svg,.optrow.on .ck i{opacity:1}
.optrow .nm{flex:1;font-weight:500;color:var(--ink);}
/* stale-results indicator — appears only when a filter change is staged
   (body.fcds-pending). Pairs with the dimmed results region so "os números na
   tela não refletem mais os filtros; clique em Buscar" is unambiguous. Âmbar de
   atenção (warning channel): os dados na tela estão desatualizados — par com o
   verde de ação do botão Buscar. Texto em --warning-text (#FA4B00, #229); o
   fundo suave e o ícone dizem "atenção". */
/* #274: sem âmbar — pendência neutra (fundo branco, filete do DS), o laranja de
   texto #FA4B00 é quem diz "atenção". */
.fcds-stale{display:none;align-items:center;gap:0.25rem;flex:0 0 auto;height: 2rem;padding:0 0.5rem;
  border-radius:2px;background:var(--surf);
  border:1px solid var(--ds-filete);
  color:var(--warning-text);font-weight:500;white-space:nowrap}
.fcds-stale svg,.fcds-stale i{width: 0.875rem;height: 0.875rem;font-size:0.875rem;flex:0 0 auto}
body.fcds-pending .fcds-stale{display:inline-flex}
/* tight topbars: drop to icon-only (tooltip carries the text) so it never
   crowds the período picker / Buscar */
@media(max-width:1399.98px){.fcds-stale{padding:0 0.5rem}.fcds-stale__t{display:none}}
/* dim the (now-stale) results while a change is staged; topbar/filters stay live */
body.fcds-pending main .grid{opacity:.5;pointer-events:none;transition:opacity .18s ease-out}
@media(prefers-reduced-motion:reduce){body.fcds-pending main .grid{transition:none}}

/* Buscar (`btn btn-primary btn-sm`, #454) só aparece com mudança de filtro backend
   pendente (período/empresa) e pulsa até o clique; o Filtros só no estreito. */
.sheet-only{display:none}
.topbar .buscar.btn:not(.pending),.topbar .filtbtn.btn{display:none}  /* vence o inline-flex de `.topbar .btn:has(> i)` */
.buscar.pending{animation:buscarpulse 1.8s ease-in-out infinite}
@keyframes buscarpulse{0%,100%{box-shadow:0 0 0 0 rgba(var(--bs-primary-rgb),0)}50%{box-shadow:0 0 0 4px rgba(var(--bs-primary-rgb),.3)}}
/* Modo backend-instantâneo (opt-in, ex.: faturamento): período/empresa aplicam
   sozinhos, então os gatilhos de Buscar não existem para o usuário. */
body.bi-backend-instant #fcds-buscar,
body.bi-backend-instant .sheet-only .fbuscar{display:none!important}

/* Filtros que não cabem na barra vão para a folha atrás do botão Filtros. Quem decide é a
   MEDIDA (fcds-filterbar.js põe .fcds-filtros-gaveta quando a barra transborda), não a largura
   da janela: Reportar e o sino nunca saem da tela (#454). */
.fcds-filtros-gaveta .topbar>.vr{display:none}
.fcds-filtros-gaveta .topbar .filtbtn.btn{display:inline-flex}
.fcds-filtros-gaveta .filters{position:absolute;top:54px;right:14px;width:max-content;min-width:18.75rem;max-width:calc(100% - 28px);overflow-x:auto;flex-direction:column;align-items:stretch;gap:0.5rem;
  padding:0.5rem;background:var(--surf);border:var(--bs-border-width) solid var(--line);border-radius:var(--r-sm);box-shadow:var(--sh2);
  z-index:60;display:none}
.fcds-filtros-gaveta.filtopen .filters{display:flex}
.fcds-filtros-gaveta .filters .fdwrap{width:100%}
.fcds-filtros-gaveta .filters :is(.fdrop,.tb-btn){width:100%;text-align:left}
.fcds-filtros-gaveta .filters .sheet-only{display:flex;gap:0.5rem;margin-top:0}
.fcds-filtros-gaveta .filters .sheet-only .fbuscar{flex:1}
.fcds-filtros-gaveta .filters .pop{position:static;box-shadow:none;border:none;padding:0.25rem 0 0;min-width:0;max-height:none;background:transparent}
/* Os toggles ("Considerar devoluções", "Formatar número?") quando o celular os
   manda para dentro da folha de filtros — ver `grupoToggles` em
   fcds-filterbar.js. Pilha, não linha: cada rótulo é uma frase inteira e lado a
   lado não cabem nos ~358px úteis da folha. Sem media query de propósito — o
   seletor é o PAI, então a regra vale exatamente quando o JS moveu o grupo, e
   não pode dessincronizar de um breakpoint escrito duas vezes. */
#fcds-filters > #fcds-toggles{flex-direction:column;gap:0.5rem;
  margin:0;padding-top:0.5rem;border-top:var(--bs-border-width) solid var(--line)}
/* O container carrega `.align-items-center` do Bootstrap, que é `!important` e
   centraliza cada switch na coluna — borda esquerda serrilhada. Em vez de
   disputar com um `!important`, os filhos ocupam a linha inteira: aí não sobra
   o que centralizar e os rótulos alinham pela esquerda, como os chips acima. */
#fcds-filters > #fcds-toggles > *{width:100%}

@media(max-width:768px){
  .buscar{display:none!important}
  /* Filtros só com o ícone (a contagem fica) e a folha dentro da tela do celular */
  .filtbtn span:not(.filtbtn__n){display:none}
  .filters{left:8px;right:8px;width:auto}
}

/* ── §9 KPI BAND — compact, data-rich (Receita · ritmo gauge · metrics · breakdown) ── */
/* The KPI band is ONE white card — the same surface recipe as every .card/.glass:
   white background, hairline border, rounded corners (from .glass). Cells are
   sections WITHIN that card, divided by inset hairlines (below), NOT tiles floating
   on a grey backing shown through 1px gaps. The old grey backing was the band's only
   deviation from the component vocabulary and the sole reason a third colour appeared
   at the rounded corners; converging to white makes the band consistent with all
   components and removes the corner artifact by construction (white-on-white clips
   cleanly, exactly like a normal card). */

/* Fixed-count variants for scalar bands (ported from legacy .kpi-band--Ncol):
   hero cell wide, the rest equal. Declared BEFORE the responsive @media blocks at
   the end of §9 so small-viewport stacking still overrides them. */

/* EXCEPTION (Batch6 Agent B): the unified KPI pad is 8/16/4, but these FCDS kpiband cells
   are tightly tuned to the faturamento fixed-height band — 8/16/4 shortens cell height ~8px
   and would force re-deriving the spark bleed below. Tuned 11/13/9 kept as justified exception. */

/* Cell dividers: FLAT 1px borders on each cell's top + left edge (shared edges →
   one crisp line). box-shadow:inset reads as a soft shadow groove between cells —
   a border is a flat hairline with no shadow. --line matches the band border, so
   the coincident line at the band's own top/left edge reads as the border. */

/* wraps to a 2nd line instead of truncating — "Custos sobre Receita" / "Margem
   Contrib." don't fit the narrow cells on one line, and the band is natural-height
   now (no fixed cap), so a 2-line label is free vertical space, not an overflow. */

/* metric cells (Receita/Líquido/Devoluções/MB/MC) carry a single number → the
   value block CENTERS in the height the band borrows from the breakdown/gauge
   cells, so the number fills the card instead of leaving dead space below. The
   label stays top-aligned across every cell for one clean header row. */

/* every metric cell drops its delta to its own line UNDER the big value (hero
   included) and gives it real presence — the chip reads as a second data point,
   not a footnote crammed beside the number. */

/* caution valences ported from legacy --warning/--previsao: amber value, mirroring
   the pos/neg value-colour mechanism instead of the old 4px coloured bottom-rule */

/* value line: big R$ number + its month-over-month delta chip, baseline-aligned,
   wrapping as a unit on narrow cells (kc__v keeps its top margin as a flex item) */

/* ritmo gauge cell */

/* dois gauges lado a lado (Atingido · Ritmo). Número e subtítulo são desenhados
   DENTRO do canvas por `biChartConfig.gauge` — aqui só se dá a caixa, então não
   há mais overlay de rótulo para manter alinhado. Meio-arco → caixa 2:1. */
/* align-items:flex-start é obrigatório: como item de flex esticado, a caixa
   herdaria a altura da linha e o aspect-ratio seria ignorado (o canvas cresce,
   a linha cresce junto). */
.krings{display:flex;gap:0.75rem;justify-content:center;align-items:flex-start;margin:0.25rem 0 0}
/* altura explícita, não aspect-ratio: o canvas é conteúdo em fluxo e o
   Chart.js escreve style.height nele — com altura automática o box cresceria
   junto e o ratio seria ignorado. */
.kgauge{flex:1 1 0;min-width:0;max-width:11rem;height:6.5rem}
.kgauge--empty{display:grid;place-items:center;width: 6rem;height: 6rem;margin:0.25rem auto 0;
  border-radius:50%;border:2px dashed var(--line-3);color:var(--ink-4);font-family:var(--mono)}

/* R$/dia útil: realizado vs necessário — leitura concreta do Ritmo */

/* scope note — shown only when the selection mixes meta and non-meta segments */

/* A lista de componentes do "Custos sobre Receita" é d-flex/justify-content-between
   do Bootstrap na própria célula — sem componente .kbd próprio. */

/* ── CÉLULA DE KPI (canônica) ───────────────────────────────────────────────
   Rótulo (`.lab`, o mesmo do cabeçalho de card) + valor + apoio. A célula É o
   card: sem `.card-body` no meio, porque `.card` já é flex-column com o padding
   canônico — o corpo extra só zerava um padding para redeclarar outro.

   O valor é o degrau Herói da escala (#476), igual em toda largura; na célula
   estreita ele quebra no espaço ("R$" | "8,69mi") em vez de encolher ou cortar.

   Distribuição vertical: como todas as células esticam até a altura da mais alta
   (a do gauge), sobra vão nas curtas. As três âncoras deixam esse vão distribuído
   de propósito em vez de virar um buraco no rodapé — rótulo no topo (uma linha de
   cabeçalho alinhada em toda a faixa), número centrado no vão (`margin-block:auto`)
   e apoio na base. */
/* O `.lab` canônico tem tracking de .1em, que numa célula de ~125px úteis custa
   uma linha inteira ("MARGEM CONTRIB." e "CUSTOS SOBRE RECEITA" quebravam em 2 e
   3 linhas). Na banda ele fica no tracking curto — mesma peça, mesma cor, mesmo
   caixa-alta; só o espaçamento cede à largura da célula. */
.kpic > .lab{letter-spacing:.03em}
.kpic__v{font-size:var(--fonte-heroi);font-weight:500;line-height:40px;letter-spacing:-.02em;
  margin-block:auto;padding-block:0.25rem}
.kpi8 .krings{margin-block:auto}
.kpic__s{margin-top:auto;padding-top:0.5rem;font-size:var(--fonte-pequena);line-height:16px;color:var(--ink-3)}
/* Celular (célula empilhada, largura de tela inteira): o número sobe para a
   linha do rótulo, encostado à direita. Empilhado na vertical, o cartão gastava
   ~110px de altura com metade da largura vazia; lado a lado ele cai para ~75px e
   a faixa inteira deixa de ser duas telas e meia de rolagem. */
@media(max-width:575.98px){
  .kpic{display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:0.75rem}
  .kpic__v{grid-column:2;grid-row:1;margin-block:0;padding-block:0;text-align:right}
  .kpic__s{grid-column:1/-1;margin-top:0;padding-top:0.25rem}
  .kpi8 .krings{grid-column:1/-1;margin-block:0}
}

/* Banda de KPI do faturamento: as 8 células numa linha só. `row-cols-*` do
   Bootstrap para em 6, então a faixa larga é grid explícito (8 só a partir de
   1600px: abaixo disso o Herói de 32px quebraria em duas linhas). Cai para 4, 2 e —
   no celular — empilha, que é onde o número ganha a largura toda da tela. */
.kpi8{display:grid;gap:0.75rem;grid-template-columns:minmax(0,1fr)}
@media(min-width:576px){.kpi8{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:768px){.kpi8{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media(min-width:1600px){.kpi8{grid-template-columns:repeat(8,minmax(0,1fr))}}
/* Numa faixa de 8 colunas a caixa do gauge é o que dita a altura da linha
   inteira — encolhe para não abrir vazio nas outras sete. */
.kpi8 .kgauge{max-width:8rem;height:4.75rem}
/* responsive: wrap the 8 cells */
/* Phone density (narrow portrait OR short landscape): the band was ~669px tall in
   portrait and ~83% of a landscape screen, owning the viewport before any chart or
   table. Shrink the values + padding so content reaches above the fold. The
   max-height clause catches landscape phones (~844px wide, missed by max-width). */
@media(max-width:575.98px), (max-height:540px){

  /* shrink the tallest driver so short tiles stop stretching into dead space:
     o gauge é quem dita a altura da faixa. */

  .krings{gap:0.5rem;margin-top:0}
}

/* ── responsive grid spans ───────────────────────────────────────────────── */
@media(max-width:992px){.hero,.kpi,.flow,.sigcol{grid-column:span 12}.sigcol{flex-direction:row;flex-wrap:wrap}.sigcol .sig{flex:1 1 30%}}
@media(max-width:768px){
  .kpi{grid-template-columns:1fr}.sigcol .sig{flex:1 1 100%}
}

/* ── §9 PARAMETRIC TOOLBAR: relocated biFiltros controls inside topbar chips ──
   Shared by every page whose filters are relocated into the FCDS topbar by
   fcds-filterbar.js. The chip/popover/button PRIMITIVES live in §8 above; here we
   restyle the RELOCATED biFiltros pills + the period inline calendar to the FCDS
   look. Selectors only match relocated-chip DOM, so pages without the toolbar are
   unaffected. Moved here from faturamento-fcds.css so all pages share one source. */
.fcds-filters-host{position:absolute!important;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;padding:0;margin:-0}

/* segmento / sub-segmento / empresa / centro de custo pills inside a popover →
   checkable rows, LEFT-aligned (align-items:stretch overrides the base
   .filter-group__pills{align-items:center}; justify-content:flex-start keeps the
   checkbox+label at the left edge like the original mockup). */
.pop:not(.pop--period) .filter-group__pills{display:flex;flex-direction:column;align-items:stretch;gap:0}

/* === CHECKROW — linha de seleção do popover de filtro ========================
   Linha de checkbox — largura total, alinhada à esquerda, caixa em `::before`,
   sem borda e sem fundo.
   Fábricas: filtros.js `_criarLinhaCheck`, inadimplencia.js (#pills-cc). */
.checkrow{display:flex;align-items:center;justify-content:flex-start;gap:0.5rem;width:100%;height:auto;padding:0.5rem;border:0;
  border-radius:var(--r-xs);background:none;font-size:var(--fonte-corpo);font-weight:500;color:var(--ink);
  text-align:left;white-space:nowrap;cursor:pointer}
.checkrow::before{content:"";width: 1.0625rem;height: 1.0625rem;border-radius:var(--bs-border-radius);border:1.5px solid var(--line-3);
  flex:0 0 auto;background:no-repeat center/11px 11px;transition:all .12s}
.checkrow:hover{background:var(--surf-2)}
.checkrow:focus-visible{outline:2px solid var(--acc);outline-offset:-2px}
/* Caixa marcada sem preenchimento de acento: some o quadrado quase-preto, fica
   o contorno um degrau mais escuro e o check em ardósia. Preenchimento suave é
   `background-color:var(--acc-d);color:var(--bi-text-on-accent)`. */
.checkrow--on::before{border-color:var(--ink-3);
  content:"\f00c";font-family:"Font Awesome 6 Free";font-weight:900;font-size:0.875rem;color:var(--acc-d);display:flex;align-items:center;justify-content:center}
/* Sem dados no período: o tracejado vai na caixa, já que a linha não tem borda. */
.checkrow--empty{opacity:0.45;font-style:italic}
.checkrow--empty::before{border-style:dashed}
.checkrow--empty:hover{opacity:0.75}

/* período popover: ONE inline flatpickr calendar (.periodo-cal) + presets. */
.pop--period{min-width: 14.75rem}
.pop--period .periodo-cal{display:flex;flex-direction:column;gap:0.5rem}
.pop--period .filter-group__label{font-size:var(--fonte-corpo);font-weight:500;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-3)}
.pop--period .periodo-cal__presets{display:flex;gap:0.25rem;flex-wrap:wrap}
/* Alternador de grão (Mês · Dia): `btn-group` na largura do calendário. */
.pop--period .periodo-cal__grao{display:flex}
.pop--period .periodo-cal__grao .btn{flex:1 1 0}
/* Só o conjunto de atalhos do grão em vigor aparece. Quem marca a classe é o
   filtros.js ao trocar de grão — mostrar/esconder é apresentação, não decisão. */
.pop--period .periodo-cal__presets[hidden]{display:none}
/* Os atalhos dividem a linha do calendário. */
.pop--period .periodo-cal__presets .btn{flex:1 1 auto}
.pop--period .periodo-cal__input{display:none}
.pop--period .flatpickr-calendar.inline{margin:0 auto;box-shadow:none;border-color:var(--line-2)}

/* flatpickr calendar → FCDS glass surface + accent (month + day cells). */
.flatpickr-calendar{background:var(--surf);border:1px solid var(--line);border-radius:var(--r-md);
  font-family:var(--sans)}
.flatpickr-calendar:before,.flatpickr-calendar:after{display:none}
.flatpickr-months .flatpickr-month,.flatpickr-current-year,.flatpickr-calendar .numInputWrapper input{color:var(--ink)}
.flatpickr-current-year,.flatpickr-calendar .cur-year{font-family:var(--mono);font-weight:600}
.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{fill:var(--ink-2)}
.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:var(--acc)}
.flatpickr-monthSelect-month{color:var(--ink-2);font-weight:500;border-radius:var(--r-xs)}
.flatpickr-monthSelect-month:hover{background:var(--surf-2);color:var(--ink)}
.flatpickr-monthSelect-month.inRange{background:var(--acc-soft);color:var(--acc-ink)}
.flatpickr-monthSelect-month.selected,.flatpickr-monthSelect-month.startRange,
.flatpickr-monthSelect-month.endRange{background:var(--acc);color:var(--bi-text-on-accent);border-color:var(--acc)}
.flatpickr-monthSelect-month.flatpickr-disabled,
.flatpickr-monthSelect-month.flatpickr-disabled:hover{color:var(--ink-4);opacity:.5;background:transparent}
.flatpickr-day{color:var(--ink-2);border-radius:var(--r-xs)}
.flatpickr-day:hover{background:var(--surf-2);color:var(--ink)}
.flatpickr-day.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.inRange,
.flatpickr-day.nextMonthDay.inRange{background:var(--acc-soft);border-color:var(--acc-soft);
  box-shadow:-5px 0 0 var(--acc-soft),5px 0 0 var(--acc-soft);color:var(--acc-ink)}
.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,
.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover{
  background:var(--acc);border-color:var(--acc);color:var(--bi-text-on-accent)}
.flatpickr-day.today{border-color:var(--acc-line)}
.flatpickr-day.flatpickr-disabled{color:var(--ink-4);opacity:.5}

/* Cabeçalho do calendário igual nos dois motores. O <select> de mês do flatpickr vem
   com `appearance:menulist`: o Chrome respeita o `background:transparent`/`border:none`
   do vendor e desenha texto chapado, o WebKit ignora e pinta o controle nativo do
   sistema (caixa cinza com moldura e seta sólida) — era o elemento mais destoante do
   componente no Safari. Zerar o appearance e desenhar a própria seta resolve nos dois. */
.flatpickr-current-month .flatpickr-monthDropdown-months{
  appearance:none;-webkit-appearance:none;background-color:transparent;border:0;
  border-radius:var(--r-xs);padding:0 0.9rem 0 0.25rem;color:var(--ink);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 0.2rem center}
/* O ano é <input type=number>: no WebKit ele nasce ~4px mais baixo e ~2px mais estreito
   que o select ao lado (medido), deixando o cabeçalho torto. Alinhar pelo flex e
   neutralizar a métrica própria do campo empata os dois motores. `.flatpickr-current-month`
   também existe no grão mês (monthSelectPlugin, sem <select>) — o `:has()` restringe o
   ajuste ao grão dia, senão o padding-top:0 desloca o "2026" ~2px no grão mês (medido). */
.flatpickr-current-month:has(select.flatpickr-monthDropdown-months){display:flex;
  align-items:center;justify-content:center;gap:0.25rem;padding-top:0}
.flatpickr-current-month:has(select.flatpickr-monthDropdown-months) input.cur-year{
  line-height:normal;padding-top:0;padding-bottom:0}

/* NOTIFICATION BELL — ghost-icon shape, so the topbar keeps
   one button family. Lives outside {% block topbar_actions %} in base_fcds.html
   (27 of 56 pages override that block), hence it is styled here and not in a
   page section. The bell itself is always present; only the count disappears
   when there is nothing unread, so clearing does not remove the control that
   was just used. */
.fcds-sino{position:relative;flex:0 0 auto}
/* the count rides the bell's top-right corner, not a separate column */
.fcds-sino__n{position:absolute;top:-0.25rem;right:-0.25rem;min-width: 1rem;height: 1rem;padding:0 0.25rem;
  display:inline-flex;align-items:center;justify-content:center;border-radius: 1rem;
  background:var(--ds-perigo);color:#fff;font-size:var(--fonte-pequena);font-weight:500;line-height:1}
/* the badge sets its own display, so the UA's [hidden] rule needs help */
.fcds-sino__n[hidden]{display:none}
.fcds-sino__pop{position:absolute;top:calc(100% + 0.5rem);right:0;z-index:1050;width: 24rem;max-width:calc(100vw - 2rem);
  background:var(--surf);border:1px solid var(--ds-filete);border-radius:0;
  box-shadow:var(--ds-sombra-balao);overflow:hidden}
.fcds-sino__topo{display:flex;align-items:center;justify-content:space-between;gap:0.5rem;
  padding:0.5rem 0.75rem;border-bottom:var(--bs-border-width) solid var(--line)}
.fcds-sino__limpar{border:0;background:none;padding:0;color:var(--ds-acao);cursor:pointer}
.fcds-sino__limpar:hover{text-decoration:underline}
.fcds-sino__lista{list-style:none;margin:0;padding:0;max-height: 24rem;overflow-y:auto}
.fcds-sino__item{display:flex;flex-direction:column;gap:0.125rem;padding:0.625rem 0.75rem;
  color:var(--ink);text-decoration:none;border-bottom:var(--bs-border-width) solid var(--line)}
.fcds-sino__lista li:last-child .fcds-sino__item{border-bottom:0}
/* O <span> (notificação sem destino) também é clicável — o clique marca como
   lida —, então os dois recebem o mesmo hover e o mesmo cursor. Sem isto o item
   sem url parece texto morto e ninguém descobre que dá para dispensá-lo. */
.fcds-sino__item{cursor:pointer}
.fcds-sino__item:hover{background:var(--surf-2)}
.fcds-sino__item small{color:var(--ink-3)}
.fcds-sino__vazio{padding:1.25rem 0.75rem;text-align:center;color:var(--ink-3)}

/* Busca de cliente/negócio da topbar (item 15, 08/09/2026). O componente é o
   combo buscável do CRM (`crm/js/combo.js`); as regras dele hoje só alcançam
   [data-pagina="crm"|"crm-deal"|"crm-clientes"|"compras"] — nenhuma bate numa
   tela de cockpit ou faturamento. Mesmo precedente de `[data-pagina="compras"]`
   mais abaixo: reusar o COMPORTAMENTO exige repetir a pintura, aqui escopada
   ao host em vez de a uma página. Hosts: o da topbar do CRM e o do Gerencial
   (#267), e o cliente da Nova proposta do portal (#471). `:is(#id…)` mantém a especificidade de id: seletor de classe perderia
   para `[data-pagina="crm"] .crm-lista`, mais abaixo. */
/* #342: 16rem → 20rem. Mudança de shell, justificada: a caixa virou a busca do
   sistema (cliente, negócio, pedido, NF) em todas as telas — o placeholder e as
   linhas de pedido/NF ("NF 28251 · CLIENTE · data · valor") cortavam em 16rem.
   Numa topbar cheia ela encolhe PRIMEIRO (flex-shrink 100, até 6rem): as ações
   da tela não podem transbordar por causa dela (medido em Faturamento, 1280px). */
.crm-busca-topbar { position: relative; flex: 0 100 20rem; min-width: 6rem; }
/* A lista não encolhe com a caixa: numa topbar cheia a caixa cede, os
   resultados continuam legíveis, alinhados à direita da caixa. */
#crm-busca-topbar-host .crm-lista.crm-lista--flutua { left: auto; min-width: 22rem; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-combo { position: relative; display: block; }
/* No portal o próprio host é o `.crm-combo` (o combo é montado nele): a lista ancora nele. */
#pn-cliente-host { position: relative; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-oculto { display: none !important; }
/* Lista no design system (#274, todas as telas): reta, com a sombra do DS; o campo é form-control-sm de fábrica (#454). */
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista {
  background: var(--surf); border: 1px solid var(--ds-filete);
  border-radius: 0; box-shadow: var(--ds-sombra-balao);
  overflow: hidden; overflow-y: auto; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista--flutua {
  position: absolute; left: 0; right: 0; z-index: 1055; max-height: 20rem; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista__item {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  border-bottom: var(--bs-border-width) solid var(--line); padding: .5rem .75rem;
  font-size: var(--fonte-corpo); color: var(--ink); cursor: pointer; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista__item:last-child { border-bottom: 0; }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista__item:hover,
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista__item:focus,
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-lista__item[data-destacado] { background: var(--surf-2); }
:is(#crm-busca-topbar-host, #pn-cliente-host) .crm-vazio {
  color: var(--ink-3); font-size: var(--fonte-pequena); padding: .6rem .75rem; }
/* #511: a linha do alto da folha diz o que a caixa fez com a lista da tela (filtrou ou não casou). */
#crm-busca-topbar-host .busca-topbar__lista {
  display: block; padding: .5rem .75rem; background: var(--surf-2);
  border-bottom: var(--bs-border-width) solid var(--line);
  font-size: var(--fonte-corpo); line-height: 1.2; color: var(--ink); }
#crm-busca-topbar-host .busca-topbar__lista span { display: block; color: var(--ink-3); }

/* GATING — the default topbar filter markup ships on every FCDS page (base_fcds.html)
   but stays dormant until fcds-filterbar.js relocates a #bi-filtros host and sets
   body.fcds-toolbar-on. Until then, hide the empty cluster + its separator so
   non-migrated pages keep a clean topbar. Scoped via :not() so when the toolbar IS
   on, the §8 rules above apply unchanged (no specificity fight). */
body:not(.fcds-toolbar-on) .topbar>.vr,
body:not(.fcds-toolbar-on) .topbar .filters,
body:not(.fcds-toolbar-on) .topbar .filtbtn,
body:not(.fcds-toolbar-on) .topbar .buscar{display:none!important}

/* ── TABS ──────────────────────────────────────────────────────────────────
   O skin do tablist NÃO mora aqui. Este bloco declarava-se canônico mas estava
   inteiro dentro de um comentário mal fechado (o `!important{...}` da prosa
   abria chave e o parser só reencontrava o fecho 20 linhas abaixo), então nunca
   foi aplicado. Removido em vez de revivido: reviver mudaria o render, e o vivo
   já é o de .fcds-tabs mais adiante neste arquivo (a declaração com !important
   vence as demais). O anel de foco de teclado também está lá, não se perdeu.
   Consolidar as declarações duplicadas de .fcds-tabs é trabalho do lote 3.   */

/* count badge inside a tab button (e.g. "Notas Fiscais 1.234") */

/* foco de teclado da linha de opção do popover (WCAG 2.4.7) */
.optrow:focus-visible{
  outline:2px solid var(--acc);outline-offset:2px;
}

/* ── §10 SHARED PAGE HELPERS ────────────────────────────────────────────────
   Generic compositional helpers promoted here from faturamento-fcds.css so EVERY
   migrated page composes the faturamento card grid without copy-pasting. The JS
   statement cluster (.hero/.kpi/.flow/.sigcol) hardcodes its own spans above;
   these explicit spans drive every OTHER section a page lays out. */
/* explicit grid spans (used with .grid) */
.fcds-span-3{grid-column:span 3}
.fcds-span-4{grid-column:span 4}
.fcds-span-5{grid-column:span 5}
.fcds-span-6{grid-column:span 6}
.fcds-span-7{grid-column:span 7}
.fcds-span-8{grid-column:span 8}
.fcds-span-9{grid-column:span 9}
.fcds-span-12{grid-column:span 12}
.fcds-row-eq{align-items:stretch}   /* equal-height row */
@media(max-width:992px){
  .fcds-span-3,.fcds-span-4,.fcds-span-5,.fcds-span-6,.fcds-span-7,.fcds-span-8,.fcds-span-9{grid-column:span 12}
}

/* mini uppercase label for a chart/sub-block inside a card */
.fcds-mini-lab{font-size:var(--fonte-rotulo);font-weight:500;color:var(--ink-3);text-transform:uppercase;
  letter-spacing:.06em;margin-bottom:var(--bi-space-xs)}

/* Link de sinal (.sig) e de pé de cartão: o link de fábrica do Bootstrap (#681, #714); aqui só o reset de <button>. */
.fcds-siglink{display:inline-block;margin-top:var(--bi-space-sm);padding:0;border:0;background:none;
  cursor:pointer;font-weight:500;color:var(--bs-link-color);text-decoration:underline;position:relative}
.fcds-siglink:hover{color:var(--bs-link-hover-color)}
/* === Etiqueta, botão de texto azul e valor drillável (#130, spec 4.14) =========
   Mudança GLOBAL justificada: o dono decidiu corrigir o design system em vez de
   abrir exceção (29/09/2026). Só acréscimos — nenhuma regra existente muda.
   O que abre o detalhe, navega ou faz é o link de fábrica (#681, #714).
   A etiqueta é estado, nunca clicável (sem cursor, sem hover). */
:root {
  --ds-atencao: #FF7B00;  /* --figure-attention: fundo de etiqueta (texto preto, 6,97:1) e área com rótulo junto; nunca texto (#229) */
  --ds-perigo: #B42727;   /* --status-danger */
  --ds-sucesso: #14743C;  /* --status-success: ÁREA de "atende" no calendário do ATENDIMENTO (#130); o texto ao lado diz o estado. Global por ser o par de --ds-atencao/--ds-perigo. */
  --ds-acao: #0d6efd;     /* --action: o azul do Bootstrap, padrão da casa (#454) */
  /* Moldura global (#274): a barra do topo de todas as telas. Os blocos de tela que já
     declaram estes nomes usam os mesmos valores. */
  --ds-acao-hover: #0b5ed7;  /* --action-hover */
  --ds-acao-tinta: #e7f1ff;  /* --action-tint: linha selecionada, ☰ travado */
  --ds-tinta: #161616;       /* --fg-black / --text-primary */
  --ds-filete: #ececec;      /* --border-subtle */
  --ds-superficie: #FFFFFF;  /* --surface-card */
  --ds-sombra-balao: 0 8px 24px rgba(22,22,22,.10); /* --shadow-3: balão do sino, lista da busca */
  /* Home com feed (#286): globais porque são do DS, não da página; os blocos de
     tela que já declaram estes nomes (painel financeiro) usam os mesmos valores. */
  --ds-fonte: var(--sans);   /* --font-sans */
  --ds-tinta-2: #4a4d52;     /* --text-secondary */
  --ds-tinta-3: #8a8f96;     /* --text-muted */
  --ds-positivo: #0F5C2F;    /* --chart-positive-text */
  --ds-negativo: #8F1F1F;    /* --chart-negative-text */
  /* Programação de Faturamento (#323) usava estes quatro só declarados em blocos de outras telas: hover de linha
     transparente, divisor de dia sem fio. Globais porque são do DS. */
  --ds-fundo: #F5F5F5;       /* --fg-gray-50: fundo de painel e hover de linha */
  --ds-filete-2: #d9dbde;    /* --border-default: sob o filtro da grade, topo do Total */
}
.modal-backdrop { --bs-backdrop-opacity: .35; } /* o véu da maquete A/C (#454) */
.modal-title { font-size: var(--fonte-destaque); } /* título de modal no degrau Destaque (#476) */
.fcds-etiqueta{display:inline-flex;align-items:center;height:20px;padding:0 8px;font-size:var(--fonte-rotulo);
  font-weight:500;letter-spacing:.08em;text-transform:uppercase;line-height:1;border-radius:2px;
  white-space:nowrap;cursor:default;vertical-align:middle}
.fcds-etiqueta--perigo{background:var(--ds-perigo);color:#FFFFFF}
.fcds-etiqueta--atencao{background:var(--ds-atencao);color:#161616}
.fcds-siglink--em-linha{display:inline;margin-top:0}
/* Valor que abre o detalhe: o link de fábrica dentro do texto (#714). */
.fcds-valor{display:inline;padding:0;border:0;background:none;font:inherit;color:var(--bs-link-color);
  text-align:inherit;cursor:pointer;text-decoration:underline;position:relative}
.fcds-valor:hover{color:var(--bs-link-hover-color)}

/* generic utility */
.is-hidden{display:none!important}
/* Algarismos tabulares. Numa coluna de 204 pesos, dígito alinhado com dígito é
   o que deixa comparar 1.748 e 1.579 de relance; com a figura proporcional a
   coluna serrilha e a comparação vira leitura. Utilitário do design system, não
   regra de uma página: vale para peso, código, data e qualquer célula numérica. */
.num-tab{font-variant-numeric:tabular-nums}
/* `.font-monospace` herda o mesmo tratamento. Enquanto a primitiva do Bootstrap
   apontava para SFMono/Consolas, a utility alinhava dígito com dígito de graça —
   é fonte de largura fixa. Com `--bs-font-monospace` remapeado para o Roboto ela
   passa a ser proporcional, e as colunas numéricas que a usam (faturamento,
   importar-of, matriz-acesso, diagnóstico) serrilhariam. Os 23 usos da utility
   neste código são todos numéricos, então ela carrega tabular-nums em vez de
   trocarmos 23 chamadas por `.num-tab`. Em <code>/<pre> é inócuo. */
.font-monospace{font-variant-numeric:tabular-nums}

/* ── BOOTSTRAP BUTTON RECONCILIATION — REMOVIDA ─────────────────────────────
   Aqui moravam os remaps de `.btn-primary`, `.btn-outline-primary` e `.btn-link`
   para a marca FCDS. Removidos por diretiva do usuário: botão é Bootstrap
   canônico, com o azul de fábrica (#0d6efd). O segundo remap, gêmeo deste, ficava
   na seção "BOOTSTRAP PALETTE to FCDS" e saiu junto — eram dois, e apagar só um
   não mudaria nada. NÃO reintroduzir nenhum dos dois. */

/* ── ALERT / NOTICE PALETTE — REMOVIDA (diretiva do usuário) ────────────────
   As variantes .alert-success/-info/-warning/-danger voltam às cores de fábrica
   do Bootstrap. Só o RAIO continua vindo do FCDS (geometria, não paleta). */
.alert{--bs-alert-border-radius:var(--r-sm)}

/* ── SHELL FREEZE (shell is untouchable) ────────────────────────────────────
   The shell topbar HOSTS injected Bootstrap action buttons and relies on the
   global --bs-* remap. Now that remap is brand-blue (content actions). Pin the
   topbar's injected buttons back to the slate command tone so the shell rail +
   topbar look is unchanged. custom.css itself stays literally untouched.
   Specificity (0,3,0) beats the global .btn-primary (0,1,0). */
/* B2: topbar-injected buttons now inherit the global brand-blue .btn-primary/-outline
   remap (slate pin removed) — all primary CTAs unified to brand-blue #006BB5. */

/* ── Zero all resting shadows (user directive) ──────────────────────────────
   Bootstrap overlay components read component-scoped --bs-*-box-shadow vars, so
   neutralise the vars AND hard-override the property to win regardless of load
   order. Focus rings (:focus-visible / --bs-*-focus-box-shadow) are untouched =
   a11y preserved; the inset 9999px table-fill trick is not a box-shadow target
   here so zebra/sticky-column backgrounds stay intact. */
:root{
  --bs-box-shadow:none;--bs-box-shadow-sm:none;--bs-box-shadow-lg:none;--bs-box-shadow-inset:none;
  --bs-dropdown-box-shadow:none;--bs-modal-box-shadow:none;--bs-toast-box-shadow:none;
  --bs-popover-box-shadow:none;--bs-offcanvas-box-shadow:none;--bs-card-box-shadow:none;
  --bs-btn-box-shadow:none;--bs-btn-active-shadow:none;
  /* B5/A3: só a GEOMETRIA de modal/dropdown segue o padrão FCDS. As cores de borda
     (--bs-*-border-color) e o tom do backdrop foram removidos por diretiva do
     usuário — ficam os valores de fábrica do Bootstrap. */
  --bs-modal-border-radius:var(--r);
  --bs-dropdown-border-radius:var(--bi-radius-md)}
/* A varredura `box-shadow:none!important` sobre dropdown/modal/toast/popover/
   offcanvas/card/tooltip saiu: cada um lê a sombra do seu `--bs-*-box-shadow`, e
   todos já estão em `none` no bloco de tokens acima — era uma segunda tranca na
   mesma porta. Medido componente a componente depois de tirar: seis dos sete
   continuam em `none`. O sétimo é o `.toast`, que redeclara
   `--bs-toast-box-shadow` no próprio seletor e por isso nunca enxergou o valor do
   `:root`; a sombra volta pelo mesmo canal, sem `!important`. */
.toast{--bs-toast-box-shadow:none}

/* ==========================================================================
   MERGED FROM bi/static/bi/css/main.css (P6 — two-layer collapse). Loads here
   (after the original FCDS rules) exactly where it loaded per-page before.
   ========================================================================== */

/* ==========================================================================
   main.css — "Editorial Finance" component system for bi/ app
   Uses ONLY tokens from tokens.css. ZERO literal color values.
   ZERO !important (except clearly marked DataTables overrides).

   Sections:
    1.  Reset / Base
    2.  Command Bar (dark filter strip)
    3.  KPI Band (top metric strip)
    4.  Section Anchor (editorial dividers)
    5.  Layout helpers
    6.  Card
    7.  KPI (operational cards)
    8.  Badge
    9.  Variation
   10.  Table + DataTables overrides
   11.  Chart
   12.  Waterfall
   13.  Heatmap
   14.  Gauge
   15.  Pills / Filters
   16.  Risco de Caixa
   17.  Toggle Devoluções
   18.  Progress Margin
   19.  Modal
   20.  Accordion
   21.  Skeleton
   22.  Error + Empty
   23.  Accessibility
   24.  Animations
   25.  Responsive
   ========================================================================== */

/* ==========================================================================
   1. RESET / BASE
   ========================================================================== */

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

.page {
  font-family: var(--sans);
  color: var(--bi-text-primary);
  background-color: var(--surface-app);
  /* SEM min-height:100vh. A .page vive DENTRO do .content, que já está abaixo da
     topbar (52px) e tem padding — forçar 100vh aqui garantia 52px + 100vh + padding
     > viewport, ou seja, uma barra de rolagem fantasma na PÁGINA, em toda tela do
     app, com tabela ou sem. Encher a tela já é papel do `.main`
     (min-height: calc(100dvh - 52px), custom.css). */
  /* padding movido p/ a def global com !important (5373, mesmo valor) — morto aqui */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* O .small do Bootstrap é .875em: 12,25px no corpo e encadeia dentro de outro .small (#476). */
small, .small { font-size: var(--fonte-pequena); }
/* Os h1–h4 do Bootstrap são fluidos (22–40px): na tela densa h1 é Título e h2–h4 é Destaque (#476). */
.page h1 { font-size: var(--fonte-titulo); }
.page :where(h2, h3, h4) { font-size: var(--fonte-destaque); }

/* ==========================================================================
   2. COMMAND BAR
   Fundo claro, borda inferior — filtros compactos e modernos
   ========================================================================== */

/* (.command-bar container removido — não renderizado; a raiz é .command-bar__filters.) */

/* Linha de filtros — coluna com 3 rows */
.command-bar__filters {
  display: flex;
  flex-direction: column;
  gap:var(--bi-space-2xs);
}
.command-bar__row {
  display: flex;
  align-items: center;
  gap:var(--bi-space-sm);
  flex-wrap: wrap;
}

.filter-group {
  display: flex;
  align-items: center;
  gap:var(--bi-space-xs);
}

.filter-group__label {
  font-size: var(--fonte-corpo);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bi-text-muted);
  line-height: 1;
  white-space: nowrap;
}

.filter-group__pills {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap:0.25rem;
}


/* ==========================================================================
   3. KPI BAND
   Faixa horizontal de 5 métricas sem cards individuais
   ========================================================================== */

.kpi-band {
  display: grid;
  grid-template-columns: 1.2fr 1.4fr 1fr 1fr 1fr 1fr 1fr;
  background: var(--bi-bg-surface);
  border: var(--bi-border);
  border-radius: var(--bi-radius-md);
  box-shadow: var(--bi-shadow-sm);
  overflow: hidden;
  /* No horizontal margin:the band aligns flush to its section/card width like
     every .cardbox. .page already supplies the page side padding, so a
     horizontal margin here double-inset the band (was 3rem narrower than cards
     across all pages). Standardized 2026-06 — see docs/planos/pilot-page-refactor.md.
     KPI band → content gap promoted to --bi-space-md (Batch 6 §2, Agent C). */
  margin: 0 0 var(--bi-space-md);
  animation: bi-fadeIn var(--bi-transition-normal) ease both;
}

/* Aging table — pct bar overlay */
.faixa-dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--bi-dot-cor, var(--ink-4));
  margin-right:var(--bi-space-xs2);
  vertical-align: middle;
}

/* Shared, page-agnostic KPI accent modifiers — every KPI page tags cells by
   value DIRECTION via these (no inline category accents). Bottom-rule only. */

/* Legacy alias (despesas_comex used --previsao) → same as warning. */

.kpi-band__label {
  font-size: var(--fonte-rotulo);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bi-text-muted);
  margin-bottom:var(--bi-space-xs);
  line-height: 1;
}

.kpi-band__value {
  /* Shared (Step 3 contract): KPI numbers are tabular on every page — the number
     is the data, dark, no colour fill. Use --mono (Roboto, loaded in
     base_fcds.html) to MATCH faturamento's .kc__v numerals; Roboto
     (official numeral font, --mono) is the canonical numeral family — the old
     --bi-font-mono fell back to a system mono that diverged from the reference.
     Roboto is also narrower → less mobile clipping. */
  font-family: var(--mono); /* --mono always resolves; dead --bi-font-mono fallback dropped */
  font-weight: 500;
  color: var(--bi-text-primary);
  line-height: 1.2;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.kpi-band__secondary {
  font-family: var(--bi-font-display);
  font-size: var(--fonte-corpo);
  font-weight: 500;
  color: var(--bi-text-secondary);
  margin-top:var(--bi-space-3xs);
  font-variant-numeric: tabular-nums;
}

/* KPI strip para cards operacionais (ritmo, PMP, PMR). O seletor desta regra foi
   perdido: a linha abria comentário e nunca fechava, engolindo a declaração
   `padding:0 var(--bi-space-lg)` e o banner da seção 6. Como o nome do seletor
   foi truncado junto, não há o que restaurar — a declaração órfã foi removida. */

/* ==========================================================================
   6. CARD
   ========================================================================== */

/* Accent na borda superior do card */

/* Accent na borda esquerda */

code {
  font-size: var(--fonte-corpo);   /* 12px floor */
}

/* Badge de contagem no header do card */

/* ==========================================================================
   7. KPI — a célula canônica é components/_kpi_cell.html (card Bootstrap).
   A classe .kpi-tile que morava aqui era legado sem markup vivo (nenhum
   template do tree renderiza class="kpi-tile"; os id="kpi-tiles" são
   containers, outra coisa) — removida em 2026-08-06 na varredura DESIGN.md §6.
   ========================================================================== */

/* ==========================================================================
   8. BADGE
   ========================================================================== */

/* Bootstrap 5.2.3 de fábrica (#454). Só a cor de quem não traz text-bg-* nem badge--*: o de
   fábrica pinta texto branco sem fundo, e o selo sumiria na página branca. */
.badge { --bs-badge-color: var(--ink-2); background-color: var(--neutral-subtle); }

/* Direction badges → canonical indicator tokens (text) + *-subtle (bg). */
.badge--success  { background: var(--positive-subtle); color: var(--positive-text); }
.badge--danger   { background: var(--negative-subtle); color: var(--negative-text); }
.badge--warning  { background: var(--warning-subtle);  color: var(--warning-text); }
/* --info is categorical (not a value direction) → neutral, no direction hue. */
.badge--info     { background: var(--neutral-subtle);  color: var(--ink-2); }
/* --neutro: o estado TERMINADO, que não pede nada de ninguém. Existe porque
   "concluído" não é "sucesso": pintar de verde tudo o que já foi faturado põe a
   cor mais forte da paleta no que ninguém pode mais mexer, e deixa a única linha
   viva como a mais apagada da lista. Sem cor de direção, sem borda forte. */
.badge--neutro   { background: var(--surf-2);          color: var(--ink-3); }
/* --primary is categorical accent (in-flight / active) → slate accent, no direction hue. */
.badge--primary  { background: var(--acc-soft);        color: var(--acc-ink); }
/* --brand is the Four heritage blue identity (masthead codes, not a value direction). */
.badge--brand    { background: var(--brand-soft);      color: var(--brand-ink); }

/* Dot modifier — categorical identity whose hue varies per data value (grupo/segmento),
   supplied at runtime via --dot on the element. Label stays fixed --ink-2 for legibility;
   only the leading dot carries the category hue (cat tokens aren't AA-safe as text). */
.badge--dot { color: var(--ink-2); }
.badge--dot::before {
  content: "";
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--dot, var(--ink-3));
  display: inline-block;
  margin-right: .25em;
  vertical-align: middle;
}

/* ==========================================================================
   9. VARIATION (inline up/down indicator)
   ========================================================================== */

/* ==========================================================================
   10. TABLE (tbl wrapper + DataTables overrides)
   ========================================================================== */

.tbl-wrapper {
  border-radius: var(--bi-radius-md);
  /* Sem borda própria: o .tbl-wrapper sempre mora dentro de um .card (convenção
     FCDS: section.card > .tbl-wrapper), e o card já desenha o contorno do
     componente. Uma borda aqui virava linha dupla em todas as telas de tabela. */
  /* MOBILE: wide ERP tables must scroll inside the card, not clip at its edge.
     (datatable adds .datatable-scroll for DataTables; this covers bare/non-DT
     wrappers — e.g. contas_a_pagar + fluxo-bancario TD tables.) */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.tbl {
  width: 100%;
  font-size: var(--bi-fs-body);
  color: var(--bi-text-primary);
  margin-bottom:0;
  border-collapse: collapse;
}

.tbl thead th {
  background-color: var(--surf-2);
  border-bottom: 2px solid var(--bi-border-color);
  font-size: var(--bi-fs-label);
  font-weight: var(--bi-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bi-text-secondary);
  white-space: nowrap;
  padding:var(--bi-space-sm) var(--bi-space-md);
}

.tbl tbody td {
  padding:var(--bi-space-sm) var(--bi-space-md);
  border-bottom: var(--bi-border-subtle);
  vertical-align: middle;
}

/* Estado de linha usa o motor do Bootstrap (overlay translúcido `--bs-table-accent-bg`,
   styles.css:2047), não um hex opaco. Hex opaco colide com qualquer faixa que use o
   mesmo valor — `--bi-bg-hover` e `--surf-2` são ambos #f3f4f7, e o hover sumia em
   cima da faixa. O overlay compõe sobre a base, então o hover é sempre mais escuro
   que a linha, seja ela branca ou faixada. */
.tbl tbody tr:hover td {
  --bs-table-accent-bg: var(--bs-table-hover-bg);
}

.tbl__numeric {
  font-family: var(--bi-font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* (removed `.tbl--sticky-first` — superseded by the unified `.stickcols`
   system; pedidos + fluxo-bancário migrated.) */

/* Total row */
.tbl .tbl__total-row td {
  font-weight: var(--bi-fw-bold);
  border-top: 2px solid var(--bi-border-color-heavy);
  background-color: var(--surf-2);
}

/* Densidade — modificador compartilhado p/ tabelas de muitas colunas (ex.: as 27
   colunas do despesas_comex). Reduz padding/line-height das células e encolhe o
   checkbox de linha. Aplique `.tbl--compact` no <table>. */
.tbl--compact thead th,
.tbl--compact tbody td {
  padding:var(--bi-space-xs) var(--bi-space-sm);
  line-height: 1.25;
}
.tbl--compact thead th {
  white-space: normal;
  line-height: 1.2;
}
.tbl--compact .form-check-input {
  width: 0.875rem;
  height: 0.875rem;
}

/* --- DataTables padrão BI — opt-in via .datatable no wrapper --- */

/* Toolbar: B (buttons) à esquerda, l (length) + f (filter) à direita */
.datatable .datatable-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap:var(--bi-space-md);
  flex-wrap: wrap;
  padding:var(--bi-space-sm) var(--bi-space-md);
  border-bottom: 1px solid var(--bi-border-color);
}
.datatable .datatable-toolbar__left,
.datatable .datatable-toolbar__right {
  display: inline-flex;
  align-items: center;
  gap:var(--bi-space-sm);
}


/* <details> sem a seta nativa do navegador: o chevron do app, que gira ao abrir
   (dono, 15/09 — chevron é ícone em todo lugar). Uma regra só para os cinco
   disclosures que ainda mostravam o triângulo do sistema. */
:is(.cl-relatorio details, .ret-avancado, #modalbox-nf-notes-card, .reportar-historico, .tf-detalhe__historico) > summary {
  list-style: none;
}
:is(.cl-relatorio details, .ret-avancado, #modalbox-nf-notes-card, .reportar-historico, .tf-detalhe__historico) > summary::-webkit-details-marker {
  display: none;
}
:is(.cl-relatorio details, .ret-avancado, #modalbox-nf-notes-card, .reportar-historico, .tf-detalhe__historico) > summary::before {
  content: '\f054'; font-family:'Font Awesome 6 Free'; font-weight:500; font-size: var(--fonte-pequena);
  display: inline-block; width: 1em; margin-right: .4em; text-align: center; vertical-align: .1em;
  transition: transform .15s ease;
}
:is(.cl-relatorio details, .ret-avancado, #modalbox-nf-notes-card, .reportar-historico, .tf-detalhe__historico)[open] > summary::before {
  transform: rotate(90deg);
}
/* Raia recolhível da Permanência no Porto (só no celular): o chevron vira com o
   `aria-expanded` que o collapse do Bootstrap mantém no cabeçalho. */
.pp-lane__chevron { transition: transform .15s ease; }
.pp-lane__head[aria-expanded="true"] .pp-lane__chevron { transform: rotate(180deg); }
/* Cartão de KPI clicável (_kpi_cell com `abre`, #161): o stretched-link leva o
   clique ao cartão inteiro; hover e foco aparecem no cartão, não no rótulo.
   Desabilitado (total 0) fica sem hover: cinza = desabilitado. */
.card:has(.kpi-cell__abre:not(:disabled)):hover { border-color: var(--bs-primary); cursor: pointer; }
.card:has(.kpi-cell__abre:focus-visible) { box-shadow: 0 0 0 .25rem rgba(var(--bs-primary-rgb), .25); }
.kpi-cell__abre:focus-visible { box-shadow: none; }


/* Length + Search inputs alinhados com pills (28px) */
.datatable .dataTables_length,
.datatable .dataTables_filter {
  margin:0;
}
.datatable .dataTables_length label,
.datatable .dataTables_filter label {
  display: inline-flex;
  align-items: center;
  gap:var(--bi-space-xs2);
  margin:0;
  font-size: .875rem;
  color: var(--bi-text-secondary);
  font-weight: var(--bi-fw-medium);
  white-space: nowrap;
}

/* Scroll horizontal isolado: só conteúdo + thead, não a toolbar nem bottom bar */
.datatable .datatable-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.datatable table.dataTable {
  min-width: 100%;
}

/* Bottom bar: info + paginate */
.datatable .datatable-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding:var(--bi-space-sm) var(--bi-space-md);
  border-top: 1px solid var(--bi-border-color);
}
.datatable .datatable-bottom .dataTables_info,
.datatable .datatable-bottom .dataTables_paginate {
  padding-top:0;
  margin:0;
  font-size: .875rem;
  color: var(--bi-text-secondary);
}

/* Paginação: nenhuma regra. Ver o bloco "PAGINAÇÃO: sem regra nenhuma" mais
   abaixo — o .pagination do Bootstrap responde por cor, borda, raio e solda. */

/* Filtros de coluna multi-seleção (Pedidos): trigger + painel flutuante.
   Antes só existia em demo/components-v2.css (não carregado em produção), então
   o controle vinha sem estilo. Portado para o FCDS: acento slate (não brand-blue),
   raio igual aos controles da toolbar (--bi-radius-sm). O painel é position:fixed
   (posicionado no abrir por pedidos-colfilter.js) para escapar do overflow do
   .datatable-scroll, que recortava a lista quando havia scroll horizontal. */
.colfilter-multi { position: relative; }
.colfilter-multi__trigger { width: 100%; cursor: pointer; }
.colfilter-multi--ativo .colfilter-multi__trigger {
  border-color: var(--ds-acao); color: var(--ds-acao); font-weight: var(--bi-fw-medium);
}
.colfilter-multi__panel {
  position: fixed; z-index: var(--bi-z-dropdown, 100);
  min-width: 11.5rem; width: max-content; max-height: 18.75rem; overflow-y: auto;
  background: var(--bi-bg-surface);
  border: var(--bs-border-width) solid var(--bi-border-color);
  border-radius: 0; /* reto, como o painel do design system (#273) */
  /* Elevação real: um menu flutuante precisa se separar do conteúdo abaixo
     (exceção de popover ao depth-flat do FCDS). Sombra suave, sem dureza. */
  box-shadow: 0 10px 28px -10px rgba(25, 28, 34, 0.22), 0 2px 8px -3px rgba(25, 28, 34, 0.12);
  padding:var(--bi-space-3xs);
  animation: biColfilterIn 0.13s cubic-bezier(0.16, 1, 0.3, 1);
}

/* "Tipo de Documento" do modal de anexos (_modais_titulo.html): o campo buscável
   do CRM (`crm/js/combo.js`, com `grupo`). As regras dele só alcançam as páginas do
   CRM/Compras e o host da topbar; aqui a pintura é escopada ao host do modal (mesmo
   precedente de `#crm-busca-topbar-host`). A lista é `fixed`: o corpo do modal rola
   (`modal-dialog-scrollable`) e uma lista `absolute` seria recortada por ele — o
   `combo.js` ancora as coordenadas quando o CSS escolhe `fixed`. z-index acima do
   modal (1055). O campo já nasce `.form-control-sm`, a altura dos vizinhos (arquivo, Enviar). */
#df-anexo-tipo-host .crm-combo { position: relative; display: block; }
#df-anexo-tipo-host .crm-oculto { display: none !important; }
#df-anexo-tipo-host .crm-lista {
  background: var(--surf); border: var(--bs-border-width) solid var(--line);
  border-radius: var(--bs-border-radius-lg); box-shadow: var(--bs-box-shadow);
  overflow: hidden; overflow-y: auto; }
#df-anexo-tipo-host .crm-lista--flutua { position: fixed; z-index: 1060; max-height: 20rem; }
#df-anexo-tipo-host .crm-lista__item {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  border-bottom: var(--bs-border-width) solid var(--line); padding: .5rem .75rem;
  font-size: var(--fonte-corpo); color: var(--ink); cursor: pointer; }
#df-anexo-tipo-host .crm-lista__item:last-child { border-bottom: 0; }
#df-anexo-tipo-host .crm-lista__item:hover,
#df-anexo-tipo-host .crm-lista__item:focus,
#df-anexo-tipo-host .crm-lista__item[data-destacado] { background: var(--surf-2); }
/* Cabeçalho de grupo do combo (crm/js/combo.js) — geral desde #190 (28/09/2026): a
   busca do topo agrupa "Recentes"; antes só o combo de tipo de anexo agrupava. */
.crm-lista__grupo {
  padding: .5rem .75rem .25rem; font-size: var(--fonte-rotulo); font-weight: 500;
  text-transform: uppercase; color: var(--ink-3); background: var(--surf-2); }
#df-anexo-tipo-host .crm-vazio { color: var(--ink-3); font-size: var(--fonte-pequena); padding: .6rem .75rem; }
@keyframes biColfilterIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .colfilter-multi__panel { animation: none; }
}
.colfilter-multi__opt {
  display: flex; align-items: center; gap:var(--bi-space-xs);
  padding:var(--bi-space-xs2) var(--bi-space-sm); margin:0;
  border-radius: var(--bi-radius-sm);
  font-size: .875rem; font-weight: var(--bi-fw-regular); color: var(--bi-text-primary);
  white-space: nowrap; cursor: pointer; text-transform: none; letter-spacing: 0;
  transition: background var(--bi-transition-fast);
}
.colfilter-multi__opt:hover { background: var(--bi-bg-hover); }
/* Opt-in `detalhe` do colfilterMulti (#113, Despesas nova): texto de apoio à direita
   do rótulo ("727 mil · 326"). Classe nova, só existe em quem passa `detalhe`; nenhuma
   tela existente muda. */
.colfilter-multi__detalhe {
  margin-left: auto; padding-left: var(--bi-space-sm); flex-shrink: 0;
  font-size: 0.85em; color: var(--bi-text-secondary); font-variant-numeric: tabular-nums;
}
/* Painel de INTERVALO (biUtils.colfilterRange): dois inputs de/até empilhados.
   Reusa a casca .colfilter-multi__panel; só arruma o layout dos campos.
   MUDANÇA GLOBAL (justificativa): este painel é compartilhado por dezenas de telas
   (grade, Pedidos, Processos Comex, Despesas, CRM). O rodapé Aplicar/Limpar, a linha
   de erro e a marca de campo inválido entram aqui, e não em cada tela, pela regra do
   dono de 21/09/2026 (reporte #113): filtro compartilhado vale para TODAS as telas,
   sem exceção local. Tema claro, tokens --bi-* já usados neste bloco; botões e
   cores de erro vêm do Bootstrap (btn, text-danger, --bs-danger). */
.colfilter-range__panel {
  min-width: 11.25rem; padding:var(--bi-space-xs);
  display: flex; flex-direction: column; gap:var(--bi-space-xs2);
}
.colfilter-range__field {
  display: flex; align-items: center; gap:var(--bi-space-xs); margin:0;
  font-size: .875rem; font-weight: var(--bi-fw-regular);
  color: var(--bi-text-secondary); text-transform: none; letter-spacing: 0;
}
.colfilter-range__field > span { width: 2.2em; flex-shrink: 0; }
.colfilter-range__field input { flex: 1; min-width: 0; }
/* Mensagem de recusa: o painel tem largura `max-content`, então sem teto a frase
   inteira alargaria o painel; quebra em vez de crescer. */
.colfilter-range__erro { max-width: 15rem; white-space: normal; text-transform: none; letter-spacing: 0; }
/* Modos opt-in do colfilterRange (#113, Tarefa 8) — só valem para quem os liga; nenhuma
   tela existente muda. Mês: o calendário do flatpickr mora DENTRO do painel (`static`,
   sondagem 8.0) e o painel base corta o que passa da borda (`overflow-y:auto` +
   `max-height`), então o modificador `--mes` solta os dois; o invólucro do flatpickr
   ocupa a linha do campo como o input ocupava. Desabilitado (`desabilitar`): o gatilho
   fica apagado e sem mão, no mesmo tom de qualquer botão desabilitado do app. */
.colfilter-range__panel--mes { overflow: visible; max-height: none; }
.colfilter-range__field .flatpickr-wrapper { flex: 1; min-width: 0; }
.colfilter-range__field .flatpickr-wrapper input { width: 100%; }
.colfilter-multi__trigger:disabled { opacity: 0.6; cursor: not-allowed; }

/* ── SELETOR DE PERÍODO (`biUtils.seletorDePeriodo`) ─────────────────────────
   MUDANÇA GLOBAL (justificativa): o dono pediu o seletor canônico de despesas/nova
   também no extrato do /banking/ (24/09/2026). O desenho saiu do trilho de
   despesas/nova (antes `.dnv-sel__bt` + `.dnv-pop--periodo`, no escopo
   `#topbar:has(.dnv-sel)`) valor por valor, para as duas telas lerem UMA regra. Só
   casa em `.fcds-seletor`, que só o componente cria: nenhuma outra tela muda. A pele
   (`--dnv-*`) vem da lista de seletores da seção DESPESAS. O corpo do popover é o
   `colfilterRange` embutido (classes dele); aqui só o vestimos. O botão é `btn btn-outline-primary btn-sm`
   de fábrica, só o valor, como na maquete A/C (#454). */
.fcds-seletor{ position:relative; display:flex }
.fcds-seletor .fcds-seletor__chave{ display:none }
.fcds-seletor .fcds-seletor__popover{
  position:absolute; top:100%; left:0; z-index:60; background:var(--dnv-surface); color:var(--dnv-ink);
  border:1px solid var(--dnv-rule-2); box-shadow:0 14px 34px -14px rgba(0,0,0,.3);
  padding:18px 20px 16px; min-width:320px; width:min(340px, calc(100vw - 28px)); cursor:default;
}
.fcds-seletor .fcds-seletor__nota{ margin:16px 0 0; padding-top:13px; border-top:1px solid var(--dnv-rule); font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.fcds-seletor .fcds-seletor__nota b{ color:var(--dnv-ink-2); font-weight:500 }
.fcds-seletor .fcds-seletor__popover .colfilter-range__panel{ min-width:0; padding:0; gap:0 }
.fcds-seletor .fcds-seletor__popover .colfilter-range__presets{ flex-direction:column; flex-wrap:nowrap; gap:4px; margin:0 0 12px!important }
.fcds-seletor .fcds-seletor__popover .colfilter-range__presets .btn{ display:flex; align-items:baseline; gap:9px; text-align:left }
.fcds-seletor .fcds-seletor__popover .colfilter-range__sub{ margin-left:auto; font-size:var(--fonte-pequena); font-weight:400; color:inherit }
.fcds-seletor .fcds-seletor__popover .colfilter-range__field{ justify-content:space-between; gap:10px; margin-bottom:8px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.fcds-seletor .fcds-seletor__popover .colfilter-range__field input{ flex:none; width:148px }
.fcds-seletor .fcds-seletor__popover .colfilter-range__erro{ max-width:none; margin:0 0 8px; font-size:var(--fonte-pequena) }
/* Seletor de um dia só (#130): mudança global ADITIVA — classes novas, usadas só com `umDia`. */
.fcds-seletor__dia{display:flex;flex-direction:column;gap:.25rem}

.chart canvas{
  width: 100%;
}

/* Degrau extra da escada, para gráfico de DOIS PAINÉIS empilhados (histórico de
   preços: preço em cima, volume embaixo). Em 25rem os dois painéis somados, menos
   a faixa dos rótulos de mês inclinados, deixavam ~11rem para o preço — apertado
   demais para uma linha com rótulo em cada ponto. */
.chart--xl     { height: 34rem; }
.chart--tall   { height: 25rem; }
.chart--medium { height: 18.75rem; }
.chart--short  { height: 17.5rem; }

/* ==========================================================================
   12. WATERFALL
   ========================================================================== */

/* Mapa UF — card e corpo preenchem a altura definida pelo align-items-stretch da row */
[data-bi-section="mapa-uf"] .card {
  display: flex;
  flex-direction: column;
}
[data-bi-section="mapa-uf"] .card-body {
  flex: 1;
  min-height: 0;
}
[data-bi-section="mapa-uf"] .mapa {
  height: 100%;
}

/* Cascata de Margens — estica para igualar altura da tabela UN */

[data-bi-section="cascata"] .card {
  display: flex;
  flex-direction: column;
}
[data-bi-section="cascata"] .card-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 17.5rem;
}

/* ==========================================================================
   13. HEATMAP
   ========================================================================== */

.heatmap-grid {
  overflow-x: auto;
}

.heatmap-table {
  border-collapse: separate;
  border-spacing: 3px;
  font-size: var(--fonte-pequena);
  min-width: 100%;
}

.heatmap-table th {
  padding:var(--bi-space-2xs) var(--bi-space-sm);
  font-weight: 500;
  color: var(--bi-text-secondary);
  white-space: nowrap;
  text-align: center;
}

.heatmap-table th:first-child {
  text-align: left;
}

.heatmap-table td {
  padding:var(--bi-space-xs2) var(--bi-space-sm);
  border-radius: var(--bi-radius-sm);
  text-align: center;
  white-space: nowrap;
  font-family: var(--bi-font-mono);
  font-variant-numeric: tabular-nums;
  transition: filter 0.15s;
}

.heatmap-table td:first-child {
  font-family: var(--sans);
  font-weight: 500;
  color: var(--bi-text-secondary);
  background: transparent !important;
  text-align: left;
}

.heatmap-table td:hover {
  filter: brightness(0.88);
}

/* Célula do Ritmo: padding reduzido para acomodar o gauge */

/* ==========================================================================
   16. RISCO DE CAIXA — caixas coloridas por threshold
   ========================================================================== */

/* ==========================================================================
   17. TOGGLE DEVOLUÇÕES
   ========================================================================== */

/* Os switches "Considerar devoluções" e "Formatar número?" vivem no MESMO grupo,
   à direita do topbar (#fcds-toggles, montado por fcds-filterbar.js). São
   .form-check.form-switch do Bootstrap puros, agrupados por utilitários
   (d-flex/gap-3/ms-auto) — nenhuma regra própria aqui. */

/* ==========================================================================
   18. PROGRESS MARGIN — colunas MB% e MC% na tabela de NFs
   ========================================================================== */

/* (variantes --sucesso/--aviso/--perigo removidas — o JS só emite
   progress-margin--neutral; nunca as coloridas.) */

/* neutral: MB/MC % carry no value direction — pct in ink, bar in the slate accent */

/* Desktop: tuck the MB/MC margin cell into the right-aligned numeric rhythm (its cell is
   text-align:right) and tighten it for the denser desktop table — keeps the magnitude bar.
   Mobile keeps the centered, roomier layout above. */

/* ==========================================================================
   19. MODAL — Detalhes da Nota Fiscal
   ========================================================================== */

/* Chrome de `.modalbox` removido — todos os modais usam o shell Bootstrap
   (biUtils.abrirModal). Sobrevive só a classe de CONTEÚDO `.modalbox__subtitulo`
   (subtítulo no header, usada por faturamento e pedidos). */
.modalbox__subtitulo {
  font-size: var(--fonte-corpo);
  color: var(--bi-text-secondary);
  margin-top:var(--bi-space-3xs);
  font-family: var(--bi-font-mono);
}

/* ==========================================================================
   20. ACCORDION — removido (colapse de seções não é necessário)
   ========================================================================== */

/* (accordion removed) */

/* ==========================================================================
   21. SKELETON (loading placeholders)
   ========================================================================== */

/* .skeleton / .skeleton--chart / .skeleton--text removidos — skeleton unificado no
   Bootstrap .placeholder (utils.js SKELETON_HTML + carregando/carregandoSecao). */

/* ==========================================================================
   21b. LOGO LOADER (Four Group signature loading state — used em F.BI)
   ========================================================================== */

/*
 * Loader em modo overlay: o container alvo recebe data-bi-loading="<size>",
 * que aplica position:relative + min-height. O loader em si fica sobreposto
 * com inset:0, deixando o conteúdo embaixo intacto (apenas escondido pelo bg).
 *
 * Estrutura HTML (injetada via biUtils.aplicarLoaderEm):
 *   <div class="logo-loader" role="status" aria-busy="true" aria-live="polite">
 *     <div class="logo-loader__base"></div>
 *     <div class="logo-loader__mask"><div class="logo-loader__fill"></div></div>
 *   </div>
 */

[data-bi-loading]            { position: relative; }
[data-bi-loading="banda"]    { /* KPI band: altura natural das células, sem reserva */ }
[data-bi-loading="tape"]     { min-height: 11.75rem; }
[data-bi-loading="chart"]    { min-height: 22.5rem; }
[data-bi-loading="board"]    { min-height: 30rem; }

.logo-loader {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;   /* clipa o logo em containers baixos (faixa KPI, modo banda) */
  background: var(--bi-bg-surface);
  border-radius: var(--bi-radius-md);
}

/* Logo "4" dimensionado pela ALTURA do container (não largura fixa): escala
   sozinho em todo modo — proeminente em board/chart, encolhe e cabe na faixa
   KPI (banda). aspect-ratio casa o logo.svg real (1311×1316). O wrapper próprio
   do despesas_comex sobrescreve width/height (100%) com specificity maior. */
.logo-loader__base,
.logo-loader__mask {
  position: absolute;
  width: auto;
  height: min(46%, 150px);
  aspect-ratio: 1311 / 1316;
  -webkit-mask-image: url("../img/logo.e911c70f8d2a.svg");
          mask-image: url("../img/logo.e911c70f8d2a.svg");
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
}

.logo-loader__base {
  background: var(--bi-loader-base);
}

.logo-loader__mask {
  overflow: hidden;
}

.logo-loader__fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0%;
  /* PRETO, e dito aqui: a logo do carregamento é a marca, não um acento nem um
     dado — não segue a cor de ação do app. Lia --command (tinta de magnitude de
     DADO), que por sua vez estava aliasado ao acento; era esse encadeamento que
     fazia a logo mudar de cor junto com botão e paginação. */
  background: var(--ink);
  animation: logo-loader-trickle 2.2s ease-in-out 0.15s infinite alternate;
}

@keyframes logo-loader-trickle {
  0%   { width: 8%; }
  100% { width: 88%; }
}

@media (prefers-reduced-motion: reduce) {
  .logo-loader__fill {
    animation: none;
    width: 50%;
  }
}

/* ==========================================================================
   22. ERROR + EMPTY STATE
   ========================================================================== */

.state-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap:var(--bi-space-sm);
  padding:var(--bi-space-lg);
  text-align: center;
  color: var(--bi-text-secondary);
}

.state-error[role="alert"] {
  /* Borda plena na cor da família + tinta -subtle — sem faixa lateral
     (o caso literal do banimento, DESIGN.md §6). */
  border: 1px solid var(--negative-text);
  border-radius: var(--bi-radius-md);
  background: var(--negative-subtle);
}

.state-error__mensagem {
  font-size: var(--fonte-corpo);
  color: var(--bi-text-secondary);
}

.state-error__botao-retry {
  display: inline-flex;
  align-items: center;
  gap:0.25rem;
  padding:var(--bi-space-xs) var(--bi-space-md);
  font-size: var(--fonte-pequena);
  font-weight: 500;
  /* AÇÃO usa o azul de ação — o verde aqui dizia "deu certo" dentro de um
     erro (critique 2026-08-07: retry na família positive). */
  color: var(--acc-ink);
  background: transparent;
  border: var(--bs-border-width) solid var(--acc);
  border-radius: var(--bi-radius-sm);
  cursor: pointer;
  transition: background var(--bi-transition-fast), color var(--bi-transition-fast);
}

.state-error__botao-retry:hover {
  background: var(--acc);
  color: var(--bi-text-on-accent);
}

.state-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap:var(--bi-space-sm);
  padding:var(--bi-space-2xl) var(--bi-space-md);
  text-align: center;
  color: var(--bi-text-muted);
  font-size: var(--fonte-corpo);
}

/* Canonical empty state inside a table body — see biUtils.mostrarEmptyLinha */
.state-empty-row {
  text-align: center;
  color: var(--bi-text-muted);
  font-size: var(--fonte-corpo);
  padding:var(--bi-space-lg) var(--bi-space-md);
}
/* ── Badge de frescor ("atualizado em X") — dot + texto ──────────────────────
   Compartilhado; substitui .gc-fresh/.mi-fresh page-scoped. */
.fresh { display: inline-flex; align-items: center; gap:0.25rem; font-size: var(--fonte-pequena); color: var(--bi-text-secondary); }
.fresh[hidden] { display: none; }
.fresh__dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--positive-text); flex-shrink: 0; }
/* Frescor vencido: o agendamento passou de 2 ciclos sem ler o Conexos. Aditivo: só
   despesas_comex.js põe a classe; as outras telas com .fresh não mudam. */
.fresh--atrasado { color: var(--warning-text); font-weight: 500; }
.fresh--atrasado .fresh__dot { background: var(--ds-atencao); } /* área; a palavra ao lado diz */

/* ── Mercado de Importação — específico da tela ──────────────────────────────
   Rebranding como "briefing competitivo" (inspiração: o deck de preços Logcomex
   FOUR×AWA×South Service): masthead do relatório → veredito de preço (a tese) →
/* ── Masthead: identidade do relatório (produto em display condensado) + faixa
   de tamanho do mercado como antetítulo. Substitui a antiga banda de 6 KPIs que
   "parecia planilha": aqui os totais são contexto editorial.
   O seletor desta regra foi perdido — a linha acima abria comentário sem fechar
   e engolia tanto o nome do seletor quanto as declarações (display/flex-wrap/
   padding-bottom/border-bottom), que nunca foram parseadas. Órfãs, removidas. */

/* Rótulos de banda: agrupam a estrutura do mercado abaixo do veredito competitivo
   (Quem importa → De onde vem). Espaçamento generoso no topo cria a hierarquia
   (sem régua/borda — a linha dura é o tell do ERP legado que rejeitamos). Mesma
   convenção page-scoped por página. */

/* ==========================================================================
   23. ACCESSIBILITY
   ========================================================================== */

.state-error__botao-retry:focus-visible{
  outline: 2px solid var(--positive);
  outline-offset: 2px;
}

/* drill-down rows are now keyboard-operable (role=button + tabindex via JS);
   give them the same focus ring instead of the black UA default. */
.seg-row:focus-visible,
[data-canal]:focus-visible {
  outline: 2px solid var(--positive);
  outline-offset: -2px;
  border-radius: var(--bs-border-radius-lg);
}

/* controls that previously had no visible keyboard focus (WCAG 2.4.7):
   modal close, map sort toggles, keyboard-operable map ranking
   rows, cockpit's quiet drill-down triggers (dropping .btn-link to de-blue
   them also dropped Bootstrap's --bs-btn-focus-shadow-rgb ring). */
#mapa-sort-desc:focus-visible,
#mapa-sort-asc:focus-visible,
.cockpit-drill-btn:focus-visible {
  outline: 2px solid var(--positive);
  outline-offset: 2px;
}
.mapa-ranking__item:focus-visible {
  outline: 2px solid var(--positive);
  outline-offset: -2px;
  border-radius: var(--bs-border-radius);
}

/* visually-hidden, screen-reader-only (table captions, etc.) */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding:0; margin:-0;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}

/* ==========================================================================
   24. ANIMATIONS
   ========================================================================== */

@keyframes bi-fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes bi-slideUp {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* @keyframes bi-shimmer removido — sem consumidores (skeleton unificado no Bootstrap). */

/* ==========================================================================
   26. DRE TOGGLE RESUMIDO/DETALHADO
   ========================================================================== */

/* ==========================================================================
   27. MAPA DE FATURAMENTO POR ESTADO
   ========================================================================== */

.mapa {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap:var(--bi-space-lg);
  align-items: stretch;
}

/* map column fills the card height so the choropleth is tall (not a wide-short
   strip) at full width; the legend is docked over the map's bottom-left as a
   compact chip (não mais uma barra solta de largura total abaixo do mapa). */
.mapa__map-col {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.mapa__map-wrap {
  flex: 1 1 auto;
  min-height: 17.5rem;
  border-radius: var(--bi-radius-md);
  overflow: hidden;
  /* Cria CONTEXTO DE EMPILHAMENTO. Sem ele, os panes do Leaflet (z-index 400) e
     seus controles (1000) são resolvidos contra a raiz da página e cobrem a
     topbar: dropdowns de filtro e o calendário do flatpickr abrem por baixo do
     mapa. `overflow:hidden` NÃO cria contexto — `position` + `z-index`
     numérico criam. Corrige /faturamento/ pelo mesmo caminho. */
  position: relative;
  /* z-index:0 + position:relative = SC deliberado: confina panes Leaflet (400) e
     controls (1000) abaixo do conteúdo. NÃO remover position/z — reabre o vazamento. */
  z-index: 0;
  /* Confina as panes do Leaflet (overlayPane z-index 400) num stacking context
     próprio, abaixo do command-bar sticky (z-index 200). Sem isto o choropleth
     pinta sobre os filtros ao rolar a página. */
  isolation: isolate;
}

#mapa-map-wrap.leaflet-container,
#mapa-map-wrap {
  background: var(--bi-bg-surface) !important;
  border-radius: var(--bi-radius-md);
  font-family: var(--bi-font-sans);
}

/* Fullscreen map — class-driven (.is-fullscreen), set by faturamento.js. The
   class (not :fullscreen) carries the layout so it works on every device incl.
   iOS Safari, where the Fullscreen API can't target a <div>. #card-mapa IS the
   FCDS .card (no descendant .cardbox / .cardbox__body); it holds .card-hd + .mapa. */
#card-mapa.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  margin:0;
  width: auto;
  height: auto;
  max-width: none;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  background: var(--bi-bg-surface);
  padding:var(--bi-space-md);
  overflow: hidden;
}

#card-mapa.is-fullscreen .mapa {
  flex: 1;
  min-height: 0;
  align-items: stretch;
}

#card-mapa.is-fullscreen .mapa__map-wrap {
  height: 100%;
}

#card-mapa.is-fullscreen .mapa__ranking {
  height: 100%;
  overflow-y: auto;
}

.mapa__tooltip {
  font-size: var(--fonte-pequena);
  min-width: 10rem;
  line-height: 1.5;
}

.mapa__tooltip-uf {
  font-weight: 500;
  font-size: var(--fonte-corpo);
  margin-bottom:var(--bi-space-3xs);
}

.mapa__pills {
  display: flex;
  gap:var(--bi-space-xs);
  margin-bottom:var(--bi-space-md);
}

.mapa__ranking {
  display: flex;
  flex-direction: column;
  gap:var(--bi-space-2xs);
  overflow-y: auto;
}

.mapa-ranking__item {
  display: flex;
  align-items: center;
  gap:var(--bi-space-xs2);
  min-width: 0;
}

.mapa-ranking__uf {
  width: 1.5rem;
  flex-shrink: 0;
  font-weight: 500;
  font-size: var(--fonte-pequena);
  color: var(--bi-text-primary);
  text-align: right;
}

/* ── Barra de proporção ──────────────────────────────────────────────────────
   Trilho + preenchimento com largura em %. Componente compartilhado: três telas
   (contas-a-receber, inadimplência, mapa) escreviam a sua com os MESMOS tokens
   (--line-2, radius -sm) divergindo só em altura, cor e duração da transição —
   divergências que ninguém decidiu, resultado de terem sido escritas em dias
   diferentes por quem não sabia da outra.

   NÃO cobre `.mx-h2h__track` nem `.mb-cell__bar`: essas duas montam sobre o
   `.progress` do Bootstrap e só o tematizam. Já são reuso; trocá-las por CSS
   próprio andaria para trás.

   Calibragem por custom property, não por classe modificadora — a altura e a
   cor variam por chamador, e criar `.barra--fina`/`.barra--verde` só moveria o
   problema para o nome. */
.barra {
  height: var(--barra-altura, 0.25rem);
  background: var(--line-2);
  border-radius: var(--bs-border-radius-sm);
  position: relative;
  min-width: 0;
}
/* Valor NEGATIVO num ranking: mesma magnitude, sentido contrário. Ancorada à
   direita e listrada — a cor continua a mesma de propósito, porque valência
   nunca é só cor (chart-config.js:145) e quem carrega o sinal é o número ao
   lado; a barra carrega a direção. */
.barra__fill--contra {
  margin-left: auto;
  background-image: repeating-linear-gradient(
    -45deg, transparent 0 3px, rgba(255, 255, 255, 0.55) 3px 6px);
}

.barra__fill {
  height: 100%;
  max-width: 100%;
  border-radius: inherit;
  background: var(--barra-cor, var(--command));
  /* 0,4s: as três divergiam (0,5s / 300ms / nenhuma). Um valor só, no meio. */
  transition: width 0.4s ease;
}

.mapa-ranking__bar-wrap { --barra-altura: 0.5rem; flex: 1; overflow: hidden; }

/* ranking rows are now a keyboard-operable proxy for the choropleth */
.mapa-ranking__item {
  cursor: pointer;
  padding:0 0.25rem;
  border-radius: var(--bs-border-radius);
  transition: background .12s;
}
.mapa-ranking__item:hover { background: var(--bi-bg-hover); }
.mapa-ranking__rank {
  width: 1.625rem; flex-shrink: 0; text-align: right; white-space: nowrap;
  font-family: var(--bi-font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fonte-pequena); color: var(--bi-text-muted);
}
.mapa-ranking__share {
  width: 2.625rem; flex-shrink: 0; text-align: right;
  font-family: var(--bi-font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fonte-pequena); color: var(--bi-text-muted);
}

/* metric colour legend for the choropleth (added for WCAG 1.4.1) */
/* map loading / empty / error overlay — covers the map area only (sibling of the
   map-wrap inside the position:relative map-col). Map-shaped, not a generic block. */
.mapa__state {
  position: absolute; inset: 0; z-index: 520;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap:var(--bi-space-sm); padding:var(--bi-space-lg);
  background: var(--bi-bg-surface);
  border-radius: var(--bi-radius-md);
  text-align: center;
}
.mapa__state[hidden] { display: none; }
/* Forma orgânica do loader do mapa; a pulsação vem do Bootstrap .placeholder-glow
   (mapa.js adiciona .placeholder a este elemento) — sem @keyframes mapa-shimmer. */
.mapa__state-skel {
  width: min(62%, 300px); aspect-ratio: 1 / 1; border-radius: 50% 46% 48% 52% / 44% 50% 50% 56%;
  background: var(--line-2);
}
.mapa__state-cap { font-size: var(--fonte-pequena); color: var(--bi-text-muted); display: flex; align-items: center; gap:0.25rem; }
.mapa__state-msg { display: flex; flex-direction: column; align-items: center; gap:0.5rem; color: var(--bi-text-secondary); font-size: var(--fonte-corpo); max-width: 18.75rem; }
.mapa__state-msg i { font-size: 1.5rem; color: var(--bi-text-muted); }

.mapa__state-retry {
  margin-top:0.25rem; padding:0.25rem 0.5rem; border: var(--bs-border-width) solid var(--bi-border-color);
  border-radius: var(--bi-radius-sm); background: var(--bi-bg-surface);
  font-size: var(--fonte-pequena); font-weight: 500; color: var(--bi-text-secondary); cursor: pointer;
}
.mapa__state-retry:hover { background: var(--bi-bg-hover); }

/* docked over the map (bottom-left), compact chip — not a full-width orphan bar */
/* Docked as a slim horizontal strip BELOW the map (in flow), not an absolute overlay:
   the overlay covered the populated south (SP/RS/SC/PR) and clipped the max value.
   Row layout wraps gracefully and gives the mono numbers room. */
.mapa__legend {
  display: flex; flex-flow: row wrap; align-items: center;
  gap:0.25rem var(--bi-space-md);
  margin-top:var(--bi-space-xs2);
  padding:0;
  font-size: var(--fonte-pequena);
}
.mapa__legend[hidden] { display: none; }
.mapa__legend-title { font-weight: 500; color: var(--bi-text-secondary); }
.mapa__legend-scale { display: flex; align-items: center; gap:0.25rem; }
.mapa__legend-ramp { flex: 1; min-width: 6rem; height: 0.5rem; border-radius: var(--bs-border-radius-sm); border: var(--bs-border-width) solid var(--bi-border-color); }
.mapa__legend-min, .mapa__legend-max { font-family: var(--bi-font-mono); color: var(--bi-text-muted); white-space: nowrap; }
.mapa__legend-nodata { display: inline-flex; align-items: center; gap:0.25rem; color: var(--bi-text-muted); }
.mapa__legend-swatch { width: 0.75rem; height: 0.75rem; border-radius: var(--bs-border-radius-sm); border: var(--bs-border-width) solid var(--bi-border-color); display: inline-block; flex-shrink: 0; }

.mapa-ranking__valor {
  flex-shrink: 0;
  font-size: var(--fonte-corpo);
  font-family: var(--bi-font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--bi-text-secondary);
  text-align: right;
  min-width: 3rem;
}

/* ==========================================================================
   29. TABELA FATURAMENTO POR SEGMENTO (Visão Operacional)
   ========================================================================== */

/* .table.table-sm do Bootstrap; sobra o corpo tipográfico da tela. */
.seg-table { font-size: var(--fonte-pequena); }

.seg-table thead th {
  padding:var(--bi-space-xs2) 0.5rem;
  font-family: var(--bi-font-display);
  font-size: var(--fonte-rotulo);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bi-text-secondary);
  border-bottom: 2px solid var(--line);
  white-space: nowrap;
  background: var(--bi-surface-card);
}

.seg-row td {
  padding:var(--bi-space-sm) 0.5rem;
  border-bottom: var(--bs-border-width) solid var(--line);
  vertical-align: middle;
}

.seg-row:last-child td {
  border-bottom: none;
}

.seg-row:hover td {
  background: var(--surf-2);
}

.seg-name {
  font-family: var(--bi-font-display);
  font-weight: 500;
  font-size: var(--fonte-corpo);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--bi-text-primary);
  white-space: nowrap;
}

/* .progress do Bootstrap; só a geometria (altura fina, largura máx, raio) fica
   aqui — width e cor da barra (.progress-bar) são data-driven por linha (JS). */
.seg-progress {
  height: 0.1875rem;
  max-width: 6.25rem;
  --bs-progress-bg: var(--line-2);
  --bs-progress-border-radius: var(--bs-border-radius-sm);
}

/* Linha TODOS */
.seg-todos .seg-name {
  font-weight: 500;
}

.seg-todos td {
  border-bottom: 2px solid var(--line);
  background: var(--surf-2);
}

/* ==========================================================================
   30. TABELA UN — SELEÇÃO PARA CASCATA DE MARGENS
   ========================================================================== */

.seg-row {
  cursor: pointer;
}

.seg-row:hover td {
  background: var(--surf-2);
}

/* Hint no cabeçalho da tabela UN */

/* ==========================================================================
   31. RESPONSIVE
   ========================================================================== */

/* ── Mobile: command bar não é sticky + Row 1 não quebra linha ────────────
   Breakpoint 767.98px = Bootstrap md − 0.02 (alinha com d-md-none/d-md-flex).
   Estender position:static até aqui evita o bloco sticky em landscape phone. */
@media (max-width: 767.98px) {
  /* Row 1 (título + período + buscar + filtros) não pode quebrar linha:
     6 colunas sticky + elementos de controle já consomem toda a tela.
     overflow-x:auto garante acesso sem layout quebrado. */
  .command-bar__filters > .command-bar__row:not(.command-bar__row--colapsavel) {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .command-bar__filters > .command-bar__row:not(.command-bar__row--colapsavel)::-webkit-scrollbar {
    display: none;
  }

  /* Título pode encolher para caber ao lado dos controles */

  /* Rows 2–3 (UN + Sub-seg): ocultas por padrão, abertas pelo botão "Filtros" */
  .command-bar__row--colapsavel {
    display: none;
  }
  .command-bar__row--colapsavel.is-show {
    display: flex;
  }
}

/* ── Viewport baixo (landscape phone): barra de filtros não pode comer a tela ─
   Celular deitado é largo (>768px → layout desktop) mas baixo (~390px). A barra
   desktop (grade multi-ano + UN + sub-segmento) chega a 92% da altura e, sticky,
   nunca sai de cena. Aqui tiramos o sticky e damos teto + scroll interno, sem
   tocar markup nem as classes d-md-* (que são por largura). */

@media (max-width: 576px) {
  .command-bar__filters {
    gap:var(--bi-space-xs);
  }

  /* Esconder labels de filtro — pills são autoexplicativas */
  .filter-group__label {
    display: none;
  }

  /* Título redundante em portrait phone — aba do browser já identifica a página */

  /* ── DataTables toolbar: stack vertical, search ocupa largura total ─────── */
  .datatable .datatable-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap:var(--bi-space-xs);
  }
  .datatable .datatable-toolbar__right {
    display: flex;
    gap:var(--bi-space-xs);
  }
  /* Length select ("Mostrar N entradas") irrelevante em mobile — esconder */
  .datatable .dataTables_length {
    display: none;
  }
  .datatable .dataTables_filter {
    flex: 1;
  }
  .datatable .dataTables_filter label {
    display: flex;
    width: 100%;
    white-space: normal;
  }
  .datatable .dataTables_filter input {
    flex: 1;
    min-width: 0 !important;
    width: 100% !important;
  }
  /* Bottom bar: info + paginação empilhados */
  .datatable .datatable-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap:var(--bi-space-xs);
    padding:var(--bi-space-xs) var(--bi-space-sm);
  }
  /* ─────────────────────────────────────────────────────────────────────── */

  .kpi-band {
    grid-template-columns: 1fr 1fr;
    margin:0 0 var(--bi-space-md);
  }
}

/* ==========================================================================
   26. ESTOQUE — badges e linha clicável
   ========================================================================== */

/* Badge entrada/saída (movimentos) — Entrada/Saída is a record TYPE, not a value
   direction, so these carry no direction hue (neutral, per Step 3 contract). */

/* Badges de cobertura (risco visual): canonical .badge--success/danger/warning/info
   already defined above (~L725) with identical tokens — duplicate block removed. */

/* Table row clicável (drill) */
.row-clickable {
  cursor: pointer;
  transition: background var(--bi-transition-fast);
}
.row-clickable:hover {
  background: var(--bi-bg-hover);
}

.row-clickable:active td {
  background: var(--bi-bg-active);
}

/* Barra secundária de controles (período / toggles / busca) — já era a receita
   exata do .card (glass/sh-glass = surf/none, ver tokens), então virou
   .card.card-body + utilities Bootstrap direto no template (d-flex/flex-row/
   align-items-center/gap-2/flex-wrap/mb-3). Zero residual: a classe
   `.secondary-bar` só permanece na marcação porque a regra mobile de `.vr`
   (abaixo) a usa como seletor ancestral. */

/* ==========================================================================
   25. RESPONSIVE (original section continues)
   ========================================================================== */

@media (max-width: 768px) {
  .kpi-band {
    grid-template-columns: repeat(2, 1fr);
    margin:0 0 var(--bi-space-md);
  }

  /* divisor vertical do topbar de filtros (Bootstrap .vr): esconder quando
     a linha quebra (flex-wrap) — evita traço solto entre grupos empilhados. */
  .command-bar__row .vr,
  .secondary-bar .vr {
    display: none;
  }
}

@media (max-width: 1200px) {
  .kpi-band {
    grid-template-columns: 1.2fr 1.4fr 1fr 1fr;
  }
}

/* MOBILE: the multi-col KPI band variants (5/4/3-col, used by estoques /
   inadimplencia / despesas_comex / fluxo via _kpi_cell.html) must ALSO collapse
   to 2-col on phones. Without this they kept their desktop column count at 390px
   and the secondary cells overlapped ("LIBERADOBLOQUEADO"). Placed after the
   ≤1200 block so it wins by source order. */

/* ==========================================================================
   26. FATURAMENTO — scoped overrides
   All rules here are gated by [data-pagina="faturamento"] so they do not
   leak to sister BI pages. See plan: /root/.claude/plans/inherited-toasting-kahn.md
   ========================================================================== */

/* --- Card header density --- */
.page[data-pagina="faturamento"] .card-header {
  padding:var(--bi-space-xs2) var(--bi-space-md);
}

/* --- Linha TOTAL da tabela de sub-segmento ---
   `.table-group-divider` do Bootstrap desenha uma régua de 2px no topo do
   <tfoot>, e a linha de total encostava nela com inset 0. A folga vai na
   classe própria `.fcds-tot` (emitida por faturamento-fcds.js) em vez de no
   `.table-group-divider`, que é do Bootstrap e serve outras páginas. */
.page[data-pagina="faturamento"] .fcds-tot > tr > * {
  padding-top:var(--bi-space-xs);
}

/* Valor da tabela de sub-segmento numa linha só: com NOTAS e TICKET MÉDIO (#434)
   o quadro de 7 colunas a 1366 partia "R$ / 7,17 / mi" em três. Sem largura,
   o quadro rola na horizontal — coluna nunca some. */
.page[data-pagina="faturamento"] #fcds-units-mount td .font-monospace {
  white-space:nowrap;
}

/* Sinais Operacionais: o override de .kpi-tile que morava aqui morreu junto
   com a classe (nenhum markup vivo — ver a nota na seção 7). */

/* --- Evolução Temporal: tighten chart heights --- */
.page[data-pagina="faturamento"] [data-bi-section="evolucao-faturamento"] .chart--short {
  height: 13.75rem;
}
.page[data-pagina="faturamento"] [data-bi-section="evolucao-margem"] .chart--short {
  height: 10rem;
}

/* --- Top Produtos: chart fills the row height (driven by the Evolução stack),
       no fixed cap → no dead whitespace. See the flex-fill block below. --- */

/* --- Top Clientes + Mapa: the data-bi-section element IS the FCDS .card
       (card-hd + content). Height-bounded in block (f); make both flex columns so
       the list / map+ranking fill or scroll within — no dead whitespace, equal
       heights. --- */
.page[data-pagina="faturamento"] [data-bi-section="mapa-uf"] {
  display: flex;
  flex-direction: column;
}
.page[data-pagina="faturamento"] [data-bi-section="mapa-uf"] > .mapa {
  flex: 1 1 auto;
  min-height: 0;
}
.page[data-pagina="faturamento"] [data-bi-section="mapa-uf"] .mapa {
  grid-template-columns: 2fr 1fr;
}

/* --- Mapa por Estado: responsive header wrap --- */
.page[data-pagina="faturamento"] .mapa__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap:var(--bi-space-sm) var(--bi-space-md);
}

.page[data-pagina="faturamento"] .mapa__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap:var(--bi-space-sm);
  margin-left:auto;
}

@media (max-width: 991.98px) {
  .page[data-pagina="faturamento"] .mapa__controls {
    margin-left:0;
    width: 100%;
    justify-content: flex-start;
  }
  .page[data-pagina="faturamento"] .mapa__actions {
    margin-left:auto;
  }
}

/* :hover base removido — 100% coberto pela def global (5495: color !important) */

/* Canonical active indicator: accent-soft pill (not an underline).
   color/background movidos p/ def global !important (5496); só border-radius sobrevive. */

/* ============================================================
   Contas a Receber — Treasury Board
   ============================================================ */

/* KPI band -------------------------------------------------- */
/* O tape de 3 pilares virou a row de cartões canônica do app (Bootstrap
   .row > .col > .card, igual a despesas/faturamento) — layout, empilhamento no
   mobile e valência de cor saem de utilities. A antiga `.cr-chart-band` (15rem)
   existia porque nenhum degrau da escala canônica servia; hoje a altura sai do
   nº de buckets via biChartConfig.alturaPorCategoria, e a classe saiu. */

/* Board ----------------------------------------------------- */
.cr-board {
  display: flex;
  flex-direction: column;
  gap:0;
}

/* Row ------------------------------------------------------- */
.cr-row {
  display: grid;
  grid-template-columns: 16.25rem 1fr 10rem;
  align-items: center;
  padding:0.5rem var(--bi-space-md);
  border-bottom: var(--bi-border-subtle);
  background: var(--bi-bg-surface);
  transition: background 0.1s;

  animation: cr-row-enter 0.25s ease both;
  animation-delay: calc(var(--i, 0) * 35ms);
}

@keyframes cr-row-enter {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .cr-row { animation-duration: 0ms !important; }
}

.cr-row:hover { background: var(--surf-2); }

/* Direção da linha por TINTA DE FUNDO da família (-subtle), não faixa
   lateral (banimento — DESIGN.md §6). O rgba esmeralda hardcoded que vivia
   aqui saiu junto: valência só via token. Hover (.cr-row:hover) vence e
   vira feedback — a direção continua no rótulo da linha. */
.cr-row--abaixo  { background: var(--negative-subtle); }
.cr-row--acima   { background: var(--positive-subtle); }

/* Identity column */
.cr-row__identity { min-width: 0; }

.cr-row__name-wrap {
  display: flex;
  align-items: center;
  gap:var(--bi-space-xs2);
}

.cr-row__name {
  font-family: var(--bi-font-display);
  font-size: var(--fonte-destaque);
  font-weight: 500;
  color: var(--command);



}

.cr-row__meta {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-corpo);
  color: var(--bi-text-muted);
  margin-top:var(--bi-space-3xs);
  font-variant-numeric: tabular-nums;
}

/* Visual column */
.cr-row__visual { padding:0 var(--bi-space-md); }

.cr-row__valor {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-destaque);
  font-variant-numeric: tabular-nums;
  color: var(--command);
  margin-bottom:0.25rem;
}

.cr-row__meter-wrap {
  position: relative;
  margin-top:var(--bi-space-3xs);
  height: 0.25rem;
}

/* Extras da tela sobre a .barra compartilhada: o marcador de estouro e o
   rótulo de mínimo, que só o ranking de portadores tem. */
.cr-row__meter { --barra-altura: 0.25rem; --barra-cor: var(--positive-text); overflow: visible; }

.cr-row__meter[data-overflow="true"]::after {
  content: '';
  position: absolute;
  right: -2px;
  top: -2px;
  bottom: -2px;
  width: 0.125rem;
  background: var(--positive-text);
  border-radius: 0 var(--bs-border-radius-sm) var(--bs-border-radius-sm) 0;
}

.cr-row__meter-label {
  position: absolute;
  right: 0;
  top: -14px;
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-corpo);
  color: var(--bi-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Status column */
.cr-row__status { text-align: right; }

.cr-row__diff {
  display: block;
  font-family: var(--bi-font-display);
  font-size: var(--fonte-destaque);
  font-weight: 500;
  margin-top:var(--bi-space-3xs);
  font-variant-numeric: tabular-nums;
}

.cr-row__diff--acima  { color: var(--positive-text); }
.cr-row__diff--abaixo { color: var(--negative-text); }

/* Toggle Vencimentos (Não desc. ↔ Descontado) — variante azul, não vermelha */

/* Chart subtitle */
.cr-chart-subtitle {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-corpo);
  color: var(--bi-text-muted);
  letter-spacing: 0.04em;
  margin-top:0;
}

/* Row valor display with filho breakdown */
.cr-row__valor-wrap {
  display: flex;
  align-items: baseline;
  gap:var(--bi-space-sm);
  margin-bottom:0;
}

.cr-row__valor {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-destaque);
  font-variant-numeric: tabular-nums;
  color: var(--command);
}

.cr-row__valor-proprio {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-corpo);
  font-variant-numeric: tabular-nums;
  color: var(--bi-text-muted);
}

/* ============================================================
   Contas a Receber — Layout Containment (proportion refactor)
   ============================================================ */

/* A barra de participação tem teto PRÓPRIO: é limite de componente (uma barra
   de 1.500px não comunica proporção melhor que uma de 480px), não de página.
   Nada mais capa largura — a tela ocupa o espaço disponível. */
.cr-row__meter-wrap {
  max-width: 30rem;
}

/* Títulos a vencer: a grade embaixo do painel, como Produtos e Previsão de
   caixa — sem cartão em volta (dono, 15/09/2026: sem moldura), a folha branca e
   o bloco da grade na altura da janela, para só as linhas rolarem. */
.content:has(> .page[data-pagina="contas_a_receber"]),
.page[data-pagina="contas_a_receber"] { background: #fff; }
.page[data-pagina="contas_a_receber"] .cr-titulos {
  display: flex; flex-direction: column; height: calc(100dvh - 52px); min-height: 420px;
}
/* Teto nas colunas de texto livre: sem ele Representante e Cliente abriam até
   caber o nome inteiro (600px) e a lista rolava o dobro de lado. */
.page[data-pagina="contas_a_receber"] .cr-col-texto { max-width: 12rem; }

/* ============================================================
   Contas a Pagar — grade da casa
   ============================================================ */

/* Mesmo teto do gêmeo Contas a Receber: sem ele Fornecedor e Observação
   abririam até caber o texto inteiro e a lista rolaria de lado. */
.page[data-pagina="contas_a_pagar"] .cp-col-texto { max-width: 12rem; }

/* ============================================================
   Inadimplência — grade da casa (Títulos em Aberto)
   ============================================================ */

/* Mesmo teto dos gêmeos Contas a Pagar/Receber: sem ele Cliente, Representante
   e Observação abririam até caber o texto inteiro e a lista rolaria de lado. */
.page[data-pagina="inadimplencia"] .in-col-texto { max-width: 12rem; }

/* Atraso em vermelho: toda linha aqui já está vencida — a cor escala a
   urgência de cobrar, o mesmo token de severidade que o Aging já usa nesta
   página (--negative-text). */
.page[data-pagina="inadimplencia"] .in-col-atraso {
    color: var(--negative-text);
    font-weight: 600;
}

/* ============================================================
   DESPESAS FINANCEIRAS (PSQ014)
   ============================================================ */

.df-venc--perigo {
    color: var(--negative-text);
    font-weight: 600;
}
.df-venc--aviso {
    color: var(--warning-text);
    font-weight: 600;
}
/* Mapa de cor semântica: perigo->danger, aviso->warning, neutro->info,
   primary->primary. Emitters re-classed in despesas_comex.js. */

@keyframes bi-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* Despesas — doughnut + legenda: deixa a legenda quebrar/encolher no mobile para a
   coluna de % não cortar. (Veio do <style> inline do template, removido na migração
   do KPI band para cards Bootstrap.) */
@media (max-width: 768px) {
    /* legenda do doughnut (despesas + despesas_logistica usam os mesmos IDs) */
    #bi-distribuicao-container { flex-wrap: wrap; }
    #bi-distribuicao-legenda { min-width: 0; font-size: 0.875rem; }
}

/* Override KPI band: 4 colunas iguais (vs default 7) — evita overflow em 1024 */
[data-pagina="despesas_comex"] .kpi-band {
    grid-template-columns: repeat(5, 1fr);
}

@media (max-width: 992px) {
    [data-pagina="despesas_comex"] .kpi-band {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ── Drawer Lote Atual (despesas comex) ────────────────────────────── */
#df-lote-drawer {
  --bs-offcanvas-width: 22.5rem;
}

/* Células de estado por linha (favorito/borderô/pago) — consumidor único
   despesas_comex → namespaced global .df-col-*. */
.df-col-favorito,
.df-col-bordero,
.df-col-pago {
    white-space: nowrap;
    min-width: 2.5rem;
    text-align: center;
}
.df-col-bordero .form-check-input,
.df-col-pago .form-check-input {
    cursor: pointer;
    width: 1rem;
    height: 1rem;
    margin:0;
}
.df-col-bordero .form-check-input:disabled,
.df-col-pago .form-check-input:disabled {
    cursor: default;
}

/* Botão estrela de favorito (df-btn-fav) — consumidor único → global. */
.df-btn-fav {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--ink-4);
    font-size: var(--fonte-destaque);
    padding:0 var(--bi-space-3xs);
    line-height: 1;
    flex-shrink: 0;
    transition: color 0.15s;
}
.df-btn-fav:hover { color: var(--warning); }
.df-btn-fav:disabled { opacity: 0.5; cursor: default; }
.df-btn-fav.df-fav--ativo { color: var(--warning); }

/* Faturamento NF tables freeze identity-only (Ações·Data·NF) via `.stickcols`.
   Keep horizontal drag from scrolling the page on touch. */
@media (max-width:767.98px) {
  .datatable .datatable-scroll { overscroll-behavior-x: contain; }
}
/* Fluxo Bancário: as tabelas usam o primitivo .stickcols canônico (stick--1/
   stick--edge no JS) — border-collapse, offset, divisor, hover, striped e
   total-row vêm todos de lá. Sem regras de coluna congelada por página. */
/* Cor semântica de número ± — CANÔNICA e compartilhada. Substitui a cópia
   ad-hoc .fb-num--* (e é a alvo p/ aposentar .delta.pos/neg, .md.pos/neg,
   .sig.neg, .cr-row__diff--*). */
/* `!important` porque isto é UTILITÁRIO, não componente: a convenção do Bootstrap
   para utilitário de cor (.text-danger e cia. também são !important). Sem isso
   qualquer regra de componente declarada DEPOIS no arquivo vencia por ordem de
   fonte — foi o que aconteceu com .pp-card__dias-num, que anulava o semáforo em
   silêncio (sem erro, sem teste vermelho). */
/* ── Rankings com drill (despesas / despesas-logística) ─────────────────────
   Critique 2026-08-07: o alvo de drill era DIV com cursor:pointer e nada mais —
   sem hover, sem foco, sem teclado. O JS agora emite role="button" + tabindex;
   aqui entram o sinal visual de clicável e o preenchimento da barra, que era
   `transition: width` INLINE (propriedade de layout + inalcançável para
   prefers-reduced-motion — estilo inline não responde a media query). */
.top-item{border-radius:var(--r-xs);transition:background .14s ease}
.top-item:hover{background:var(--surf-2)}
.top-item:focus-visible{outline:2px solid var(--acc);outline-offset:2px;background:var(--surf-2)}
.rank-bar__fill{transition:width .5s ease}
@media (prefers-reduced-motion: reduce){ .rank-bar__fill{transition:none} }
/* Linha única de ranking (redesign 2026-08-07) — mesma anatomia do ranking do
   mapa do faturamento: rank e % em mono/tabular, barra fina `.barra` de
   largura fixa (comprimento comparável entre linhas, não entre cards). */
.toplist__rank{width:1.25rem;flex-shrink:0;text-align:right;font-family:var(--bi-font-mono);font-variant-numeric:tabular-nums;font-size:var(--fonte-pequena);color:var(--bi-text-muted)}
.toplist__share{width:2.875rem;flex-shrink:0;text-align:right;font-family:var(--bi-font-mono);font-variant-numeric:tabular-nums;font-size:var(--fonte-pequena);color:var(--bi-text-muted)}
.toplist__bar{width:64px;flex-shrink:0}
/* Detalhamento em demonstrativo (redesign 2026-08-07): um card, hierarquia
   por tipografia + indentação — grupo é linha forte com faixa, contas
   indentadas, TOTAL com régua no pé (assinatura de demonstrativo). */
/* Anel hairline: os passos claros da rampa (Gerenciais ~16% de opacidade)
   sumiam no fundo — o anel dá contorno sem trair a cor da legenda. */
.gblo__dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex-shrink:0;box-shadow:inset 0 0 0 1px rgba(15,23,42,.18)}
.dstm__grupo{display:flex;align-items:center;gap:.5rem;padding:.4375rem .625rem;margin-top:.25rem;background:var(--surf-2);border-radius:var(--r-xs);cursor:pointer}
.dstm__grupo:first-child{margin-top:0}
.dstm__grupo:focus-visible{outline:2px solid var(--acc);outline-offset:-2px}
.dstm__grupo-nome{font-size:var(--fonte-rotulo);font-weight:500;text-transform:uppercase;letter-spacing:.04em}
.dstm__grupo-total{margin-left:auto;font-size:var(--fonte-destaque);font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap}
.dstm__conta{padding:.5rem 0 .5rem 2.25rem;border-bottom:var(--bi-border);border-radius:var(--r-xs);cursor:pointer;transition:background .14s ease}
.dstm__conta:hover{background:var(--surf-2)}
.dstm__conta:focus-visible{outline:2px solid var(--acc);outline-offset:-2px;background:var(--surf-2)}
.dstm__contas > .dstm__conta:last-of-type{border-bottom:0}
.dstm__valor{font-size:var(--fonte-corpo);font-weight:500;text-align:right;min-width:4.25rem;flex-shrink:0;font-variant-numeric:tabular-nums}
.dstm__itens{background:var(--surf-2);padding:0 12px 8px;margin-left:2.25rem;border-radius:var(--r-xs)}
.dstm__total{display:flex;justify-content:space-between;align-items:center;gap:1rem;margin-top:.5rem;padding:.5rem .625rem 0;border-top:1px solid var(--ink-2);font-weight:500;font-size:var(--fonte-rotulo);text-transform:uppercase;letter-spacing:.04em}
/* Bloco colapsado: controles do header apontariam para corpo escondido. */
.card.is-colapsado [data-oculta-colapsado]{display:none}
/* Destaques do período: tira de callout por severidade, sem card nem
   cabeçalho — fundo -subtle, título -text, descrição rebaixada na mesma
   linha (Regra do Degrau: fill=área, -text=texto, -subtle=fundo). */
.destaque{display:flex;align-items:baseline;gap:.5rem;padding:.4375rem .75rem;border-radius:var(--r-sm);font-size:var(--fonte-corpo);background:var(--surf-2)}
.destaque__dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;align-self:center;background:var(--ink-3)}
.destaque__desc{color:var(--bi-text-muted)}
.destaque--negative{background:var(--negative-subtle)}
.destaque--negative .destaque__dot{background:var(--negative)}
.destaque--negative strong{color:var(--negative-text)}
.destaque--warning{background:var(--warning-subtle)}
.destaque--warning .destaque__dot{background:var(--warning)}
.destaque--warning strong{color:var(--warning-text)}
.destaque--positive{background:var(--positive-subtle)}
.destaque--positive .destaque__dot{background:var(--positive)}
.destaque--positive strong{color:var(--positive-text)}
/* Números comparáveis verticalmente pedem dígito tabular (A Regra do Número
   Tabular) — a tela inteira é coluna de número. */
[data-pagina="despesas"]{font-variant-numeric:tabular-nums}
/* Banda da despesas: 5 células .kpic (herói · variação · 3 grupos) no mesmo
   grid .kpi8 do faturamento — o breakpoint de 8 colunas não serve para 5. */
[data-pagina="despesas"] .despesas-band{margin-bottom:0}
@media(min-width:992px){[data-pagina="despesas"] .despesas-band{grid-template-columns:repeat(5,minmax(0,1fr))}}
[data-pagina="despesas"] .kpic .spark-linha{opacity:.85}
/* Micro-barra de composição do herói (Realizado × Não Contabilizado). */
.despesas-compo{height:6px;border-radius: var(--raio-chip);background:var(--surf-2);overflow:hidden;display:flex;margin-top:.4rem}
.despesas-compo > div{height:100%}

.num--pos { color: var(--positive-text) !important; }
.num--neg { color: var(--negative-text) !important; }
/* Faixa de atenção (entre o verde e o vermelho) — mesma laranja dos gráficos, no
   degrau de TEXTO: .num--* pinta número, e o degrau base (3,40:1) só serve p/ área. */
.num--alerta { color: var(--warning-text) !important; font-weight: 500; }

/* PORT do Bootstrap 5.3 (o build vendorizado é 5.2.3, onde estes utilitários ainda
   não existem). Nomes e semântica idênticos aos de upstream, alimentados pelos
   tokens --bs-secondary-color/--bs-tertiary-color, que apontam para a escada de
   tinta do FCDS. Existem para que `color: var(--ink-3)` deixe de ser declarado
   dentro de cada componente: são ~99 declarações no arquivo que colapsam em dois
   utilitários. Ao subir para o Bootstrap 5.3, APAGUE este bloco — o upstream passa
   a fornecer as mesmas regras a partir dos mesmos tokens. */
.text-body-secondary { color: var(--bs-secondary-color) !important; }
.text-body-tertiary  { color: var(--bs-tertiary-color) !important; }
/* `.fw-medium` também só existe a partir do 5.3 — sem o port ela é no-op
   SILENCIOSA: a classe entra no HTML, ninguém reclama, e o peso cai para 400. */
.fw-medium { font-weight: 500 !important; }
/* Escalas do 5.3 na íntegra (0–5 = 0/.25/.5/1/1.5/3rem), não só os passos usados
   hoje: utilitário pela metade é no-op silenciosa no primeiro consumidor novo. */
.row-gap-0 { row-gap:0 !important; }
.row-gap-1 { row-gap:0.25rem !important; }
.row-gap-2 { row-gap:0.5rem !important; }
.row-gap-3 { row-gap:1rem !important; }
.row-gap-4 { row-gap:1.5rem !important; }
.row-gap-5 { row-gap:3rem !important; }
.column-gap-0 { column-gap:0 !important; }
.column-gap-1 { column-gap:0.25rem !important; }
.column-gap-2 { column-gap:0.5rem !important; }
.column-gap-3 { column-gap:1rem !important; }
.column-gap-4 { column-gap:1.5rem !important; }
.column-gap-5 { column-gap:3rem !important; }
.overflow-y-auto { overflow-y: auto !important; }
.overflow-y-hidden { overflow-y: hidden !important; }
.overflow-y-visible { overflow-y: visible !important; }
.overflow-y-scroll { overflow-y: scroll !important; }
.overflow-x-auto { overflow-x: auto !important; }
.overflow-x-hidden { overflow-x: hidden !important; }
.overflow-x-visible { overflow-x: visible !important; }
.overflow-x-scroll { overflow-x: scroll !important; }

/* ── .caps-label — micro-rótulo em CAIXA ALTA ────────────────────────────────
   O mesmo rótulo (Rótulo 11 + uppercase + tracking + tinta secundária) está
   escrito 58 vezes neste arquivo, com 12 valores diferentes de letter-spacing:
   cabeçalho de tabela, rótulo de filtro, título de painel, rótulo de KPI…
   Uma peça só, com o tracking parametrizado por `--caps-track` para o caso
   raro em que a densidade do bloco pede outro valor. Peso e cor seguem
   utilitário (`fw-bold`, `text-body-secondary`) quando divergem do padrão. */
.caps-label {
  font-size: var(--fonte-rotulo);  /* Rótulo 11 da escala (#541; era o corpo 14) */
  font-weight: 500;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: var(--caps-track, .04em);
  color: var(--ink-3);
}

/* ════════════════════════════════════════════════════════════════════════
   TD dos bancos — pivot drill-down (conta corrente → conta financeira)
   Linha-pai expansível (negrito + caret), linha-filha indentada, Total Geral
   no rodapé. Fiel ao Excel "TD dos bancos".
   ════════════════════════════════════════════════════════════════════════ */
/* Conta-pai: negrito; expansível = clicável */
.fb-td-conta > td {
    font-weight: 500;
}
.fb-td-conta--expansivel {
    cursor: pointer;
}
.fb-td-conta--expansivel:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
}
/* Caret: reserva largura fixa em todas as contas-pai → rótulos alinhados,
   tenham filhas ou não. Sinal só nas expansíveis: + recolhido, − expandido. */
/* Caret = pílula .drill-plus canônica, dirigida pelo aria-expanded da linha
   (sem JS extra). Linhas-pai não-expansíveis viram espaçador 16px p/ alinhar. */
.fb-td-caret {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1rem; height: 1rem; margin-right:0.35em; vertical-align: middle; flex: 0 0 auto;
}
.fb-td-conta--expansivel .fb-td-caret {
    color: var(--ink-2); cursor: pointer;
}
.fb-td-conta--expansivel:hover .fb-td-caret { color: var(--ink); }
.fb-td-conta--expansivel .fb-td-caret { position: relative; }
.fb-td-conta--expansivel .fb-td-caret::before,
.fb-td-conta--expansivel .fb-td-caret::after {
    content: ""; position: absolute; inset: 0; margin: auto; background: currentColor;
    border-radius: 1px; transition: transform .15s ease;
}
.fb-td-conta--expansivel .fb-td-caret::before { width: 11px; height: 2px; }
.fb-td-conta--expansivel .fb-td-caret::after { width: 2px; height: 11px; }
.fb-td-conta--expansivel[aria-expanded="true"] .fb-td-caret::after { transform: scaleY(0); }
@media (prefers-reduced-motion: reduce){ .fb-td-conta--expansivel .fb-td-caret::before, .fb-td-conta--expansivel .fb-td-caret::after { transition: none } }
/* Conta financeira (filha): indentada, peso normal, tom secundário */
.fb-td-cf > td:first-child {
    padding-left:var(--bi-space-xl);
    font-weight: 500;
    color: var(--bi-text-secondary);
}
/* Total Geral: célula congelada casa o cinza do total-row → agora coberto pelo
   primitivo .stickcols tr.tbl__total-row (ver §stickcols). */
/* Botão "Expandir tudo" no header do card */
.fb-td-toggle-all {
    font-size: var(--fonte-pequena);
    white-space: nowrap;
}

/* === Promoted from statement-theme.css (Batch 8) — permanent ownership ===
   These component rules are appended at the END of main.css (the last content
   stylesheet in the per-page load order) so they keep winning over earlier
   main.css + custom.css rules exactly as statement-theme.css did when
   it loaded last. !important and selectors are preserved verbatim. The 4
   SAFE-TO-DROP duplicates (font @import, --color-indicator-*, --color-chart-cat-*, soft borders
   -------------------------------------------------------------------------- */
/* .cardbox saiu daqui — seu base (§6 .cardbox) já define surf/line/--r/none
   idênticos; o !important era resíduo de quando este bloco era statement-theme.css
   (arquivo separado carregado depois). .kpi-band FICA: o !important sobrescreve
   de propósito o raio/sombra do base dela pra casar o "statement glass". */
.kpi-band{
  background:var(--surf) !important;
  border:var(--bs-border-width) solid var(--line) !important;
  border-radius:var(--r) !important;
  box-shadow:none !important;
}

.command-bar__filters{   /* .command-bar (bare) saiu — container não renderizado */
  background:var(--glass) !important;
  /* backdrop-filter removed — see note on .cardbox above */
  border:var(--bs-border-width) solid var(--line) !important;
  border-radius:var(--bi-radius-lg) !important;
  box-shadow:var(--sh-glass) !important;
}

/* ── LINHA SELECIONADA (list-group) ───────────────────────────────────────────
   Fundo `--acc-soft` + borda `--acc-line`: uma só ideia de "isto está
   selecionado" na app inteira. Antes eram três — importar-of caía no
   `.list-group-item.active` de fábrica (fill #0d6efd sólido, texto branco),
   metas tinha override próprio (fill --acc, texto branco) e histórico-preços
   usava `--surf-2` via `.is-focused`.

   Fundo suave + texto escuro em vez de fill sólido + texto branco não é só
   gosto: com texto branco, qualquer regra de hover que clareie o fundo apaga o
   conteúdo — foi exatamente o bug que o override do metas existia para contornar.
   Com texto escuro essa classe de bug não existe. A barra inset marca a linha
   escolhida sem depender de contraste de fundo, igual ao item ativo da sidebar.

   Especificidade (0,2,0) empata com a do Bootstrap e vence por ordem de arquivo
   (custom.css carrega depois de styles.css) — inclusive sobre
   `.list-group-item-action:hover`, que também é (0,2,0) e vem antes. */
.list-group-item.active{
  background:var(--acc-soft);
  border-color:var(--acc-line);
  color:var(--ink);
  box-shadow:inset 3px 0 0 var(--acc);
}
/* Linha inerte: o texto acinzentado do Bootstrap sozinho não diz "não clicável".
   Vale tanto para `.disabled` quanto para o atributo `disabled` de <button>. */
.list-group-item:disabled,
.list-group-item.disabled{ background:var(--surf-2); cursor:not-allowed; }

/* toggle switch → statement */

/* tables, mono numerals */
.tbl,
.dataTable,
table.datatable{ font-family:var(--sans); }
.tnum,[class*="-value"],[class*="__value"]{ font-family:var(--bi-font-mono); font-variant-numeric:tabular-nums; }

/* --------------------------------------------------------------------------
   6. SEGMENTED ABC badges + deltas → statement semantic
   -------------------------------------------------------------------------- */
.text-success{ color:var(--positive-text) !important; }
.text-danger{ color:var(--negative-text) !important; }
/* A terceira, que faltava desde sempre. Sem ela `.text-warning` cai no #ffc107
   de fábrica do Bootstrap — 1,63:1 sobre branco, ilegível como número — e era
   isso que apagava o KPI de R$ 16,4M da previsão de caixa, o "Em breve" do
   forecast e o ponto de alteração pendente da matriz de acesso. `.text-warning`
   é utilitário de TEXTO por definição: não existe uso legítimo dele como
   preenchimento, então o remap é seguro. Ver cores.md §4. */
.text-warning{ color:var(--warning-text) !important; }

/* ==========================================================================
   10. PAGE COHERENCE — give the legacy .cardbox sections the statement glass
   look + an aligned, evenly-inset grid (one visual language across the page).
   ========================================================================== */
/* a) horizontal alignment: inset everything from the page edge equally.
   Gutter applied ONCE: a casca do FCDS (`.content`) já paga os 20px laterais,
   então a `.page` fica sem recuo horizontal (era 24px) para não somar 20+24=44.
   A `.page` guarda só o recuo de baixo.

   Sem `!important` (18/08/2026): a trava impedia qualquer página de repor o
   próprio recuo e obrigava quem precisava a responder com outro `!important`
   (inadimplência) ou a desviar para `margin-right` (dre-gerencial).
   Especificidade normal basta — quem quiser repor, repõe. */
.page{ padding:0 0 var(--bi-space-lg); }
/* MORREU em 18/08/2026: `.page > section{padding-left/right:0 !important}`.
   Existia para a tabela poder encostar nas bordas do cartão, mas atingia 34
   seções em 19 telas — 26 delas sem tabela nenhuma — e colava rótulo, cabeçalho
   e filtro na borda (medido: "Pedidos separados" a 1px em /consulta-separacao/).
   Nenhuma tabela pedia por isso: o `.tbl-wrapper` documenta que sempre vive
   dentro de um `.card` e que o card é quem desenha o contorno, e nenhuma das
   seções medidas rolava na horizontal. Sangria agora é local, no bloco de quem
   a quer, com o par `margin-inline`/`padding-inline`. */
.page .row.g-2{
  --bs-gutter-x:var(--bi-space-md) !important; --bs-gutter-y:var(--bi-space-md) !important;
}

/* c) card header → statement label (small, muted, airy); drop heavy border/accent */

/* tame the section title labels too */

/* d) density caps: tall lists/tables scroll inside the card instead of stretching
   the page. Caps come from FCDS tokens (custom.css) so every scroll tier is
   defined in one place: card-list (--bi-scroll-cap / .card-scroll), table
   (--bi-table-scroll-cap), datatable (--bi-dt-scroll-cap). */
/* Reusable scroll-capped table (shared pattern): a long table scrolls inside its
   card and keeps its column header pinned, instead of stretching the page.
   Vertical sticky header — the metas grid is the reference.
   Override the cap per table with `--bi-table-scroll-max`. */
.tbl-scroll{ max-height:var(--bi-table-scroll-max, var(--bi-table-scroll-cap)); overflow:auto; }
.tbl-scroll thead th{ position:sticky; top:0; z-index:2; background:var(--bi-bg-surface); }
/* Every DataTable renders inside a .datatable-scroll wrapper (the toolbar above it stays
   put). Cap it so long / large-page grids scroll inside the card instead of stretching
   the page, and pin the column-label header row. `thead tr:last-child th` is
   grouped-header-safe: a multi-row (grouped) header pins only the label row, so the
   rows never stack/overlap at top:0. z:10 sits above the body's left-column-sticky
   cells (z 5-9); each page's own col-sticky header rules keep the corner cell on top.
   Override the cap per table with --bi-dt-scroll-max.
   (Replaces the old dead `[data-bi-section="transacoes"] .cardbox__body` cap — the
   FCDS markup has no such element, so the NF grid was stretching the page.) */
.datatable-scroll{ max-height:var(--bi-dt-scroll-max, var(--bi-dt-scroll-cap)); isolation:isolate; }
/* O DataTables põe 6px de margem na tabela (`table.dataTable{margin:6px 0 !important}`, CSS da CDN): dentro da rolagem,
   o cabeçalho grudado descia 6px com o corpo antes de grudar e o Total subia 6px no fim da lista. Sem margem, gruda desde o primeiro pixel. */
.datatable-scroll > table.dataTable{ margin-top:0 !important; margin-bottom:0 !important; }
/* !important: DataTables' own CSS sets `position:relative` on the sort header and
   `.tbl.dataTable thead th{background:transparent !important}` — both would
   otherwise beat this on pages without a left-column-sticky rule. (Sticky still acts
   as the containing block for the sort-arrow ::after, so sorting is unaffected.) */
/* TODAS as linhas do thead grudam, não só a última. Onde há uma 2ª linha (os
   filtros por coluna), `tr:last-child` prendia só ela e deixava a linha de
   TÍTULOS rolar embora — o usuário ficava com as caixas de filtro flutuando sem
   os nomes das colunas em cima. A 2ª linha desce pela altura da 1ª, medida em JS
   (biUtils.recalcularColunasTravadas → --thead-linha1-altura), porque a altura
   depende de fonte/zoom/quebra e não dá para fixar em CSS. Tabela de uma linha
   só: nth-child(2) não casa e nada muda. */
.datatable-scroll thead tr th{ position:sticky !important; z-index:10; background:var(--bi-bg-surface) !important; }
.datatable-scroll thead tr:first-child th{ top:0 !important; }
.datatable-scroll thead tr:nth-child(2) th{ top:var(--thead-linha1-altura, 0px) !important; z-index:9; }
/* Painel de filtro de coluna ABERTO tem de flutuar acima da chrome sticky. Ele é
   `position:fixed` com coordenadas de viewport (biUtils.ancorarDropdown), mas mora
   dentro do <th> — e DOIS ancestrais o prendiam num contexto de empilhamento, o que
   torna o `z-index:100` dele inútil: resolvia lá dentro, pintando no nível do
   ancestral (9) e sumindo atrás da topbar (--z-topbar 900).
     1. .datatable-scroll — `isolation:isolate` (acima), sem z-index → confina tudo
        no nível 0 da página;
     2. o próprio <th> — `position:sticky` + z-index.
   Os dois só relaxam ENQUANTO há painel aberto, então fora disso o empilhamento da
   grade é exatamente o de antes. `overflow` fica intocado de propósito: elemento
   `fixed` não é recortado por overflow de ancestral, só por transform/filter. */
.datatable-scroll:has(.colfilter-multi__panel:not([hidden])){ isolation:auto; }
.datatable-scroll thead tr th:has(.colfilter-multi__panel:not([hidden])){
  z-index:calc(var(--z-topbar) + 1);
}
[data-bi-section="transacoes"] .dataTables_wrapper{ font-size:0.875rem; }

/* e) calm the coloured table cells to the soft palette (already via tokens, but
   force the inline green/red used in transações to the statement tones) */
[data-bi-section="transacoes"] .text-success,
.tbl .text-success{ color:var(--positive-text) !important; }
[data-bi-section="transacoes"] .text-danger,
.tbl .text-danger{ color:var(--negative-text) !important; }

/* ==========================================================================
   11. FULL REFINEMENT — legacy charts, tables, tabs, lists to statement grade
   ========================================================================== */
/* --- tabs (transações) → canonical accent-soft pill (same as fcds.components) --- */


/* Célula de margem (MB/MC) = .progress do Bootstrap; só a geometria responsiva
   da barrinha e o tamanho do rótulo ficam aqui (utilitário do BS não cobre). */
.mb-cell__bar{ height: 0.25rem; width: 3.75rem;
  /* magnitude é neutra de propósito (sem valência verde/âmbar/vermelho): mantém o
     slate do --command em vez do primary azul que o .progress-bar traz por padrão */
  --bs-progress-bar-bg: var(--command); }
.mb-cell__pct{ font-size:var(--bi-fs-body); }
@media (min-width:768px){
  .mb-cell__bar{ width: 3rem; }
  .mb-cell__pct{ font-size:var(--bi-fs-label); }
}


/* Checkbox/radio/switch = Bootstrap ORIGINAL (styles.css), sem recolor FCDS.
   O accent-recolor foi removido a pedido do usuário — NÃO restaurar. */

/* Tabs = .nav-pills do Bootstrap, temadas pela API de variáveis dele (substituem .fcds-tabs) */
/* Só GEOMETRIA e tipografia: as três variáveis de COR (--bs-nav-link-color,
   -hover-color e o par --bs-nav-pills-link-active-*) foram removidas por diretiva
   do usuário — a pill ativa volta ao azul de fábrica do Bootstrap. */
.nav-pills{
  --bs-nav-link-padding-y: var(--bi-space-xs2);
  --bs-nav-link-padding-x: var(--bi-space-md);
  --bs-nav-link-font-size: 0.875rem;
  --bs-nav-link-font-weight: 500;
  --bs-nav-pills-border-radius: var(--r-sm, 11px);
  gap:var(--bi-space-xs2);
  margin-bottom:var(--bi-space-xs);
}

/* --- DataTables → statement table styling --- */
.tbl.dataTable thead th{
  font-size:0.875rem !important; font-weight:600 !important; letter-spacing:.08em; text-transform:uppercase;
  color:var(--bi-text-muted) !important; background:var(--bi-bg-surface) !important; border-bottom:1px solid var(--bi-border-color) !important;
  padding:var(--bi-space-xs2) calc(var(--bi-space-sm) + var(--bi-space-xs2)) var(--bi-space-sm) !important;
}
.tbl.dataTable tbody td{
  font-size:0.875rem !important; color:var(--bi-text-secondary); border-top:1px solid var(--bi-border-color-subtle) !important; border-bottom:0 !important;
  padding:var(--bi-space-sm) calc(var(--bi-space-sm) + var(--bi-space-xs2)) !important; vertical-align:middle;
}
/* `:not()` cobre os DOIS painéis congelados. Só a esquerda estava excluída, e a
   célula congelada à DIREITA caía aqui: fundo transparente + a listra do
   Bootstrap, que é um overlay de 5% de preto — não fundo opaco. Resultado
   medido na fila de separação: `background-color: rgba(0,0,0,0)` nas linhas
   `.odd`, com a data da coluna de trás aparecendo através do botão. */
.tbl.dataTable.table-striped > tbody > tr:nth-of-type(odd)
  > *:not([class*="stick--"]):not([class*="stick-r--"]){ background:transparent !important; }
/* Ver a nota do hover em `.tbl tbody tr:hover td`: o estado é overlay do Bootstrap,
   não fundo opaco. Sem `!important` porque não há mais fundo opaco pra vencer. */
.tbl.dataTable tbody tr:hover > *{ --bs-table-accent-bg: var(--bs-table-hover-bg); }

/* Cabeçalho de bloco do rowGroup (hoje só a inadimplência agrupa: um bloco por
   cliente). O CSS do CDN pinta a linha com rgba(0,0,0,.1) — tarja escura que, em
   clientes de 1-2 títulos, cai quase a cada duas linhas e o olho lê como zebra
   quebrada. O bloco passa a ser marcado por hierarquia e espaço: nome do cliente
   com peso, filete de início de bloco e ar acima. Cor não carrega essa informação. */
.tbl.dataTable tbody tr.dtrg-group,
.tbl.dataTable tbody tr.dtrg-group th{
  background:var(--bi-bg-surface) !important;
  color:var(--bi-text-primary) !important;
  font-size:0.875rem !important; font-weight:600 !important;
  border-top:1px solid var(--bi-border-color) !important;
  padding:var(--bi-space-md) calc(var(--bi-space-sm) + var(--bi-space-xs2)) var(--bi-space-xs2) !important;
}
.tbl.dataTable tbody tr.dtrg-group:first-child th{ border-top:0 !important; padding-top:var(--bi-space-xs2) !important; }
/* O hover marca a linha de título (a unidade acionável). O cabeçalho não é clicável. */
.tbl.dataTable tbody tr.dtrg-group:hover > *{ --bs-table-accent-bg: transparent; }
.tbl.dataTable .tnum,
.tbl.dataTable td[class*="valor"],.tbl.dataTable td[class*="margem"]{ font-family:var(--bi-font-mono); font-variant-numeric:tabular-nums; }

/* Espaço à direita do rótulo para a seta de ordenação do DataTables. As setas
   são ::before/::after absolutas em right:10px; o padding shorthand acima só
   reservava ~8px, então a seta colidia/sobrepunha o texto do cabeçalho. Vale
   para QUALQUER DataTables (mobile e desktop) — especificidade maior que as
   regras de padding acima, então ganha sem depender da ordem. */
.tbl.dataTable thead th.sorting,
.tbl.dataTable thead th.sorting_asc,
.tbl.dataTable thead th.sorting_desc,
.tbl.dataTable thead th.sorting_disabled{
  padding-right:calc(var(--bi-space-sm) + 1rem) !important;
}

/* SETA DE ORDENAÇÃO TORTA — defeito global, medido em 02/09/2026.
   O `dataTables.bootstrap5` desenha ▲/▼ como ::before/::after com
   `font-size:.8em` e `line-height:9px` FIXO. Os 9px foram escolhidos para o
   cabeçalho pequeno do tema do fornecedor; o cabeçalho da FCDS tem 14px, então
   o glifo sai com 11,2px dentro de uma caixa de linha de 9px. Ele transborda
   ~2,2px, e como o ▲ ancora em `bottom:50%` e o ▼ em `top:50%`, as duas caixas
   se sobrepõem sobre a linha média — o par vira um borrão alongado. Vale para
   TODA tabela do app (medido igual em /contas-a-receber/ e /processos-comex/).

   `line-height:1` faz a caixa da linha valer o próprio glifo: o par volta a
   empilhar simétrico em torno do meio. Não é escolha de estilo — é a métrica do
   fornecedor casando com a escala de tipo da casa. */
/* Escopo = o MESMO do fornecedor, sem exigir `.tbl`: só parte das tabelas do
   app carrega essa classe (medido — `#cr-drill-tabela`, `#bi-tabela-registros`,
   `.sim-lista` e outras não carregam), e a métrica errada é do DataTables, não
   da `.tbl`. Escopar em `.tbl` consertava uma parte das telas e deixava a outra
   torta.

   `.dataTable.dataTable` NÃO é redundância: o `<link>` do DataTables é incluído
   no `{% block styles %}` (base_fcds.html linha 38) e portanto carrega DEPOIS do
   custom.css (linha 36). Com a mesma especificidade do seletor do fornecedor
   (0,2,5) quem vence é ele, por ordem. A classe repetida sobe para (0,3,5) e a
   correção passa a valer independente da ordem de carga — sem `!important`. */
table.dataTable.dataTable thead > tr > th.sorting::before,
table.dataTable.dataTable thead > tr > th.sorting::after,
table.dataTable.dataTable thead > tr > th.sorting_asc::before,
table.dataTable.dataTable thead > tr > th.sorting_asc::after,
table.dataTable.dataTable thead > tr > th.sorting_desc::before,
table.dataTable.dataTable thead > tr > th.sorting_desc::after,
table.dataTable.dataTable thead > tr > th.sorting_asc_disabled::before,
table.dataTable.dataTable thead > tr > th.sorting_desc_disabled::after,
table.dataTable.dataTable thead > tr > td.sorting::before,
table.dataTable.dataTable thead > tr > td.sorting::after,
table.dataTable.dataTable thead > tr > td.sorting_asc::before,
table.dataTable.dataTable thead > tr > td.sorting_asc::after,
table.dataTable.dataTable thead > tr > td.sorting_desc::before,
table.dataTable.dataTable thead > tr > td.sorting_desc::after{
  line-height:1;
  font-size:.7em;
}
/* A seta de ordenação é o ícone do app, não o par de glifos ▲▼ do DataTables
   (dono, 15/09): o mesmo `fa-sort`/`fa-sort-up`/`fa-sort-down` da grade da casa,
   num ícone só, no lugar do par. A grade tem o desenho dela e fica de fora. */
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td):is(.sorting, .sorting_asc, .sorting_desc)::before{
  content:none;
}
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td):is(.sorting, .sorting_asc, .sorting_desc)::after{
  content:'\f0dc'; font-family:'Font Awesome 6 Free'; font-weight:900;
  top:50%; bottom:auto; transform:translateY(-50%); line-height:1; font-size:.75em; opacity:.3;
}
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td).sorting_asc::after{ content:'\f0de'; opacity:.8; }
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td).sorting_desc::after{ content:'\f0dd'; opacity:.8; }
/* Coluna com um sentido só: o DataTables mostrava só a metade do par que vale. */
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td):is(.sorting_asc_disabled, .sorting_desc_disabled)::before{ content:none; }
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td):is(.sorting_asc_disabled, .sorting_desc_disabled)::after{
  content:'\f0dd'; font-family:'Font Awesome 6 Free'; font-weight:900; display:block;
  top:50%; bottom:auto; transform:translateY(-50%); line-height:1; font-size:.75em; opacity:.3;
}
table.dataTable.dataTable:not(.grade-tabela) thead > tr > :is(th, td).sorting_desc_disabled::after{ content:'\f0de'; }

/* Desktop refinement (≥768px): standardize the four faturamento DataTables on FCDS type
   tokens + symmetric, tighter padding (recovers the horizontal room a 4–6 col freeze needs),
   right-align numeric headers over their values, and width-cap the long descriptive columns
   to 2 lines. The base rules above are left intact, so mobile renders exactly as before. */
@media (min-width:768px){
  /* Typography unified app-wide on the base .tbl tokens (12px/600 heads, --bi-fs-body
     body, .06em letter-spacing). Only the LAYOUT refinements (tighter symmetric padding,
     numeric right-align) stay here; the former 13px/700 + .04em escape hatch was removed. */
  .tbl.dataTable thead th{
    padding:var(--bi-space-xs2) var(--bi-space-sm) !important;
  }
  .tbl.dataTable thead th.tbl__numeric{ text-align:right; }
  .tbl.dataTable tbody td{
    line-height:1.3;
    padding:var(--bi-space-xs2) var(--bi-space-sm) !important;
  }
  /* Cap the long descriptive columns at the TD level so the table can't park its
     fill-the-container slack as one big inter-column gap on wide screens (the columns
     ballooned to ~283px at 2560px). The table still fills (width:100%); residual slack
     spreads thinly across the remaining columns. */
  .tbl.dataTable td.col-text{ max-width: 15rem; }
  /* 2-line clamp for long text (cliente, representante, sub-segmento, histórico). Lives on an
     inner <div> — `display:-webkit-box` on the <td> itself would drop table-cell layout. Fills
     the (capped) cell so text no longer floats left inside a wider TD. Full value via title (hover). */
  .tbl.dataTable td .cell-clamp2{
    display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
    overflow:hidden; max-width:100%; white-space:normal; overflow-wrap:anywhere;
  }
  /* (Removed escape hatch: the 7-table 13px/700 head override + numeric font-family
     override. Heads/body now follow the unified base .tbl tokens — auditoria P5/ruling 4.) */
  /* Despesas-comex tem cabeçalhos de 2 palavras que quebram em 2 linhas e preenchem a
     largura — reserva uma calha à direita p/ as setas de ordenação (▲▼ em right:10px)
     não sobreporem o texto. Escopo só nas 3 tabelas para não mexer no Faturamento. */
  #df-tabela-previsoes thead th, #df-tabela-abertos thead th, #df-tabela-pagos thead th{
    padding-right:1rem !important;
  }
  
  /* Valor Bruto stays semibold on mobile (the JS span keeps `fw-semibold` so mobile is untouched);
     on desktop force it to the uniform 400. !important needed to beat Bootstrap's .fw-semibold. */
  #bi-tabela-notas td .fw-semibold, #bi-tabela-notas-maes td .fw-semibold,
  #bi-tabela-devolucoes td .fw-semibold{ font-weight:400 !important; }
  /* KILL THE INTER-COLUMN GAP. The table was forced to fill its container (`.tbl{width:100%}`
     + `.datatable table.dataTable{min-width:100%}` + Bootstrap `w-100`), so on screens wider
     than the content the slack inflated columns into gaps (and the col-text max-width couldn't
     hold against width:100%). Size the table to its CONTENT instead: width:max-content (so columns
     are tight and the col-text caps actually apply), max-width:100% so it still scrolls when the
     content is wider than the area. On an ultra-wide monitor the table ends and the rest of the
     card is blank — that is the cost of "no gaps". Desktop-only; mobile keeps the full-bleed w-100. */
  #bi-tabela-notas, #bi-tabela-devolucoes, #bi-tabela-despesas-fundo, #bi-tabela-notas-maes{
    width:max-content !important; max-width:100%; min-width:0;
  }
}

/* ============================================================================
   STICKY / FROZEN COLUMNS — unified
   Replaces the old per-page engines (faturamento `bi-col-sticky` +
   despesas_comex `df-col-sticky`). The visual contract (opacity, z ladder, edge,
   isolation) is pure CSS; only the per-column `left` offset is data-driven, set
   as `--stick-left-N` by biUtils.recalcularColunasTravadas. That helper is
   wired into the standard DataTable `drawCallback` (utils.js), so it recomputes on
   EVERY draw — init, sort, page, filter, AND column-visibility (ColVis) — plus a
   shared resize listener. That `draw.dt` coupling is the fix for the old engine,
   which only re-fired on init/resize/tab-switch and so misaligned after ColVis.
   (Pure-CSS calc() offsets were ruled out: in table-layout:auto a <td>'s width is
   only a hint, so declared widths don't hold and the cumulative lefts drift.)

   Usage: add `stickcols` to the <table>; tag each frozen cell `stick--N`
   (1-based, contiguous from the left) and the LAST frozen cell also `stick--edge`.
   `.datatable-scroll` carries `isolation:isolate` so this z ladder can't fight page
   dropdowns/modals. Placed AFTER the striped/hover rules above so frozen cells read
   opaque by source order, not by an !important pile-up. ======================== */
table.stickcols{ border-collapse:separate; border-spacing:0; }
/* opaque cells so scrolled content never shows through the frozen panel */
.stickcols > tbody > tr > td[class*="stick--"]{ position:sticky; background:var(--bi-bg-surface); }
/* position !important: DataTables sets `position:relative` on SORTABLE sort-headers
   (para a seta ::after), o que vence a sticky e faz a coluna congelada do CABEÇALHO
   scrollar horizontalmente (só a não-ordenável escapava). Mesma armadilha já tratada
   p/ o header vertical em .datatable-scroll (ver acima). Sticky segue como bloco
   contêiner da seta, ordenação intacta. */
.stickcols > thead > tr > th[class*="stick--"]{ position:sticky !important; background:var(--bi-bg-surface); }
/* Célula congelada NÃO repinta no hover: ela mantém a surface opaca (que é o que
   impede o conteúdo rolado de aparecer por baixo) e recebe o mesmo overlay de hover
   da linha, igual às demais. Repintar aqui com o hex antigo empilhava overlay sobre
   #f3f4f7 e deixava a coluna congelada mais escura que o resto da linha. */
/* striped: célula congelada casa a faixa zebra do Bootstrap .table-striped
   (senão a coluna sticky mostra a surface e "quebra" a listra). Genérico. */
.stickcols.table-striped > tbody > tr:nth-of-type(odd) > td[class*="stick--"]{ background:var(--surf-2); }
/* espelho da regra acima para o painel congelado à DIREITA. Faltava: o bloco do
   `stick-r--` foi escrito depois e herdou tudo menos a listra, então a coluna
   fixa ficava branca (ou transparente, sob o DataTables) contra a faixa zebra. */
.stickcols.table-striped > tbody > tr:nth-of-type(odd) > td[class*="stick-r--"]{
  background:var(--surf-2); }
/* linha de total: célula congelada casa o cinza do .tbl__total-row */
.stickcols tr.tbl__total-row > td[class*="stick--"]{ background:var(--surf-2); }
/* per-column left offset — JS-measured (biUtils.recalcularColunasTravadas) */
.stickcols .stick--1{ left:var(--stick-left-1, 0px); }
.stickcols .stick--2{ left:var(--stick-left-2, 0px); }
.stickcols .stick--3{ left:var(--stick-left-3, 0px); }
.stickcols .stick--4{ left:var(--stick-left-4, 0px); }
.stickcols .stick--5{ left:var(--stick-left-5, 0px); }
/* z ladder — leftmost paints over next, header over body, corner wins */
.stickcols > tbody > tr > .stick--1{ z-index:5; }
.stickcols > tbody > tr > .stick--2{ z-index:4; }
.stickcols > tbody > tr > .stick--3{ z-index:3; }
.stickcols > tbody > tr > .stick--4{ z-index:2; }
.stickcols > tbody > tr > .stick--5{ z-index:1; }
.stickcols > thead > tr > th.stick--1{ z-index:15; }
.stickcols > thead > tr > th.stick--2{ z-index:14; }
.stickcols > thead > tr > th.stick--3{ z-index:13; }
.stickcols > thead > tr > th.stick--4{ z-index:12; }
.stickcols > thead > tr > th.stick--5{ z-index:11; }
/* Frozen-panel right edge: hairline PLANO, marcando onde o congelamento acaba.
   Sem sombra — o dono pediu a tela plana e a sombra saiu dos cinco usos.
   Drawn with a ::after pseudo (NOT box-shadow on the cell): Bootstrap `.table-striped`
   paints its zebra with `box-shadow: inset 0 0 0 9999px` on every cell, which would
   override a cell box-shadow and make the divider vanish on striped rows. The pseudo
   is immune. The cells are position:sticky (positioned), so ::after anchors to them. */
.stickcols td.stick--edge::after{
  content:""; position:absolute; top:0; right:0; bottom:0; width:1px; pointer-events:none;
  background:var(--bi-border-color);
}
/* NO CABEÇALHO a borda NÃO pode usar ::after: ele já é do DataTables, que
   desenha ali a seta ▼ (`content:"▼"; top:50%`). Um elemento tem um ::after só,
   e as propriedades se misturavam — o `content` vinha do DataTables (0,2,5) e o
   `bottom:0`, `width:1px`, `background` e `box-shadow` vinham daqui. A seta
   virava um risco vertical de 1px COM SOMBRA, do meio até o fim do th. Era
   isso, e não a métrica da fonte, o borrão que aparecia em toda tabela com
   coluna congelada (medido em 02/09/2026: `::after` de 17,6px de altura na
   coluna de borda contra 9,8px nas demais).

   No th não há zebra do Bootstrap — que é o motivo de o ::after existir nas
   células do corpo —, então borda e sombra no próprio elemento resolvem sem
   disputar o pseudo. */
.stickcols th.stick--edge{
  border-right:1px solid var(--bi-border-color);
}

/* ── RIGHT-edge frozen columns (mirror of the left freeze) ──────────────────────
   For wide worksheet/matrix tables that pin a trailing TOTAL column. Tag each frozen
   cell `stick-r--N` (1-based, contiguous from the RIGHT; --1 = rightmost) and the
   leftmost right-frozen cell also `stick-r--redge` (draws the divider on its LEFT).
   JS sets `--stick-right-N`, accumulated right→left, in the same single pass as the
   left offsets (biUtils.recalcularColunasTravadas). Selectors are disjoint from the
   left set ("stick-r--" never contains "stick--"). ============================ */
.stickcols > tbody > tr > td[class*="stick-r--"]{ position:sticky; background:var(--bi-bg-surface); }
.stickcols > thead > tr > th[class*="stick-r--"]{ position:sticky; background:var(--bi-bg-surface); }
/* Sem repintura no hover — mesma razão da coluna congelada à esquerda (ver acima). */
.stickcols .stick-r--1{ right:var(--stick-right-1, 0px); }
.stickcols .stick-r--2{ right:var(--stick-right-2, 0px); }
.stickcols .stick-r--3{ right:var(--stick-right-3, 0px); }
/* z ladder — right panel sits above body cells and above the left stack's edges */
.stickcols > tbody > tr > .stick-r--1{ z-index:8; }
.stickcols > tbody > tr > .stick-r--2{ z-index:7; }
.stickcols > tbody > tr > .stick-r--3{ z-index:6; }
.stickcols > thead > tr > th.stick-r--1{ z-index:18; }
.stickcols > thead > tr > th.stick-r--2{ z-index:17; }
.stickcols > thead > tr > th.stick-r--3{ z-index:16; }
/* divider on the LEFT edge of the right-frozen panel */
.stickcols td.stick-r--redge::before{
  content:""; position:absolute; top:0; left:0; bottom:0; width:1px; pointer-events:none;
  background:var(--bi-border-color);
}
/* Espelho do defeito da borda esquerda: aqui o pseudo é o `::before`, que o
   DataTables usa para a seta ▲. No cabeçalho a borda vai no próprio elemento. */
.stickcols th.stick-r--redge{ border-left:1px solid var(--bi-border-color); }

/* ── Standard drill/expand affordance ──────────────────────────────────────────
   The system-wide cue that an element opens a drill/detail panel. Put `.drill-plus`
   on a <button> (or span[role=button]) inside the drillable header/row/cell. Subtle by
   default, accent on hover/focus; keyboard-focusable. One affordance, every surface. */
/* Sem caixa: o dono vetou a pílula com borda — o símbolo fica nu, cor
   rebaixada que sobe pra ink no hover da linha/foco. Área de clique segue
   16px (e a linha inteira também é clicável em todo caller). */
.drill-plus{
  display:inline-flex; align-items:center; justify-content:center;
  width: 1rem; height: 1rem; padding:0; flex:0 0 auto; cursor:pointer;
  border:0; border-radius:var(--bs-border-radius);
  background:transparent; color:var(--ink-2);
  transition:color .15s ease;
}
/* Ícone canônico: cruz DESENHADA em CSS (dois traços de 1.5px, cor herdada) —
   o dono quer o símbolo +, mas o glifo FA 900 era gordo demais. Ao abrir, o
   traço vertical colapsa (morph + → −). Estado pela classe .is-open. */
.drill-plus{ position:relative; }
.drill-plus::before, .drill-plus::after{
  content:""; position:absolute; inset:0; margin:auto; background:currentColor;
  border-radius:1px; transition:transform .15s ease;
}
.drill-plus::before{ width:11px; height:2px; }
.drill-plus::after{ width:2px; height:11px; }
.drill-plus.is-open::after{ transform:scaleY(0); }
/* O mesmo morph dirigido pelo estado NATIVO, sem classe: <details open> e
   aria-expanded (no próprio controle ou no ancestral que o contém). É o que
   deixa o CRM inteiro — blocos da ficha, linha do histórico, detalhe do
   acompanhamento, raia do funil no telefone — usar UM vocabulário de
   "abre isto" (19/08/2026: o dono vetou os chevrons e os ▸). */
details[open] > summary .drill-plus::after,
[aria-expanded="true"] .drill-plus::after,
.drill-plus[aria-expanded="true"]::after{ transform:scaleY(0); }
@media (prefers-reduced-motion: reduce){ .drill-plus::before, .drill-plus::after{ transition:none } }
.drill-plus:hover{ color:var(--ink); }
.drill-plus:focus-visible{ outline:2px solid var(--info); outline-offset:1px; color:var(--ink); }

/* ── Directional cell tint (cores.md DIRECTION channel) ─────────────────────────
   Worksheet/matrix result cells whose value carries good/bad meaning. Background uses
   the *-subtle tint, text the AA-safe *-text token (warning uses the deeper indicator
   alias for small-text contrast). ALWAYS pair with a non-color backup (sign/icon) in
   the cell content — never hue alone (cores.md §5, colorblind-safe). ================ */

/* ── Faturamento wide tables (Notas Fiscais / Notas Mães): RESPONSIVE TIERED FREEZE ──
   Desktop-only. Identity Ações·Data·NF (--1..--3) freeze from 768px; Valor Bruto (--4)
   joins at 1024px; MB·MC (--5·--6) join at 1360px. Columns release from the right edge
   inward as the viewport narrows, keeping the frozen panel ≲40% of the table at every
   width. NF keeps `stick--edge` (its mobile identity pin); on desktop the frozen-panel
   divider is hidden on NF and redrawn on the LAST frozen column of the active tier.
   The phone block below (≤767px OR ≤540px height) is UNCHANGED: every tier here carries
   `and (min-height: 33.8125rem)` so short-landscape phones never hit it, and none use
   `!important`, so the phone block's `!important` always wins there. The cumulative
   `--stick-left-N` offsets are set for ALL six cols by biUtils.recalcularColunasTravadas
   regardless of tier; a column rendered `static` simply ignores its unused `left`.
   Reusable divider recipe is duplicated per tier (CSS can't @apply a pseudo). */
@media (min-width:768px) and (min-height:541px){
  /* extra left offsets (cols 1–4 left come from the base rules above) + full z ladder */
  #bi-tabela-notas .stick--5,#bi-tabela-notas-maes .stick--5{ left:var(--stick-left-5,0px); }
  #bi-tabela-notas .stick--6,#bi-tabela-notas-maes .stick--6{ left:var(--stick-left-6,0px); }
  #bi-tabela-notas > tbody > tr > .stick--4,#bi-tabela-notas-maes > tbody > tr > .stick--4{ z-index:3; }
  #bi-tabela-notas > tbody > tr > .stick--5,#bi-tabela-notas-maes > tbody > tr > .stick--5{ z-index:2; }
  #bi-tabela-notas > tbody > tr > .stick--6,#bi-tabela-notas-maes > tbody > tr > .stick--6{ z-index:1; }
  #bi-tabela-notas > thead > tr > th.stick--4,#bi-tabela-notas-maes > thead > tr > th.stick--4{ z-index:13; }
  #bi-tabela-notas > thead > tr > th.stick--5,#bi-tabela-notas-maes > thead > tr > th.stick--5{ z-index:12; }
  #bi-tabela-notas > thead > tr > th.stick--6,#bi-tabela-notas-maes > thead > tr > th.stick--6{ z-index:11; }
  /* NARROW (768–1023): only identity frozen — Valor·MB·MC scroll with the data.
     Only `position:static` (static cells ignore `left`); we must NOT clear `left` here, or the
     wide tier — which re-sets position:sticky but inherits `left` from above — would lose its
     offset and fail to pin. */
  #bi-tabela-notas .stick--4,#bi-tabela-notas .stick--5,#bi-tabela-notas .stick--6,
  #bi-tabela-notas-maes .stick--4,#bi-tabela-notas-maes .stick--5,#bi-tabela-notas-maes .stick--6{
    position:static;
  }
}
/* MID (≥1024): freeze Valor Bruto (--4); divider moves to after Valor, off NF */
@media (min-width:992px) and (min-height:541px){
  #bi-tabela-notas .stick--4,#bi-tabela-notas-maes .stick--4{ position:sticky; left:var(--stick-left-4,0px); }
  #bi-tabela-notas .stick--edge::after,#bi-tabela-notas-maes .stick--edge::after{ display:none; }
  #bi-tabela-notas td.stick--4::after,#bi-tabela-notas th.stick--4::after,
  #bi-tabela-notas-maes td.stick--4::after,#bi-tabela-notas-maes th.stick--4::after{
    content:""; position:absolute; top:0; right:0; bottom:0; width:1px; pointer-events:none;
    background:var(--bi-border-color);
  }
}
/* WIDE (≥1360): also freeze MB·MC (--5·--6); divider moves to after MC%, off Valor */
@media (min-width:1400px) and (min-height:541px){
  #bi-tabela-notas .stick--5,#bi-tabela-notas .stick--6,
  #bi-tabela-notas-maes .stick--5,#bi-tabela-notas-maes .stick--6{ position:sticky; }
  #bi-tabela-notas td.stick--4::after,#bi-tabela-notas th.stick--4::after,
  #bi-tabela-notas-maes td.stick--4::after,#bi-tabela-notas-maes th.stick--4::after{ display:none; }
  #bi-tabela-notas td.stick--6::after,#bi-tabela-notas th.stick--6::after,
  #bi-tabela-notas-maes td.stick--6::after,#bi-tabela-notas-maes th.stick--6::after{
    content:""; position:absolute; top:0; right:0; bottom:0; width:1px; pointer-events:none;
    background:var(--bi-border-color);
  }
}
/* Phones (narrow portrait OR short landscape): collapse the frozen panel to just
   the edge/identity column so it stops eating the viewport. The other frozen cols
   go static and scroll with the data; only `.stick--edge` (the NF number — the
   row identity) stays pinned at left:0. The max-height clause catches landscape
   phones, whose width (~844px) would otherwise miss a max-width breakpoint. */
@media (max-width:767.98px), (max-height: 540px){
  /* Body cells of the non-edge frozen cols scroll horizontally (free the width). */
  .stickcols > tbody > tr > td[class*="stick--"]:not(.stick--edge){ position:static !important; }
  /* Header cells must KEEP their vertical pin (top:0) — only drop the horizontal
     freeze (left:auto). Forcing them static killed the sticky header row. */
  .stickcols > thead > tr > th[class*="stick--"]:not(.stick--edge){ left:auto !important; }
  .stickcols .stick--edge{ left:0 !important; }
}

/* REMOVIDO — `.content .card{width:100vw;margin-inline:calc(50% - 50vw)}` no mobile
   (0185647c). Valia quando toda seção do celular era UM card de linha inteira; quando as
   bandas de KPI viraram GRADE de cards (`row row-cols-2` em 12 telas, `.kpi8` aqui), a
   mesma regra passou a estourar card de meia linha: 100vw dentro de trilha de ~189px =
   duas cartas sobrepostas, a da esquerda fora da tela. `body{overflow-x:clip}` engolia o
   estouro sem barra de rolagem, então só se via conteúdo decepado. NÃO reintroduzir: o
   card no mobile é o card canônico, e a goteira lateral é do `.content` (§5). */

/* ── Faturamento mobile layout (rides on the full-width drawer shell) ─────────
   Gate matches the shell mobile gate (760/540) so it's active in both orientations. */
@media (max-width:767.98px), (max-height: 540px){
  /* UF map: stack map over ranking — side-by-side clips the ranking values at phone
     width. Source order is map→ranking, so no `order` (preserves focus order). */
  .page[data-pagina="faturamento"] [data-bi-section="mapa-uf"] .mapa{ grid-template-columns:1fr; gap:var(--bi-space-md); }
  .mapa__map-wrap{ min-height: 13.75rem; }
  .mapa-ranking__share{ width:auto; min-width: 2.625rem; }
  #card-mapa.is-fullscreen .mapa{ grid-template-columns:3fr 2fr !important; }
  /* Nem o CARD nem o GAP da grade são retocados aqui: o card fica com o padding
     canônico (8/16/16) em qualquer largura e `--gap` já é 0.5rem — a regra que
     "apertava" o gap no mobile repetia o valor padrão e foi removida. O que o mobile
     ajusta é a goteira da superfície (.content, §5), não o componente. */
  /* The data grids themselves reach the band edges (cancel the card's inset) so the
     table uses the full width; the toolbar/tabs above keep the inset as chrome. The
     band's hairlines still frame the section, so it reads coherent, not detached.
     Applies to every page's table-wrapper / ranking-table wrapper. */
  .content .tbl-wrapper{
    margin-left:calc(-1 * var(--bi-space-md)); margin-right:calc(-1 * var(--bi-space-md));
    /* the wrapper's own 16px radius + side borders would show as rounded corners at the
       band edges — drop them; the band frames the table. */
    border-radius:0; border-left:0; border-right:0;
  }
}

/* DataTables chrome (info / paginate) → minimal light; busca e "por pág." são form-control/form-select-sm de fábrica (#454) */
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter{ font-size:0.875rem; color:var(--bi-text-muted); }
/* PAGINAÇÃO: sem regra nenhuma. Moravam aqui ~45 linhas que repintavam link,
   página ativa, hover e desabilitado, e depois soldavam as células com borda
   compartilhada e cantos retos — tudo com !important, e tudo reimplementando o
   que o .pagination do Bootstrap já faz de fábrica (inclusive a solda, via
   `.page-item:not(:first-child) .page-link{margin-left:-1px}`). Apagado por
   diretiva do usuário: a paginação é a do Bootstrap, sem intermediário. */

/* --- charts: give them consistent comfortable heights --- */
.chart{ position:relative; }


/* ==========================================================================
   12. LAYOUT REFINEMENT — cards become true flex columns so their charts FILL
   the card (no dead vertical voids), each row's two columns end at the same
   baseline, and one column drives the row height.
   ========================================================================== */

/* b) Top-20 Produtos: the section IS the FCDS .card (card-hd + .chart--xl).
   Make it a flex column so the chart fills the bounded card height
   (maintainAspectRatio:false → 20 bars compress to fit, no whitespace). */
[data-bi-section="top-produtos"]{ display:flex; flex-direction:column; }

/* f) Bound the two mixed-content rows: a tall element (20-bar chart / 20-row
   client list) must not balloon its neighbour (evolução stack / choropleth).
   The data-bi-section element is itself the .card. Fixed row height + internal
   fill/scroll; released on mobile (<993px) where cards stack to span-12. */
@media (min-width:992px) {
  /* Row A — Sub-segmento + Evolução de Faturamento: equal height via the row's
     align-items:stretch (.fcds-row-eq); no fixed height so the capped sub-board
     and the chart match the taller of the two. */
  [data-pagina="faturamento"] [data-bi-section="mapa-uf"] { height: 33.25rem; }
  [data-pagina="faturamento"] [data-bi-section="mapa-uf"] .mapa__ranking { overflow-y: auto; }
}

/* c) Evolução (two stacked cards on the right) FILLS to the Top-20 height:
   each card's body grows and its chart fills it — no more void band. */
[data-bi-section="evolucao-faturamento"] #bi-evolucao-view-grafico,
[data-bi-section="evolucao-faturamento"] #bi-evolucao-view-sazonalidade{ flex:1 1 auto; display:flex; flex-direction:column; min-height:0; }
[data-bi-section="evolucao-faturamento"] .chart,
[data-bi-section="evolucao-margem"] .chart{ flex:1 1 auto; height:auto !important; min-height: 11.875rem; }
[data-bi-section="evolucao-faturamento"] #heatmap{ flex:1 1 auto; }

/* d) Clientes ↔ Mapa row: both fill to equal height; the clientes bar list and
   the map+ranking get matching internal scroll instead of stretching the page. */
[data-bi-section="mapa-uf"] .card-body{ flex:1 1 auto; display:flex; flex-direction:column; min-height:0; }
[data-bi-section="mapa-uf"] .mapa{ flex:1 1 auto; min-height: 21.25rem; }

/* e) section headers with inline toggles align like statement card-hd (label
   left, controls right, shared baseline) instead of wrapping. */

.card-header .card-title{ margin-right:auto; }

/* ==========================================================================
   PAGE-LOCAL STYLES (Fase 3 — extraídos de blocos <style> inline dos templates;
   token-clean, escopados por [data-pagina]/classes próprias. Movidos p/ cá para
   sair do HTML; cascata idêntica — main.css já era carregado por essas páginas).
   ========================================================================== */

/* ── catalogo ── */
.mermaid-container { overflow: auto; min-height: 25rem; }
.mermaid-container .mermaid { background: transparent; text-align: center; }
.catalogo-legenda {
    display: flex; gap:var(--bi-space-md); flex-wrap: wrap;
    font-size: var(--fonte-corpo); color: var(--ink-2);
}
.catalogo-legenda span { display: inline-flex; align-items: center; gap:var(--bi-space-2xs); }
.catalogo-legenda i { width: 0.625rem; height: 0.625rem; border-radius: 50%; flex-shrink: 0; }
.catalogo-legenda .swatch-codori  { background: var(--cat-1); }
.catalogo-legenda .swatch-codfam  { background: var(--cat-3); }
.catalogo-legenda .swatch-centro  { background: var(--cat-2); }
#bi-segpills { flex-wrap: wrap; }
.catalogo-empty { color: var(--ink-3); font-style: italic; padding:var(--bi-space-xl); text-align: center; }

/* ── despesas_logistica ── */

/* despesas_logistica: bloco `grid-column:1/-1` removido — os tiles são .card em
   .row row-cols-* (flexbox); grid-column em flex-item é inerte (regra morta). */
/* #bi-distribuicao-* consolidado acima (global; despesas + despesas_logistica) */

.fc-via { white-space: nowrap; }
.fc-via > i {
    margin-right: .4em;
    color: var(--bi-text-muted);
    width: 1em;
    text-align: center;
    flex: none;
}
.fc-sit {
    display: inline-flex;
    align-items: baseline;
    gap:0.4em;
    white-space: nowrap;
}
.fc-zero { color: var(--bi-text-muted); }
.fc-atraso { color: var(--negative-text); font-weight: 500; }
/* Banner de status do refresh: cantos arredondados como os cards (não a faixa
   full-bleed quadrada herdada do despesas), borda completa + leve sombra. */
.fc-banner {
  border-radius: var(--bi-radius-md);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
}

/* ==========================================================================
   AUDITORIA DA TELA (09/08/2026) — o modal e o popover dos verbetes.
   `.ajuda-markdown` é o corpo do modal (bi/components/modal_ajuda.html).
   Não é markdown renderizado: é o envelope daquela carga, então o estilo mora
   aqui (regra dura: nenhum .css novo) e usa os mesmos tokens do resto do app.
   ========================================================================== */
/* O recorte primeiro: sem "qual empresa, qual período" nenhum número abaixo é
   defensável. Grade de pares em vez de frase corrida — é para conferir, não ler. */
/* ── VERBETE NO PONTO DE USO ────────────────────────────────────────────────
   Popover ancorado ao número clicado, no lugar do modal. O modal cobria 52% da
   tela e escurecia o resto: quem apontava um número perdia de vista o número e a
   tabela em volta — o contrário do "abrir o verbete no ponto de uso" que a regra
   pede. `position: fixed` e filho de <body> porque o número pode viver dentro de
   uma tabela que rola, onde um absolute seria recortado. Compartilhado pelas três
   telas que publicam verbetes (cockpit, inadimplência e produtividade). */
.ajuda-pop{
  position:fixed;z-index:var(--z-modal);width:min(24rem,calc(100vw - 1rem));
  background:var(--surf);border:1px solid var(--line-3);border-radius:var(--r);
  box-shadow:0 8px 28px rgba(15,23,42,.16);padding:.75rem .875rem;
  font-size:var(--fonte-corpo);line-height:1.5;color:var(--ink-2);
}
.ajuda-pop__topo{display:flex;align-items:baseline;justify-content:space-between;gap:.75rem;
  padding-bottom:.4rem;margin-bottom:.5rem;border-bottom:1px solid var(--line)}
.ajuda-pop__titulo{margin:0;font-size:var(--fonte-corpo);font-weight:500;color:var(--ink)}
/* O valor é o motivo do clique: vem junto do título, não escondido no corpo.
   QUEBRA DE LINHA (09/09/2026): era `nowrap`, que servia enquanto todo valor
   era um número curto ("R$ 8.038.927,61"). O verbete do percentual de
   inadimplência traz a conta inteira ("2,7% — R$ 7,1 mi vencidos … sobre
   R$ 269,3 mi faturados de … a …") e a linha vazava o balão de 24rem por cima
   do board. `wrap` no topo para o valor descer para a própria linha quando não
   couber ao lado do título. */
.ajuda-pop__topo{flex-wrap:wrap}
/* Verbete `resumido` (09/09/2026): sem conceito/fórmula/listas embaixo, a borda
   do topo separaria o título de nada. */
.ajuda-pop__topo--resumido{border-bottom:0;padding-bottom:0;margin-bottom:.35rem}
.ajuda-pop__valor{margin:0;font-family:var(--bi-font-mono);font-variant-numeric:tabular-nums;
  font-size:var(--fonte-corpo);font-weight:500;color:var(--ink);white-space:normal}
/* O MEMORIAL DE CÁLCULO (09/09/2026). A primeira tentativa foi uma string com
   `\n` em fonte monoespaçada: os três números saíam com o mesmo peso, a prosa
   lia como código e o RESULTADO — que é o que se procura — não se destacava de
   nada. Agora é uma grade de três colunas, que é como demonstrativo financeiro
   se lê: operador num vão estreito, rótulo à esquerda com o detalhe embaixo,
   número alinhado à DIREITA numa coluna só. O filete e o corpo maior separam o
   resultado dos operandos.

   `max-content` na coluna do número (e não `1fr`) porque é ele que dita a
   largura: alinhamento à direita só significa alguma coisa se os três números
   compartilharem a mesma borda direita. */
.ajuda-calc{display:grid;gap:.1rem}
.ajuda-calc__linha{display:grid;grid-template-columns:.9rem 1fr max-content;
  align-items:baseline;gap:.25rem .5rem;padding:.25rem 0}
.ajuda-calc__op{color:var(--ink-3);font-size:var(--fonte-pequena);text-align:center}
.ajuda-calc__rotulo{display:flex;flex-direction:column;color:var(--ink-2);font-size:var(--fonte-corpo)}
.ajuda-calc__detalhe{color:var(--ink-3);font-size:var(--fonte-pequena);line-height:1.2}
.ajuda-calc__numero{font-variant-numeric:tabular-nums;text-align:right;
  color:var(--ink);font-size:var(--fonte-corpo);font-weight:500;white-space:nowrap}
/* O RESULTADO é o motivo do clique: ganha o filete que fecha a conta e o corpo
   que os operandos não têm. */
.ajuda-calc__linha--resultado{border-top:1px solid var(--line);margin-top:.15rem;
  padding-top:.4rem}
.ajuda-calc__linha--resultado .ajuda-calc__rotulo{color:var(--ink);font-weight:500}
.ajuda-calc__linha--resultado .ajuda-calc__numero{font-size:var(--fonte-destaque);font-weight:500}
.ajuda-pop__conceito{margin:0 0 .5rem}
/* A fórmula é literal — monoespaçada, em caixa própria, para não se ler como frase. */
.ajuda-pop__formula{margin:0 0 .5rem;padding:.35rem .5rem;background:var(--surf-2);
  border-radius:var(--bi-radius-xs,.25rem);font-family:var(--bi-font-mono);font-size:var(--fonte-pequena);color:var(--ink)}
.ajuda-pop__nota{margin:0 0 .4rem;font-size:var(--fonte-pequena)}
.ajuda-pop__nota b{color:var(--ink)}
.ajuda-pop__origem{margin:0;font-size:var(--fonte-pequena);color:var(--ink-3)}
.ajuda-pop__mais{margin-top:.5rem;padding:0;border:0;background:none;font:inherit;font-size:var(--fonte-pequena);
  color:var(--chart-azul);cursor:pointer;text-decoration:underline}
.ajuda-pop__mais:focus-visible{outline:2px solid var(--chart-azul);outline-offset:2px;border-radius:2px}

.ajuda-recorte{background:var(--surf-2);border:1px solid var(--line);
  border-radius:8px;padding:.6rem .75rem;margin-bottom:.75rem}
.ajuda-recorte__grade{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:.35rem .75rem;margin:0}
.ajuda-recorte__par{display:flex;gap:.35rem;min-width:0}
.ajuda-recorte__par dt{color:var(--ink-3);font-size:var(--fonte-corpo);font-weight:500}
/* Duas linhas: o eixo sub-segmento vem com 37 nomes no recorte real e sozinho
   empurrava o primeiro verbete para fora da primeira dobra. O valor inteiro
   continua no `title` e no texto que o botão Copiar produz. */
.ajuda-recorte__par dd{margin:0;color:var(--ink);font-size:var(--fonte-corpo);font-weight:500;min-width:0;
}
.ajuda-recorte__quando{margin:.4rem 0 0;color:var(--ink-3);font-size:var(--fonte-pequena)}
.ajuda-auditoria__acoes{display:flex;justify-content:flex-end;margin-bottom:.5rem}
.ajuda-verbete{padding:.85rem 0;border-top:1px solid var(--line)}
.ajuda-verbete:first-of-type{border-top:0;padding-top:.25rem}
.ajuda-verbete__titulo{font-size:var(--fonte-destaque);font-weight:500;color:var(--ink);margin:0 0 .25rem}
/* O valor exibido é o que transforma "definição do indicador" em "defesa DESTE
   número": vem em tamanho de número, não de texto. */
.ajuda-verbete__valor{margin:0 0 .35rem;font-size:var(--fonte-titulo);font-weight:500;color:var(--ink);
  font-variant-numeric:tabular-nums lining-nums}
.ajuda-verbete__valor-nota{font-size:var(--fonte-pequena);font-weight:500;color:var(--ink-3);
  margin-left:.35rem;vertical-align:middle}
.ajuda-verbete__conceito{margin:0 0 .5rem;color:var(--ink-2);font-size:var(--fonte-corpo);line-height:1.5;
  max-width:70ch}
.ajuda-verbete__rotulo{margin:.5rem 0 .2rem;font-size:var(--fonte-pequena);font-weight:500;color:var(--ink-3)}
/* A fórmula é o único bloco largo do modal: `overflow-x:auto` para ela rolar
   DENTRO da própria caixa (medido: transbordava em todas as resoluções, de 390
   a 1920, empurrando a barra lateral do modal), e `overflow-wrap:anywhere` para
   quebrar o token longo — nome de campo do ERP e caminho de arquivo não têm
   espaço onde quebrar. */
/* `.ajuda-markdown pre` (corpo do modal) fixa `white-space:pre` e VENCIA por
   especificidade (0,1,1 contra 0,1,0) — a fórmula não quebrava linha e rolava
   de lado em toda resolução, de 390 a 1920. Casar a especificidade resolve. */
.ajuda-auditoria .ajuda-verbete__formula{margin:0;padding:.5rem .65rem;background:var(--surf-2);
  border:1px solid var(--line);border-radius:6px;font-size:var(--fonte-corpo);line-height:1.5;
  color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere;word-break:normal;
  overflow-x:auto;max-width:100%}
/* Origem e listas carregam caminho de arquivo (bi/services/...py:funcao), que
   não quebra sozinho e estourava a caixa do modal na horizontal. */
.ajuda-verbete__lista li{overflow-wrap:anywhere}
.ajuda-verbete__lista{margin:0;padding-left:1.1rem;color:var(--ink-2);font-size:var(--fonte-corpo);
  line-height:1.5}
.ajuda-verbete__obs{margin:.5rem 0 0;color:var(--ink-2);font-size:var(--fonte-corpo);line-height:1.5;
  max-width:70ch}
/* Chegou pelo clique NUM número: o verbete daquele valor abre marcado, senão o
   operador cai numa lista e procura de novo o que já tinha apontado. */
.ajuda-verbete--destacado{background:var(--info-subtle);border-radius:8px;
  padding-left:.6rem;padding-right:.6rem;box-shadow:0 0 0 1px color-mix(in srgb, var(--info) 22%, var(--surf))}

.ajuda-markdown { color: var(--ink); font-size: var(--fonte-destaque); line-height: 1.5; }

.ajuda-markdown h3 { font-size: var(--fonte-destaque); font-weight: 500; margin-top:1rem; color: var(--ink-2); }

.ajuda-markdown p { margin-bottom:0.5rem; }
.ajuda-markdown ul, .ajuda-markdown ol { padding-left:1.5rem; margin-bottom:0.5rem; }
.ajuda-markdown li { margin-bottom:0.25rem; }

.ajuda-markdown pre {
    background: var(--surf-2);
    border: var(--bs-border-width) solid var(--line);
    border-radius: var(--bs-border-radius-sm);
    padding:0.5rem 1rem;
    font-size: var(--fonte-corpo);
    overflow-x: auto;
    color: var(--ink);
    white-space: pre;
}

/* Modal footer separador */

/* ===== MERGED FROM bi/static/bi/css/faturamento-fcds.css (P5 — page-local dissolve) ===== */
/* ==========================================================================
   faturamento-fcds.css — page-owned glue for the Faturamento page on FCDS.
   The GENERIC helpers that used to live here (grid spans .fcds-span-*, equal-
   height .fcds-row-eq, the .fcds-tabs underline
   skin, .fcds-mini-lab, .fcds-siglink, .is-hidden) were PROMOTED to the shared
   layer (custom.css §10 + the canonical TABS block) so
   every migrated page composes them without copy-paste. What remains here is
   faturamento-ONLY section choreography. Uses ONLY fcds tokens — no hardcoded
   colours.
   ========================================================================== */

/* P7 — CLS: #fcds-grid starts empty and faturamento-fcds.js injects the KPI band
   after data loads. Reserve the band height while empty so the fill no longer
   collapses→expands (measured CLS ~1.77 → 0.13). */
#fcds-grid { min-height: 10.5rem; }

/* Sinais operacionais como linha full-width (mês corrente): 3 cards lado a lado.
   Fora do mês corrente a .sigcol mantém o padrão vertical (coluna span-4).
   .is-hidden (oculta o Ritmo Diário fora do mês corrente) é compartilhado. */
.sigcol.is-row { flex-direction: row; }
.sigcol.is-row .sig { flex: 1; }
@media (max-width: 992px) {
  .sigcol.is-row { flex-direction: column; }
}

/* Row B — Evolução de Margem (50%) ao lado do Mapa (50%), em altura igual.
   O card vira coluna flex e o gráfico ocupa a altura restante; o canvas é
   posicionado em absoluto para acompanhar essa altura (em vez de uma única
   linha de tendência inflar para ~571px via o loop de aspect-ratio do Chart.js
   quando não há altura definida). Resultado: a linha escala junto com o mapa. */
[data-bi-section="evolucao-margem"] { display: flex; flex-direction: column; }
[data-bi-section="evolucao-margem"] .chart {
  flex: 1 1 auto; height: auto; min-height: 15rem; position: relative;
}
[data-bi-section="evolucao-margem"] .chart canvas {
  position: absolute; inset: 0; height: 100% !important;
}

/* Ritmo Diário — gráfico ocupa toda a altura do card (mesmo padrão da margem),
   acompanhando a altura do board de Sub-segmento ao lado (fcds-row-eq). */
[data-bi-section="corredor-diario"] { display: flex; flex-direction: column; }
[data-bi-section="corredor-diario"] .chart {
  flex: 1 1 auto; height: auto; min-height: 15rem; position: relative;
}
[data-bi-section="corredor-diario"] .chart canvas {
  position: absolute; inset: 0; height: 100% !important;
}


/* Switch de formato numérico (abreviado ↔ completo) injetado no topbar por
   faturamento.js. Reusa o componente global .toggle ("Considerar devoluções");
   aqui só ajustamos o encaixe no topbar (altura, alinhamento, não encolher). */

/* AUTO-SHRINK — números completos ("R$ 16.201.272,89") são bem mais largos que os
   abreviados. Os valores da banda já são nowrap; no modo completo encolhemos o
   font-size com clamp() em unidades cqi (container query inline-size) → o tamanho
   acompanha a LARGURA REAL DA CÉLULA, não a viewport. Isso resolve os dois furos do
   vw anterior: (a) sidebar aberta deixa a viewport larga mas a célula estreita;
   (b) o grid colapsa 8→4→2 colunas. O teto px = tamanho original, então no desktop
   amplo fica praticamente inalterado. Escopo: .kpiband--completo (modo compacto
   intocado). Cada célula vira um container inline-size. */

/* ===== MERGED FROM bi/static/bi/css/gerencial.css (P5 — page-local dissolve) ===== */

/* ============================================================================
   gerencial.css — porte PIXEL-PERFECT do mockup aprovado, responsivo.
   Tokens e valores transcritos do mockup (paleta fria/clara, mono nos números).
   Escopo em .gc (dentro do shell FCDS). Sem legenda de rodapé (decisão do
   usuário). Drills em overlay próprio (.gc-ov), como o mockup.
   ========================================================================== */
.gc {
  /* Paleta Bootstrap literal (spec 2026-07-28 §11). A build vendorizada é
     5.2-era: NÃO existem --bs-tertiary-bg nem as famílias -bg-subtle /
     -border-subtle / -text-emphasis. Só o que está aqui existe.
     PREFIXO --gc- obrigatório (2026-08-06, DESIGN.md §6 Don'ts): este bloco
     redefinia os nomes GLOBAIS --ink/--ink-4/--line…, e todo componente
     compartilhado dentro da página mudava de valor sem aviso (--ink-4 virava
     #ced4da, ~1,6:1). Página cria token PREFIXADO ou consome o global.
     --gc-accent é #0d6efd (BS puro), por decisão do usuário — diverge do
     --brand #006BB5 que o resto do app usa.
     --gc-ink-2/--gc-ink-3 são rgba TRANSLÚCIDOS: usar só em color, nunca como
     fundo de coluna sticky (senão a coluna vaza no scroll horizontal).
     --amber saiu: #ffc107 tem ~1.9:1 em branco, ilegível como texto. O nível
     "alerta" agora é sinalizado por preenchimento, não por cor de número.
     --accent-dim/--steel/--steel-hi saíram: zero uso (auditado 2026-07-28). */
  --gc-panel:var(--bs-body-bg); --gc-panel-3:var(--bs-gray-100);
  --gc-ink:var(--bs-body-color); --gc-ink-2:var(--bs-secondary-color);
  --gc-ink-3:var(--bs-tertiary-color); --gc-ink-4:var(--bs-gray-400);
  --gc-line:var(--bs-border-color); --gc-line-2:var(--bs-border-color-translucent);
  --gc-accent:var(--bs-primary);
  --gc-red:var(--bs-danger); --gc-green:var(--bs-success);
  /* Sem override local de fonte: herda a fonte única do :root (--sans/--mono). */
  margin:0 auto; display:flex; flex-direction:column; gap:0.5rem;
  color:var(--gc-ink); font-family:var(--sans);
}
/* Rótulos/cabeçalhos herdam a sans do mockup (o shell usa Roboto); números já
   forçam --mono, então continuam monoespaçados. */
.gc, .gc button, .gc input { font-family:var(--sans); }

/* ── Abas de mês ─────────────────────────────────────────────────────────── */
/* Vivem na `.gc-barra`, a linha simples acima da matriz (sem card desde o
   #280), então não têm bordo/fundo/padding próprios; aqui só o residual sem primitiva:
   linha flex das abas + scroll horizontal (a build vendorizada do Bootstrap só
   tem .overflow-auto, que travaria o eixo Y também). */
.gc-months { display:flex; flex-direction: row; gap:0.25rem; align-items:center; overflow-x:auto;
  flex:1 1 auto; min-width:0; }
.gc-months__lbl { font-size:var(--fonte-corpo); letter-spacing:.16em; text-transform:uppercase; color:var(--gc-ink-3);
  font-weight:500; padding:0 0.5rem 0 0.25rem; white-space:nowrap; }
.gc-mtab { flex:1 1 0; min-width: 2.875rem; text-align:center; padding:0.5rem 0.25rem; border-radius:var(--bs-border-radius-lg); font-size:var(--fonte-corpo);
  font-weight:500; color:var(--gc-ink-2); cursor:pointer; white-space:nowrap; background:transparent; border:0; }
.gc-mtab:hover:not(.gc-mtab--off):not(.gc-mtab--on) { background:var(--gc-panel-3); }
.gc-mtab--on { background:var(--gc-accent); color:var(--bi-text-on-accent); font-weight:500; cursor:default; }
.gc-mtab--off { color:var(--gc-ink-3); opacity:.45; cursor:default; }

/* ── Nota de mês fechado ─────────────────────────────────────────────────── */
/* Cor/padding vêm de .alert-secondary (Bootstrap); aqui só o layout em linha
   do ícone+texto, sem moldura lateral. */
.gc-pastnote { display:flex; flex-direction: row; align-items:center; gap:0.5rem; margin:0;
  border-radius:0; border-left:0; border-right:0; border-top:0;
  font-size:var(--fonte-corpo); font-weight:500; }
.gc-pastnote i { flex:0 0 auto; }

/* ── Painéis ─────────────────────────────────────────────────────────────── */
/* .gc-panel/.gc-panel__hd (bordo/bg/radius/overflow + layout do cabeçalho)
   viraram .card/.card-header (+ utilities Bootstrap d-flex/justify-content-
   between/align-items-baseline/flex-wrap/gap-2 direto no template). Fica só
   a tipografia "eyebrow" do título, que não tem equivalente Bootstrap. */
/* (.gc-panel__ttl saiu com a tira: o título do saldo virou `.gc-hd__ttl`,
   dentro da própria célula de rótulo do cabeçalho da matriz.) */

/* toggle de ordenação */
.gc-ord { display:inline-flex; align-items:center; gap:0.5rem; }
.gc-ord__lbl { font-size:var(--fonte-corpo); letter-spacing:.22em; text-transform:uppercase; color:var(--gc-ink-3); font-weight:500; }

/* ── Cabeçalho da bitola (era a tira `.gc-strip`) ────────────────────────── */
/* Saldo, barra, rótulo e código na MESMA célula da coluna: o alinhamento passa
   a ser o da tabela (morreram o espaçador de 216px que imitava a coluna de
   rótulo e o `min-width` repetido nos dois componentes) e a bitola é escrita
   uma vez só, não uma na tira e outra no cabeçalho. */
.gc-mx th.gc-bh { vertical-align:bottom; }
/* `nowrap` no NÚMERO (não no rótulo): sem ele o saldo partia no meio — "−17,3"
   virava "−17," / "3" quando a coluna aperta. */
.gc-bh__num { display:block; white-space:nowrap; font-family:var(--mono); font-size: var(--fonte-corpo); line-height:1.2; font-weight:500;
  font-variant-numeric:tabular-nums; color:var(--gc-green); }
.gc-bh--dn .gc-bh__num { color:var(--gc-red); }
.gc-bh__bar { display:block; position:relative; height: 2.75rem; margin:0.25rem 0 0.375rem; }
.gc-bh__bar i { position:absolute; left:0; right:0; top:50%; border-top:var(--bs-border-width) dashed var(--gc-ink-3); opacity:.45; }
.gc-bh__bar b { position:absolute; left:26%; right:26%; background:var(--gc-green);
  border-radius: var(--bs-border-radius-sm) var(--bs-border-radius-sm) 0 0; }
.gc-bh--dn .gc-bh__bar b { background:var(--gc-red); border-radius: 0 0 var(--bs-border-radius-sm) var(--bs-border-radius-sm); }
/* Desliga a HERANÇA de `word-break:break-word` do `thead th` em vez de PROIBIR a
   quebra: "15,2mm"/"12,7eng" são token único (sem espaço, sem oportunidade de
   quebra) e seguem inteiros — que era o motivo do antigo `nowrap` —, enquanto
   "BWG 18 torcido 10kg" (conjunto Arame, 16 colunas) quebra nos ESPAÇOS dentro
   da própria coluna. Com `nowrap` ele vazava por cima da coluna vizinha em
   qualquer largura de tela. */
.gc-bh__lbl { display:block; white-space:normal; word-break:normal; overflow-wrap:normal;
  font-size: var(--fonte-corpo); font-weight:500; color:var(--gc-ink); text-transform:none; letter-spacing:0; }
.gc-bh--dn .gc-bh__lbl { color:var(--gc-red); }
.gc-bh__cod { display:block; white-space:nowrap; font-family:var(--mono); font-size: var(--fonte-pequena); letter-spacing:-0.02em; color:var(--gc-ink-3); }
/* Gerencial, 17/09/2026 (decisão do dono): o CÓDIGO é o nome do produto e o
   apelido da bitola é apoio — o par troca de ordem no HTML e de peso aqui.
   Escopado a `.gc-mx` de propósito: a Curva ABC (`.cabc-mx`) usa as mesmas
   classes na ordem antiga, e mexer na regra-base vazaria para ela.
   O código NÃO ganha corpo maior: fica no mesmo `--bi-fs-compact` que o apelido
   tinha, porque a coluna é fixa em 4.75rem e 8 dígitos já a ocupam quase toda
   (ver o comentário do `.gc-bh__und`). O destaque vem do PESO e da COR, que não
   custam pixel — o `letter-spacing` mais fechado devolve o que o corpo maior
   consumiu. */
.gc-mx .gc-bh__cod { font-size: var(--fonte-corpo); font-weight:500; color:var(--gc-ink); letter-spacing:-0.04em; }
.gc-mx .gc-bh--dn .gc-bh__cod { color:var(--gc-red); }
.gc-mx .gc-bh__lbl { font-size: var(--fonte-pequena); font-weight:400; color:var(--gc-ink-2); }
/* O vermelho do saldo negativo fica no código (a identidade da coluna); repeti-lo
   no apelido pintaria a célula inteira de vermelho e diluiria o sinal. */
.gc-mx .gc-bh--dn .gc-bh__lbl { color:var(--gc-ink-2); }
/* Selo de unidade da coluna: aparece em TODA coluna de um conjunto de unidades
   mistas (Cercamento, Fixadores). Fica em LINHA PRÓPRIA, não emendado no código:
   a linha do código é `nowrap` numa coluna de largura fixa (4.75rem) e o código
   de 8 dígitos já a ocupa quase toda — inline, o selo era cortado. */
.gc-bh__und { display:inline-block; margin-top:0.125rem; padding:0 0.25rem; border:var(--bs-border-width) solid var(--gc-line); border-radius:var(--bs-border-radius-sm); font-family:var(--bs-body-font-family); font-size: var(--fonte-pequena); line-height:1.5; color:var(--gc-ink-2); background:var(--gc-panel-3); }
.gc-bh__skel { display:block; margin:0 auto 0.25rem; }
/* Rótulo da 1ª coluna do cabeçalho: título (botão do resumo geral) + fórmula. */
.gc-hd__ttl { display:block; border:0; background:transparent; padding:0; cursor:pointer; text-align:left;
  font-size:var(--fonte-corpo); letter-spacing:.15em; text-transform:uppercase; font-weight:500; color:var(--gc-ink-2); }
.gc-hd__ttl:hover { color:var(--gc-accent); }
.gc-hd__sub { display:block; font-size: var(--fonte-corpo); font-weight:400; letter-spacing:0; text-transform:none; color:var(--gc-ink-3); }
.gc-hd__cap { font-size: var(--fonte-rotulo); letter-spacing:.08em; text-transform:uppercase; font-weight:500; color:var(--gc-ink-3); }

/* ── Runway: para onde o saldo caminha (2ª linha do cabeçalho) ───────────── */
/* A série e o mês da virada vêm prontos do backend (`runway`); aqui só a
   polilinha. Responde "quando falta", que a matriz de um mês só não responde. */
.gc-mx tr.gc-rwrow th { background:var(--gc-panel-3); padding:0.375rem 0.375rem 0.25rem; vertical-align:middle; cursor:default; }
.gc-mx tr.gc-rwrow th.gc-rowh { background:var(--gc-panel-3); }
.gc-rw { display:block; width:100%; height: 1.625rem; }
/* A nota só existe quando há virada; a coluna calma fica em silêncio. O
   `min-height` reserva a linha de texto para as colunas mudas não subirem e
   desalinharem as sparklines vizinhas. */
.gc-mx tr.gc-rwrow th { min-height:0; }
.gc-rw__nota { display:block; white-space:nowrap; font-size: var(--fonte-pequena); font-weight:500; letter-spacing:0;
  text-transform:none; text-align:center; }
.gc-rw__nota--zera_em { color:var(--gc-red); }
.gc-rw__nota--recupera_em { color:var(--gc-green); }

/* ── Matriz ──────────────────────────────────────────────────────────────── */
/* A matriz rola sozinha, com cabeçalho grudado: as barras e os rótulos de
   bitola são a referência de leitura de toda linha — se saem de vista ao
   rolar, o número do meio da tabela vira número sem dono. A altura é MEDIDA
   (`esticarMatriz` no gerencial.js, #280) para ocupar o content até o pé da
   janela; os 70vh só valem até o JS medir. */
.gc-mxwrap { overflow:auto; max-height:70vh; }
/* O piso acompanha o Nº DE COLUNAS (`--gc-cols`, carimbado no render): 59.25rem
   fixo era calibrado para as 13 bitolas da cordoalha e espremia as 16 do arame
   até o rótulo virar ilegível. Quem rola é o `.gc-mxwrap` (já `overflow:auto`);
   a PÁGINA nunca rola na horizontal. */
/* `separate`, nunca `collapse` (#430): no modelo colapsado o fio é da TABELA,
   não da célula — a célula grudada (cabeçalho no topo, rótulo à esquerda, total
   no pé) andava e o fio ficava, e a grade desalinhava ao rolar. Aqui cada célula
   é dona do próprio fio (direita + baixo). */
table.gc-mx { border-collapse:separate; border-spacing:0; width:100%; font-size:var(--fonte-corpo); table-layout:fixed;
  min-width: calc(14.75rem + var(--gc-tot-min, 5.5rem) + var(--gc-cols, 13) * var(--gc-col-min, 4.75rem)); }
.gc-mx col.gc-c-rowh { width: 14.75rem; }
/* Coluna Total (reporte #159): largura própria e fixa — fora do `--gc-cols`, que
   multiplica só as bitolas. Separada delas só pelo peso do número, sem fio. */
.gc-mx col.gc-c-tot { width: var(--gc-tot-min, 5.5rem); }
.gc-mx thead th.gc-tot { cursor:default; text-align:right; padding-right:0.625rem; color:var(--gc-ink-2); }
.gc-mx td.gc-tot { text-align:right; padding:0.4375rem 0.625rem; line-height:1.5; cursor:default; }
.gc-mx td.gc-tot .gc-cv { font-weight:500; }
.gc-mx td.gc-tot .gc-cv.gc-z { font-weight:400; }
.gc-mx th, .gc-mx td { padding:0; white-space:nowrap; }
.gc-mx thead th { font-size:var(--fonte-corpo); color:var(--gc-ink-3);
  font-weight:500; text-align:center; padding:0.5rem 0.375rem 0.375rem; border-bottom:var(--bs-border-width) solid var(--gc-line);
  border-right:var(--bs-border-width) solid var(--gc-line-2);
  vertical-align:bottom; cursor:pointer;
  white-space:normal; line-height:1.2; word-break:break-word;
  position:sticky; top:0; z-index:2; background:var(--gc-panel); }
/* A 2ª linha do cabeçalho (runway) gruda logo ABAIXO da 1ª — a altura é medida
   no cliente (`--gc-hd-h`), não chutada, porque depende da fonte e do zoom. */
.gc-mx tr.gc-rwrow th { top:var(--gc-hd-h, 8.75rem); z-index:2; }
.gc-mx thead th.gc-rowh { z-index:4; }
.gc-mx tr.gc-rwrow th.gc-rowh { z-index:5; }
/* Fundo OPACO obrigatório: a coluna fixa cobre as células que passam por
   baixo no scroll horizontal. Nunca usar --gc-ink-2/--gc-ink-3 aqui (são rgba). */
.gc-mx thead th.gc-rowh { border-right:var(--bs-border-width) solid var(--gc-line-2); text-align:left; padding-left:0.875rem; width: 14.75rem; cursor:default;
  position:sticky; left:0; z-index:3; background:var(--bs-gray-100); }
.gc-mx thead th:not(.gc-rowh):hover { color:var(--gc-accent); background:var(--gc-panel-3); }
/* Ponto de risco no cabeçalho da bitola — canal não-cromático (ADR-006).
   Carrega sozinho o nível "alerta", que perdeu a cor de número quando a
   paleta virou Bootstrap (--bs-warning é ilegível como texto, mas como
   preenchimento de um ponto de 5px tem contraste de sobra). */
.gc-mx thead th .gc-rd { display:inline-block; width: 0.3125rem; height: 0.3125rem; border-radius:50%;
  margin-right:0.25rem; vertical-align:middle; }
.gc-mx thead th .gc-rd--critico { background:var(--bs-danger); }
.gc-mx thead th .gc-rd--alerta  { background:var(--bs-warning); }
/* Régua nos dois eixos (decisão do usuário): a matriz é lida célula a célula
   contra o Sênior, e a coluna precisa ser tão delimitada quanto a linha. */
.gc-mx tbody td { border-bottom:var(--bs-border-width) solid var(--gc-line-2);
  border-right:var(--bs-border-width) solid var(--gc-line-2); }
.gc-mx td.gc-k { border-right:var(--bs-border-width) solid var(--gc-line-2); padding:0.4375rem 0.625rem 0.4375rem 0.875rem; color:var(--gc-ink); font-weight:500; font-size: var(--fonte-corpo); width: 14.75rem;
  white-space:normal; line-height:1.2; position:sticky; left:0; z-index:2; background:var(--bs-gray-100); }
/* Calha do operador da conta (#430): + − ± = alinhados numa coluna estreita,
   em mono; vazia na linha fora da soma. */
.gc-mx td.gc-k { padding-left:0.5rem; }
.gc-mx td.gc-k .gc-op { display:inline-block; width:1rem; vertical-align:top; font-family:var(--mono);
  font-weight:500; color:var(--gc-ink-2); }
.gc-mx td.gc-k .gc-kt { display:inline-block; width:calc(100% - 1rem); vertical-align:top; }
.gc-mx tr.gc-hinge td.gc-k .gc-op, .gc-mx tr.gc-result td.gc-k .gc-op { color:var(--gc-ink); }
.gc-mx td.gc-k .gc-kx { display:block; color:var(--gc-ink-3); font-weight:400; font-size: var(--fonte-pequena); margin-top:0; }
/* Recuo lateral de 0.5rem (#430): com 0.625rem, "312.447 PÇ" cortava 2px na
   coluna mínima dos Fixadores — número nunca cortado. */
.gc-mx td.gc-cell { text-align:right; padding:0.4375rem 0.5rem; line-height:1.5; }
.gc-cv { font-family:var(--mono); font-variant-numeric:tabular-nums; font-size: var(--fonte-corpo); }
.gc-cv.gc-z { color:var(--bs-gray-500); }
/* Segunda linha da célula: o dinheiro do pedido firme. Menor e cinza — o peso
   continua sendo a grandeza da tela; o valor é contexto, não concorrente. */
.gc-cr { display:block; font-family:var(--mono); font-size: var(--fonte-pequena); line-height:1.2;
  font-variant-numeric:tabular-nums; color:var(--gc-ink-3); }
/* Nível ALERTA (saldo positivo, mas abaixo dos pedidos já firmes). Era número
   preto — igual a uma linha qualquer — porque --bs-warning reprova contraste
   como texto; `--warning-text` é o laranja de texto #FA4B00 (#229),
   e o preenchimento suave garante que o nível não dependa só da cor do
   algarismo (ADR-006: o ponto do cabeçalho continua como canal não-cromático). */
.gc-cv.gc-cv--alerta { color:var(--warning-text); font-weight:500; }
/* Precisa vencer `.gc-mx tr.gc-result td` (mesma célula, banda do resultado),
   que é mais específica — sem os dois seletores o preenchimento não aparecia. */
.gc-mx td.gc-cell--alerta,
.gc-mx tr.gc-result td.gc-cell--alerta { background:var(--warning-subtle); }
.gc-bh--alerta .gc-bh__num { color:var(--warning-text); }
/* bandas: zona (forte) e grupo (leve) */
.gc-mx tr.gc-zone td { background:var(--gc-panel-3); color:var(--gc-ink-2); font-size: var(--fonte-rotulo); letter-spacing:.1em;
  text-transform:uppercase; font-weight:500; text-align:left; padding:0.375rem 1rem;
  border-bottom:var(--bs-border-width) solid var(--gc-line); }
/* Sem fio em cima: com `border-collapse: separate` (#430) ele dobraria com o fio
   de baixo da linha anterior. */
/* Rótulo da banda (PASSADO/FUTURO) fixo à esquerda no scroll horizontal. A
   célula é colspan de largura total (sem folga p/ `sticky` nela mesma), então
   quem gruda é o SPAN interno — mais estreito que a célula, ele tem folga p/
   ficar em left:18px (alinhado ao recuo da coluna Indicador) ao arrastar a
   matriz no mobile. O fundo opaco `--gc-panel-3` da célula cobre o que passa por baixo. */
.gc-mx tr.gc-zone td .gc-zone__lbl { position:sticky; left:18px; display:inline-block; }
/* Contexto da banda ("· jul/26, fecha no estoque atual") em caixa normal: a
   faixa inteira em caixa-alta com travessões pesava como título de seção. */
.gc-mx tr.gc-zone .gc-zone__ctx { font-size: var(--fonte-corpo); font-weight:400; letter-spacing:0;
  text-transform:none; color:var(--gc-ink-3); }
/* Dobradiça (Estoque atual) e resultado (Saldo projetado / se converter) pesam
   por SUPERFÍCIE. As duas réguas vermelhas em volta do saldo gritavam mais que
   os próprios números, que já são a única coisa colorida da matriz. */
.gc-mx tr.gc-hinge td, .gc-mx tr.gc-hinge td.gc-k { background:var(--gc-panel-3); }
.gc-mx tr.gc-hinge td.gc-k { font-weight:500; }
.gc-mx tr.gc-result td, .gc-mx tr.gc-result td.gc-k { background:var(--gc-panel-3); }
.gc-mx tr.gc-result td { box-shadow: inset 0 var(--bs-border-width) 0 var(--gc-ink-3); }
.gc-mx tr.gc-result td.gc-k { font-weight:500; }
.gc-mx tr.gc-result .gc-cv { font-weight:500; font-size: var(--fonte-corpo); }
.gc-mx tr.gc-dim td.gc-k { color:var(--gc-ink-2); font-weight:400; }
.gc-mx tr.gc-dim .gc-cv { color:var(--gc-ink-3); }
/* Total final fixo no pé da matriz (#430): o `=` que fecha a conta (o Saldo
   projetado, ou o fechamento do mês fechado) gruda no rodapé do `.gc-mxwrap`,
   que já rola; o rótulo gruda nos dois eixos. O fio de cima vira sombra: borda
   de célula grudada não acompanha. Desde o #445 as linhas informativas vêm
   DEPOIS do saldo, por isso o resultado gruda sem ser a última linha. */
.gc-mx tbody tr.gc-result td, .gc-mx tbody tr.gc-hinge:last-child td { position:sticky; bottom:0; z-index:2; background:var(--gc-panel-3);
  border-top:0; box-shadow: inset 0 var(--bs-border-width) 0 var(--gc-ink-3); }
.gc-mx tbody tr.gc-result td.gc-k, .gc-mx tbody tr.gc-hinge:last-child td.gc-k { left:0; z-index:4; }
/* ── Mira ────────────────────────────────────────────────────────────────── */
/* Hover acende a linha inteira e a coluna inteira: em 13 colunas é o que
   impede ler o número de uma bitola na linha de outra. */
/* Classes `bi-mira-*` vêm de `biUtils.ligarMira`, compartilhado com a Curva ABC
   e as Metas por Vendedor; a TINTA é de cada página. */
.gc-mx tbody tr.bi-mira-linha td, .gc-mx tbody tr.bi-mira-linha td.gc-k { background:var(--gc-panel-3); }
.gc-mx tbody td.bi-mira-coluna { background:var(--gc-panel-3); }
.gc-mx thead th.bi-mira-coluna { box-shadow: inset 0 -2px 0 var(--gc-accent); }

/* Divisor do mês corrente na tira de meses: à esquerda fechado, à direita
   projeção. */
.gc-mdiv { flex:0 0 auto; align-self:stretch; width:var(--bs-border-width); background:var(--gc-line); margin:0.25rem 0.375rem; }

/* afford: célula viva clicável (recorte L3) */
.gc-mx td.gc-cell.gc-hot { cursor:pointer; }
.gc-mx td.gc-cell.gc-hot:hover { background:var(--acc-soft); box-shadow: inset 0 0 0 var(--bs-border-width) var(--gc-accent); }
/* Origem do drill: fica acesa enquanto o painel lateral mostra o conteúdo dela. */
.gc-mx td.gc-sel, .gc-mx td.gc-cell.gc-sel { box-shadow: inset 0 0 0 2px var(--gc-accent); }
.gc-mx tbody tr:not(.gc-band):not(.gc-zone):not(.gc-dim) td.gc-k { cursor:pointer; }
.gc-mx tbody tr:not(.gc-band):not(.gc-zone):not(.gc-dim) td.gc-k:hover { color:var(--gc-accent); }

/* ── Linha "carregando" (Task 7) ─────────────────────────────────────────── */
/* A fase que preenche esta linha ainda não chegou (backend manda
   `pendente:true`, sem `valores`) — sem drill, sem hover, só uma barra de
   esqueleto por célula no lugar do número. */
.gc-mx tr.gc-pendente td.gc-k { color:var(--gc-ink-3); font-weight:400; cursor:default; }
.gc-mx tr.gc-pendente td.gc-cell { cursor:default; }
.gc-skel { display:inline-block; width:2.5rem; height:0.625rem; border-radius:var(--bs-border-radius-sm);
  background:linear-gradient(90deg, var(--gc-panel-3) 25%, var(--gc-line) 50%, var(--gc-panel-3) 75%);
  background-size:200% 100%; animation:gc-skel-shimmer 1.4s ease-in-out infinite; }
@keyframes gc-skel-shimmer { 0% { background-position:200% 0; } 100% { background-position:-200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .gc-skel { animation:none; background:var(--gc-panel-3); }
}

/* ── Degradação Conexos ──────────────────────────────────────────────────── */
/* Banner de degradação: cor e contraste vêm de .alert-warning (Bootstrap);
   aqui só o layout em linha e o encaixe edge-to-edge dentro do card. */
.gc-degraded { display:flex; align-items:center; gap:0.5rem; margin:0;
  border-radius:0; border-left:0; border-right:0; border-top:0;
  font-size:var(--fonte-corpo); font-weight:500; }
.gc-degraded i { flex:0 0 auto; }
/* Aviso de fonte fora do ar colado no subtítulo do cabeçalho ("Conexos
   indisponível"): o único espaço que separava os dois era o do HTML. */
.gc-zwarn { margin-left:0.5rem; }

/* (Overlay/diálogo/tabela de drill `.gc-ov/.gc-dlg/.gc-dt/.gc-drow` removidos —
   o drill agora usa o modal-padrão compartilhado abaixo, `biUtils.gridModal`.) */

/* === MODAL PADRÃO (biUtils.modalPadrao / gridModal) ============================
   Shell Bootstrap único (header/body/footer, título "Assunto — Item") + corpo de
   GRADE ordenável com thead/tfoot fixos. Body-appended → só tokens de :root
   (--gc-ink, --gc-line, --mono e variantes); nada de --gc-panel/--gc-accent (esses são
   .gc-scoped). NÃO escreva "asterisco+barra" dentro de comentário: fecha o
   comentário cedo e a regra seguinte some silenciosamente. */
/* Altura presa à viewport e UM só scroller: a grade. O corpo vira coluna flex que
   não rola; resumo, abas, pills e paginação ficam parados, e a sobra vai para o
   scroller da tabela (`.datatable-scroll` do DataTables ou `.fcds-gm__wrap` do
   gridModal), que rola com `thead` e `tfoot` grudados.
   Esta cadeia é o que sustenta o cabeçalho fixo — sem ela quem rola é o
   `.modal-body`, e aí `position:sticky` do `thead` não tem contra o que grudar e
   o cabeçalho da grade sai de vista. Cada seletor da lista do meio é um container
   intermediário que precisa repassar a altura adiante; um elo de fora e a altura
   morre ali (foi o que aconteceu com o `div` cru do `frameGrade`, que passou a
   levar `.fcds-modal__pane` justamente para entrar aqui). */
.fcds-modal .modal-body { display:flex; flex-direction:column; overflow:hidden; }
.fcds-modal .modal-body > * { flex:0 0 auto; }
.fcds-modal .tab-content,
.fcds-modal .tab-pane.active,
.fcds-modal [data-razao],
.fcds-modal [data-movimentos],
.fcds-modal .tbl-wrapper.datatable,
.fcds-modal .tbl-wrapper.datatable > .dataTables_wrapper,
.fcds-modal .fcds-modal__pane {
  display:flex; flex-direction:column; flex:1 1 auto; min-height:0;
}
.fcds-modal .datatable-scroll,
.fcds-modal .fcds-gm__wrap { flex:1 1 auto; min-height:0; max-height:none; }
/* Enquanto carrega, o alvo do loader recobra a reserva de altura — o
   `min-height:0` do item flex acima esmagaria o logo-loader a zero. */
.fcds-modal [data-bi-loading="tape"] { min-height: 11.75rem; }
/* Ícone de AÇÃO usa a cor de ação, não o cinza do shell: voltar e "mais info"
   são as duas coisas clicáveis do corpo, e vestidas de --gc-ink-3 liam como
   decoração da moldura. */
.fcds-modal__voltar { border:0; background:transparent; color:var(--brand); cursor:pointer; padding:0 0.25rem; font-size:var(--fonte-destaque); line-height:1; }
.fcds-modal__voltar:hover { color:var(--brand-ink); }
/* Metadado recua para 13px: antes era 20px, o MESMO tamanho do título, e assunto
   e contexto competiam. Rende mais no drill de estoque, cujo item é a descrição
   inteira do produto e quebrava o header em duas linhas (93px). */
.fcds-modal__item { color:var(--gc-ink-3); font-weight:400; }
/* (A cifra do header saiu junto com o markup: era o mesmo número do TOTAL do
   rodapé, repetido a dois centímetros de distância.) */
/* (O `padding:0` que fazia a grade sangrar de borda a borda saiu: o corpo usa a
   calha de 1rem do Bootstrap como qualquer outro modal.) */
/* (A regra que escondia o rodapé no corpo de grade saiu: o shell do
   `modalPadrao` não emite mais `.modal-footer` nenhum, então ela não tinha
   sobre o que agir.) */
/* `flex:0 0 auto`: a faixa de abas é irmã do pane dentro de um `.fcds-modal__pane`
   (coluna flex). Sem isto ela encolheria junto com a grade ao faltar altura. */
.fcds-modal__tabs { padding:0.25rem 1rem 0; margin:0; flex:0 0 auto; }
.fcds-modal__tabs .nav-link { padding:0.25rem 0.625rem; color:var(--gc-ink-3); }
.fcds-modal__tabs .nav-link.active { color:var(--gc-ink); font-weight:500; }
/* (A faixa de escopo saiu: o recorte por bitola virou parte do TÍTULO do painel,
   e "ver todas as bitolas" já era o clique no rótulo da linha na matriz.) */
/* ── Chassi LATERAL (biUtils.gridPainel) ─────────────────────────────────── */
/* Mesmo corpo de grade do modal, moldura diferente: painel ancorado à direita
   que DOCA — `.main` cede a largura em vez de ficar coberto. Nasceu da matriz
   do gerencial, onde o gesto é comparar célula a célula: com modal, cada
   comparação custava abrir-fechar-abrir e a origem do drill ficava tapada.
   Alinhado ao rail lateral (abaixo da topbar sticky, que continua clicável). */
.fcds-lateral { position:fixed; top:var(--topbar-h, 52px); right:0; height:calc(100vh - var(--topbar-h, 52px));
  width:var(--fcds-lateral-w, min(32.5rem, 92vw)); z-index:30; visibility:hidden; transform:translateX(100%);
  transition:transform .22s cubic-bezier(.22,1,.36,1), visibility .22s, width .22s cubic-bezier(.22,1,.36,1); }
.fcds-lateral[data-aberto] { transform:none; visibility:visible; }
.fcds-lateral .modal-content { height:100%; background:var(--surf); border:0;
  border-left:var(--bs-border-width) solid var(--gc-line);
  border-radius:0; box-shadow:-1rem 0 2.5rem rgba(16,24,40,.10); }
/* Calhas EXPLÍCITAS. `.fcds-lateral` é um <aside>, não um `.modal`, então as
   custom properties `--bs-modal-*` não resolvem e o padding do header/body do
   Bootstrap cai para zero: título e botão de fechar nasciam colados na borda.
   Uma calha só (1rem) alinha título, chip de escopo e 1ª coluna da grade. */
.fcds-lateral .modal-header { padding:0.875rem 1rem 0.625rem; gap:0.5rem; align-items:flex-start;
  border-bottom:var(--bs-border-width) solid var(--gc-line-2); }
.fcds-lateral .fcds-modal__titulo { margin:0; }
.fcds-lateral .btn-close { margin:0.125rem 0 0 auto; flex:0 0 auto; }
/* Corpo sem calha própria: a grade sangra de borda a borda e quem dá o recuo
   é a 1ª/última célula (1rem), senão o texto da tabela ficaria 32px para
   dentro enquanto o título fica em 16px. */
.fcds-lateral .modal-body { padding:0; }
/* No painel a largura é curta: o texto livre (fornecedor, observação) quebra
   a linha, só entre palavras, em vez de ser cortado ou pintado por cima da
   coluna vizinha. Data e código (`.fcds-gm__inteiro`) nunca quebram; se não
   couberem, a grade rola na horizontal (reporte #576). */
.fcds-lateral .fcds-gm td:not(.fcds-gm__num):not(.fcds-gm__inteiro) { max-width:15rem; white-space:normal; overflow-wrap:break-word; }
.fcds-lateral .fcds-gm thead th { padding-top:0.375rem; padding-bottom:0.375rem; }
.fcds-lateral .fcds-gm tbody td { padding-top:0.3125rem; padding-bottom:0.3125rem; }
.fcds-lateral .fcds-gm tfoot td { padding-top:0.4375rem; padding-bottom:0.4375rem; }
.main { transition:margin-right .22s cubic-bezier(.22,1,.36,1); }
body[data-lateral] .main { margin-right:var(--fcds-lateral-w, min(32.5rem, 92vw)); }
/* Docar exige rail (3rem) + calhas (2.5rem) + o piso da matriz + o painel mais
   largo (42rem) — ~106.75rem. Abaixo disso ceder a largura não "abre espaço",
   espreme: a 1366px sobravam 606px de matriz e a célula que originou o drill
   saía de vista. Então o painel SOBREPÕE, como já fazia no mobile. */
@media (max-width:106.75rem) {
  body[data-lateral] .main { margin-right:0; }
}
@media (prefers-reduced-motion: reduce) {
  /* `.side` e `.subnav` são o SHELL, e não estavam cobertos por nenhum dos
     blocos de reduced-motion do arquivo: `.fcds-lateral` é outra classe, e os
     blocos por página (`[data-pagina="crm-deal"] *`, por exemplo) ficam presos
     à `div.page`, que é descendente do `main` — a sidebar mora fora dela.
     Resultado medido: a sidebar animava `width` (.26s) e cada `.subnav`
     animava `max-height` (.24s) mesmo com o sistema pedindo movimento
     reduzido, em toda página do app. São propriedades de LAYOUT, as que mais
     incomodam quem pediu para reduzir. */
  .fcds-lateral, .main, .side, .subnav { transition:none; }
}

.fcds-gm__wrap { overflow:auto; }
table.fcds-gm { border-collapse:collapse; width:100%; font-size: var(--fonte-corpo); }
/* `text-align:left` NÃO volta aqui: `td` já é left por default do navegador, e a
   declaração só existia para — sem querer — vencer `.fcds-gm__num` (0,1,1 > 0,1,0).
   Era por isso que Qtd, R$ e data nunca alinharam à direita. O `th` precisa da
   declaração porque `th` é center por default.
   `border-right` também sai: com 7 colunas × 100+ linhas o quadriculado vira ruído.
   Quem separa o bloco numérico do bloco de texto agora é o respiro de §num. */
.fcds-gm th, .fcds-gm td { padding:0.25rem 0.625rem; white-space:nowrap; line-height:1.5;
  border-bottom:var(--bs-border-width) solid var(--gc-line-2); }
.fcds-gm th { text-align:left; }
.fcds-gm tbody td:first-child, .fcds-gm thead th:first-child, .fcds-gm tfoot td:first-child { padding-left:1rem; }
.fcds-gm tbody td:last-child, .fcds-gm thead th:last-child, .fcds-gm tfoot td:last-child { padding-right:1rem; }
/* Coluna numérica ganha 6px a mais à esquerda: é o espaçamento que assume o
   trabalho da régua vertical removida. Sem ele, "12,7mm" cola em "39,6". */
.fcds-gm th.fcds-gm__num, .fcds-gm td.fcds-gm__num { text-align:right; padding-left:1rem;
  font-family:var(--mono); font-variant-numeric:tabular-nums; }
.fcds-gm thead th { position:sticky; top:0; z-index:2; background:var(--surf); cursor:pointer; user-select:none;
  padding-top:0.375rem; padding-bottom:0.375rem;
  font-size: var(--fonte-rotulo); letter-spacing:.09em; text-transform:uppercase; color:var(--gc-ink-3);
  font-weight:500; border-bottom:var(--bs-border-width) solid var(--gc-line); }
.fcds-gm thead th:hover { color:var(--gc-ink); }
.fcds-gm thead th:focus-visible { outline:2px solid var(--acc); outline-offset:-2px; }
/* Seta de ordenação em slot de largura fixa — sem isto o cabeçalho reflowa a cada
   clique, porque a seta era concatenada ao texto. */
.fcds-gm__seta { display:inline-block; width:0.75rem; text-align:center; opacity:0.8; }
/* Total lê como banda: fundo próprio e régua de 1px (era 2px), sem peso extra. */
.fcds-gm tfoot td { position:sticky; bottom:0; z-index:2; background:var(--surf-2); font-weight:500;
  padding-top:0.3125rem; padding-bottom:0.3125rem; border-top:var(--bs-border-width) solid var(--gc-ink); }
.fcds-gm tbody tr:hover td { background:var(--gc-line-2); }
.fcds-gm__acao { width: 2.75rem; text-align:center; }
.fcds-gm__info { border:0; background:transparent; color:var(--brand); cursor:pointer; padding:0; font-size:var(--fonte-destaque); line-height:1; }
.fcds-gm__info:hover { color:var(--brand-ink); }
/* Linha-mãe que abre as filhas na MESMA grade (#260 — drill nativo, sem caixa:
   o detalhe é linha da grade, não painel empilhado). A seta gira ao abrir; a
   filha recua sob a mãe e lê um tom abaixo. */
.fcds-gm__abrir { border:0; background:transparent; color:var(--brand); cursor:pointer; padding:0; font-size:var(--fonte-corpo); line-height:1; }
.fcds-gm__abrir:hover { color:var(--brand-ink); }
.fcds-gm__abrir:focus-visible { outline:2px solid var(--acc); outline-offset:2px; }
.fcds-gm__abrir i { transition:transform .12s; }
.fcds-gm__abrir[aria-expanded="true"] i { transform:rotate(90deg); }
.fcds-gm__abrir + .fcds-gm__info { margin-left:0.5rem; }
.fcds-gm tbody tr.fcds-gm__filha td { color:var(--ink-2); }
.fcds-gm tbody tr.fcds-gm__filha td:first-child { padding-left:2rem; }
@media (prefers-reduced-motion: reduce) { .fcds-gm__abrir i { transition:none; } }

/* ── Responsivo ──────────────────────────────────────────────────────────── */
@media (max-width:575.98px) {
  /* Calha 16px → 12px nas faixas próprias do componente; o cabeçalho ficou com a
     do Bootstrap. As faixas rolam na horizontal em vez de quebrar linha. */
  .fcds-modal__tabs { padding-left:0.75rem; padding-right:0.75rem;
    flex-wrap:nowrap; overflow-x:auto; }
  .fcds-gm th, .fcds-gm td { padding-left:0.5rem; padding-right:0.5rem; }
  .fcds-gm th.fcds-gm__num, .fcds-gm td.fcds-gm__num { padding-left:0.75rem; }
  .fcds-gm tbody td:first-child, .fcds-gm thead th:first-child, .fcds-gm tfoot td:first-child { padding-left:0.75rem; }
  .fcds-gm tbody td:last-child, .fcds-gm thead th:last-child, .fcds-gm tfoot td:last-child { padding-right:0.75rem; }
  .gc-mx td.gc-k, .gc-mx thead th.gc-rowh { width: 9.375rem; }
  .gc-mx col.gc-c-rowh { width: 9.375rem; }
}

/* ── Aba Metas (gerência 26/08): realizado × em negociação × meta ─────────── */
.gc-meta-aviso { display: block; margin-top: 0.125rem; font-size: var(--fonte-pequena);
  font-weight: 400; line-height: 1.2; color: #FA4B00; white-space: normal; }
.gc-sugerida { font-style: italic; }
.gc-metas { padding: 1rem 1.25rem 1.25rem; }
.gc-metas__bar { display:flex; align-items:center; gap:0.625rem; flex-wrap:wrap;
  margin-bottom: 0.875rem; }
.gc-metas__ttl { margin: 0.875rem 0 0.375rem; font-size: var(--fonte-rotulo);
  font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--bs-secondary-color, #6c757d); }
.gc-mtable { max-width: 68.75rem; margin-bottom: 0.25rem; }
.gc-mtable td, .gc-mtable th { vertical-align: middle; }
/* Mesma inversão da matriz: R$ é o número principal, tonelada é a linha de
   apoio (.gc-cr, compartilhada com a célula da matriz). */
.gc-mtv { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.gc-mtotal td { font-weight: 500; border-top: 2px solid var(--bs-border-color, #dee2e6); }

/* ── Modo Compras (#271/#160): meta por SKU, falta/sobra e compra sugerida ── */
/* Tela usa a janela inteira: o contêiner ocupa a altura toda mesmo com pouca linha. */
.gc-compras { padding: 1rem 1.25rem 1.25rem; background: #fff; }
.gc-compras__campo { display: inline-flex; align-items: center; gap: 0.375rem; margin: 0;
  font-size: var(--fonte-pequena); color: var(--bs-secondary-color, #6c757d); }
.gc-compras__campo .form-select { width: auto; }
.gc-compras__nota { margin: -0.5rem 0 0.75rem; font-size: var(--fonte-pequena);
  color: var(--bs-secondary-color, #6c757d); }
.gc-compras__corpo { min-height: 12rem; }
.gc-compras__avisos { margin-bottom: 0.75rem; }
.gc-compras__prazo { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.gc-compras__dias { width: 5rem; }
.gc-compras__atencao { color: #FA4B00; }
.gc-compras__msg { margin-bottom: 0.5rem; font-weight: 500; }
.gc-compras__conc { margin-bottom: 0.375rem; transition: opacity 0.15s; }
.gc-compras__cod { color: var(--bs-secondary-color, #6c757d); font-size: var(--fonte-pequena); }

/* ===== MERGED FROM bi/static/bi/css/inadimplencia.css (P5 — page-local dissolve) ===== */
/* ── Foco banner (FCDS inline status / active-filter banner) ─────────────── */

.foco-banner {
  margin:var(--bi-space-sm) var(--bi-space-md);
  padding:var(--bi-space-xs2) var(--bi-space-sm);
  border: var(--bs-border-width) solid color-mix(in srgb, var(--brand, var(--bi-text-primary)) 22%, transparent);
  border-radius: var(--bi-radius-sm);
  background: color-mix(in srgb, var(--brand, var(--bi-text-primary)) 6%, white);
  color: var(--bi-text-primary);
  font-size: var(--fonte-pequena);
}

.foco-banner__clear {
  margin-left:var(--bi-space-sm);
  padding:0;
  border: 0;
  background: none;
  color: var(--brand, var(--negative-text));
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

/* ── Ranked list-row component (aging faixas + devedores) ─────────────────── */
/* Generated by inadimplencia.js (renderizarAgingTable / renderizarDevedores);
   this file is the sole definition — do not delete while that markup exists.   */

.top5__row {
  padding:var(--bi-space-sm) var(--bi-space-md);
  border-bottom: var(--bs-border-width) solid var(--line);
  border-left: 3px solid transparent;
  cursor: pointer;
  transition: background 120ms ease, border-left-color 120ms ease;
}

.top5__row:hover {
  background: var(--surf-2);
}

.top5__row--ativo {
  background: color-mix(in srgb, var(--negative-text) 6%, white);
  border-left-color: var(--negative-text);
}

/* Modal "Recebimentos a Vencer": a faixa é gatilho do filtro da grade de títulos (#249). */
#modalbox-pmr-bucket-tbody tr[data-faixa],
#modalbox-pmr-bucket-todas {
  cursor: pointer;
}

#modalbox-pmr-bucket-tbody tr[data-faixa]:hover {
  background: var(--surf-2);
}

#modalbox-pmr-bucket-tbody .modalbox-faixa--ativa {
  background: color-mix(in srgb, var(--ds-acao) 8%, white);
}

/* Aging active uses per-faixa severity color (--faixa-cor set inline by JS) */
#bi-aging-lista .top5__row--ativo {
  background: color-mix(in srgb, var(--faixa-cor, var(--negative-text)) 8%, white);
  border-left-color: var(--faixa-cor, var(--negative-text));
}

.top5__rank {
  font-size: var(--fonte-pequena);
  color: var(--bi-text-muted);
  font-weight: 500;
  flex-shrink: 0;
}

.top5__nome {
  font-size: var(--fonte-corpo);
  font-weight: 500;
  color: var(--bi-text-primary);



  flex: 1;
  min-width: 0;
}

.top5__row--ativo .top5__nome {
  color: var(--negative-text);
}

.top5__valor {
  font-family: var(--sans);
  font-size: var(--fonte-titulo);
  font-weight: 500;
  color: var(--negative-text);
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
  flex-shrink: 0;
}

.top5__bar-track { --barra-altura: 0.375rem; --barra-cor: var(--negative-text); margin-top:var(--bi-space-xs2); }

/* ── 2×2 analysis cards: equal-height scroll bodies ──────────────────────── */
/* The aging + devedores list bodies use the shared .card-scroll utility
   (custom.css) so they cap at --bi-scroll-cap and read at one height.
   See bi/templates/bi/inadimplencia.html (#bi-aging-card-body, #bi-top-clientes). */

/* ===== MERGED FROM bi/static/bi/css/mercado-importacao.css (P5 — page-local dissolve) ===== */
/* ============================================================================
   Mercado de Importação — folha de estilo própria da tela (rebuild "do zero").
   NÃO depende de main.css nem dos componentes legados (.card/.rank/.grid).
   Linguagem MODERNA: superfícies brancas macias, muito respiro, tipografia
   confiante (Roboto em numerais e corpo), paleta contida,
   barras desenhadas à mão (sem o visual padrão do Chart.js), micro-motion.

   Perspectiva: briefing competitivo de preço (inspirado no deck Logcomex
   FOUR × AWA × South Service) — veredito de preço como tese, estrutura de
   mercado como apoio. Tudo escopado em `.mx` para não vazar para o resto do app.
   ========================================================================== */

.mx {
  /* superfícies — CONSOLIDADO 2026-08-06 (DESIGN.md §6): os sete tokens de
     estrutura eram cópias a Δ≤10 dos globais; viram alias para matar a deriva
     sem tocar nas ~40 regras da página. --mx-ink-3 era #98a1ae (~2,6:1 como
     texto, reprova AA) e agora lê o --ink-3 global — a única mudança visível. */
  --mx-panel: var(--surf);
  --mx-inset: var(--surf-2);    /* trilhos de barra, insets */
  --mx-ink: var(--ink);
  --mx-ink-2: var(--ink-2);
  --mx-ink-3: var(--ink-3);
  --mx-line: var(--line-2);
  --mx-line-2: var(--line-3);

  /* identidade / papéis (cor com significado — é DADO, fica) */
  --mx-four: #006bb5;           /* FOUR — azul da marca */
  --mx-rival: #d97706;          /* concorrente nomeado — âmbar */
  --mx-other: #7c8aa0;          /* demais importadores — slate sólido (não "disabled") */
  --mx-bar: #2f7dc4;            /* barras de ranking neutras — azul confiante */

  /* veredito = DIREÇÃO: alias da família global (era um rosa-vermelho e um
     esmeralda próprios — terceira família para dizer bom/ruim). Os pares
     *-soft morreram sem uso, junto com --mx-shadow e os -soft de identidade. */
  --mx-up: var(--negative-text);    /* mais cara = ruim */
  --mx-down: var(--positive-text);  /* mais barata = bom */

  /* Raio e sombra próprios REMOVIDOS 2026-08-07 (decisão do dono, DESIGN.md
     §4/A Regra do Plano): raio lê o global, sombra vira borda hairline. */
  --mx-radius: var(--r);
  --mx-radius-sm: var(--r-sm);
  --mx-radius-xs: var(--r-xs);
  --mx-gap:clamp(1rem, 1.4vw + 0.5rem, 1.5rem);

  color: var(--mx-ink);
  font-variant-numeric: tabular-nums;
}

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

.mx-body[hidden] { display: none; }

/* ── Estado vazio / erro ──────────────────────────────────────────────────── */
.mx-empty {
  margin-top:var(--mx-gap);
  padding:clamp(1.5rem, 6vw, 3rem) 1.5rem;
  background: var(--mx-panel); border-radius: var(--mx-radius);
  border: 1px solid var(--line);
  text-align: center; color: var(--mx-ink-2);
}

/* ════════════════════════════════════════════════════════════════════════════
   MASTHEAD — identidade do relatório + tamanho do mercado
   ════════════════════════════════════════════════════════════════════════════ */
.mx-mast {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap:1rem 3rem;
  padding:0.25rem 0 1.5rem;
}
.mx-mast__id { min-width: 0; }
.mx-mast__title {
  margin:0; font-family: var(--bi-font-display); font-weight: 500;
  font-size: var(--fonte-titulo); line-height: 28px;
  letter-spacing: -0.015em; color: var(--mx-ink); text-wrap: balance;
}
/* #451: a data do último dado não quebra na topbar apertada */
#mi-fresh { flex-shrink: 0; white-space: nowrap; }
/* faixa de totais do mercado — chips suaves */
.mx-totals { display: flex; flex-wrap: wrap; gap:0.5rem; margin:0; }
.mx-tot {
  display: flex; flex-direction: column; gap:0;
  padding:0.5rem 1rem; background: var(--mx-panel); border-radius: var(--mx-radius-xs);
  border: 1px solid var(--line);
}
.mx-tot__l { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: var(--mx-ink-3); white-space: nowrap; }
.mx-tot__v { font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-destaque); line-height: 24px; color: var(--mx-ink); white-space: nowrap; }
.mx-tot--lead { background: var(--mx-four); }
.mx-tot--lead .mx-tot__l { color: rgba(255, 255, 255, .78); }
.mx-tot--lead .mx-tot__v { color: var(--bi-text-on-accent); }

/* ════════════════════════════════════════════════════════════════════════════
   VEREDITO — a tese da página (assinatura)
   ════════════════════════════════════════════════════════════════════════════ */
/* Bordo/bg/radius/sombra vêm de .card.shadow-sm.border-0 (aplicado no
   template); aqui só o residual sem primitiva: grid interno de 2 colunas +
   espaçamentos responsivos (clamp) que o .card fixo não cobre. */
.mx-verdict {
  display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap:clamp(1.5rem, 3vw, 3rem);
  margin-top:var(--mx-gap);
  padding:clamp(1.5rem, 2.4vw, 3rem);
}
.mx-verdict__kick {
  display: block; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--mx-ink-3); margin-bottom:1rem;
}
.mx-verdict__headline {
  margin:0 0 1.5rem; display: flex; align-items: baseline; flex-wrap: wrap; gap:0 1rem;
}
.mx-delta {
  font-family: var(--bi-font-display); font-weight: 500;
  font-size: var(--fonte-heroi); line-height: 40px; letter-spacing: -0.02em;
  color: var(--mx-ink); white-space: nowrap; /* #451: o "%" não desce sozinho */
}
.mx-delta--up { color: var(--mx-up); }
.mx-delta--down { color: var(--mx-down); }
.mx-delta--brand { color: var(--mx-four); }
.mx-verdict__word {
  font-size: var(--fonte-titulo); font-weight: 400; color: var(--mx-ink);
  max-width: 18ch; line-height: 28px;
}
.mx-verdict__word b { font-weight: 500; }

/* head-to-head: FOUR vs rival mais barato (o callout do deck) */
.mx-h2h { display: flex; flex-direction: column; gap:0.5rem; max-width: 28.75rem; }
.mx-h2h__row { display: grid; grid-template-columns: 4rem 1fr auto; align-items: center; gap:0.5rem; }
.mx-h2h__name { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: var(--mx-ink-2); }
.mx-h2h__row--four .mx-h2h__name { color: var(--mx-four); }
.mx-h2h__row--rival .mx-h2h__name { color: var(--mx-rival); }
.mx-h2h__track { height: 0.875rem; --bs-progress-bg: var(--mx-inset); border-radius: var(--raio-chip); }
.mx-h2h__fill { border-radius: var(--raio-chip); transform-origin: left center; }
.mx-h2h__row--four .mx-h2h__fill { --bs-progress-bar-bg: var(--mx-four); }
.mx-h2h__row--rival .mx-h2h__fill { --bs-progress-bar-bg: var(--mx-rival); }
.mx-h2h__val { font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-destaque); color: var(--mx-ink); white-space: nowrap; }
.mx-h2h__foot { margin:0.25rem 0 0; font-size: var(--fonte-pequena); color: var(--mx-ink-3); }

/* coluna direita: fatia + rank */
.mx-verdict__stats {
  display: flex; flex-direction: column; justify-content: center; gap:1.5rem;
  padding-left:clamp(1.5rem, 3vw, 3rem); border-left: var(--bs-border-width) solid var(--mx-line);
}
.mx-stat { display: flex; flex-direction: column; gap:0.25rem; }
.mx-stat__v { font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-heroi); line-height: 40px; letter-spacing: -0.02em; color: var(--mx-ink); }
.mx-stat--share .mx-stat__v { color: var(--mx-four); }
.mx-stat__l { color: var(--mx-ink-2); max-width: 22ch; }

/* ════════════════════════════════════════════════════════════════════════════
   PAINEL genérico + cabeçalho
   ════════════════════════════════════════════════════════════════════════════ */
/* Bordo/bg/radius/sombra e a estrutura cabeçalho+corpo vêm de
   .card.shadow-sm.border-0 > .card-header (+ utilities d-flex/justify-
   content-between/align-items-baseline/flex-wrap/gap-2) > .card-body,
   aplicado direto no template. .card já é flex-column e .card-body já é
   flex:1 1 auto (Bootstrap), então os painéis de gráfico (ex-.mx-panel--chart)
   não precisam mais de regra própria — só ganham a classe `d-flex` no
   .card-body para os filhos que crescem (.mx-spark/.mx-transporte, abaixo)
   se esticarem dentro dele. Residual: min-width:0 evita overflow do item
   dentro do CSS Grid (.mx-grid), efeito que o .card sozinho não resolve. */
.mx-panel { min-width: 0; }
.mx-panel__title { margin:0; font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -0.01em; color: var(--mx-ink); }
.mx-panel__note { font-size: var(--fonte-pequena); color: var(--mx-ink-3); }

/* ── Escada de preços (painel destacado) ──────────────────────────────────── */
.mx-ladder { margin-top:var(--mx-gap); }
.mx-legend { display: flex; flex-wrap: wrap; gap:0.5rem 1rem; margin:-0.25rem 0 1rem; }
.mx-legend__i { display: inline-flex; align-items: center; gap:0.5rem; color: var(--mx-ink-2); }
.mx-legend__i::before { content: ''; width: 0.6875rem; height: 0.6875rem; border-radius: var(--bs-border-radius-sm); }
.mx-legend__i--four::before { background: var(--mx-four); }
.mx-legend__i--rival::before { background: var(--mx-rival); }
.mx-legend__i--other::before { background: var(--mx-other); }

/* barras horizontais da escada */
.mx-bars { display: flex; flex-direction: column; gap:1rem; }
.mx-bar { display: grid; grid-template-columns: minmax(6.875rem, 10.5rem) 1fr; align-items: center; gap:1rem; }
.mx-bar__name { color: var(--mx-ink-2); }
.mx-bar--self .mx-bar__name { font-weight: 500; color: var(--mx-four); }
.mx-bar__track { position: relative; display: flex; align-items: center; gap:0.5rem; }
.mx-bar__fill { flex: 0 0 auto; height: 1.625rem; border-radius: var(--bs-border-radius-lg); transform-origin: left center; min-width: 0.1875rem; }
.mx-bar__fill--four { background: var(--mx-four); }
.mx-bar__fill--rival { background: var(--mx-rival); }
.mx-bar__fill--other { background: var(--mx-other); }
.mx-bar__val { font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-destaque); color: var(--mx-ink); white-space: nowrap; }

/* ════════════════════════════════════════════════════════════════════════════
   SEÇÕES + GRID
   ════════════════════════════════════════════════════════════════════════════ */
.mx-sec { display: flex; align-items: baseline; gap:0.5rem; margin:clamp(1.5rem, 4vw, 3rem) 0 0; }
.mx-sec__t { margin:0; font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-titulo); letter-spacing: -0.01em; color: var(--mx-ink); white-space: nowrap; }
.mx-sec__s { font-size: var(--fonte-pequena); color: var(--mx-ink-3); }

.mx-grid { display: grid; gap:var(--mx-gap); margin-top:var(--mx-gap); }
.mx-grid--8-4 { grid-template-columns: 2fr 1fr; }
.mx-grid--2 { grid-template-columns: 1fr 1fr; }

/* ── Lista ranqueada (própria — substitui .rank) ───────────────────────── */
.mx-rank { display: flex; flex-direction: column; }
.mx-rank__row { padding:0.5rem 0; border-top: var(--bs-border-width) solid var(--mx-line); }
.mx-rank__row:first-child { border-top: 0; }
.mx-rank__top { display: flex; align-items: baseline; gap:0.5rem; margin-bottom:0.5rem; }
.mx-rank__pos { flex-shrink: 0; min-width: 1.375rem; font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-destaque); color: var(--mx-ink-3); }
.mx-rank__name { flex: 1 1 auto; min-width: 0; color: var(--mx-ink); }
.mx-rank__val { flex-shrink: 0; font-family: var(--bi-font-display); font-weight: 500; font-size: var(--fonte-destaque); color: var(--mx-ink); }
.mx-rank__sub { margin:-0 0 0.5rem 1.5rem; font-size: var(--fonte-pequena); color: var(--mx-ink-3); }
.mx-rank__track { height: 0.4375rem; --bs-progress-bg: var(--mx-inset); border-radius: var(--raio-chip); }
.mx-rank__fill { border-radius: var(--raio-chip); --bs-progress-bar-bg: var(--mx-bar); transform-origin: left center; }
.mx-rank__row--self .mx-rank__name { font-weight: 500; color: var(--mx-four); }
.mx-rank__row--self .mx-rank__fill { --bs-progress-bar-bg: var(--mx-four); }
.mx-rank__row--self .mx-rank__pos { color: var(--mx-four); }

/* card-scroll: limita altura de listas longas mantendo painéis alinhados */
.mx-scroll { max-height: 22.5rem; overflow: auto; }
.mx-scroll::-webkit-scrollbar { width: 0.5rem; }
.mx-scroll::-webkit-scrollbar-thumb { background: var(--mx-line-2); border-radius: var(--raio-chip); }

/* ── Tendência mensal (spark de barras verticais — próprio) ───────────────── */
.mx-spark { flex: 1 1 auto; width: 100%; display: flex; align-items: flex-end; justify-content: space-around; gap:clamp(0.5rem, 2vw, 1.5rem); min-height: 13.125rem; padding-top:1.5rem; }
.mx-spark__col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap:0.5rem; height: 100%; justify-content: flex-end; min-width: 0; }
.mx-spark__bar-wrap { flex: 1 1 auto; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap:0.25rem; }
.mx-spark__bar { width: min(100%, 60px); border-radius: var(--bs-border-radius-lg) var(--bs-border-radius-lg) 0 0; background: var(--mx-four); transform-origin: bottom center; min-height: 0.1875rem; }
.mx-spark__v { font-family: var(--bi-font-display); font-weight: 500; color: var(--mx-ink-2); white-space: nowrap; }
.mx-spark__x { font-size: var(--fonte-pequena); color: var(--mx-ink-3); white-space: nowrap; }

/* ── Mapa UF (Leaflet) + ranking ──────────────────────────────────────────── */
.mx-geo { display: grid; grid-template-columns: 1.4fr 1fr; gap:1rem; align-items: start; }
.mx-geo__map { height: 20rem; border-radius: var(--mx-radius-sm); overflow: hidden; background: var(--mx-inset); }
.mx-geo__map .leaflet-container { background: transparent; font: inherit; outline: none; }
.mx-geo__map .leaflet-interactive:focus { outline: none; }

/* ── Donut do modal de transporte (conic-gradient — próprio, sem Chart.js) ── */
/* display:flex + flex:1 1 auto residual: antes vinha de
   `.mx-panel--chart > :last-child` (removido); precisa continuar crescendo
   dentro do .card-body.d-flex e sendo container flex para o .mx-donut-wrap. */
.mx-transporte { width: 100%; display: flex; flex: 1 1 auto; }
.mx-donut-wrap { flex: 1 1 auto; width: 100%; display: flex; align-items: center; justify-content: center; gap:clamp(1rem, 3vw, 3rem); flex-wrap: wrap; }
.mx-donut { --mx-donut-bg: conic-gradient(var(--mx-inset) 0 100%);
  flex-shrink: 0; width: clamp(160px, 14vw, 210px); aspect-ratio: 1; border-radius: 50%;
  background: var(--mx-donut-bg);
  -webkit-mask: radial-gradient(circle 60px at center, transparent 98%, var(--ink) 100%);
          mask: radial-gradient(circle 60px at center, transparent 98%, var(--ink) 100%);
}
.mx-donut-leg { display: flex; flex-direction: column; gap:0.5rem; min-width: 0; }
.mx-donut-leg__i { display: grid; grid-template-columns: 0.75rem 1fr auto; align-items: center; gap:0.5rem; }
.mx-donut-leg__dot { width: 0.75rem; height: 0.75rem; border-radius: var(--bs-border-radius-sm); }
.mx-donut-leg__l { color: var(--mx-ink-2); }
.mx-donut-leg__v { font-family: var(--bi-font-display); font-weight: 500; color: var(--mx-ink); }

.mx-mini-empty { padding:1.5rem 0.5rem; text-align: center; color: var(--mx-ink-3); }

/* ── Picker no topbar (escopo global, fora de .mx) ────────────────────────── */
.mi-pick { display: flex; align-items: center; gap:0.5rem; min-width: 0; }
.mi-pick__lab { font-size: var(--fonte-corpo); font-weight: 500; color: var(--bi-text-secondary); }
.mi-pick__sel { width: auto; min-width: 10.625rem; max-width: 21.25rem; }
.mi-pick__per { font-size: var(--fonte-corpo); white-space: nowrap; }

/* ════════════════════════════════════════════════════════════════════════════
   MOTION — entrada suave + crescimento de barras (respeita reduced-motion)
   ════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
  .mx-verdict, .mx-ladder, .mx-panel, .mx-mast { animation: mx-rise .5s cubic-bezier(.22, 1, .36, 1) both; }
  .mx-ladder { animation-delay: .04s; }
  @keyframes mx-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

  .mx-bar__fill, .mx-rank__fill, .mx-h2h__fill { animation: mx-grow-x .55s cubic-bezier(.22, 1, .36, 1) both; }
  @keyframes mx-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  .mx-spark__bar { animation: mx-grow-y .55s cubic-bezier(.22, 1, .36, 1) both; }
  @keyframes mx-grow-y { from { transform: scaleY(0); } to { transform: scaleY(1); } }
}

/* ════════════════════════════════════════════════════════════════════════════
   RESPONSIVO
   ════════════════════════════════════════════════════════════════════════════ */
@media (max-width:991.98px) {
  .mx-grid--8-4, .mx-grid--2 { grid-template-columns: 1fr; }
  .mx-geo { grid-template-columns: 1fr; }
}
@media (max-width:767.98px) {
  .mx-verdict { grid-template-columns: 1fr; }
  .mx-verdict__stats { flex-direction: row; gap:1.5rem; padding-left:0; border-left: 0; padding-top:1.5rem; border-top: var(--bs-border-width) solid var(--mx-line); }
  .mx-bar { grid-template-columns: 6rem 1fr; }
  .mx-tot--lead { width: 100%; }
}

/* .fresh (badge de frescor) é canônico único acima (§ Badge de frescor) —
   dedup: o bloco duplicado que vivia aqui (hardcode #059669) foi removido. */

/* === METAS — planilha do ano por segmento (#376) ===============================
   A folha é a planilha da casa (seção PLANILHA DA CASA). Aqui só o que é da
   tela: abas de segmento, blocos (sub-segmento, TOTAL, despesas), a coluna ANO,
   o seletor de unidade do volume e o aviso. A tela ocupa a janela inteira: só a
   folha rola, com cabeçalho e primeira coluna presos. */
.page.met { padding-top: .5rem; }   /* altura: `content--altura-cheia` (a folha fica com a sobra) */
.met-ano select { min-width: 6rem; }
.met-abas { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: .5rem; flex-wrap: wrap; }
.met-aba { border: 0; background: none; padding: .45rem .9rem; font-size: var(--fonte-corpo); color: var(--ink-2);
           border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; }
.met-aba:hover { color: var(--ink); }
.met-aba[aria-selected="true"] { color: var(--ink); font-weight: 500; border-bottom-color: var(--bs-primary); }
.met-aba:focus-visible { outline: none; box-shadow: var(--ring); }
.met-folha { flex: 1 1 auto; min-height: 0; }
.met-vazio { padding: 1rem; color: var(--ink-3); }
/* Rótulo de bloco: o nome do sub-segmento, o TOTAL, as DESPESAS. */
.met-planilha tr.met-bloco th { font-weight: 500; padding-top: .7rem; }
.met-planilha tr.met-bloco td { border-bottom-color: var(--line-2); }
.met-planilha tr.met-linha th { padding-left: 1.5rem; color: var(--ink-2); }
/* TOTAL e a coluna ANO são do servidor e não se editam: peso médio, sem fundo
   cinza (cinza lê como desabilitado). */
.met-planilha tr.met-total td, .met-planilha td:last-child { font-weight: 500; }
.met-planilha .met-coluna-ano, .met-planilha td:last-child { border-left: 1px solid var(--line); }
.met-planilha tr.met-total.met-bloco th { border-top: 1px solid var(--line-3); }
/* Volume na unidade de VENDA, travada pelo servidor (#376). Área que vende em
   mais de uma unidade diz isso abaixo do rótulo, sem cor de alarme. */
.met-unidade-aviso { display: block; font-size: var(--fonte-pequena); line-height: 1.2; color: var(--ink-3); }
/* Unidade ao lado do número em toda célula (#393): menor e mais clara, o número manda. */
.met-planilha .met-unidade { font-size: var(--fonte-pequena); color: var(--ink-3); font-weight: 400; }
/* Faturamento calculado pelo servidor (Volume × Valor unitário, #441): só leitura. */
.met-planilha td.met-calculada { color: var(--ink-2); cursor: default; }
/* Realizado em KG e meta antiga noutra unidade (#452): só leitura, tom do calculado.
   Mês com item sem peso diz isso no lugar do número; a lista dos itens fica abaixo da área. */
.met-planilha tr.met-realizado td, .met-planilha tr.met-volume-antigo td, .met-planilha td.met-sem-peso { color: var(--ink-2); cursor: default; }
.met-planilha td.met-sem-peso { font-size: var(--fonte-pequena); color: var(--ink-3); }
.planilha.met-planilha tr.met-sem-peso-lista td { text-align: left; white-space: normal; font-size: var(--fonte-pequena); color: var(--ink-3); font-weight: 400; border-left: 0; }
/* Com a unidade em toda célula o ano inteiro só cabe em 1600 px apertando a
   folha: o fio vertical entre os meses (dono, #393) separa as colunas, então o
   respiro lateral encolhe; o rótulo é mais estreito e quebra em duas linhas em
   vez de cortar (medido em 14/10: 1678 -> 1511 px na área de 1512). */
/* `.planilha.met-planilha`: a seção `.planilha` vem depois no arquivo. */
.planilha.met-planilha td, .planilha.met-planilha thead th:not(.planilha-rotulo) { padding-left: .15rem; padding-right: .15rem; }
.planilha.met-planilha .planilha-editor-caixa { padding: 0 .15rem; }
.planilha.met-planilha .planilha-rotulo { min-width: 9rem; max-width: 10rem; }
.planilha.met-planilha td + td, .planilha.met-planilha thead th + th { border-left: 1px solid var(--line-2); }
/* ANO segue separado de DEZ pelo fio mais escuro. */
.planilha.met-planilha td:last-child, .planilha.met-planilha thead th:last-child { border-left: 1px solid var(--line); }
/* "+ Meta para sub-segmento sem venda": link discreto no fim da aba; a lista
   abre ali mesmo, sem modal (dono, 13/10). */
.met-ocultos { padding: .75rem .45rem 1rem; font-size: var(--fonte-corpo); }
.met-ocultos button { border: 0; background: none; padding: .2rem .5rem; color: var(--bs-primary); cursor: pointer; }
.met-ocultos button:hover { text-decoration: underline; }
.met-ocultos button:focus-visible { outline: none; box-shadow: var(--ring); }
.met-ocultos-abrir { padding-left: 0 !important; }
.met-ocultos-lista { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .35rem; }
.met-ocultos-lista[hidden] { display: none; }
/* Ocultar/Reexibir no cabeçalho da área (#496): link pequeno, não pesa no rótulo.
   A área ocultada, aberta em "Mostrar ocultos", vem só leitura e mais clara. */
.planilha.met-planilha td.met-acoes { text-align: left; }
/* #526: os botões ficam presos logo à direita do rótulo (10rem, o max-width do rótulo da folha, + o respiro da célula) quando o ano rola. */
.met-planilha .met-acoes-fixas { display: inline-block; position: sticky; left: 10.15rem; }
.met-planilha .met-acao { border: 0; background: none; padding: 0 .25rem; font-size: var(--fonte-pequena); font-weight: 400; color: var(--bs-primary); cursor: pointer; }
.met-planilha .met-acao:hover { text-decoration: underline; }
.met-planilha .met-acao:focus-visible { outline: none; box-shadow: var(--ring); }
.met-planilha tr.met-ocultado th { color: var(--ink-3); }
.met-ocultados-alternar { padding-left: 0 !important; }
/* SKUs da área aberta (#496): recuados sob a área; o título é código + descrição
   (quebra em duas linhas, nunca corta). MB herdada da família vem mais clara.
   A Soma dos SKUs é do servidor; o mês que falta para a meta da área em laranja de texto. */
.met-planilha tr.met-sku-titulo th { padding-left: 1.5rem; padding-top: .7rem; font-weight: 500; color: var(--ink); white-space: normal; }
/* #526: o título acompanha a rolagem do ano; o código, mais claro, separa-se da descrição. */
.met-planilha .met-sku-nome { display: inline-block; position: sticky; left: 1.5rem; }
.met-planilha .met-sku-codigo { margin-right: .35rem; color: var(--ink-2); font-weight: 400; }
.met-planilha tr.met-sku th { padding-left: 2.5rem; }
.met-planilha td.met-herdada { color: var(--ink-3); }
/* Sugestão (#537): o número sugerido na célula vazia vem no tom da MB herdada (sem cor nova,
   dono 21/10); o clique abre a conta numa caixa branca, como o aviso da gravação. */
.met-planilha td.met-sugerida, .met-planilha td.met-sugerida.met-calculada { color: var(--ink-3); cursor: pointer; }
.met-conta { position: absolute; z-index: 1080; max-width: 26rem; padding: .5rem .75rem; background: #fff;
             color: var(--ink); font-size: var(--fonte-pequena); white-space: pre-line;
             border: 1px solid var(--line-3); box-shadow: 0 8px 24px rgba(22,22,22,.16); }
.met-conta[hidden] { display: none; }
/* Reajuste % e "+ Produto novo" na faixa da área, ao lado de "Aplicar sugestão". */
.met-planilha .met-reajuste { font-size: var(--fonte-pequena); color: var(--ink-2); margin: 0 .25rem; white-space: nowrap; }
.met-planilha .met-reajuste input { display: inline-block; width: 4.5rem; margin-left: .25rem; }
.met-planilha .met-produto-novo { display: inline-block; width: auto; max-width: 18rem; margin-left: .25rem; }
.met-planilha .met-acao:disabled { color: var(--ink-3); cursor: default; text-decoration: none; }
.met-planilha .met-sku-marca { margin: 0 .35rem; font-size: var(--fonte-pequena); font-weight: 400; color: var(--ink-2); }
.met-planilha tr.met-soma-skus td { color: var(--ink-2); cursor: default; }
.met-planilha tr.met-soma-skus th { font-weight: 500; }
.met-planilha tr.met-soma-skus td.met-falta { color: var(--warning-text); font-weight: 500; }
/* Aviso da gravação: branco, filete e barra de 3px (toast preto foi reprovado). */
.met-aviso { position: fixed; bottom: 1.25rem; left: 50%; transform: translateX(-50%); z-index: 1090;
             max-width: 40rem; padding: .6rem 1rem; background: #fff; color: var(--ink); font-size: var(--fonte-corpo);
             border: 1px solid var(--line-3); border-left: 3px solid var(--negative-text);
             box-shadow: 0 8px 24px rgba(22,22,22,.16); }
.met-aviso[hidden] { display: none; }
/* Versões (#510), da maquete aprovada (.claude/toolbox/maquetes/510): o painel Versões é o
   offcanvas do Bootstrap com 420px (a topbar já o põe abaixo dela); na comparação, a
   diferença A − B (pronta do servidor) em verde quando positiva, vermelho quando negativa. */
.met-versoes-painel { --bs-offcanvas-width: 420px; }
.planilha.met-planilha td.met-delta-positiva { color: #198754; }
.planilha.met-planilha td.met-delta-negativa { color: #dc3545; }

/* ===== MERGED FROM static/css/forecast-comex.css (P5 — page-local dissolve) ===== */
/* ============================================================
   Forecast Comex — FCDS reskin
   Proprietary "FIDS" styling dropped (IBM Plex + bespoke header).
   Now built on the FCDS design language: the page uses the FCDS
   shell (topbar actions + .kpiband stats + .card board); this file
   only styles the board's own grid/rows/badges/obs/modals/drawer,
   all through the FCDS token set (--fc-* are FCDS-aliased tokens).
   ============================================================ */

/* off-screen drawer must not trigger horizontal scroll.
   Escopado à própria tela: como regra global (`body{...}`) vinda de uma folha
   page-local, atingia todas as páginas e podia matar `position:sticky` em
   descendentes. Mesmo padrão `body:has(...)` já usado pela tracking-comex. */
body:has(.page[data-pagina="forecast_comex"]) { overflow-x: hidden; }

/* A BARRA DE MESES É A MESMA DO GERENCIAL (.gc-months/.gc-mtab/.gc-mdiv) —
   pedido do dono, 31/08/2026 ("vamos replicar a barra de meses do gerencial").
   Aquelas regras leem tokens `--gc-*`, que só existem dentro de `.gc`, e uma
   custom property indefinida INVALIDA a declaração (a aba sairia sem cor — a
   mesma armadilha já anotada no bloco do Gerencial). Redeclara aqui só as cinco
   que a barra usa, apontando para as MESMAS fontes `--bs-*`: não é uma segunda
   paleta, é o mesmo alias em outro escopo. */
.page[data-pagina="forecast_comex"] {
  --gc-panel-3: var(--bs-gray-100);
  --gc-ink-2: var(--bs-secondary-color);
  --gc-ink-3: var(--bs-tertiary-color);
  --gc-line: var(--bs-border-color);
  --gc-accent: var(--bs-primary);
}

/* A LISTA É A TELA: ocupa a janela inteira, não os 46vh do teto global.
   `#fids-table-body` é um `.card-scroll`, cujo `max-height:var(--bi-scroll-cap)`
   (clamp(320px,46vh,460px)) existe para listas que dividem a página com outros
   cartões. Aqui a lista é o único conteúdo do cartão e o cartão é o único
   conteúdo da página — o teto só sobrava faixa branca embaixo. A página vira
   coluna flex de altura fixa (mesmo literal 52px da topbar já usado pela
   .wsurface, linha 8031: não existe token de altura de topbar em :root) e a
   lista fica com a sobra, rolando por dentro com o cabeçalho e a legenda parados. */
.page[data-pagina="forecast_comex"] {
  display: flex; flex-direction: column;
  height: calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b));
}
.page[data-pagina="forecast_comex"] > .grid.mt-2 { flex: 1; min-height: 0; }
.page[data-pagina="forecast_comex"] > .grid.mt-2 > .card {
  display: flex; flex-direction: column; min-height: 0;
}
.page[data-pagina="forecast_comex"] #fids-table-body {
  max-height: none; flex: 1; min-height: 0;
}

/* shared 6-column grid (Processo · Produto · Chegada · Entrega · Freetime · Ações).
   Col-headers, rows and skeleton rows MUST stay in lockstep. */
.fids-col-headers,
.fids-row {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr) 236px 140px 168px 116px;
  gap:0.75rem;
  align-items: start;
}

/* Filtros = .btn-check + .btn do Bootstrap; a barra é utilitária no template. */

/* ── Column headers ────────────────────────────────────────── */
.fids-col-headers {
  padding:0 0.25rem 0.375rem;
  margin-bottom:0;
  border-bottom: var(--bs-border-width) solid var(--fc-border);
}
.fids-col-header {
  font-size: var(--fonte-corpo);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1.2;
}
/* ── Rows ──────────────────────────────────────────────────── */
.fids-row {
  padding:0.375rem 0.25rem;
  border-bottom: var(--bs-border-width) solid var(--fc-border);
  animation: fids-row-in .28s ease both;
  transition: background var(--fc-transition);
}
.fids-row:hover { background: var(--surf-2); }
.fids-row--urgent { box-shadow: inset 3px 0 0 var(--negative); }
@keyframes fids-row-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.fids-cell { min-width: 0; display: flex; flex-direction: column; gap:0.25rem; }
/* Processo é uma linha que quebra (código · containers · observação), não uma
   pilha: a coluna tem largura para dois desses lado a lado. */
.fids-cell--processo { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap:0.125rem 0.5rem; }
.fids-cell--acoes { flex-direction: row; align-items: flex-start; gap:0.125rem; flex-wrap: wrap; }
/* AÇÃO DA LINHA É ÍCONE, NÃO CAIXA. Eram três `btn-outline-secondary` por
   linha — 114 molduras cinzas na tela —, e cinza aqui quer dizer DESABILITADO,
   que é o contrário do que as três ações são. Mesmo desenho da tela irmã
   `processos-comex`: `btn-link` sem sublinhado, alvo de 1.75rem, e a cor no
   ÍCONE carregando o estado (azul = pendente, verde = etapa registrada). O
   estado nunca fica só na cor: a data continua no `title` de cada botão. */
.fids-acao {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem;
  border-radius: var(--fc-radius);
  text-decoration: none;
}
.fids-acao:hover, .fids-acao:focus-visible { background: var(--surf-2); text-decoration: none; }

.fids-processo-head { display: inline-flex; align-items: baseline; gap:0.375rem; }
.fids-transport-icon { color: var(--ink-3); font-size: var(--fonte-corpo); width: 1rem; text-align: center; flex-shrink: 0; }
.fids-processo-code { font-family: var(--bi-font-mono); font-weight: 500; font-size: var(--fonte-corpo); color: var(--ink); word-break: break-word; }

.fids-produto-item { display: flex; flex-wrap: wrap; align-items: baseline; gap:0 0.5rem; }
.fids-produto-item + .fids-produto-item { margin-top:0.125rem; }
/* A observação do produto fica na PRÓPRIA linha, não espremida no fim da
   descrição (pedido do dono): dentro da descrição ela lia como parte do nome. */
.fids-produto-item > .fids-obs-secao { flex: 0 0 100%; }
.fids-produto-item-desc { font-size: var(--fonte-corpo); color: var(--ink); line-height: 1.2; }
.fids-produto-item-qty { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); color: var(--ink-3); white-space: nowrap; }

/* ── Date pair (Chegada: previsão de entrega / chegada real) ── */
.fids-date-pair { display: flex; flex-direction: column; gap:0.125rem; }
.fids-date-linha { display: flex; align-items: baseline; gap:0.375rem; }
.fids-date-prev-label {
  flex: 0 0 2.5rem;
  font-size: var(--fonte-corpo);
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.fids-date-prev { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); color: var(--ink-2); }
.fids-date-real { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); }
.fids-date-real--empty { color: var(--ink-3); font-weight: 400; }
.fids-eta-ts { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); font-weight: 400; color: var(--ink-4); letter-spacing: 0; white-space: nowrap; }

/* ── Badges (urgência) — pill FCDS: bg sutil + dot + texto ──── */

.fids-badge-dot { width: 0.375rem; height: 0.375rem; border-radius: 50%; background: currentColor; flex-shrink: 0; }

/* ── Freetime ──────────────────────────────────────────────── */
.fids-cell--freetime { gap:0.25rem; }
.fids-freetime-prazo { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); color: var(--ink-2); }
.fids-freetime-na { color: var(--ink-3); font-size: var(--fonte-corpo); }
/* ── Observação inline ─────────────────────────────────────── */
.fids-obs-secao { align-self: flex-start; max-width: 100%; }
.fids-obs-container { display: flex; flex-direction: column; gap:0.25rem; }
.fids-obs-display {
  font-size: var(--fonte-corpo);
  line-height: 1.2;
  color: var(--ink-2);
  cursor: text;
  border-radius: var(--fc-radius);
}
.fids-obs-secao--processo .fids-obs-display {
  border: var(--bs-border-width) solid transparent;
  padding:0 0.25rem;
}
.fids-obs-secao--processo .fids-obs-display:hover { border-color: var(--line-3); background: var(--surf-2); }
.fids-obs--vazio { color: var(--ink-3); }
.fids-obs--placeholder { color: var(--ink-3); font-style: italic; }
.fids-obs-edit { display: flex; flex-direction: column; gap:0.25rem; }
/* .form-control-sm + só a largura mínima que a célula da grade exige. */
.fids-obs-textarea { min-width: 11.25rem; resize: vertical; }
.fids-obs-actions { display: flex; gap:0.25rem; }

.fids-obs-status { font-size: var(--fonte-corpo); color: var(--fc-urgent-fg); }

/* ── Loading / skeleton / empty / error ────────────────────── */
/* .fids-loading/.fids-skeleton removidos — loading unificado (overlay Bootstrap). */

.fids-empty { display: flex; flex-direction: column; align-items: center; gap:0.5rem; padding:3rem 0; text-align: center; }
.fids-empty-icon { font-size: var(--fonte-heroi); color: var(--ink-4); }
.fids-empty-title { font-size: var(--fonte-destaque); font-weight: 500; color: var(--ink-2); }
.fids-empty-sub, .fids-empty-ts { font-size: var(--fonte-corpo); color: var(--ink-3); }
.fids-empty-ts { color: var(--ink-4); }

.fids-error { display: flex; flex-direction: column; align-items: center; gap:0.5rem; padding:3rem 0; text-align: center; }
.fids-error-icon { font-size: var(--fonte-heroi); color: var(--fc-urgent-fg); }
.fids-error-msg { font-size: var(--fonte-destaque); font-weight: 500; color: var(--ink); }
.fids-error-hint { font-size: var(--fonte-corpo); color: var(--ink-3); }

/* ── KPI: banda apertada + cartão de containers por família ── */
/* A lista é a tela (ver o bloco de altura no topo): cada rem que a banda gasta
   é uma linha a menos no board, então o cartão perde respiro de propósito. */
.page[data-pagina="forecast_comex"] #fids-stats .card-body { padding:0.5rem 0.75rem; }
/* O board é o último bloco da página: o respiro de baixo já vem do padding da
   própria página, o do cartão só empurrava a lista para cima. */
.page[data-pagina="forecast_comex"] > .grid.mt-2 > .card { padding-bottom:0.5rem; }

/* Quebra por família do cartão "Containers no mês" — chips de texto, sem
   moldura: são 4 a 6 famílias e uma borda em cada viraria ruído. */
.fids-familias { display: flex; flex-wrap: wrap; align-items: baseline; gap:0 0.625rem; line-height: 1.2; }
.fids-familias-mes { font-weight: 500; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-4); }
.fids-familia { display: inline-flex; align-items: baseline; gap:0.25rem; }
.fids-familia-nome { color: var(--ink-3); }
.fids-familia-qtd { font-family: var(--bi-font-mono); font-weight: 500; color: var(--ink-2); }
.fids-familias-vazio { color: var(--ink-4); font-style: italic; }

/* ── Legenda ───────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════
   MODAIS — overlay único compartilhado, shell = .modal do Bootstrap
   (dialog/content/header/body/footer/btn-close). Só sobra aqui o que
   é conteúdo próprio deste modal.
   ══════════════════════════════════════════════════════════ */
.fids-modal-codigo { font-family: var(--bi-font-mono); font-weight: 500; color: var(--ink-2); }
.fids-modal-loading { display: flex; align-items: center; gap:0.5rem; color: var(--ink-3); font-size: var(--fonte-corpo); }
.fids-modal-status { font-size: var(--fonte-corpo); color: var(--ink-3); }
.fids-modal-marcar-todos { display: flex; align-items: center; gap:0.5rem; flex-wrap: wrap; padding-bottom:0.5rem; border-bottom: var(--bs-border-width) solid var(--fc-border); }
.fids-modal-container-list { display: flex; flex-direction: column; gap:0.25rem; max-height: 20rem; overflow: auto; }
.fids-modal-container-row { display: flex; align-items: center; justify-content: space-between; gap:0.5rem; }
.fids-modal-container-num { font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); color: var(--ink); }

/* ══════════════════════════════════════════════════════════
   ETL DRAWER — .offcanvas do Bootstrap (backdrop/ESC/scroll nativos)
   ══════════════════════════════════════════════════════════ */
#fids-etl-drawer { --bs-offcanvas-width: min(560px, 94vw); }
.fids-etl-drawer-title { display: flex; align-items: center; gap:0.5rem; }

.fids-etl-log {
  flex: 1; margin:0; overflow: auto;
  padding:1rem 1rem;
  font-family: var(--bi-font-mono); font-size: var(--fonte-corpo); line-height: 1.5;
  color: var(--ink-2); background: var(--surf-2);
  white-space: pre-wrap; word-break: break-word;
}

/* ── Responsivo: rola a grade horizontalmente em telas estreitas ── */
@media (max-width:991.98px) {
  .fids-col-headers, .fids-row { min-width: 51rem; }
  .card:has(#fids-table-body) { overflow-x: auto; }
}

/* ===== MERGED FROM static/css/obs-produtos-comex.css (P5 — page-local dissolve) ===== */
/* ══════════════════════════════════════════════════════════
   OBS-PRODUTOS-COMEX — Gerenciamento de Observações de Produto
   Surface/cards/header come from FCDS (.card, .card-hd, .lab,
   .grid). Only page-specific form/table/inline-edit rules live here.
   ══════════════════════════════════════════════════════════ */

.obs-page {
  padding:1.5rem;
}

/* ── Nova observação (form lives inside an FCDS .card) ── */
.obs-nova-form {
  display: flex;
  gap:0.5rem;
  align-items: flex-end;
  flex-wrap: wrap;
}
.obs-nova-field {
  display: flex;
  flex-direction: column;
  gap:0.25rem;
}
.obs-nova-field--obs {
  flex: 1;
  min-width: 12.5rem;
}
.obs-nova-label {
  font-size: var(--fonte-corpo);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-3);
}
/* .form-control-sm cobre borda/altura/foco; residual = largura fixa + mono (código de produto). */
.obs-nova-input {
  width: 10rem;
  font-family: var(--mono);
}
.obs-nova-textarea {
  width: 100%;
  font-size: var(--fonte-corpo);
  border: var(--bs-border-width) solid var(--line-3);
  border-radius: var(--bs-border-radius-sm);
  padding:0.25rem 0.5rem;
  resize: vertical;
  min-height: 3.25rem;
  outline: none;
  font-family: inherit;
  line-height: 1.5;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.obs-nova-textarea:focus {
  border-color: var(--acc);
  box-shadow: var(--ring);
}
.obs-nova-actions {
  display: flex;
  align-items: center;
  gap:0.5rem;
  padding-bottom:0;
}

.obs-nova-status {
  font-size: var(--fonte-corpo);
  font-family: var(--mono);
  color: var(--negative-text);
}
.obs-nova-status--ok {
  color: var(--positive-text);
}

/* ── Table ── */
/* .table + .table-hover do Bootstrap; aqui só o que é desta tela. */
table.obs-table { font-size: var(--fonte-corpo); }
table.obs-table thead th {
  background: var(--surf-2);
  border-bottom: 2px solid var(--line);
  padding:0.5rem 1rem;
  font-weight: 500;
  color: var(--ink-2);
  font-size: var(--fonte-corpo);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
table.obs-table td { padding:0.5rem 1rem; color: var(--ink); }
.obs-col-obs {
  width: 50%;
}

/* ── Cell content ── */
.obs-codigo {
  font-family: var(--mono);
  font-weight: 500;
  font-size: var(--fonte-corpo);
  color: var(--acc);
  white-space: nowrap;
}
.obs-meta {
  font-size: var(--fonte-corpo);
  color: var(--ink-3);
  white-space: nowrap;
}

/* ── Inline edit ── */
.obs-display {
  cursor: pointer;
  padding:0.25rem 0.25rem;
  border-radius: var(--bs-border-radius-sm);
  border: var(--bs-border-width) solid transparent;
  min-height: 1.6rem;
  word-break: break-word;
  line-height: 1.5;
  transition: border-color 0.15s, background 0.15s;
  position: relative;
}
.obs-display:hover {
  border-color: var(--line-3);
  background: var(--surf-2);
}
.obs-display:hover::after {
  content: '\f303';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  font-size: 0.875rem;
  color: var(--ink-4);
  position: absolute;
  top: 0.25rem;
  right: 0.3rem;
}
.obs-display--vazio {
  color: var(--ink-3);
  font-style: italic;
}
.obs-edit {
  display: none;
}
.obs-textarea {
  width: 100%;
  font-size: var(--fonte-corpo);
  border: var(--bs-border-width) solid var(--acc);
  border-radius: var(--bs-border-radius-sm);
  padding:0.25rem 0.5rem;
  resize: vertical;
  min-height: 3.25rem;
  outline: none;
  box-shadow: var(--ring);
  font-family: inherit;
  line-height: 1.5;
}
.obs-actions {
  display: flex;
  gap:0.25rem;
  margin-top:0.25rem;
}

.obs-status {
  font-size: var(--fonte-corpo);
  color: var(--negative-text);
  min-height: 0.9rem;
  font-family: var(--mono);
  margin-top:0.25rem;
}

/* ── Delete button ── */

/* ── States ── */
.obs-empty {
  padding:3rem 1.5rem;
  text-align: center;
  color: var(--ink-4);
  font-size: var(--fonte-corpo);
}
.obs-empty-icon {
  font-size: 1.5rem;
  display: block;
  margin-bottom:0.5rem;
}

/* Loading: shimmer skeleton bars (FCDS skeleton tokens) in place of a
   spinner, matching the project-wide .skeleton standard. */
/* .obs-loading / .obs-skeleton / shimmer removidos — obs-produtos usa o overlay
   Bootstrap unificado (carregando('obs-table-wrap')). */

/* ── Mobile (≤768px) ── */
@media (max-width: 768px) {
  .obs-page {
    padding:0;
  }
  table.obs-table {
    min-width: 35rem;
  }
  .obs-col-obs {
    width: auto;
    min-width: 12.5rem;
  }
  
}

/* ===== MERGED FROM static/css/processos-comex.css (P5 — page-local dissolve) ===== */
/* ============================================================
   Processos Comex — Listagem paginada via Conexos direto
   Page-local presentation. Tokens come from custom.css.
   ============================================================ */


/* ── Página cuja LISTA é a tela ────────────────────────────────────────────
   A lista ocupa a janela inteira menos a topbar, rola POR DENTRO, e cabeçalho +
   linha de filtros ficam parados no topo dela.

   `height` (não `min-height`) é o ponto todo. O `.main` do app declara
   min-height:calc(100vh - 52px); com apenas um mínimo, um filho `flex:1;
   min-height:0` não tem altura definida contra a qual se dimensionar — ele cresce
   até o conteúdo, o scroller interno deixa de existir e o `position:sticky` do
   cabeçalho passa a se ancorar numa caixa que sobe junto com a página. Foi essa a
   causa do cabeçalho "não grudar". Com altura definida a cadeia fecha, o
   .datatable-scroll volta a ser o elemento que rola, e o th gruda nele — parado.

   Ativada por `{% block content_class %}content--altura-cheia{% endblock %}`. */
.main:has(> .content--altura-cheia) {
  height: calc(100dvh - 52px);   /* 52px = .topbar (3.25rem), fixa no topo */
  min-height: 0;
  overflow: hidden;              /* quem rola é a lista, não a página */
  display: flex;
  flex-direction: column;
}
.content--altura-cheia { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.content--altura-cheia > .page { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.content--altura-cheia .fcds-filters-host { flex: 0 0 auto; }
/* Tela de altura cheia não tem "moldura de página": o recuo do shell (16px em
   cima, 20px nas laterais, 24px embaixo do .page) empurrava o conteúdo para
   dentro e roubava 40px de altura — a barra de decisão terminava a 24px do
   fim da janela. Quem dá respiro aqui é o próprio conteúdo, que já tem os
   seus paddings (capa, corpo, rodapé). */
.content--altura-cheia { padding: 0; }
/* Horizontal reposto (18/08/2026): com `padding:0` nos quatro lados, a primeira
   coluna nascia em x=48 — 15px ATRÁS da barra lateral, que vai até x=64 (medido
   em /romaneio/ e descrito no antigo remendo da inadimplência). O eixo vertical
   segue zerado, que é o que devolve altura à tela; o horizontal usa o mesmo
   recuo do resto do app (`--content-pad-x`), então a coluna começa em x=68 aqui
   e nas telas normais. */
.content--altura-cheia > .page { padding: 0 var(--content-pad-x); }
/* Exceção: o FUNIL não tem capa nem rodapé próprios para dar o recuo — quem
   segura a margem lá é a página. A tela do negócio fica colada porque cada
   faixa dela (capa, corpo, rodapé) já traz o seu. */
.content--altura-cheia > .page[data-pagina="crm"] {
  padding: 1rem var(--crm-respiro-x, 1.25rem) 0 !important; }
/* A promessa do comentário acima, cumprida: a tela do NEGÓCIO fica colada.
   A exceção só existia para o funil, e a capa e o rodapé do negócio paravam
   20px antes da borda (defeito relatado pelo dono, 25/08/2026) — cada faixa
   já traz o próprio recuo (`padding-inline` com centragem), então o da
   página só afastava a pele da janela. */
.content--altura-cheia > .page[data-pagina="crm-deal"] { padding: 0 !important; }
.content--altura-cheia > .page > .grid { flex: 1 1 auto; min-height: 0; display: grid; }
.content--altura-cheia .grid > .card { min-height: 0; display: flex; flex-direction: column; }

/* O card cede o PADDING, não a superfície. Tirar `background` dele jogava as
   linhas direto no canvas (--surface-app #edf0f4) e a hairline de separação
   (--line #e6e8ec) sumia contra ele: a tabela ficava sem grade e sem contraste,
   e o campo Buscar deixava de parecer um campo. O contorno e o fundo ficam; some
   só o recuo interno, que é o que de fato devolve espaço aos dados. */
.content--altura-cheia .grid > .card { padding: 0; }
/* Com o card sem padding, quem afasta o conteúdo da borda é cada faixa. */
.content--altura-cheia .card-hd,
.content--altura-cheia .datatable-toolbar,
.content--altura-cheia .datatable-bottom { padding-inline: var(--bi-space-md); }
.content--altura-cheia .card-hd { padding-block: var(--bi-space-sm); }

/* Separação de linha um passo mais firme que a hairline padrão: são 13 colunas
   numéricas lidas na diagonal, e `--line-2` desaparece nessa densidade. */
.content--altura-cheia .tbl tbody td { border-bottom: 1px solid var(--line); }
/* Zebra por linha, com a paridade reiniciando a cada bloco de cliente (classe posta
   no draw, ver acompanhamento-inadimplencia.js — `nth-child` do CSS não serve porque
   os cabeçalhos de bloco entram na paridade e o cinza escorrega).
   A faixa usa o MESMO overlay do hover (`--bs-table-accent-bg`), um degrau abaixo
   dele: .035 aqui, .075 no hover. Enquanto era `background: var(--surf-2)` — hex
   opaco idêntico ao `--bi-bg-hover` do hover — o hover pintava a mesma cor que já
   estava lá e sumia em cima da faixa. Duas escalas separadas colidem; uma só, não.
   `:not(:hover)` é o que devolve a linha ao hover: esta regra tem `.content--altura-cheia`
   a mais e venceria a regra genérica de hover na especificidade. Fora de hover a faixa
   pinta; sob o cursor ela para de casar e o overlay .075 assume. */
.content--altura-cheia .tbl tbody tr.linha-alternada:not(:hover) > td { --bs-table-accent-bg: rgba(0, 0, 0, .035); }

/* Grade vertical. Mais clara (--line-2) que o separador de linha (--line) de
   propósito: a horizontal carrega a identidade da linha, a vertical é guia de
   coluna. No mesmo peso as duas competem e a tabela lê como gaiola.
   `:not(:last-child)` evita filete dobrado contra a borda do card — o DataTables
   tira do DOM as colunas ocultas, então o último visível é o último de fato.
   Só a 1ª linha do thead (os rótulos) leva grade: a 2ª é a dos filtros, onde cada
   controle já tem borda própria e o filete só somava traço em cima de traço. */
.content--altura-cheia .tbl thead tr:first-child th:not(:last-child),
.content--altura-cheia .tbl tbody td:not(:last-child) {
  border-right: 1px solid var(--line-2);
}
/* O cabeçalho de grupo atravessa a tabela inteira (colspan): filete vertical ali
   cortaria o nome do cliente ao meio. */
.content--altura-cheia .tbl tbody tr.dtrg-group th { border-right: 0 !important; }

/* Dinheiro e atraso são as duas colunas que decidem a ligação: alinhadas,
   tabulares e com peso. O resto da linha fica em tom secundário. */
.content--altura-cheia .tbl tbody td.tbl__numeric {
  font-variant-numeric: tabular-nums;
  font-weight: var(--bi-fw-semibold);
  color: var(--ink);
}

.content--altura-cheia .tbl-wrapper { flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
/* Só o corpo rola; toolbar (topo) e info+paginação (base) ficam sempre à vista. */
.content--altura-cheia .dataTables_wrapper { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.content--altura-cheia .datatable-scroll {
  flex: 1 1 auto; min-height: 0; max-height: none; overflow: auto;
}
/* Âncora do sticky volta a ser o .datatable-scroll (parado): topo zerado. */
.content--altura-cheia .datatable-scroll thead tr:first-child th { top: 0 !important; }
.content--altura-cheia .datatable-scroll thead tr:nth-child(2) th {
  top: var(--thead-linha1-altura, 0px) !important;
}

/* Tela baixa: volta a fluir, senão a lista não cabe junto da barra de filtros. */
@media (max-height: 560px) {
  .main:has(> .content--altura-cheia) { height: auto; overflow: visible; display: block; }
  .content--altura-cheia { display: block; }
  .content--altura-cheia .datatable-scroll { max-height: var(--bi-dt-scroll-cap); }
}

.pcx-summary { font-size: var(--fonte-corpo); white-space: nowrap; }

/* ── Table ── */
/* A tabela é a grade da casa (.grade-tabela, static/js/grade.js): base/freeze
   de coluna vêm de lá (congelarColunas monta .stickcols sozinho). Aqui só os
   cosméticos específicos do Processos Comex. */
.pcx-col-num { text-align: right; font-family: var(--bi-font-mono); }

.pcx-cell-detail {
  text-align: center;
  width: 2rem;
  color: var(--ink-3);
}

.pcx-table-wrapper { position: relative; }



/* ── Detail Modal content ── */
.pcx-detail-section {
  margin-bottom:1.5rem;
}
.pcx-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13.75rem, 1fr));
  gap:0.5rem 1rem;
}
.pcx-detail-field-label {
  font-family: var(--bi-font-mono);
  font-size: var(--fonte-corpo);
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.pcx-detail-field-value {
  font-size: var(--fonte-destaque);
  color: var(--ink);
}
/* .table.table-sm do Bootstrap dá largura, colapso, padding e borda de linha. */
.pcx-detail-table { font-size: var(--fonte-corpo); }
.pcx-detail-table th, .pcx-detail-table td { text-align: left; }
.pcx-detail-table th {
  background: var(--surf-2);
  font-weight: 500;
  font-family: var(--bi-font-display);
}
.pcx-hist-lista { max-height: 16.25rem; overflow-y: auto; }
.pcx-hist__item { padding:0.5rem 0; border-bottom: var(--bs-border-width) solid var(--line); }
.pcx-hist__item:last-child { border-bottom: 0; }
.pcx-hist__cab { font-size: var(--fonte-corpo); margin-bottom:0.25rem; }
.pcx-hist__item--falha .pcx-hist__cab strong { color: var(--negative-text); }

/* ── Pré-alerta ao despachante (#188): coluna Despachante e painel ── */
.pcx-pa-situacao { white-space: nowrap; color: var(--ink-2); }
.pcx-pa-situacao--enviado { color: var(--ink); }
.pcx-pa-situacao--incerto { color: var(--warning-text); font-weight: 500; }
.pcx-btn-pre-alerta { margin-left: 0.5rem; padding: 0 0.5rem; white-space: nowrap; }
.pcx-pa-campos { display: grid; grid-template-columns: 9rem minmax(0, 1fr); gap: 0.5rem 1rem; align-items: start; }
.pcx-pa-campos .form-label { margin: 0.25rem 0 0; color: var(--ink-2); font-size: var(--fonte-corpo); }
.pcx-pa-corpo-email { min-height: 8rem; max-height: 18rem; overflow-y: auto; font-size: var(--fonte-corpo); }
.pcx-pa-corpo-email p { margin: 0 0 0.25rem; }
.pcx-pa-assinatura { font-size: var(--fonte-corpo); }
.pcx-pa-assinatura img { max-width: 100%; height: auto; }
/* Prévia: os links da assinatura não agem aqui (o da arte tiraria a pessoa do painel e o texto se perderia). */
.pcx-pa-assinatura a { pointer-events: none; }
.pcx-pa-anexos { display: grid; gap: 0.25rem; }
.pcx-pa-anexo { display: flex; gap: 0.5rem; align-items: baseline; font-size: var(--fonte-corpo); cursor: pointer; }
.pcx-pa-locais { display: grid; gap: 0.25rem; margin-bottom: 0.5rem; }
.pcx-pa-locais:empty { display: none; }
.pcx-pa-local { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; font-size: var(--fonte-corpo); }
.pcx-pa-local select { width: auto; min-width: 12rem; }
.pcx-pa-local__ged { display: inline-flex; gap: 0.25rem; align-items: center; cursor: pointer; }
.pcx-pa-local__erro { flex-basis: 100%; margin: 0; color: var(--negative-text); }
.pcx-pa-adicionar { justify-self: start; }
.pcx-pa-reenvio, .pcx-pa-aviso { margin: 0 0 0.75rem; font-size: var(--fonte-corpo); }
.pcx-pa-aviso { color: var(--warning-text); font-weight: 500; }
.pcx-pa-rodape { flex-wrap: wrap; gap: 0.5rem; }
.pcx-pa-mensagem { flex: 1 1 100%; margin: 0; font-size: var(--fonte-corpo); color: var(--ink-2); }
.pcx-pa-mensagem:empty { display: none; }
.pcx-pa-mensagem--erro { color: var(--negative-text); }
.pcx-pa-mensagem--ok { color: var(--ink); font-weight: 500; }
.pcx-pa-confirmacao { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; justify-content: flex-end; }
.pcx-pa-confirmacao[hidden] { display: none; }
.pcx-pa-confirmacao p { flex: 1 1 100%; margin: 0; font-size: var(--fonte-corpo); color: var(--warning-text); font-weight: 500; }
@media (max-width: 575.98px) { .pcx-pa-campos { grid-template-columns: minmax(0, 1fr); } }

/* ===== MERGED FROM static/css/tracking-comex.css (P5 — page-local dissolve) ===== */
/* =====================================================
   VARIÁVEIS CSS DINÂMICAS - Responsive ao sidebar
   ===================================================== */

:root {
    --sidebar-width: 14.0625rem;
    --sidebar-margin:0.5rem;
    --header-height: 3.5rem;
    --tracking-header-height: 4.375rem;

    /* =====================================================
       CANONICAL COLOR SOURCE (Stage 1 foundation)
       Single source of truth for category/status color on this page.
       Resolved in JS via getTrackingColor() (static/js/tracking-comex.js).
       NEVER hardcode hex in JS or templates — read these tokens instead.
       ===================================================== */

    /* Product-group identity → FCDS categorical tokens (--cat-*).
       13 group names collapse onto their original color families; each
       family gets ONE distinct, legible cat token (the label carries the
       finer identity). De-duplicates the colliding raw hex (was #E28702 ×3,
       #B42727 ×6). Stable map — reuse in markers, dots, badges (stages 2-5). */
    /* Cor por SEGMENTO do catálogo do admin. Os 13 "grupos" antigos já apontavam
       para 5 cores (todo o aço era --cat-8): a paleta sempre foi por segmento, só o
       código é que fingia treze. O sub-segmento é o texto do badge, não a cor.
       Este mapa vale SÓ para o tracking (dots/badges do mapa) — em gráfico,
       categorizar é a rampa do azul (decisão do dono 2026-08-06, DESIGN.md §2). */
    --tcx-segmento-steel:       var(--cat-8);  /* STEEL — cordoalha, arames, fixadores… */
    --tcx-segmento-agro:        var(--cat-3);  /* AGRO */
    --tcx-segmento-nutritional: var(--cat-1);  /* NUTRITIONAL */
    --tcx-segmento-resin:       var(--cat-2);  /* RESIN */
    --tcx-segmento-wine:        var(--cat-2);  /* WINE */
    --tcx-segmento-trading:     var(--cat-2);  /* TRADING */
    --tcx-segmento-medical:     var(--cat-4);  /* MEDICAL */
    --tcx-segmento-outros:      var(--cat-6);  /* OUTROS */
    --tcx-segmento-fallback:    var(--ink-3);  /* segmento desconhecido → tinta neutra */

    /* Status identity → NEUTRAL (One-Command Rule: status counts/tiles stay
       neutral; identity is carried by the LABEL + optional small dot, not a
       per-status hue). All point at neutral ink here; a later stage may
       repoint a specific status to a --positive/--negative/--warning token
       ONLY if a real good/bad direction is declared. Replaces the rainbow
       palette (was #dc3545/#ffc107/#17a2b8/#28a745/#fd7e14/#20c997/#6f42c1/
       #e83e8c/#198754/#6c757d). */
    --tcx-status:               var(--ink-3);

    /* Map markers & route — meaning-carrying color (the map keeps semantic hue:
       line color = progress, markers/dots = unidade de negócio). Tokenized,
       never hardcoded hex. Buttons/status tiles stay neutral; only the map
       carries this color. */
    --tcx-marker-vessel:    var(--cat-1);    /* vessel bubble + traveled route = blue (progress "percorrido") */
    --tcx-route-pending:    var(--ink-4);    /* restante (gray dashed) */
    --tcx-marker-dest:      var(--cat-3);    /* arrival = green */
    --tcx-transship-passed: var(--negative); /* passed waypoint = red */
}

body.sb-sidenav-toggled {
    --sidebar-width: 0;
}

/* =====================================================
   FOCUS MODE - Destaque de elemento selecionado no mapa
   ===================================================== */

/* Focus mode is scoped under `#map.map-focus-mode` (id + class = high
   specificity), so dim/focus rules win the cascade WITHOUT a wall of
   !important. Leaflet does not set inline opacity/filter on markers, and for
   SVG paths an inline `stroke-opacity` style beats the presentation attribute —
   so those properties win on specificity alone. Only z-index / stroke-width,
   which Leaflet writes inline for positioning/rendering, retain !important. */

/* Elementos desabilitados no focus mode (dim every status tile while a
   process is focused on the map). Scoped under .tracking-comex-page so it
   wins on cascade without !important. */
.tracking-comex-page .tracking-badge.tracking-badge-disabled {
    opacity: 0.55;            /* keep dimmed badge text ≥3:1 (was 0.4, too faint) */
    filter: grayscale(100%);
    pointer-events: none;
    cursor: not-allowed;
}

/* =====================================================
   Marcadores e Polylines - Focus/Disabled (scoped, low-!important)
   ===================================================== */

/* Marcadores de navio - SEM transições (evita flicker) */
#map.map-focus-mode .leaflet-marker-icon.vessel-marker,
#map.map-focus-mode .leaflet-marker-icon[class*="vessel"] {
    transition: none;
    will-change: opacity;
}

/* Elementos desabilitados - com transição SUAVE para outros elementos */
#map.map-focus-mode .leaflet-marker-disabled:not(.vessel-marker):not([class*="vessel"]) {
    opacity: 0.3;
    filter: grayscale(60%);
    transition: opacity 0.2s ease, filter 0.2s ease;
}

/* Marcadores de navio desabilitados - SEM transição */
#map.map-focus-mode .leaflet-marker-disabled.vessel-marker,
#map.map-focus-mode .leaflet-marker-disabled[class*="vessel"] {
    opacity: 0.3;
    filter: grayscale(60%);
    transition: none;
}

#map.map-focus-mode .leaflet-polyline-disabled {
    opacity: 0.25;
    stroke-opacity: 0.25;
    transition: opacity 0.2s ease, stroke-opacity 0.2s ease;
}

#map.map-focus-mode .leaflet-popup-disabled {
    opacity: 0.4;
    pointer-events: none;
}

/* Elementos focados - aparecem INSTANTANEAMENTE, com anel de destaque ESTÁTICO
   (independente do pulso, então legível p/ reduced-motion). */
#map.map-focus-mode .leaflet-marker-focused {
    opacity: 1;
    filter: drop-shadow(0 0 0 2px var(--acc));
    z-index: 1000 !important;   /* Leaflet writes z-index inline → needs !important */
    transition: none;
}

/* Forçar visibilidade de marcadores focados */
#map.map-focus-mode .leaflet-marker-focused,
#map.map-focus-mode .leaflet-marker-focused .custom-div-icon,
#map.map-focus-mode .leaflet-marker-focused .vessel-marker-wrapper {
    display: block;
    visibility: visible;
}

#map.map-focus-mode .leaflet-polyline-focused {
    opacity: 1;
    stroke-opacity: 1;
    stroke-width: 4 !important;  /* Leaflet writes stroke-width inline → needs !important */
    z-index: 999 !important;
    transition: none;
}

/* Wrapper do marcador de navio - otimização de performance */
.vessel-marker-wrapper {
    will-change: opacity, transform;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* =====================================================
   Select2 e Modais
   ===================================================== */

.tracking-comex-page .select2-container { z-index: 1150 !important; }
.tracking-comex-page .select2-dropdown { z-index: 1151 !important; }

/* Acima do overlay de estado do mapa (.tcx-map-state 1200) e dos status-cards (1100),
   ainda muito abaixo do backdrop dos modais Comex (11900). Sem empate por ordem de DOM. */
body:has(.tracking-comex-page) #topbar { z-index: 1250; }

.tracking-modal {
    --bs-modal-zindex: 12000 !important;
    z-index: 12000 !important;
}

.tracking-modal .modal-dialog {
    position: fixed !important;
    left: calc(var(--sidebar-width) + var(--sidebar-margin) + 12px) !important;
    top: calc(var(--header-height) + var(--tracking-header-height) + 80px) !important;
    transform: none !important;
    margin:0 !important;
    max-width: 35rem !important;
    width: calc(100% - var(--sidebar-width) - calc(var(--sidebar-margin) * 2) - 24px) !important;
    max-height: calc(100vh - var(--header-height) - var(--tracking-header-height) - 100px) !important;
    transition: left 0.15s ease-in-out, width 0.15s ease-in-out, top 0.15s ease-in-out;
}

@media (min-width: 992px) {
    .tracking-modal .modal-dialog {
        left: calc(var(--sidebar-width) + var(--sidebar-margin) + 12px) !important;
        max-width: 35rem !important;
        top: calc(var(--header-height) + var(--tracking-header-height) + 80px) !important;
    }
}

.tracking-modal.fade .modal-dialog {
    transition: transform 0.3s ease-out, opacity 0.3s ease-out !important;
    transform: translateX(-100%) !important;
    opacity: 0;
}

.tracking-modal.show .modal-dialog {
    transform: translateX(0) !important;
    opacity: 1;
}

@media (max-width:991.98px) {
    .tracking-modal .modal-dialog {
        left: calc(var(--sidebar-width) + var(--sidebar-margin) + 12px) !important;
        max-width: 32.5rem !important;
        top: calc(var(--header-height) + var(--tracking-header-height) + 75px) !important;
    }
}

@media (max-width: 768px) {
    .tracking-modal .modal-dialog {
        left: calc(var(--sidebar-width) + 8px) !important;
        width: calc(100% - var(--sidebar-width) - 16px) !important;
        max-width: 30rem !important;
        top: calc(var(--header-height) + var(--tracking-header-height) + 70px) !important;
    }
    
    .tracking-comex-page .tracking-modal .modal-body { 
        max-height: calc(100vh - var(--header-height) - var(--tracking-header-height) - 140px);
    }
}

@media (max-width: 576px) {
    .tracking-modal .modal-dialog {
        left: 12px !important;
        width: calc(100% - 24px) !important;
        max-width: none !important;
        max-height: calc(100vh - var(--header-height) - 55px - 20px) !important;
        top: calc(var(--header-height) + 55px + 60px) !important;
    }
    
    .tracking-comex-page .tracking-modal .modal-body { 
        max-height: calc(100vh - var(--header-height) - 55px - 140px);
    }
}

/* =====================================================
   Produtos e Summary
   ===================================================== */

.process-products {
    display: grid;
    gap:0.25rem;
    margin-top:0.5rem;
}

/* Bordo/bg/radius/padding-base (+ layout em coluna) vêm de .card.card-body
   (Bootstrap), aplicado junto no JS — sem residual próprio. */

.process-product-name {
    font-weight: 500;
    color: var(--ink);
    font-size: var(--fonte-destaque);
}

/* Bordo/bg/radius/padding-base vêm de .card.card-body (Bootstrap), aplicado
   junto no JS; aqui só o residual: linha flex com quebra (labels+valores lado
   a lado, várias colunas) que o .card (coluna) não dá. */
.process-summary {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap:0.5rem 1rem;
    margin-bottom:0.5rem;
}

.process-summary-item {
    min-width: 8.75rem;
}

.process-summary-label {
    font-size: var(--fonte-corpo);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-3);
}

.process-summary-value {
    font-weight: 500;
    color: var(--ink);
    font-size: var(--fonte-destaque);
}

/* Numeric summary value (FOB / Total / Itens / counts / USD / qty): Roboto
   (official numeral font, --mono) tabular, right-aligned so figures
   align and compare (Tabular Rule). The
   text labels (Encomendante/Exportador/Status…) keep the proportional value. */
.process-summary-value.is-num {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    text-align: right;
    letter-spacing: -0.01em;
}

/* Status-dot chip: small direction/neutral dot + neutral ink label, legible
   without hue (colorblind-safe). Dot hue supplied inline via --tcx-status-dot
   (defaults to neutral ink). */
.tcx-status-chip {
    display: inline-flex;
    align-items: center;
    gap:0.25rem;
    font-weight: 500;
    color: var(--ink);
    font-size: var(--fonte-destaque);
}
.tcx-status-chip::before {
    content: "";
    width: 0.4375rem;
    height: 0.4375rem;
    border-radius: 50%;
    background: var(--tcx-status-dot, var(--ink-3));
    flex: 0 0 auto;
}

/* FCDS inline warning note (replaces Bootstrap alert-warning). Subtle amber
   tint fill, texto #FA4B00 (via --color-indicator-warning-text = --warning-text,
   #229),
   single --line hairline, no left stripe, real FontAwesome glyph. */
.tcx-warn-note {
    display: flex;
    align-items: flex-start;
    gap:0.5rem;
    padding:0.5rem 0.5rem;
    margin-bottom:1rem;
    background: var(--warning-subtle);
    border: var(--bs-border-width) solid var(--line);
    border-radius: var(--r-sm);
    color: var(--color-indicator-warning-text);
    font-size: var(--fonte-corpo);
    line-height: 1.5;
}
.tcx-warn-note .tcx-warn-icon {
    color: var(--color-indicator-warning-text);
    margin-top:0;
    flex: 0 0 auto;
}

/* =====================================================
   Timeline / Progress bar do Navio (modal de detalhes)
   ===================================================== */
.process-timeline { margin-bottom:0.5rem; }
.process-timeline-top { font-size: var(--fonte-destaque); color: var(--ink-2); }
.process-timeline .timeline-origin,
.process-timeline .timeline-dest { max-width: 46%; }
/* Progress = MAGNITUDE → slate only (--acc); never group-hued. Track is a
   neutral --line rail. Width/left transitions are gated behind
   prefers-reduced-motion: no-preference so reduced-motion users get the final
   position instantly (no animated decoration). */
.timeline-track { position: relative; height: 1.25rem; }
.timeline-line { position: absolute; left: 0; top: 50%; height: 0.125rem; transform: translateY(-50%); border-radius: var(--bs-border-radius-sm); background: var(--line); width: 100%; }
.timeline-progress { position: absolute; left: 0; top: 50%; height: 0.125rem; transform: translateY(-50%); border-radius: var(--bs-border-radius-sm); background: var(--acc); }
.timeline-ship { position: absolute; top: 50%; transform: translate(-50%,-50%); z-index: 5; }
@media (prefers-reduced-motion: no-preference) {
    .timeline-progress { transition: width 200ms cubic-bezier(.2,.8,.2,1); }
    .timeline-ship { transition: left 200ms cubic-bezier(.2,.8,.2,1); }
}
.ship-icon { width: 1.375rem; height: 1.375rem; display: inline-flex; align-items: center; justify-content: center; background: var(--surf); border-radius: 50%; box-shadow: var(--sh1); border: var(--bs-border-width) solid var(--line); font-size: 0.875rem; color: var(--acc); }
.process-timeline-meta { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap:0.5rem; font-size: var(--fonte-corpo); color: var(--ink-3); }
.process-timeline-meta .timeline-meta-left,
.process-timeline-meta .timeline-meta-right { font-size: var(--fonte-corpo); color: var(--ink-3); font-family: var(--mono); font-variant-numeric: tabular-nums; }
.process-timeline-meta .timeline-meta-center { text-align: center; font-weight: 500; color: var(--ink); }
.process-timeline .progress-percent { font-weight: 500; color: var(--ink); font-family: var(--mono); font-variant-numeric: tabular-nums; }
@media (max-width: 576px) {
    .process-timeline-meta { grid-template-columns: 1fr auto 1fr; gap:0.25rem; }
    .process-timeline-meta .timeline-meta-center { font-size: 1rem; }
}
@media (max-width: 576px) {
    .process-timeline .timeline-origin, .process-timeline .timeline-dest { max-width: 40%; }
}

/* =====================================================
   Modal Backdrop
   ===================================================== */

/* Backdrop: o do Bootstrap, sem override. O que morava aqui era
   `background-color: rgba(0,0,0,.25) !important`, que combinado com o
   `opacity:.5` do `.show` dava .125 efetivo — clareamento global, com
   `!important`, sem nenhum token do FCDS por trás. */

/* A elevação p/ z-11900 é SÓ da tracking-comex (backdrop acima do topbar-1200 e
   do mapa Leaflet). Escopada via body:has(.tracking-comex-page) p/ não vazar e
   soterrar os modais Bootstrap padrão (z-1055) nas demais telas. Só mexe no
   z-index — a regra .tracking-comex-modal-open .modal-backdrop (transparência)
   continua vencendo por não haver conflito de propriedade. */
body:has(.tracking-comex-page) .modal-backdrop {
    --bs-backdrop-zindex: 11900 !important;
    z-index: 11900 !important;
}

.tracking-comex-modal-open .modal-backdrop {
    background-color: transparent !important;
    opacity: 0 !important;
}

.tracking-comex-page .modal.show ~ .select2-container--open .select2-dropdown {
    z-index: 12500 !important;
}

/* =====================================================
   Header / toolbar (FCDS tokens, sem !important)
   ===================================================== */

/* spinner do Atualizar durante reload */
@media (prefers-reduced-motion: no-preference) {
    #tcx-refresh-btn.is-loading .tcx-refresh-icon { animation: tcx-spin .8s linear infinite; transform-origin: 50% 50%; }
}
@keyframes tcx-spin { to { transform: rotate(360deg); } }

.tracking-comex-page .tracking-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap:0.5rem;
    padding:0.5rem 1rem;
    margin:0;
    background: var(--surf);
    border-bottom: var(--bs-border-width) solid var(--line);
}
/* barra fina do corpo: só a busca Select2, ocupando a largura disponível */
.tracking-comex-page .tracking-header .process-search-wrapper {
    flex: 1 1 auto;
    max-width: 35rem;
}

/* ── Filtros no popover do topbar (fora de .tracking-comex-page → sem escopo de
   página; este CSS só carrega no tracking, então é seguro) ──
   Escopo/Via usam o vocabulário FCDS .optrow (.lab + .ck + .nm); "Com posição
   AIS" usa o .form-switch nativo do Bootstrap. Os <select> de Escopo/Via ficam
   escondidos (.tcx-state-select) como modelo de estado lido por
   _fetchTrackingData; o switch é o próprio input visível. */
.tcx-state-select, .tcx-state-check {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; padding:0; margin:-0;
}
.tcx-filter-group { margin-bottom:0.25rem; }
.tcx-filter-lab { padding:0.25rem 0.5rem 0; }
/* .optrow é botão (single-select por grupo); marca de seleção via aria-checked */
#tcx-filtros-pop .optrow[aria-checked="true"] .ck { background: var(--acc); border-color: var(--acc); }
#tcx-filtros-pop .optrow[aria-checked="true"] .ck svg { opacity: 1; }
#tcx-filtros-pop .popftog { display: flex; align-items: center; }
/* .form-switch nativo espalhado na linha: label à esquerda, switch à direita
   (neutraliza o padding-left/margin-left do .form-switch p/ layout space-between). */
#tcx-filtros-pop .popftog .form-check { width: 100%; display: flex; align-items: center; justify-content: space-between; padding-left: 0; margin: 0; }
#tcx-filtros-pop .popftog .form-check-input { margin: 0; float: none; }
#tcx-filtros-pop .popftog .form-check-label { margin: 0; }

/* (header__title / header-controls / header__check removidos — controles foram
   p/ o topbar na reskin Fase 2e; só a busca Select2 permanece em .tracking-header) */

/* Select da busca no toolbar: a altura é a do -sm de fábrica. */
.tracking-comex-page .tracking-header .form-select-sm {
    width: auto;
    min-width: 8.125rem;
}

/* Wrapper do search */
.tracking-comex-page .tracking-header .process-search-wrapper {
    display: flex;
    align-items: center;
    width: 30rem;
    min-width: 25rem;
    flex-shrink: 0;
}

/* Select2 dentro do toolbar: a caixa é a do form-select-sm de fábrica (31px, borda e raio do Bootstrap). */
.tracking-comex-page .tracking-header .select2-container {
    display: block;
    width: 100% !important;
}

.tracking-comex-page .tracking-header .select2-selection--single {
    height: calc(1.5em + .5rem + 2px);
    padding: .25rem .5rem;
    display: flex;
    align-items: center;
    font-size: var(--fonte-corpo);
    border: var(--bs-border-width) solid var(--bs-border-color);
    border-radius: var(--bs-border-radius-sm);
}

.tracking-comex-page .tracking-header .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 100%;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.tracking-comex-page .tracking-header .select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 1.5;
    padding:0;



}

/* Dropdown do Select2 */
.tracking-comex-page .select2-dropdown .select2-search--dropdown .select2-search__field {
    width: 100%;
    padding:0.5rem 0.5rem;
    box-sizing: border-box;
    font-size: var(--fonte-destaque);
    border: var(--bs-border-width) solid var(--line);
    border-radius: var(--r-sm);
}

.tracking-comex-page .select2-results__option {
    padding:0.5rem 0.5rem;
    font-size: var(--fonte-corpo);
    transition: background-color 160ms ease, color 160ms ease;
}

/* Mesmo seletor do Select2 (`--highlighted.--selectable`, 0,3,0) sob o escopo da
   página: vence o #5897fb dele pela especificidade, sem `!important`. */
.tracking-comex-page .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable,
.tracking-comex-page .select2-results__option:hover {
    background-color: var(--acc-soft);
    color: var(--acc);
}

.tracking-comex-page .select2-container--open .select2-selection--single,
.tracking-comex-page .select2-container--focus .select2-selection--single {
    border-color: var(--acc);
    box-shadow: var(--ring);
    transition: box-shadow 180ms ease, border-color 180ms ease;
}

@media (prefers-reduced-motion: reduce) {
    .tracking-comex-page .select2-container--open .select2-selection--single,
    .tracking-comex-page .select2-container--focus .select2-selection--single { transition: none; }
}

/* Placeholder lê em contraste de corpo (--ink-3 ~4.7:1). */
.tracking-comex-page .select2-selection__placeholder {
    color: var(--ink-3);
}

/* Estado loading/disabled do search enquanto processosData resolve. A classe é
   posta no wrapper por tracking-comex.js; mostra um skeleton sobre o controle e
   bloqueia interação até os dados chegarem. */
/* .process-search is-loading skeleton removido — loading unificado (overlay Bootstrap). */

.tracking-comex-page .select2-dropdown {
    border: var(--bs-border-width) solid var(--line);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--sh-glass);
}

/* Responsive - Header */
@media (max-width: 576px) {
    .tracking-comex-page .tracking-header {
        flex-direction: column;
        align-items: stretch;
    }

    .tracking-comex-page .tracking-header .process-search-wrapper {
        width: 100%;
        min-width: 0;
        max-width: none;
        order: 3;
        margin-top:0.5rem;
    }
}

/* =====================================================
   Layout e Mapa
   ===================================================== */

.tracking-comex-page {
    height: calc(100vh - 56px) !important;
    display: flex;
    flex-direction: column;
}

.tracking-comex-page .d-flex.flex-column.h-100 > .tracking-row {
    flex: 1 1 auto;
    min-height: 0;
    /* Trap the map's stacking context: Leaflet panes (z-index up to ~700) and
       the .tcx-map-state overlay (z-index 1200) would otherwise bubble to the
       root and paint OVER the shell sidebar (z-index 30/60) and topbar. isolate
       contains them so the shell chrome always wins. */
    isolation: isolate;
}

/* (#layoutSidenav_content.tracking-comex-active removido — esse elemento/classe
   eram da shell SB-Admin antiga e nunca existem no FCDS; regras eram mortas.) */

.tracking-comex-page #map {
    width: 100%;
    height: 100%;
    border-radius: 0;
    box-shadow: none;
    /* Join the FCDS surface ladder: a 1px --line hairline separates the canvas
       from the worksheet/topbar instead of bleeding edge-to-edge. */
    border-top: var(--bs-border-width) solid var(--line);
}

/* Reskin Leaflet's default control chrome to FCDS tokens (was white boxes /
   #ccc borders / blue focus). */
.tracking-comex-page .leaflet-control-zoom a,
.tracking-comex-page .leaflet-control-attribution {
    background: var(--surf);
    border: var(--bs-border-width) solid var(--line);
    color: var(--ink-2);
}

.tracking-comex-page .leaflet-control-zoom a {
    border-radius: var(--r-sm);
    transition: background-color 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}

.tracking-comex-page .leaflet-control-zoom a:hover {
    background: var(--acc-soft);
    border-color: var(--acc-line);
    color: var(--acc);
}

.tracking-comex-page .leaflet-control-zoom a:focus-visible {
    outline: none;
    box-shadow: var(--ring);
}

.tracking-comex-page .leaflet-control-attribution {
    border-radius: var(--r-xs);
}

.tracking-comex-page .leaflet-control-attribution a {
    color: var(--ink-2);
}

@media (prefers-reduced-motion: reduce) {
    .tracking-comex-page .leaflet-control-zoom a { transition: none; }
}

/* country-flag pin — chrome moved off inline styles to the surface ladder:
   --surf fill, 1px --surf hairline, one soft low-alpha lift (no heavy shadow). */
.tracking-comex-page .country-flag-marker {
    background: var(--surf);
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: var(--bs-border-width) solid var(--line);
    box-shadow: 0 1px 3px rgba(25, 28, 34, 0.18);
    cursor: pointer;
}

/* =====================================================
   Cards Overlay
   ===================================================== */

.tracking-comex-page #status-cards-container {
    position: absolute;
    top: 12px;
    left: calc(var(--sidebar-width) + var(--sidebar-margin));
    z-index: 1100;
    pointer-events: auto;
    transition: left 0.15s ease-in-out;
}

@media (max-width:767.98px) {
    .tracking-comex-page #status-cards-container {
        left: 8px !important;
        right: 8px;
        flex-wrap: wrap;
    }
}

/* Stage 1: #group-cards / #group-cards-container rules removed (dead code —
   renderGroupCards deleted; #group-cards never existed in the template). */
.tracking-comex-page #status-cards {
    display: flex;
    gap:0.5rem;
    align-items: stretch;
    background: var(--surf);
    border: var(--bs-border-width) solid var(--line);
    padding:0.25rem;
    border-radius: var(--r-xs);
    box-shadow: none;
    max-height: 60vh;
    overflow-x: auto;
    white-space: nowrap;
    pointer-events: auto;
}

.tracking-comex-page #status-cards > div {
    flex: 0 0 auto;
}

@media (max-width:767.98px) {
    .tracking-comex-page #status-cards { gap:0.25rem; padding:0.25rem; }
}

/* Skeleton dos status-cards enquanto _fetchTrackingData resolve. Reserva a
   mesma altura/box da faixa real (#status-cards) para não causar CLS quando os
   cards reais aparecem. */
/* .tcx-cards-skeleton / .tcx-skb-pill removidos — loading unificado (overlay Bootstrap). */

/* =====================================================
   Estados de página sobre o mapa (loading / vazio / erro)
   -----------------------------------------------------
   Nunca deixa o mapa silenciosamente em branco: distingue carregando, sem
   processos, e falha de fetch/parse. data-state alterna qual bloco é exibido.
   ===================================================== */
.tracking-comex-page .tcx-map-state {
    position: absolute;
    inset: 0;
    z-index: 1200;
    display: grid;
    place-items: center;
    padding:1rem;
    pointer-events: none;
}
/* Some quando há dados plotados (data-state="ready"). */
.tracking-comex-page .tcx-map-state[data-state="ready"] { display: none; }
.tracking-comex-page .tcx-map-state__card {
    pointer-events: auto;
    min-width: 15rem;
    max-width: 22.5rem;
    padding:1.5rem 1.5rem;
    gap:0.5rem;
    background: var(--surf);
    border: var(--bs-border-width) solid var(--line);
    border-radius: var(--r-sm);
    box-shadow: var(--sh2);
    text-align: center;
    color: var(--ink-2);
}
.tracking-comex-page .tcx-map-state__icon {
    width: 1.875rem;
    height: 1.875rem;
    color: var(--ink-3);
    margin-bottom:0.25rem;
}
.tracking-comex-page .tcx-map-state__msg {
    margin:0;
    font-size: var(--fonte-corpo);
    line-height: 1.5;
    color: var(--ink-2);
}
/* alterna blocos conforme data-state */
.tracking-comex-page .tcx-map-state__loading,
.tracking-comex-page .tcx-map-state__empty,
.tracking-comex-page .tcx-map-state__error { display: none; flex-direction: column; align-items: center; gap:0.5rem; }
.tracking-comex-page .tcx-map-state[data-state="loading"] .tcx-map-state__loading { display: flex; }
.tracking-comex-page .tcx-map-state[data-state="empty"]   .tcx-map-state__empty   { display: flex; }
.tracking-comex-page .tcx-map-state[data-state="error"]   .tcx-map-state__error   { display: flex; }
.tracking-comex-page .tcx-map-state__loading .tcx-map-state__msg { margin-top:0.25rem; color: var(--ink-3); }

/* =====================================================
   Marcadores e Tooltips
   ===================================================== */

.tracking-comex-page .custom-div-icon { background: transparent !important; border: none !important; }

.tracking-comex-page .leaflet-tooltip.custom-tooltip {
    background-color: var(--ink);
    color: var(--surf);
    border: none;
    border-radius: var(--bs-border-radius-sm);
    padding:0.25rem 0.5rem;
    font-size: var(--fonte-corpo);
    font-weight: 500;
    box-shadow: var(--sh2);
    min-width: 10rem;
    max-width: 22.5rem;
    white-space: normal;
    word-break: break-word;
    line-height: 1.2;
}

.tracking-comex-page .leaflet-tooltip.custom-tooltip::before { border-top-color: var(--ink); }

/* marker utilities consolidated (moved from inline templates).
   Depth = a 1px --surf hairline ring + ONE soft low-alpha lift. App-wide
   --sh1/--sh2 are `none` for worksheet cards, but a marker floats over the
   raster basemap and needs minimal separation from the tiles; --tcx-marker-sh
   centralizes that soft shadow (replaces the legacy `border:3px solid white` +
   `box-shadow:0 3px 10px rgba(0,0,0,.5)` heavy-shadow tell). */
:root { --tcx-marker-sh: 0 1px 3px rgba(25, 28, 34, 0.18); }
.pulse { animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.15); } }
@media (prefers-reduced-motion: reduce) {
    .pulse { animation: none; }
}

/* shared 32px round map bubble (origin/destination/vessel/consolidated) */
.custom-div-icon .consolidated-marker,
.consolidated-marker,
.custom-div-icon .destination-marker,
.destination-marker,
.custom-div-icon .vessel-marker,
.vessel-marker,
.port-marker {
    width: 2rem; height: 2rem; border-radius:50%;
    display:flex; align-items:center; justify-content:center;
    border:var(--bs-border-width) solid var(--surf);
    box-shadow:var(--tcx-marker-sh);
    cursor:pointer;
}

/* arrival = green (destination); origin = unidade de negócio (group color,
   supplied inline via --tcx-marker, fallback slate) */
.destination-marker,
.port-marker--destination { background: var(--tcx-marker-dest); }
.port-marker--origin { background: var(--tcx-marker, var(--acc)); }

.consolidated-count-badge { position:absolute; top:-8px; right:-8px; background:var(--acc); width: 1.5rem; height: 1.5rem; border-radius:50%; border:var(--bs-border-width) solid var(--surf); display:flex; align-items:center; justify-content:center; box-shadow:var(--tcx-marker-sh); }
/* count is magnitude → mono tabular ink-on-surf, never red (Tabular + One-Command) */
.consolidated-count-text { color:var(--surf); font-family:var(--mono); font-variant-numeric:tabular-nums; font-weight:500; font-size:var(--fonte-corpo); }

/* per-process group identity dots over the vessel (categorical → cat token fill,
   supplied inline; chrome is a neutral --surf ring) */
.vessel-group-dot {
    width: 0.5rem; height: 0.5rem; border-radius:50%;
    border:var(--bs-border-width) solid var(--surf);
    box-shadow:var(--tcx-marker-sh);
}

/* transshipment dot: passed = solid red, pending = hollow gray ring.
   Differentiated by FILL (solid vs ring) AND hue — colorblind-safe + colorful. */
.transshipment-dot {
    width: 0.75rem; height: 0.75rem; border-radius:50%;
    box-shadow:var(--tcx-marker-sh);
}
.transshipment-dot.is-passed {
    background: var(--negative);
    border:var(--bs-border-width) solid var(--surf);
}
.transshipment-dot.is-pending {
    background: var(--surf);
    border:2px solid var(--ink-4);
}

/* =====================================================
   Badges
   ===================================================== */

/* FCDS number-first tile (status filter). Magnitude (count) is MONO ink and
   never hued; the status name is an --ink-3 label that carries identity.
   Background is the neutral surface ladder — no per-status hue. */
.tracking-badge {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap:0;
    padding:0.25rem 0.5rem;
    border-radius: var(--r-xs);
    background: var(--surf);
    border: var(--bs-border-width) solid var(--line);
    cursor: pointer;
    transition: background-color 0.16s ease, border-color 0.16s ease;
    white-space: nowrap;
    margin:0;
}

.tracking-badge:hover {
    background: var(--acc-soft);
    border-color: var(--acc-line);
}

.tracking-badge:focus-visible {
    outline: none;
    box-shadow: var(--ring);
}

.tracking-badge:active {
    background: var(--surf-2);
}

.tracking-badge .badge-count {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    font-size: var(--fonte-destaque);
    line-height: 1;
    color: var(--ink);
    letter-spacing: -0.01em;
}

.tracking-badge .badge-label {
    font-size: var(--fonte-corpo);
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* Real zero-count disabled state: dimmed + non-interactive. The 0 stays in
   strong --ink so it remains legible through the .55 opacity; only the label
   recedes to --ink-4. */
.tracking-badge.is-disabled {
    background: var(--surf-2);
    border-color: var(--line-2);
    opacity: 0.55;
    pointer-events: none;
    cursor: default;
}

.tracking-badge.is-disabled .badge-label {
    color: var(--ink-4);
}

@media (prefers-reduced-motion: reduce) {
    .tracking-badge { transition: none; }
}

.tracking-badges-container {
    display: flex;
    flex-wrap: wrap;
    padding:0 0;
    gap:0;
    background: transparent;
}

/* Hairline-separated process rows (replaces Bootstrap .list-group boxed cards):
   no per-item box, just a single --line bottom hairline. */
.tracking-comex-page .tracking-modal .process-row {
    padding:0.5rem 0;
    border-bottom: var(--bs-border-width) solid var(--line);
}
.tracking-comex-page .tracking-modal .process-row:first-child { padding-top:0; }
.tracking-comex-page .tracking-modal .process-row:last-child { border-bottom: none; padding-bottom:0; }
.tracking-comex-page .tracking-modal .process-row h6 { margin-bottom:0.25rem; }

/* =====================================================
   Popups Customizados
   ===================================================== */

/* =====================================================
   Modal Styles
   ===================================================== */

/* Depth = opaque --surf fill + flat --sh2 popover shadow + a single --line
   hairline. No backdrop-filter blur, no hard !important border (the
   .tracking-modal id+class scope wins on specificity). */
.tracking-comex-page .tracking-modal .modal-content {
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--sh2);
    border: var(--bs-border-width) solid var(--line);
    background-color: var(--surf);
}

.tracking-comex-page .tracking-modal .modal-header {
    border-top-left-radius: 10px !important;
    border-top-right-radius: 10px !important;
    background: linear-gradient(135deg, var(--surf-2) 0%, var(--surf) 100%);
    border-bottom: var(--bs-border-width) solid var(--line);
    padding:1rem 1rem;
}

.tracking-comex-page .tracking-modal .modal-title {
    font-size: var(--fonte-destaque);
    font-weight: 500;
    color: var(--ink);
}

.tracking-comex-page .tracking-modal .modal-footer {
    border-bottom-left-radius: 10px !important;
    border-bottom-right-radius: 10px !important;
    background-color: var(--surf-2);
    padding:0.5rem 1rem;
    border-top: var(--bs-border-width) solid var(--line);
}

.tracking-comex-page .tracking-modal .modal-body {
    max-height: calc(100vh - var(--header-height) - var(--tracking-header-height) - 160px);
    overflow-y: auto;
    overflow-x: hidden;
    padding:1rem 1rem;
}

.tracking-comex-page .tracking-modal .modal-body::-webkit-scrollbar {
    width: 0.5rem;
}

.tracking-comex-page .tracking-modal .modal-body::-webkit-scrollbar-track {
    background: var(--surf-2);
    border-radius: var(--bs-border-radius-sm);
}

.tracking-comex-page .tracking-modal .modal-body::-webkit-scrollbar-thumb {
    background: var(--line-3);
    border-radius: var(--bs-border-radius-sm);
}

.tracking-comex-page .tracking-modal .modal-body::-webkit-scrollbar-thumb:hover {
    background: var(--ink-4);
}

/* FCDS tab treatment — clean cascade, no !important. Bootstrap's .nav-tabs
   borders are neutralised once via `border:0;background:none`, then we draw a
   single transparent bottom border that becomes --acc on the active tab
   (active underline). Specificity (.tracking-comex-page .tracking-modal
   .nav-tabs .nav-link) wins against Bootstrap's .nav-tabs .nav-link without
   forcing. */
.tracking-comex-page .tracking-modal .nav-tabs {
    border-bottom: var(--bs-border-width) solid var(--line);
    margin-bottom:1rem;
}

.tracking-comex-page .tracking-modal .nav-tabs .nav-link {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom:-0;
    color: var(--ink-3);
    padding:0.5rem 0.5rem;
    font-weight: 500;
    font-size: var(--fonte-destaque);
    transition: color 0.16s ease, border-color 0.16s ease;
}

.tracking-comex-page .tracking-modal .nav-tabs .nav-link:hover {
    color: var(--ink-2);
    border-bottom-color: var(--line-3);
}

.tracking-comex-page .tracking-modal .nav-tabs .nav-link:focus-visible {
    outline: none;
    box-shadow: var(--ring);
    border-radius: var(--r-xs);
}

.tracking-comex-page .tracking-modal .nav-tabs .nav-link.active {
    color: var(--acc);
    border-bottom-color: var(--acc);
    font-weight: 500;
}

@media (prefers-reduced-motion: reduce) {
    .tracking-comex-page .tracking-modal .nav-tabs .nav-link { transition: none; }
}

.tracking-comex-page #countryProcessModal .nav-tabs {
    display: flex;
    flex-wrap: nowrap;
    gap:0.25rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom:0.25rem;
    scrollbar-width: thin;
}

.tracking-comex-page #countryProcessModal .nav-tabs .nav-item {
    flex: 0 0 auto;
}

.tracking-comex-page #countryProcessModal .nav-tabs .nav-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap:0.25rem;
    width: auto;
    padding:0.25rem 0.5rem;
    font-size: var(--fonte-corpo);
    white-space: nowrap;
    text-align: center;
}

/* FCDS mono count pill on tabs (replaces Bootstrap badge bg-secondary). Neutral
   --acc-soft fill, mono tabular count in slate ink — never grey Bootstrap. */
.tracking-comex-page .tracking-modal .nav-tabs .tcx-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    padding:0 0.5rem;
    margin-left:0.5rem;
    border-radius: var(--raio-chip);
    background: var(--acc-soft);
    color: var(--acc-ink);
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    font-size: var(--fonte-corpo);
    line-height: 1.5;
}

.tracking-comex-page #countryProcessModal .modal-dialog {
    max-width: 32.5rem !important;
}

/* Bordo/bg/radius/padding-base vêm de .card.card-body (Bootstrap), aplicado
   junto no JS. cursor:pointer + hover elevado do bloco antigo foram removidos:
   este item é só informativo dentro do modal consolidado, sem handler de
   clique (afordância morta). Resta o espaçamento entre itens da lista. */
.tracking-comex-page .consolidated-process-item {
    margin-bottom:0.5rem;
}

.tracking-comex-page .consolidated-process-item:last-child {
    margin-bottom:0;
}

.tracking-comex-page .consolidated-process-item strong {
    font-size: var(--fonte-destaque);
}

.tracking-comex-page .consolidated-process-item div {
    font-size: var(--fonte-destaque);
    line-height: 1.5;
}

/* ===== MERGED FROM bi/static/bi/css/despesas_comex.css (P5) ===== */
/* ============================================================================
   Despesas Comex — pilot reference page (FCDS reference-quality refactor)

   Pilot-scoped ONLY. Every rule is namespaced under
   .page[data-pagina="despesas_comex"] so nothing here leaks to other pages
   or to the shared main.css / fcds/*.css layers. Loaded in {% block styles %}
   (after main.css, before statement-theme.css) — selectors carry the
   [data-pagina] attribute so they outrank statement-theme's lower-specificity
   rules without !important wherever possible.

   Goal: resolve the incoherences the audit found on this page —
     · the .content (gradient) vs .page (flat panel) surface seam,
     · KPI numbers not monospace (FCDS rule 3),
     · the 5-colour KPI "rainbow" (FCDS rule 1: one accent; rule 2: colour=meaning),
     · sub-12px filter labels,
     · filter strip / tab skin coherence.
   References: docs/planos/pilot-visual-audit-B.md, pilot-datatables-audit-C.md,
   pilot-color-audit-D.md.
   ========================================================================== */

/* ── 1. Surface seam ───────────────────────────────────────────────────────
   .content (shell) shows the body's 4-stop gradient over #edf0f4; .page
   painted a flat opaque #edf0f4 panel on top, masking the gradient inside the
   page while it stayed visible in the shell margins. Make the page transparent
   so the single body gradient is the one canvas under everything (system.md §9
   "one quiet gradient under everything"). Page-scoped; global .page untouched. */
.page[data-pagina="despesas_comex"] {
  background-color: transparent;
}

/* ── 1b. Linha em foco (clique numa notificação do balão) ──────────────────
   `?titulo=fil-tip-doc-tit` na URL faz `despesas_comex.js` abrir a aba, paginar
   até a linha e acender esta classe. Âmbar e não o acento da casa: é um "olhe
   aqui" temporário, não um estado da linha — mesmo precedente de `.dre-focada`.
   O gradiente do fundo pede `background` na CÉLULA (o <tr> não pinta em tabela
   com colunas sticky). Escopo de página; nada aqui vaza. */
.page[data-pagina="despesas_comex"] tr.df-focada > td {
  animation: df-piscar 1.6s ease-out;
}
/* Vazio por "Apenas favoritos" (#633): a célula ocupa a largura da tabela,
   que rola na horizontal; centralizado, o aviso caía fora da vista. */
.page[data-pagina="despesas_comex"] td.dataTables_empty.df-vazio-favoritos {
  text-align: left;
}
/* "Apenas favoritos" ligado esconde quase tudo (#635): o rótulo deixa de ser
   miúdo e cinza para quem chega à aba não perder que o filtro está ativo. */
.page[data-pagina="despesas_comex"] #df-favoritos-toggle:has(input:checked) label {
  font-size: var(--fonte-destaque);
  font-weight: 500;
  color: var(--bs-primary) !important;
}
@keyframes df-piscar {
  0%, 30% { background: var(--warning-subtle); }
  100%    { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  /* Sem pulso, mas o destaque tem de sobrar: quem desligou animação continua
     precisando achar a linha. */
  .page[data-pagina="despesas_comex"] tr.df-focada > td {
    animation: none;
    background: var(--warning-subtle);
  }
}

/* ── 2. Topbar timestamp ────────────────────────────────────────────────────
   Was inline style="font-size:0.875rem"; now a class on the same element.
   (KPI-band, filter-strip e length-select responsivo desta página foram
   canonizados: .kpi-band__secondary tabular-nums vive no componente global; os
   filtros migraram para os widgets colfilter canônicos; o length-select em mobile
   é tratado no componente .datatable compartilhado.) */
.df-timestamp {
  font-size: var(--fonte-pequena);
  font-variant-numeric: tabular-nums;
}

/* ===== DIAGNOSTICO (dp-*) ===== */
/* Diagnóstico de preenchimento — só o que NÃO é da permanência.
   Card, raias, KPIs e modais reusam custom.css (classes pp-*). */

.dp__escopo { color: var(--ink-2); }

/* A lista de processos preenche a altura restante do shell (.pp é flex column,
   altura fixa = 100vh - topbar) e ROLA sozinha. Antes o container herdava
   .pp__kanban, que é flex horizontal com overflow-y:hidden — feito para as raias
   rolarem lado a lado — e decepava a tabela alta por volta da 13ª linha: as 86
   linhas existiam no DOM mas só ~13 apareciam. overflow-x cobre telas estreitas. */
.dp__lista {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: auto;
}

/* Chip de sugestão do e-mail: `.card.border-start.border-success.border-3`
   (montarSugestao em diagnostico-preenchimento.js). Verde = resolvível, em
   contraste com o âmbar/vermelho da anomalia que o card responde; a faixa
   esquerda + `.card-body` bastam, sem CSS autoral. */

/* Tabela de processos. Cores do semáforo = as mesmas da permanência
   (custom.css), para que a régua de dias seja uma só na cabeça de
   quem lê as duas telas. */
.dp-tabela { font-size: var(--fonte-corpo); }
.dp-tabela th {
  font-size: var(--fonte-corpo);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink-3);
  font-weight: 500;
}
.dp-tabela tbody tr { cursor: pointer; }

.dp-modal__bl {
  padding:0.5rem 0;
  border-top: var(--bs-border-width) solid var(--line);
}
.dp-modal__bl-titulo { font-weight: 500; }
.dp-modal__bl-meta { font-size: var(--fonte-corpo); color: var(--ink-3); }
.dp-modal__anomalia {
  padding:0.5rem 0;
  border-top: var(--bs-border-width) solid var(--line);
}
.dp-modal__anomalia-detalhe { margin-top:0.25rem; color: var(--ink-2); }
.dp-modal__anomalia-bls { margin-top:0; font-size: var(--fonte-corpo); color: var(--ink-3); }
.dp-modal__evidencia { margin-top:0.25rem; }

/* ==========================================================================
   Painel "Motivos de bloqueio" (#149) — componente `pareto-bloqueio.js`.
   ========================================================================== */

/* Barra com período e as duas alternâncias; aviso "Sem motivo" no laranja de
   TEXTO de atenção (#FA4B00, nunca âmbar); a quebra e os lotes são linhas que
   abrem dentro da linha-filha da grade, sem caixa própria. */
.motivos-bloqueio__barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin-bottom: 1rem;
}
.motivos-bloqueio__alerta {
  display: block;
  padding: 0;
  margin-bottom: .5rem;
  border: 0;
  background: none;
  color: var(--warning-text);
  text-align: left;
  cursor: pointer;
}
.motivos-bloqueio__alerta:hover { text-decoration: underline; }
.motivos-bloqueio__lotes-sem-motivo { margin-bottom: 1rem; }
.motivos-bloqueio__grafico {
  position: relative;
  height: 16rem;
  margin-bottom: 1rem;
}
.motivos-bloqueio__tabela { background: transparent; }
/* Os lotes de um item rolam dentro da linha: um motivo com dezenas de lotes
   não empurra o resto da grade para fora da tela. `width: 0` + `min-width`
   impede a tabela larga dos lotes de alargar as colunas da grade-mãe. */
.motivos-bloqueio__lotes {
  width: 0;
  min-width: 100%;
  max-height: 20rem;
  overflow: auto;
}
/* A grade não quebra linha; nos lotes o nome do produto quebra, o resto não
   (`text-nowrap` nas colunas curtas). */
.grade .grade-tabela .motivos-bloqueio__lotes td { white-space: normal; }
/* O produto (código — descrição) é a coluna que se lê: largura mínima para
   não virar uma coluna de cinco linhas ao lado da observação longa. */
.motivos-bloqueio__lotes td:first-child { min-width: 20rem; }
/* A quebra é filha da linha: recuo, nas mesmas colunas. */
.grade .grade-tabela tbody .motivos-bloqueio__quebra > td:first-child { padding-left: 1.75rem; }
.motivos-bloqueio__quebra,
.motivos-bloqueio__lote { cursor: pointer; }
.motivos-bloqueio__quebra:hover > td,
.motivos-bloqueio__lote:hover > td { background: var(--surf-2); }
.motivos-bloqueio__quebra[aria-expanded="true"] > td { font-weight: 500; }

/* ============================================================================
   Importar OF (Conexos → NF rascunho no Senior homolog) — tela oculta, F440GNE.
   O Romaneio dividia esta casca (o seletor carregava os dois prefixos) até ser
   recriado em 17/08/2026 com layout próprio de altura cheia: as regras dele
   moram na seção `romaneio` mais abaixo, e daqui só sobrou o que é da /importar-of/.
   Tokens FCDS.
   ============================================================================ */

/* A tela entrou na bancada em 18/08/2026: a casca (colunas, rolagem, régua) é
   `.bnc*`; daqui para baixo é só o conteúdo da NF. `.iof-panel`,
   `.iof-searchrow`, `.iof-list` e `.iof-actionbar` morreram com os cards e com
   a barra de ação do corpo — a ação vive na régua. */
.iof-barra{display:flex;align-items:center;gap:0.75rem;
  padding:0.75rem 1rem;border-bottom:var(--bs-border-width) solid var(--line)}
.iof-deprow{display:flex;align-items:center;gap:0.5rem;margin:0;
  font-size:var(--fonte-corpo);color:var(--ink-3)}
.iof-deprow input{width: 4.375rem}

.iof-empty{padding:3rem 1rem;text-align:center;color:var(--ink-3)}
.iof-empty--err{color:var(--negative-text)}

.iof-doc__t{font-weight:500}
.iof-doc__sub{color:var(--ink-3);font-size:var(--fonte-corpo);margin-top:0.25rem}
.iof-muted{color:var(--ink-3)}

.iof-sec{padding:1rem 1rem;border-top:var(--bs-border-width) solid var(--line)}
.iof-sec>h3{font-size:var(--fonte-corpo);text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-3);font-weight:500;margin:0 0 0.5rem}
.iof-sec--muted>h3{color:var(--ink-4,var(--ink-3))}
.iof-fields{display:grid;
  grid-template-columns:repeat(auto-fill,minmax(11.25rem,1fr));gap:1rem 1rem}
.iof-f{display:flex;flex-direction:column;gap:0.25rem;min-width:0}
.iof-f__k{font-size:var(--fonte-corpo);color:var(--ink-3);display:flex;align-items:center;gap:0.25rem}
.iof-f__v{font-weight:500;color:var(--ink);word-break:break-word}

/* itens: Bootstrap .table .table-sm (larg./bordas/padding). Só o cabeçalho
   uppercase-pequeno e o sub-texto de alíquota ficam custom (sem primitiva). */
.iof-items{font-size:var(--fonte-corpo)}
.iof-items th{font-size:var(--fonte-corpo);text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink-3)}
.iof-sub{color:var(--ink-3);font-size:var(--fonte-corpo)}

.iof-lote{display:flex;gap:1rem;align-items:flex-start;
  padding:1rem;border-radius:var(--r-sm);background:var(--surf-2);border:var(--bs-border-width) dashed var(--line-3);
  color:var(--ink-3)}
.iof-lote__ic{width: 1.875rem;height: 1.875rem;border-radius:var(--bs-border-radius-lg);background:var(--surf);
  border:var(--bs-border-width) solid var(--line-3);display:grid;place-items:center;flex:none;color:var(--ink-3)}
.iof-lote b{color:var(--ink-2)}

.iof-note{padding:1rem;border-top:var(--bs-border-width) solid var(--line);
  font-size:var(--fonte-corpo);color:var(--ink-3)}
.iof-note b{color:var(--ink-2)}

.iof-result{display:flex;align-items:center;gap:0.5rem;
  padding:1rem 1rem;border-top:var(--bs-border-width) solid var(--line);font-size:var(--fonte-corpo);color:var(--ink-2)}
.iof-result__ic{width: 1.875rem;height: 1.875rem;border-radius:50%;flex:none;
  display:grid;place-items:center;color:var(--bi-text-on-accent);font-weight:500}
.iof-result--loading{color:var(--ink-3)}
.iof-result--ok{background:var(--positive-subtle)}
.iof-result--ok .iof-result__ic{background:var(--positive)}
.iof-result--ok b{color:var(--positive-text)}
.iof-result--err{background:var(--negative-subtle)}
.iof-result--err .iof-result__ic{background:var(--negative)}
.iof-result--err b{color:var(--negative-text)}

/* O JSON do payload — hoje na prancheta, antes num modal. `.iof-modal-sub`
   morreu junto: a prancheta usa `.iof-note` para a linha de contexto. */
.iof-json{margin:0;font-family:var(--mono);font-size:var(--fonte-pequena);line-height:1.5;
  font-variant-numeric:tabular-nums;white-space:pre;overflow-x:auto;color:var(--ink-2)}
.iof-json .iof-jk{color:var(--brand-ink)}
.iof-json .iof-js{color:var(--positive-text)}
.iof-json .iof-jn{color:var(--cat-4)}
.iof-json .iof-jp{color:var(--ink-3)}
.iof-dup-list{margin:0.25rem 0 0.5rem;padding-left:1rem}
.iof-dup-list li{margin:0 0}

/* Situação intermediária (sobra/falta) ganha o terceiro tom (--warn), ao lado
   de --ok/--err acima. */
.iof-result--warn{background:var(--warning-subtle)}
.iof-result--warn .iof-result__ic{background:var(--warning)}
.iof-result--warn b{color:var(--warning-text)}

/* ── Histórico de Preços — controles compactos (produto + período no card) ───
   Produto e os dois campos de mês (De/Até) vivem no MESMO card, numa linha só.
   O produto cresce; os campos de mês têm largura fixa; Buscar alinha ao fim. */

/* ── Separação: a superfície aberta NÃO é um cartão ──────────────────────────
   Pedido do dono, 27/08/2026: "não precisa ser dentro de card nenhum". Aberta,
   a superfície JÁ é a tela — ela tem altura fixa, fundo próprio e cada painel
   rola por dentro. A moldura em volta (borda, raio e o recuo do `.content`)
   desenhava um cartão flutuando sobre um fundo que ninguém vê, e cobrava
   40 px de largura e 52 px de altura por isso. Medido ao vivo: 1512x796 vira
   1552x848, e a lista de lotes passa de 10 para 11 peças à vista.

   Zera os TOKENS, não o `padding`: a altura da `.wsurface` é
   `calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b))`, então
   mexer no token corrige o recuo e a altura de uma vez. Zerar só o `padding`
   deixaria a superfície 52 px mais curta que a janela.

   `:has()` em vez de uma classe no `<body>` porque a MESMA página serve os dois
   estados: a fila é um cartão de verdade, sobre o fundo do app, e continua com
   o recuo do resto do BI. Quem manda é o que está na tela agora, e o seletor lê
   exatamente isso.

   O RECUO LATERAL É ASSIMÉTRICO, e isso não é desleixo — é o que a geometria
   do shell pede. `aside.side` é `position:fixed` com 64 px, mas `main` tem
   `margin-left:48px`: a barra cobre os primeiros 16 px de `main` em TODA página
   do app, e é o recuo do `.content` que sempre escondeu isso. Sem recuo nenhum
   a capa perdia a primeira letra de cada rótulo ("EDIDO", "TENS DO PEDIDO"),
   visto ao vivo. Então à ESQUERDA os 16 px são obrigatórios — e invisíveis,
   porque a barra ocupa exatamente eles.

   À DIREITA não há barra nenhuma para desviar, e um recuo igual ao da esquerda
   só desenhava uma tira do fundo do app colada na janela — que é o que parece
   espaço reservado para uma rolagem que não existe (nenhum ancestral aqui tem
   `overflow-y:scroll` nem `scrollbar-gutter`). Zerado, a superfície branca
   encosta na janela e a tabela ganha os 16 px. O respiro entre a tabela e a
   borda continua existindo: é o `padding` do próprio `.wsurface__main`.

   Consertar o desencontro na raiz é `main{margin-left:64px}` — mexe no shell
   das ~28 páginas e não cabe neste commit. */
.content:has(#sep-superficie:not([hidden])){
  --content-pad-y:0px;--content-pad-b:0px;padding:0 0 0 16px}
.content:has(#sep-superficie:not([hidden])) #sep-superficie{border:0;border-radius:0}

/* ── Separação e faturamento ─────────────────────────────────────────────────
   A linha da tabela de itens é o alvo que troca o produto da etapa de lotes.
   Só o cursor entra aqui: a marcação da linha aberta é `.table-active` do
   Bootstrap e o anel de foco é o `:focus-visible` do Bootstrap — nada de
   destaque ou de foco autoral nesta tela. */
.sep-item-linha{cursor:pointer}
/* O cartão do item é TRÊS LINHAS CURTAS (descrição, código, estado) e vivia
   com o respiro de parágrafo do shell: 89 px por item, com 24 px de altura de
   linha para textos de 13 px. Apertado ao que ele é — entrelinha de leitura de
   rótulo, não de prosa — cai para 77 px, e o trilho ganha um item inteiro a
   cada seis. Escopado à `.sep-item-linha`, nunca à `.wsurface__item` do FCDS,
   que outras bancadas usam com conteúdo mais longo. */
.sep-item-linha{padding:.5rem .75rem;line-height:1.2}

/* ── O estado de cada item no trilho, e o progresso do pedido ─────────────
   Três estados servidos pelo backend (`/resumo-itens/`): pendente, marcado e
   não gravado, gravado. Antes o cartão só sabia dizer "Já com lote", e um item
   com sete lotes marcados era visualmente idêntico a um intocado — foi assim
   que a marcação evaporou sem ninguém ver (pedido 20878).
   Cor só onde ela significa: o marcado é o único que pede ação e leva o acento;
   o gravado é história e fica em positivo discreto; o pendente é texto morno. */
.sep-item-estado{margin-top:.125rem;font-weight:500;color:var(--ink-3)}
.sep-item-estado[data-estado="marcado"]{color:var(--acc)}
.sep-item-estado[data-estado="gravado"]{color:var(--positive-text)}
.sep-progresso{font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0}
/* O pedido inteiro ao lado da ação, no rodapé. Só aparece com mais de um item
   marcado — o texto vem pronto do backend. */
.sep-consolidado{font-weight:500;color:var(--ink-2);white-space:nowrap}
/* A lista de itens dentro da confirmação: o que exatamente vai ser gravado,
   um por linha, antes de uma escrita sem desfazer. */
.sep-confirma-itens{margin:.5rem 0 0;padding-left:1.1rem}
.sep-confirma-itens li{margin-bottom:.15rem}
/* O efeito no pedido (cresce / encolhe) dentro da linha da revisão. Ele morava
   no diálogo do item, que deixou de existir quando a revisão virou uma só, do
   pedido inteiro: aqui é a última coisa que se lê antes de autorizar a escrita,
   então destaca do resto da linha sem virar alarme. */
.sep-confirma-efeito{font-weight:500;color:var(--ink-2)}
/* A marca da linha aberta é a classe `.table-active` do Bootstrap, mas a
   pintura dela mora em `.table > :not(caption) > * > *` — e a tabela desta
   tela é `.tbl`, não `.table`, então a classe entrava no DOM e não pintava
   nada (conferido ao vivo: background rgba(0,0,0,0) na linha marcada).
   Só se repete o seletor; a cor continua sendo a do Bootstrap — o token
   `--bs-table-active-bg` também só é declarado em `.table`, daí o fallback
   com o mesmo valor que o Bootstrap 5.2.3 lhe dá. */
.tbl > tbody > tr.table-active > td{background:var(--bs-table-active-bg,rgba(0,0,0,.1))}

/* ── Fila de pedidos da separação (escolher em QUAL pedido trabalhar) ─────────
   Onze colunas em 1.560 px, e a coluna da AÇÃO tem de ser uma delas. Medido
   antes: `Criado` saía cortada na borda direita e o botão Separar ficava FORA da
   tela — a fila oferecia trabalho que ninguém alcançava sem rolar de lado.
   `.cell-clip` genérico dá 22 rem, largo demais quando quatro colunas o usam
   (cliente, produto, comentário, vendedor). O truncamento em si é no JS, com o
   texto inteiro no `title`.

   E o cabeçalho no mesmo tom do resto da tela: caixa normal, miúdo, tinta fraca
   — o versalete espaçado do padrão FCDS empatava em peso com os badges de
   situação e urgência, que são o que a pessoa varre. Escopado à página; nenhuma
   outra tela muda. A superfície de trabalho é irmã deste bloco no template, não
   descendente, então não é alcançada por este seletor: quem a veste é `.pickbox`. */
/* AS COLUNAS SE AJUSTAM AO CONTEÚDO. O teto de 10rem foi calibrado quando a
   fila tinha ONZE colunas e quatro delas eram texto largo (cliente, produto,
   comentário, vendedor). Sobraram oito, e três daquelas quatro saíram — o teto
   fixo agora só serve para cortar nome de cliente numa tabela que tem espaço de
   sobra. `table-layout:auto` (já herdado) distribui pelo conteúdo; o
   truncamento continua existindo para o caso extremo, mas com um teto que
   respira e sem largura mínima que empurre as outras. */
/* LARGURA POR PAPEL, não uma trava só para todas. O teto único de 10rem
   cortava tudo igual — nome de cliente, produto e observação — num layout que
   já tinha espaço. Agora cada coluna de texto tem o teto do que ela precisa:

   - observação: é INSTRUÇÃO de quem vendeu ("ENTREGAR SÓ PELA MANHÃ",
     "FATURAR SOMENTE EM SETEMBRO"), lida antes de escolher o pedido — ganha o
     maior teto e quebra em até três linhas;
   - cliente: identifica, não instrui. Razão social de 50 caracteres não precisa
     caber inteira; o `title` guarda o resto;
   - financeiro: o motivo cabe em duas linhas curtas.

   `table-layout:auto` (herdado) distribui o resto pelo conteúdo. */
[data-pagina="separacao_faturamento"] .cell-clip{max-width:none}
/* Na grade da casa (15/09/2026) as larguras vão por CLASSE da coluna, não pela
   posição: o `nth-child` prendia a regra na coluna errada toda vez que a ordem
   mudava. O invólucro `.grade-celula` corta em uma linha; as duas colunas que
   se LEEM (Financeiro e Observação) voltam a quebrar em duas. */
[data-pagina="separacao_faturamento"] .grade .grade-tabela :is(th, td){padding-left:.4rem;padding-right:.4rem}

/* ── .detrow — LINHA DE DETALHE DE UMA TABELA (componente) ────────────────────
   O conteúdo que a linha truncada esconde, aberto embaixo dela. O corpo é
   desenhado por quem chama; aqui está a fita de rótulos, a célula do controle e
   o botão que gira. Casado com `row().child()` do DataTables — é a tabela que
   fecha a filha ao reordenar, filtrar e paginar. */
/* O controle é `.drill-plus`, a afordância canônica de abrir detalhe (mais ↔
   menos, glifo no `::before` do componente). A seta que girava aqui era
   invenção local: um segundo vocabulário de "abre isto" na mesma app. */
.detrow__cel{width:1%;padding-right:0}
/* A LINHA-FILHA não é uma linha de dados: não se lista, não reage ao mouse e não
   tem moldura. O DataTables cria o <tr> da filha sem classe, então ela caía nas
   regras de listra e de hover das outras linhas — e como o painel cinza tem
   fundo próprio, quem mudava de cor era só o PADDING da <td> em volta dele: uma
   moldura de 8 px que acendia e apagava conforme o cursor passava. Padding zero
   faz o painel preencher a célula, e o `box-shadow:none` desliga a listra e o
   realce (é por `box-shadow` inset que o Bootstrap pinta os dois).
   O `!important` do padding não é preferência: `.tbl.dataTable tbody td`
   já declara o dele com `!important`, e sem isto o zero é ignorado —
   medido no navegador, a moldura continuava lá. */
.tbl tbody tr.detrow__filha > td,
.tbl tbody tr.detrow__filha:hover > td{padding:0 !important;box-shadow:none;background:none}
/* Fundo BRANCO, como as linhas de dados: o painel é a continuação do pedido que
   está logo acima, não um bloco estranho encaixado na lista. O cinza que estava
   aqui competia com a listra da tabela e criava uma terceira cor de fundo. */
.detrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));
  gap:.625rem 1.5rem;margin:0;padding:.75rem 1rem;background:var(--surf)}
.detrow__campo{min-width:0}
.detrow__campo dt{margin:0;font-size: var(--fonte-pequena);font-weight:500;color:var(--ink-3)}
/* Componente compartilhado (justificativa explícita, achado do dono em
   /banking/ 24/09/2026): um valor comprido e sem espaço (ex.: identificador de
   transação do BB, "BB0013155000000204000202609010136010001800011 8") não tinha
   onde quebrar — a célula do grid pode encolher (`min-width:0` acima), mas o
   TEXTO em si só transbordava por cima da célula vizinha. `overflow-wrap` deixa
   o navegador quebrar dentro da palavra quando não há espaço — não muda nada
   para um valor curto/normal, só evita a sobreposição do comprido. */
.detrow__campo dd{margin:.125rem 0 0;font-size: var(--fonte-corpo);color:var(--ink);overflow-wrap:anywhere}
/* TELA ESTREITA PAGA COM RECUO, NÃO COM ALTURA. Abaixo de 1400px a régua de dez
   colunas não fecha (medido: pedia 1.326px num vão de 1.276) e a saída óbvia
   seria deixar Entrega e Quantidade quebrarem de novo — mas isso devolve 12px
   de altura a TODAS as 72 linhas para acomodar duas. Apertar o recuo lateral
   das células devolve 8px por coluna, 80px na linha inteira, e não custa
   nenhuma altura: a tabela volta a caber e a densidade vale em toda largura. */
@media (max-width:1399px){
  [data-pagina="separacao_faturamento"] .tbl.dataTable td,
  [data-pagina="separacao_faturamento"] .tbl.dataTable th{
    padding-inline:.25rem !important}
}

/* O RODAPÉ DA TABELA É UMA LINHA, não uma faixa. "1–72 de 72" mais um paginador
   de uma página só ocupavam 59px — mais que uma linha de pedido. O texto e os
   controles ficam (o contador é o que avisa quando um filtro escondeu gente);
   some o recuo que os cercava. */
[data-pagina="separacao_faturamento"] .datatable-bottom{padding-block:.25rem}
[data-pagina="separacao_faturamento"] .datatable-bottom .page-link{
  padding:.125rem .5rem;font-size: var(--bi-fs-compact)}
[data-pagina="separacao_faturamento"] .tbl thead th{text-transform:none;
  letter-spacing:0;font-size: var(--bi-fs-compact)}
/* A coluna da AÇÃO fica grudada na borda direita (componente `.stickcols` +
   `stick-r--1`, o mesmo das telas de matriz): são doze colunas num cartão de
   1.512 px, a tabela rola de lado, e o que saía de vista era justamente o botão
   — a pessoa via o pedido e não alcançava o trabalho dele sem rolar.
   Aqui só a largura: o resto (opacidade, listra, divisor, escada de z) já é do
   componente. Tentei antes um `position:sticky` local com `box-shadow` de
   divisor e caí exatamente na armadilha que o comentário do componente
   documenta: a listra do `.table-striped` é pintada com `box-shadow inset
   9999px`, que atropela o divisor e deixa a célula transparente em metade das
   linhas (medido: `background-color: rgba(0,0,0,0)` nas linhas `.odd`, com a
   data da coluna de trás aparecendo através do botão). */
[data-pagina="separacao_faturamento"] .tbl td.stick-r--1,
[data-pagina="separacao_faturamento"] .tbl th.stick-r--1{white-space:nowrap}

/* Alvo de toque do checkbox de lote. A caixa desenhada tem 14x14 px — metade
   do mínimo da WCAG 2.2 e impossível de acertar de luva num tablet do galpão.
   O <label> em volta alterna a caixa nativamente, então basta dimensioná-lo:
   44x44 px de área clicável com a caixa centrada e um pouco maior. */
.sep-alvo-toque{display:flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;margin:0;cursor:pointer}
.sep-alvo-toque .form-check-input{width:1.5rem;height:1.5rem;margin:0;flex:none}

/* Barra de progresso da fila (separado × saldo). Fina de propósito: informa a
   proporção de relance sem competir com o número, que é o dado exato. O
   percentual vem pronto do backend (`progresso_pct`). */
.sep-progresso{height:.35rem;margin-top:.25rem}

/* Rodapé fixo do modal do pedido. Medido antes: um produto com 204 lotes dá
   `scrollHeight` 8.247 px numa janela de 779 px — dez telas de checkbox até o
   botão, que ficava DEPOIS da lista. Sticky dentro do `.modal-body` rolável põe
   a decisão sempre à mão. As margens negativas sangram o padding do corpo para
   a faixa ir de borda a borda, como um rodapé de modal de verdade. */
.sep-rodape{position:sticky;bottom:0;z-index:2;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  margin:1rem -1rem -1rem;padding:.75rem 1rem;
  background:var(--surf);border-top:var(--bs-border-width) solid var(--line)}

/* Régua de peso — a peça de assinatura da tela e a única coisa dela que muda de
   cor. O pedido pede um número redondo (6.000 KG), o mundo entrega números
   tortos (1.748 + 1.579 + 1.702), e a pergunta que a pessoa faz o tempo todo é
   "o que marquei já cobre o pedido, e quanto passou?". Sem animação nenhuma:
   galpão, tablet, luva — a cor é o sinal inteiro, e por não se mover ela já
   respeita `prefers-reduced-motion`. A classificação (falta/coberto/passa) vem
   decidida do Python; aqui só se escolhe a cor de cada uma. */
.sep-regua{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;
  font-variant-numeric:tabular-nums}
.sep-regua__estado{font-weight:500;padding:.125rem .5rem;border-radius:var(--r-xs)}
.sep-regua--falta   .sep-regua__estado{background:var(--surf-3);color:var(--ink-2)}
.sep-regua--coberto .sep-regua__estado{background:var(--positive-subtle);color:var(--positive-text)}
.sep-regua--passa   .sep-regua__estado{background:var(--warning-subtle);color:var(--warning-text)}

/* ── .wsurface — SUPERFÍCIE DE TRABALHO (componente, não página) ─────────────
   Modo-tarefa em tela cheia: a lista de onde se veio some, e a tela inteira
   passa a ser a tarefa. Nasceu para a separação de pedidos, mas nada aqui sabe
   o que é um lote — serve qualquer fluxo em que a pessoa entra num registro,
   trabalha nele e sai (conferência, importação, fechamento).

   Por que não um modal: o modal é uma caixa por cima de uma lista, com duas
   barras de rolagem e um corpo que encolhe conforme o conteúdo cresce. Numa
   tarefa de galpão com 200 lotes isso é uma janelinha rolando dentro de outra.
   A superfície ocupa a altura útil e distribui: capa em cima, trilho de
   contexto à esquerda, trabalho no centro, decisão grudada embaixo. Cada painel
   rola por si; a página nunca rola.

   Estrutura:
     .wsurface > .wsurface__cap  (capa: quem é o registro)
               > .wsurface__body > .wsurface__rail  (contexto/navegação interna)
                                 > .wsurface__main  (o trabalho)
               > .wsurface__foot (medida + ação, sempre à vista) */
.wsurface{display:flex;flex-direction:column;gap:0;
  /* Altura FIXA, não mínima: é ela que faz o rodapé com a medida e a ação ficar
     sempre à vista. Com `min-height` a superfície crescia com a lista de lotes
     (11 lotes já passavam da dobra) e a decisão ia junto para o fim da página —
     exatamente o que o rodapé grudado existe para evitar. Quem rola é o painel
     de dentro. 52px = a topbar fixa (`.topbar`, 3.25rem), o mesmo literal que a
     coluna de conteúdo já desconta na linha 6677; não existe token de altura de
     topbar em `:root` e inventar um aqui criaria uma segunda verdade. */
  height:calc(100dvh - 52px);   /* o padding do `.content` já foi anulado acima */
  background:var(--surf);border:var(--bs-border-width) solid var(--line);
  border-radius:var(--r);overflow:hidden}
/* A CAPA É UMA GRADE, não uma fila de blocos. Em flex, cada bloco aninhado
   media a própria largura e o que sobrava na linha ficava em branco: a linha do
   cliente acabava a 540px numa capa de 1.660 e as outras informações esperavam
   embaixo. Colunas de largura dinâmica (`auto-fill` + `minmax`) e cada
   informação como célula fazem a linha fechar sozinha, com a hierarquia dada
   pelo quanto cada uma ocupa: o cliente vale duas colunas, a data de entrega
   (que tem controle) duas, cada campo uma, e a advertência toma a sobra. */
/* A CAPA É UMA CAIXA DE FATOS ADENSADA.
   O formato continua o mesmo — rótulo miúdo em cima, valor embaixo —, o que
   muda é o quanto cada fato ocupa e como eles se arrumam. Antes: entrelinha de
   texto corrido, recuos de 1rem, colunas fixas e fileiras conforme sobrasse —
   uma ficha gastava 40px de altura para dizer "Carga · Carreta ou truque", e a
   capa ia a 364px.
   Agora a ficha tem 28px (rótulo em 11px/1.1, valor em 13px/1.2), o fluxo é por
   COLUNA sobre duas trilhas fixas — os fatos descem, viram a coluna e descem de
   novo, então quem se ajusta ao volume é o número de colunas, não a altura — e
   o cliente ocupa duas colunas de UMA fileira, não as duas: comendo as duas ele
   deixava um vão do tamanho dele embaixo do nome. */
.wsurface__cap{display:grid;
  /* 8 e 4 na régua de 12 do Bootstrap: os fatos com dois terços, a advertência
     com um. O voltar é trilha `auto` — tem largura de botão, não de coluna. */
  /* As fichas tomam a largura que PRECISAM e a advertência fica com o resto —
     não uma fatia fixa. Com 8fr/4fr as colunas de fato eram todas do mesmo
     tamanho, então "Cidade · JOINVILLE · SC" reservava tanto quanto "Frete ·
     CIF — frete por nossa conta" e sobrava um vão depois de cada valor curto,
     mais um vão maior antes da advertência. */
  /* 50/50: fichas e advertência com metade cada. Sem observação a regra abaixo
     colapsa para uma coluna só e as fichas tomam a capa inteira. */
  /* A ADVERTÊNCIA MEDE O QUE ELA DIZ. Com metade da capa reservada, uma
     observação de uma linha ficava com 654px de caixa para 426px de texto —
     228px de amarelo vazio — e as fichas espremidas na metade restante, com
     vão depois de cada valor curto (marcado na captura do dono, 13/08/2026).
     `fit-content` dá à advertência o tamanho do texto dela, até um teto de
     30rem para o recado longo não comer a capa; o que sobra vai para as
     fichas, que se espalham por ele. */
  /* O TETO DA ADVERTÊNCIA É UMA FRAÇÃO DA CAPA. `max-content` + `max-width:
     30rem` no item eram 480px numa capa de 1.830 (1920px): fichas com meia
     fileira vazia e o recado cortado a três linhas — "travado de um jeito
     pequeno" (dono, 18/08/2026). `fit-content(42%)` mede o texto (recado curto
     continua do tamanho dele) até 42% da capa; o resto é das fichas — mesma
     proporção em qualquer largura. Percentual no `max-width` do item não serve:
     resolve contra a própria trilha e volta a 30rem. */
  grid-template-columns:minmax(0,1fr) fit-content(42%);
  /* E ela também não estica em ALTURA: `stretch` pintava 79px de amarelo para
     16px de frase. Quem manda na altura da capa são as fichas. */
  align-items:start;gap:.375rem .875rem;
  padding:.5rem .875rem;border-bottom:var(--bs-border-width) solid var(--line);
  background:var(--surf-2)}
/* Sem observação não há segunda coluna: os fatos tomam a capa inteira. */
.wsurface__cap:has(> .wsurface__cap-obs:empty){grid-template-columns:minmax(0,1fr)}
/* AS FICHAS SE EMPACOTAM, NÃO SE ALINHAM EM COLUNAS. Numa grade de colunas, a
   coluna tem a largura da ficha MAIS LARGA dela: "Cliente · ALYA CONSTRUTORA
   S/A" esticava a coluna e deixava rastro branco depois de "Pedido · 20318",
   que está em cima. E `max-content` em todas as colunas estourava a capa em tela
   estreita — a advertência caía para o mínimo e era cortada.
   Empacotadas (flex com quebra), cada ficha mede o que o valor dela mede, elas
   enchem a linha até o fim e a seguinte recomeça. Não sobra rastro porque não
   há coluna a respeitar. */
/* AS FICHAS COMEÇAM NA ESQUERDA, COM ESPAÇAMENTO IGUAL. Com
   `space-between` a folga da fileira era repartida ENTRE as fichas, e cada
   fileira repartia de um jeito: "Carga" caía embaixo de "Cliente", "Valor do
   pedido" embaixo de "Cidade" e nada se alinhava com nada — a grade parecia
   torta (marcado pelo dono, 13/08/2026). O `space-between` existia para matar o
   rastro branco antes da advertência, e esse rastro deixou de existir quando a
   advertência passou a medir o próprio texto. Grade de trilhas iguais foi
   tentada e custou uma fileira a mais (10 fichas de larguras muito desiguais em
   colunas de 156px: 3 fileiras, 145px de capa) — empacotar continua sendo o que
   cabe em duas. */
.wsurface__cap-esq{display:flex;flex-wrap:wrap;align-content:flex-start;
  align-items:flex-start;justify-content:flex-start;
  gap:.25rem 1.5rem;min-width:0}
/* A `<dl>` some como caixa para que cada ficha entre no empacotamento. Sem isto
   a fita inteira é UM item e não há o que empacotar. */
.wsurface__cap-esq > .wsurface__cap-campos{display:contents}
/* O cliente é ficha como as outras — mesmo rótulo miúdo, mesmo corpo de valor —
   só que com o dobro de LARGURA: a razão social tem 25 caracteres e numa coluna
   só ela quebraria em três linhas, esticando a fileira inteira. */

/* AS FICHAS SE ESPALHAM ATÉ AS DUAS BORDAS. Empacotadas só pelo tamanho do
   conteúdo, a última de cada fileira parava onde o texto dela acabava e o resto
   ficava em branco até a advertência — a faixa que estava circulada. Deixá-las
   CRESCER não resolve: a folga entra dentro da última ficha e o branco continua
   no mesmo lugar, só que dentro de uma caixa maior. Espalhando (`space-between`)
   a folga vira distância ENTRE as fichas, a primeira encosta na esquerda e a
   última na direita — não existe mais ponta livre. */
.wsurface__cap-campo{min-width:0}
/* Cliente e vendedor são razões sociais de 25 a 50 caracteres: numa célula só
   quebrariam em três linhas e esticariam a fileira inteira. Duas células. */
.wsurface__cap-campo.sep-cliente{grid-column:span 2}
.wsurface__cap-campo dt{font-size: var(--fonte-rotulo);line-height:1.2;text-transform:uppercase;
  letter-spacing:.02em;color:var(--ink-3);font-weight:500;margin:0}
.wsurface__cap-campo dd{margin:.0625rem 0 0;font-size: var(--fonte-corpo);line-height:1.2;
  color:var(--ink);font-weight:500}
.wsurface__body{display:grid;grid-template-columns:minmax(15rem,20rem) minmax(0,1fr);
  flex:1;min-height:0}
.wsurface__rail{border-right:var(--bs-border-width) solid var(--line);
  overflow-y:auto;padding:.75rem}
/* Sem trilho, o trabalho toma a largura inteira. Sem esta regra a primeira
   trilha da grade continuaria reservada e sobraria uma coluna vazia de 15rem. */
.wsurface__body:has(> .wsurface__rail[hidden]){grid-template-columns:minmax(0,1fr)}
.wsurface__main{overflow-y:auto;padding:.75rem 1rem;min-width:0}
.wsurface__foot{position:sticky;bottom:0;z-index:2;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  padding:.75rem 1rem;background:var(--surf);
  border-top:var(--bs-border-width) solid var(--line)}
/* O painel de confirmação EMPILHA: texto e previsão em cima, botões embaixo à
   direita. Como linha de rodapé, a previsão de 8 linhas crescia e os botões
   flutuavam no meio da lateral — era a "tela estranha" da foto do usuário. Com
   teto e rolagem própria, um pedido de 24 linhas não empurra a decisão para
   fora da tela. */
#sep-confirmacao{flex-direction:column;align-items:stretch;flex-wrap:nowrap;
  max-height:70vh;overflow:auto}
#sep-confirmacao > .d-flex{justify-content:flex-end}
/* Num tablet em pé o trilho vira uma faixa em cima do trabalho, não some:
   é ele que diz de qual item são as linhas do centro. */
@media (max-width:991.98px){
  .wsurface__body{grid-template-columns:minmax(0,1fr)}
  .wsurface__rail{border-right:0;border-bottom:var(--bs-border-width) solid var(--line);
    max-height:14rem}
}

/* Item selecionável do trilho — a versão em bloco da linha de tabela marcada.
   `aria-current` é quem manda: o estado visual segue o atributo que o leitor de
   tela já anuncia, em vez de uma classe paralela que pode divergir dele. */
.wsurface__item{display:block;width:100%;text-align:left;cursor:pointer;
  padding:.5rem .625rem;border:var(--bs-border-width) solid transparent;
  border-radius:var(--r-sm);background:none;color:inherit;margin-bottom:.25rem}
.wsurface__item:hover{background:var(--surf-2)}
.wsurface__item[aria-current="true"]{background:var(--acc-soft);
  border-color:var(--acc-line)}
/* As medidas dentro do cartão do item: mesmo componente, escala do trilho. A
   coluna tem ~300 px e a ficha padrão (7rem de largura mínima) só deixava duas
   por linha com folga nenhuma. Aqui elas encolhem para caber as três, e a
   margem de baixo sai porque quem separa os cartões é a margem do próprio
   cartão. */
.wsurface__item .measures{margin:0;gap:.25rem}
.wsurface__item .measure{min-width:0;flex:1 1 4.5rem;padding:.25rem .5rem}
.wsurface__item .measure__v{font-size: var(--fonte-corpo)}
.wsurface__item[aria-current="true"] .measure{background:var(--surf)}
.wsurface__item[aria-current="true"] .measure--dest{background:var(--acc-soft)}

/* ── .fillbar — BARRA SEGMENTADA RUMO A UM ALVO (componente) ─────────────────
   Uma barra de progresso responde "quanto por cento". Esta responde "de que
   PARTES o total é feito": um segmento por parcela, cada um com a largura da
   sua contribuição. Na separação, cada segmento é uma bobina — e é assim que se
   enxerga que 20 t são treze bobinas e não um número. Serve igual para meta
   composta por vendedor, carteira por faixa, orçamento por rubrica.

   As larguras (`pct`), o traço do alvo (`alvo_pct`) e quem é excesso chegam
   calculados do backend. A escala é o maior entre alvo e total, então quando a
   seleção passa do alvo o traço cai antes do fim e o excesso aparece hachurado
   em vez de estourar o contêiner.

   Sem transição: galpão, tablet, luva — e por não se mover já respeita
   `prefers-reduced-motion` sem uma media query. */
/* Fina e em pílula, como no desenho aprovado: 20 px de altura davam a uma medida
   auxiliar o peso visual de um gráfico, competindo com o número exato que está
   logo abaixo dela. A barra responde "de quantas partes"; quem responde "quanto"
   é a legenda. */
.fillbar{position:relative;display:flex;height:.625rem;overflow:visible;
  background:var(--surf-3);border-radius:var(--r-full)}
.fillbar__seg{min-width:1px;background:var(--acc);
  border-right:1px solid var(--surf)}
.fillbar__seg:first-child{border-start-start-radius:var(--r-full);
  border-end-start-radius:var(--r-full)}
.fillbar__seg:last-child{border-right:0;
  border-start-end-radius:var(--r-full);border-end-end-radius:var(--r-full)}
.fillbar__seg--over{background:repeating-linear-gradient(45deg,
  var(--ds-atencao) 0 4px,var(--warning-subtle) 4px 8px)}
/* Traço do alvo: onde o pedido termina. Fica por cima dos segmentos e sobra 3 px
   para cada lado — numa barra de 10 px, um traço contido nela desaparece. */
.fillbar__mark{position:absolute;top:-3px;bottom:-3px;width:2px;margin-left:-1px;
  background:var(--ink);pointer-events:none}
.fillbar__mark::after{content:attr(data-rotulo);position:absolute;top:100%;
  left:0;transform:translateX(-50%);white-space:nowrap;
  font-size: var(--bi-fs-micro);color:var(--ink-3)}
/* Legenda da barra: números tabulares e o estado em pílula. A classificação
   (falta/coberto/passa) vem decidida do backend; aqui só se pinta cada uma. */
.fillbar-leg{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;
  font-variant-numeric:tabular-nums}
.fillbar-leg__estado{font-weight:500;padding:.125rem .5rem;border-radius:var(--r-xs)}
.fillbar-leg--falta   .fillbar-leg__estado{background:var(--surf-3);color:var(--ink-2)}
.fillbar-leg--coberto .fillbar-leg__estado{background:var(--positive-subtle);color:var(--positive-text)}
.fillbar-leg--passa   .fillbar-leg__estado{background:var(--warning-subtle);color:var(--warning-text)}

/* ── .stepbar — FAIXA DE PASSOS QUE INSTRUI (componente) ─────────────────────
   Não é um "stepper" decorativo com bolinhas numeradas: o TEXTO de cada passo
   muda com o estado, então a faixa responde "o que eu faço agora, e o que isto
   vai causar no registro" em vez de enumerar etapas. Numa tela que grava de
   forma irreversível num ERP, é ela que carrega a consequência em português
   antes de a pessoa clicar — o número sozinho não avisa nada.

   Serve qualquer fluxo de poucos passos onde a consequência importa mais que a
   contagem (separação, importação, fechamento). Nada aqui sabe o que é um lote.

   `data-ativo` / `data-feito` são atributos, não classes: quem escreve a faixa
   decide o estado num lugar só e o CSS lê exatamente o mesmo dado.

   As divisórias saem de `gap` sobre um fundo da cor da linha, não de
   `border-right` no passo: com `auto-fit` os passos podem quebrar em duas
   fileiras, e a borda lateral deixaria a fileira de baixo sem separador em cima
   (e o último da primeira fileira com uma borda sobrando). */
/* OS PASSOS PESAM IGUAL. O passo zero ("Voltar à fila") é um botão de largura
   própria; 1, 2 e 3 dividem em partes iguais o que sobra, cada um com título e
   frase. O passo ativo se distingue pela cor e pelo numeral, não por roubar
   largura dos vizinhos — uma faixa que muda de geometria a cada marcação faz o
   olho reprocessar a instrução inteira. */
.stepbar{display:flex;flex-wrap:wrap;
  gap:var(--bs-border-width);background:var(--line);
  border-bottom:var(--bs-border-width) solid var(--line)}
.stepbar__passo{display:flex;align-items:center;gap:.625rem;flex:1 1 0;
  min-width:0;padding:.5rem 1rem;background:var(--surf-2)}
.stepbar__voltar{flex:0 1 auto}
.stepbar__num{flex:none;display:flex;align-items:center;justify-content:center;
  width:1.375rem;height:1.375rem;border-radius:var(--r-full);
  background:var(--surf-3);color:var(--ink-3);
  font-size: var(--fonte-corpo);font-weight:500;line-height:1}
/* UMA LINHA POR PASSO. Título em cima e descrição embaixo davam 80px de faixa
   permanente — duas linhas de instrução para três passos, dos quais só um está
   acontecendo. Título e descrição na MESMA linha, e o que não couber na fatia
   do passo é cortado com reticências (o texto inteiro fica no `title`). A faixa
   cai para 40px e os 40 que sobram vão para a lista de lotes, que é onde o
   trabalho acontece. */
.stepbar__txt{min-width:0;}
.stepbar__txt b{font-size: var(--fonte-corpo);font-weight:500;color:var(--ink)}
.stepbar__txt span{font-size: var(--fonte-corpo);color:var(--ink-2);line-height:1.5}
.stepbar__txt span::before{content:" — "}
/* O passo ZERO: mesmo desenho dos outros, mas é botão. `.stepbar__voltar` não
   tem numeral — tem a seta —, e é o único da faixa que reage ao ponteiro. */
.stepbar__voltar{border:0;font:inherit;text-align:left;color:var(--acc);cursor:pointer}
.stepbar__voltar .stepbar__num{background:var(--acc-soft);color:var(--acc)}
.stepbar__voltar .stepbar__txt b{color:var(--acc)}
.stepbar__voltar:hover{background:var(--acc-soft)}
.stepbar__passo[data-ativo="1"]{background:var(--surf)}
.stepbar__passo[data-ativo="1"] .stepbar__num{background:var(--acc);color:#fff}
.stepbar__passo[data-feito="1"] .stepbar__num{background:var(--positive-text);color:#fff}
/* Passo que ainda não chegou: só o título recua de tinta, para o passo ativo
   ser o que salta sem que os outros virem texto ilegível. */
.stepbar__passo[data-ativo="0"][data-feito="0"] .stepbar__txt b{color:var(--ink-3)}

/* ── .pickbox — BLOCO DE ESCOLHA (componente) ────────────────────────────────
   O par "o que eu já escolhi" × "o que ainda há para escolher", cada um num
   bloco com cabeçalho e contagem próprios. Uma lista só, com as marcações
   espalhadas entre 200 linhas, obriga a reler a lista inteira para conferir a
   escolha; partida em dois, a conferência é o bloco de cima e nada mais.

   Nada aqui sabe o que é bobina: serve qualquer seleção dentro de um catálogo
   longo (notas de um lote, títulos de uma remessa, linhas de uma conferência). */
/* O par de blocos lado a lado numa tela larga, empilhado no tablet em pé.
   Empilhados sempre, uma escolha de 34 itens ocupa a tela e a lista de onde se
   escolhe nasce fora da dobra (medido: 700 px de profundidade). Lado a lado, o
   item sai de uma coluna e entra na outra à vista. */
.pickbox-par{display:grid;gap:1rem;grid-template-columns:minmax(0,1fr)}
@media (min-width:1200px){.pickbox-par{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.pickbox{margin-bottom:1rem}
.pickbox__cab{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;
  margin-bottom:.375rem}
.pickbox__cont{font-size: var(--fonte-corpo);color:var(--ink-3);font-variant-numeric:tabular-nums}
/* A dica de ordenação encosta na direita: é ajuda de uso, não título. */
.pickbox__dica{margin-left:auto;font-size: var(--fonte-corpo);color:var(--ink-3)}
/* Vazio INSTRUTIVO — diz o que fazer, não só que está vazio. Tracejado para não
   se confundir com uma tabela de verdade que por acaso não tem linhas. */
.pickbox__vazio{border:var(--bs-border-width) dashed var(--line-3);
  border-radius:var(--r-sm);padding:.875rem;text-align:center;
  font-size:var(--fonte-corpo);color:var(--ink-3)}
/* O bloco dos escolhidos leva o fundo do acento nas linhas: é o que distingue
   "escolhido" de "livre" com a lista rolada. */
.pickbox--escolhidos tbody > tr > td{background:var(--acc-soft)}
/* Cada bloco rola por si, com altura limitada — é o que faz os dois caberem na
   mesma tela. Sem isto, uma escolha de 34 itens empurra a lista do que ainda há
   para escolher a 2.101 px de profundidade (medido), e o trabalho seguinte fica a
   duas telas de distância. O bloco dos escolhidos é mais baixo: ele existe para
   conferir a escolha, não para navegar nela. */
.pickbox__rolo{max-height:22rem;overflow:auto}
/* AS LISTAS ESTICAM ATÉ O RODAPÉ. O teto de 22rem acima é o fallback das telas
   baixas e do empilhado; lado a lado (≥1200px), a altura vem da corrente de
   flex que desce do painel: o que sobrar entre o cabeçalho do produto e o
   rodapé é das listas — era a faixa morta que sobrava embaixo delas. Cada elo
   com `min-height:0`, senão o flex recusa encolher e a rolagem interna morre. */
/* A margem do resultado só existe quando há resultado: o `mt-3` do Bootstrap
   (que é !important) contava 16px de faixa morta mesmo com o nó vazio. */
#sep-resultado:not(:empty){margin:1rem 0}
/* O resultado da data (aviso/erro/sucesso do salvar) nasce num <span> dentro da
   célula da capa: sem virar bloco com respiro próprio, o alert encosta no campo
   e na borda da célula. */
#sep-data-resultado:not(:empty){display:block;margin-top:.375rem}
/* O CÁLCULO NO BACKEND TEM CARA: enquanto a releitura do estoque corre, régua e
   passos apagam meio tom (o número visível é o ANTERIOR) e um girador aparece
   na ponta da régua. Some sozinho quando a resposta chega e tudo é reescrito. */
.sep-aguarda{opacity:.55;transition:opacity .15s}
#sep-medida.sep-aguarda::after{content:"";display:inline-block;
  width:.875rem;height:.875rem;margin-left:.5rem;vertical-align:-.125rem;
  border:2px solid var(--acc);border-right-color:transparent;
  border-radius:var(--r-full);animation:bi-spin .6s linear infinite}
@media (prefers-reduced-motion:reduce){
  #sep-medida.sep-aguarda::after{animation:none;border-right-color:var(--acc-soft)}
}
@media (min-width:1200px){
  .wsurface__main{display:flex;flex-direction:column}
  .wsurface__main #sep-lotes{display:flex;flex-direction:column;flex:1;min-height:0}
  .wsurface__main #sep-lotes-listas{flex:1;min-height:0}
  .wsurface__main .pickbox-par{height:100%;grid-template-rows:minmax(0,1fr)}
  .wsurface__main .pickbox{display:flex;flex-direction:column;min-height:0}
  .wsurface__main .pickbox__rolo{flex:1;min-height:0;max-height:none}
}
/* Cabeçalho que acompanha a rolagem do próprio bloco. Numa lista de 166 itens ele
   é mais que rótulo de coluna: é o único controle de ordenação, e rolar embora o
   tornava inalcançável sem voltar ao topo.
   `border-collapse:separate` é REQUISITO, não estética: com o `collapse` do `.tbl`
   o Chromium simplesmente ignora `sticky` em `th` (medido — o cabeçalho rolou
   junto, a 634 px acima do topo do painel). */
.pickbox .grade-tabela{border-collapse:separate;border-spacing:0}
/* A coluna da CAIXINHA vem primeiro e é a mais estreita possível: é o controle
   de inclusão, e a pessoa varre a lista por ela. A segunda coluna (o código do
   lote) é a identidade do item e absorve toda a folga da tabela — sem isto
   (medido) a coluna do peso ficava com 522 px e o número nadava a 300 px do seu
   próprio cabeçalho. */
.pickbox thead th:first-child,.pickbox tbody td:first-child{width:1%;
  padding-right:0;white-space:nowrap}
.pickbox thead th:nth-child(2),.pickbox tbody td:nth-child(2){width:100%}
/* A caixinha alinhada ao centro da sua célula, sem esticar a linha rasa. */
.pickbox__marca{text-align:center;vertical-align:middle}
.pickbox__marca .form-check-input{margin:0;cursor:pointer}
/* A linha inteira responde à marcação — o fundo já distingue os dois blocos, mas
   dentro do bloco de escolhidas a caixinha marcada é o que confirma "esta entra". */
.pickbox tbody tr:has(.form-check-input:checked){background:var(--acc-soft)}
/* O campo numérico é `display:block` com largura fixa (Bootstrap), e `text-align`
   não move caixa de bloco — `margin-left:auto` é o que o encosta no fim da coluna,
   embaixo do cabeçalho dela. Escopado ao `.pickbox`: o mesmo `.inp-qty` é usado
   dentro de linhas flex noutros lugares, onde `auto` empurraria para o lado errado. */
.pickbox td > .inp-qty{margin-left:auto}
/* Densidade e tom de instrumento, portados do mockup aprovado. Duas diferenças
   deliberadas do `.tbl` padrão do app, e só dentro do `.pickbox`:
   - cabeçalho em caixa NORMAL, sem letter-spacing, miúdo e em tinta fraca. O
     versalete espaçado do padrão grita numa tabela de 200 linhas onde o
     cabeçalho é permanente (é `sticky`) e o que importa são os números.
   - linhas mais rasas. A 32 px por linha caberiam 6 bobinas na área do bloco; a
     26 px cabem 8, e é lista de escolher, não de ler.
   Fora do `.pickbox` o padrão do FCDS segue intacto — nenhuma outra tela muda. */
.pickbox .grade-tabela{font-size:.8125rem}
/* DENSIDADE DA MESA DE SEPARAÇÃO (27/08/2026, pedido do dono: "deixar o
   conteúdo mais compacto"). Feito na folha, não com `zoom` num container: o
   `zoom` é o Ctrl+- de verdade, mas o painel `position:fixed` dos filtros de
   coluna é posicionado por JS com `getBoundingClientRect`, e sob zoom ele abre
   130 px fora do gatilho (medido a 0.9 e a 0.8, em `body`, `main` e no bloco).
   Encolher os valores de projeto não tem esse efeito colateral.

   O ALVO DE TOQUE é o piso da altura da linha, não a fonte: os 44x44 da caixa
   de marcar sozinhos faziam a linha de 53 px. A 36 px a linha cai para 43 e
   cabem 10 lotes na tela em vez de 8 — e 36 continua muito acima do mínimo de
   24 px da WCAG 2.2, que é o que protege quem separa de luva. Abaixo disso
   (32 px, 11 lotes) o ganho é UM lote por tela e o alvo começa a encostar no
   piso: não vale. */
.pickbox .sep-alvo-toque{min-width:36px;min-height:36px}
.pickbox .sep-alvo-toque .form-check-input{width:1.25rem;height:1.25rem}
/* QUEM CEDE LARGURA É O CABEÇALHO, NUNCA O DADO (27/08/2026). Duas medidas
   que só funcionam juntas:
   - Respiro lateral de .375rem, não .625rem: são NOVE colunas, e a folga larga
     custava 180 px de padding puro num bloco de ~570 px — quase um terço da
     largura visível gasto em branco, com o "Levar" atrás do rolo horizontal.
   - Título livre para quebrar em duas linhas. Sem isso o cabeçalho é o PISO da
     coluna mesmo sendo maior que o dado: "Em estoque (KG)" reservava 128 px
     para "3.128 KG", que ocupa 65. A altura cresce uma linha, uma vez, no topo
     do bloco — contra 60 px ganhos em toda linha da tabela.
   Medido ao vivo (pedido 20953): a tabela de disponíveis cai de 830 px para
   668 px. */
.pickbox .grade-tabela tbody td{padding:.1875rem .375rem}
/* O DADO NUNCA QUEBRA. Com o título livre, a coluna pode ficar mais estreita
   que o valor — e "3.128 KG" virou "3.128" / "KG" em duas linhas, dobrando a
   altura de TODA linha para economizar 6 px de largura. Aqui cada célula é um
   átomo curto (código do lote, nome do depósito, um dígito, uma data), e
   nenhum deles se lê partido: o código "COR3075/22H-MO110225-150768 A"
   quebrado desalinha a linha inteira, e truncá-lo é pior que rolar — é ele que
   a pessoa confere contra a etiqueta da bobina. Quando não couber, o bloco
   rola de lado (`.pickbox__rolo` já é `overflow:auto`). */
.pickbox .grade-tabela tbody td{white-space:nowrap}
/* Campo dentro de linha rasa: o `form-control-sm` do Bootstrap ainda tem 31 px de
   altura e esticava a linha da bobina escolhida em 8 px sobre as demais. */
.pickbox .inp-qty{padding-block:.125rem;height:auto}
/* O ENDEREÇO NÃO PAGA CROMO DE FILTRO (27/08/2026). Rua, Posição e Nível
   guardam um caractere cada, mas quem fixava a largura das três colunas era o
   GATILHO do filtro — funil + a palavra "Todos" + a seta, `nowrap`, ~95 px por
   coluna: ~285 px de cabeçalho para três traços, e o "Levar" empurrado para
   trás do rolo horizontal. Sem recorte o gatilho fica só o funil; quem nomeia
   a coluna é o `th` logo acima. Assim que há recorte o valor volta, porque aí
   o texto é o ESTADO da coluna e não enfeite — a mesma régua do `rotulo()` em
   utils.js, que só acende `--ativo` quando o filtro realmente corta.
   Escopado ao bloco de disponíveis: o gatilho do FCDS segue inteiro em toda
   coluna larga do resto do BI, onde o texto cabe e ajuda. */
/* As tabelas de lotes vestem a grade da casa (15/09/2026): cabeçalho em uma
   linha, seta cheia, filtro que diz o estado ("Todas") em vez de um funil mudo,
   e sem caixa em volta. A grade aqui não estica a tela: o bloco rola por dentro. */
.pickbox .grade--lotes{flex:1;min-height:0}
.pickbox .grade--lotes .grade-tabela thead tr:first-child th{padding:.35rem .375rem}
.pickbox .grade--lotes .grade-tabela thead tr.grade-filtros-col th{padding:.2rem .375rem .35rem}
.pickbox .grade--lotes .th-ord{cursor:pointer}
.pickbox .grade--lotes .th-ord sup{margin-left:.15rem}

/* ── .sep-estado — O PEDIDO COMO ESTÁ HOJE, na coluna de contexto ────────────
   A tabela vive numa coluna de ~300 px e é de LEITURA, não de trabalho: nada
   nela pode ser cortado, ou ela deixa de responder à única pergunta que existe
   para fazer ("como está o pedido?"). `table-layout:fixed` + `width:100%` fazem
   as duas colunas dividirem a largura disponível em vez de exigirem a largura do
   conteúdo — medido: sem isto a coluna da quantidade saía da caixa e mostrava
   "1", "28", "250" no lugar de "1.771 KG". */
.sep-estado .tbl{table-layout:fixed;width:100%;font-size: var(--bi-fs-compact)}
.sep-estado .tbl th,.sep-estado .tbl td{padding:.375rem .5rem}
.sep-estado .tbl thead th{text-transform:none;letter-spacing:0;font-size: var(--bi-fs-micro)}
/* O código da bobina é longo e aqui pode quebrar: nesta coluna ele é referência
   de leitura, não o campo que se confere contra a etiqueta (esse está na lista
   de escolha, onde não quebra). */
.sep-estado .tbl td{white-space:normal;overflow-wrap:anywhere}
.sep-estado .badge{margin-top:.125rem}

/* ── .sep-obs — O QUE A CAPA NÃO DIZ E O GALPÃO PRECISA ───────
   A observação do pedido é INSTRUÇÃO de quem vendeu para quem carrega ("ENTREGAR SÓ
   PELA MANHÃ", o cronograma inteiro) e estava em `small` cinza no pé da coluna: sobe
   a corpo de leitura. */
.sep-obs p:last-child{margin-bottom:0}
.sep-obs{font-size:var(--fonte-corpo)}

/* ── .measures — AS MEDIDAS DE UM REGISTRO, EM FICHAS (componente) ───────────
   Os números que decidem o trabalho, um por ficha, com a ficha do ALVO em
   acento. Era uma fita de `<dt>/<dd>` do mesmo tamanho para tudo: pedido,
   separado e saldo pesavam igual, e o saldo — o único número que a pessoa
   precisa cobrir com bobinas — não se destacava de nada.
   `--dest` marca a medida que é o alvo do trabalho, nunca "a mais importante do
   ponto de vista do negócio": quem escolhe é quem monta a tela. */
.measures{display:flex;gap:.5rem;flex-wrap:wrap;margin:0 0 .75rem}
.measure{min-width:7rem;padding:.375rem .75rem;background:var(--surf-2);
  border:var(--bs-border-width) solid var(--line);border-radius:var(--r-sm)}
.measure dt,.measure__k{margin:0;font-size: var(--fonte-pequena);font-weight:500;color:var(--ink-3)}
.measure dd,.measure__v{margin:.0625rem 0 0;font-size:var(--fonte-destaque);font-weight:500;
  color:var(--ink);font-variant-numeric:tabular-nums}
.measure--dest{background:var(--acc-soft);border-color:var(--acc-line)}
.measure--dest dd,.measure--dest .measure__v{color:var(--acc-ink)}
/* `--alerta` é a medida que PEDE ATENÇÃO quando não é zero (pedidos atrasados,
   pedidos bloqueados). Distinta de `--dest`, que é o alvo do trabalho: uma diz
   "é isto que você tem de cobrir", a outra "olhe para isto". */
.measure--alerta{background:var(--warning-subtle);
  border-color:color-mix(in srgb,var(--warning) 34%,transparent)}
.measure--alerta dd,.measure--alerta .measure__v{color:var(--warning-text)}

/* ── .nota — RECADO QUE EXPLICA (componente) ─────────────────────────────────
   O `.alert` do Bootstrap é feito para interromper: fundo saturado, tinta da
   própria cor, peso de anúncio. Isto é para EXPLICAR uma regra de negócio no
   lugar onde ela morde — tinta normal (legível em bloco de 3 linhas), fundo
   discreto, e a cor só na borda e no título. Numa tela que grava sem volta, a
   pessoa tem de LER o recado; um `.alert` amarelo de quatro linhas é o que se
   aprende a pular. */
.nota{padding:.625rem .8125rem;margin-bottom:.875rem;
  border:var(--bs-border-width) solid var(--line);border-radius:var(--r-sm);
  background:var(--surf-2);font-size:var(--fonte-corpo);line-height:1.5;color:var(--ink)}
.nota__t{display:block;font-weight:500;margin-bottom:.125rem}
.nota--info{background:var(--acc-soft);border-color:var(--acc-line)}
.nota--info .nota__t{color:var(--acc-ink)}
.nota--aviso{background:var(--warning-subtle);
  border-color:color-mix(in srgb,var(--warning) 34%,transparent)}
.nota--aviso .nota__t{color:var(--warning-text)}
.nota--risco{background:var(--negative-subtle);
  border-color:color-mix(in srgb,var(--negative) 34%,transparent)}
.nota--risco .nota__t{color:var(--negative-text)}

/* ── .chglist — O QUE VAI MUDAR NO REGISTRO (componente) ─────────────────────
   Uma linha por alteração, tingida pelo tipo dela, e o total antes → depois no
   pé. Substitui duas tabelas lado a lado ("como está" × "como fica"): medido, um
   pedido de 35 rolos gerava 40 linhas de tabela em duas colunas — 700 px de
   conferência antes de a pessoa chegar ao trabalho. A informação é a mesma,
   porque cada linha do depois já vem classificada em nova/alterada/intacta pelo
   backend: a cor diz o que a segunda tabela dizia por comparação. */
.chglist{display:flex;flex-direction:column;gap:.125rem}
.chg{display:grid;grid-template-columns:2.5rem minmax(0,1fr) 5.5rem 7rem;gap:.5rem;
  align-items:baseline;padding:.3125rem .625rem;border-radius:var(--r-sm);
  font-size:var(--fonte-corpo);background:var(--surf-2)}
.chg__seq{font-size: var(--fonte-corpo);color:var(--ink-3);font-variant-numeric:tabular-nums}
.chg__lote{color:var(--ink-2);font-size: var(--fonte-corpo);
}
.chg__kg{font-weight:500;font-variant-numeric:tabular-nums;text-align:right}
/* A data de entrega da linha (#223, pedido multilinha): cada linha tem a sua. */
.chg__data{font-size: var(--fonte-corpo);color:var(--ink-3)}
.chg__et{display:block;font-size: var(--fonte-rotulo);font-weight:500;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.03em}
/* "sem lote" é rótulo de estado, como as etiquetas — mesma caixa alta. */
.chg--nova .chg__lote{text-transform:uppercase;font-size: var(--fonte-corpo)}
.chg--nova{background:var(--positive-subtle)}
.chg--nova .chg__et{color:var(--positive-text)}
.chg--alterada{background:var(--acc-soft)}
.chg--alterada .chg__et{color:var(--acc-ink)}
/* A linha que a separação cancela. Tachada porque cancelar é só de ida: o
   Senior não desfaz, e a quantidade riscada diz isso sem precisar de legenda. */
.chg--cancelada{background:var(--negative-subtle)}
.chg--cancelada .chg__et{color:var(--negative-text)}
.chg--cancelada .chg__lote,.chg--cancelada .chg__kg{text-decoration:line-through}
.chg__tot{display:flex;justify-content:space-between;gap:.625rem;
  margin-top:.625rem;padding-top:.625rem;
  border-top:var(--bs-border-width) solid var(--line);
  font-size:var(--fonte-corpo);color:var(--ink-2)}
.chg__tot strong{color:var(--ink);font-variant-numeric:tabular-nums}
.pickbox thead th{position:sticky;top:0;z-index:1;
  background:var(--surf-2);box-shadow:inset 0 -1px 0 var(--line-3)}

/* ── .th-ord — CABEÇALHO QUE ORDENA A COLUNA (componente) ────────────────────
   Clique troca o critério, invertendo o sentido se já era ele; shift+clique
   acrescenta um segundo critério como desempate, e aí cada seta ganha o número
   da sua prioridade. `aria-sort` é o que o leitor de tela anuncia — e é o mesmo
   atributo que o CSS lê para pintar, então áudio e tela não podem divergir.

   Para tabelas montadas à mão (`.tbl`). Quem usa DataTables já ganha o
   ordenador do plugin e não precisa disto. */
.th-ord{cursor:pointer;user-select:none}
.th-ord:hover{background:var(--surf-2)}
.th-ord[aria-sort]:not([aria-sort="none"]){color:var(--acc-ink)}
.th-ord__seta{margin-left:.25rem;font-size: var(--fonte-corpo);opacity:.45}
.th-ord__seta--on{opacity:1}
.th-ord__seta sup{font-size:var(--fonte-pequena);margin-left:.0625rem}

/* O utilitário `.rail--danger|warning|positive` (filete de cor na borda esquerda
   da linha) FOI REMOVIDO por pedido do usuário. Ele existia para dar à fila de
   pedidos um sinal de urgência legível de longe, mas repetia em cor o que a
   coluna Urgência diz em palavra — e com 119 dos 121 pedidos atrasados a lista
   inteira ficava vermelha: uma marca que vale para todos não distingue ninguém.
   A fila tinha o único consumidor; sem ele o CSS ficaria morto. Se um dia
   alguma tela precisar do padrão, o histórico do git tem a implementação (e o
   porquê de ser `::before` posicionado e não `box-shadow: inset`, que o zebrado
   do Bootstrap 5.2 apagava nas linhas pares). */

/* ── .cell-clip — CÉLULA QUE NÃO DEIXA A TABELA CRESCER (utilitário) ─────────
   Um texto longo numa célula (uma observação de pedido com 300 caracteres)
   empurra as colunas seguintes para fora da tela. Com `text-truncate` do
   Bootstrap junto, a célula mostra o começo e o resto vive no `title`. */
.cell-clip{max-width:22rem}

/* ── .inp-qty — CAMPO NUMÉRICO DENTRO DE CÉLULA (utilitário) ─────────────────
   Quantidade editável numa tabela: estreito, alinhado à direita, tabular, e sem
   as setas do `number` (que roubam 1rem da largura e disparam com a rolagem do
   dedo). O `inputmode` é o que traz o teclado numérico no tablet. */
.inp-qty{width:7.5rem;text-align:right;font-variant-numeric:tabular-nums}
.inp-qty::-webkit-outer-spin-button,
.inp-qty::-webkit-inner-spin-button{appearance:none;margin:0}
.inp-qty[type=number]{appearance:textfield;-moz-appearance:textfield}

/* ── Skip link do shell ──────────────────────────────────────────────────────
   Primeiro focável do documento. Fora do foco fica acima da borda da janela
   (nunca `display:none`, que o tiraria da ordem de tabulação e o mataria);
   ao receber foco de teclado desce para o canto e vira um botão comum.
   Medido antes dele: 86 Tabs até o primeiro elemento do conteúdo. */
.skip{position:fixed;top:-4rem;left:.75rem;z-index:2000;
  padding:.5rem .875rem;border-radius:.5rem;
  background:var(--brand);color:#fff;text-decoration:none;font-weight:500}
.skip:focus-visible{top:.75rem}
/* O contêiner de conteúdo só é focável para receber o salto — sem anel. */
.content:focus{outline:none}

/* ── Separação · a linha do tempo do produto no pedido ───────────────────────
   Só LEITURA. Era uma lista de rádios para escolher em qual parte se trabalha,
   e ela morreu junto com o recorte por linha: o pool de separação é o produto,
   e no pedido 19880 essa lista tinha 24 rádios para escolher um. O que sobra é
   o que ela sempre respondeu bem — "o que tem neste produto": o que falta
   separar, o que já está com lote, o que virou nota, o que foi cancelado.

   Uma coluna só: o painel tem 400px. Viva em tinta cheia, histórico em tinta
   fraca; a quantidade à direita, alinhada, porque é ela que distingue uma parte
   da outra quando duas têm o mesmo estado. */
.sep-item-cab{display:flex;align-items:center;justify-content:space-between;
  gap:.5rem 1rem;flex-wrap:wrap}
.sep-item-cab .min-w-0{min-width:0}
/* Nome, código e entrega na MESMA linha de base; os controles da lista
   (filtro, depósito, histórico) fecham a faixa à direita. */
.sep-item-cab__id{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}
.sep-item-cab__acoes{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  margin-left:auto}
/* A FAIXA DO ITEM CABE EM UMA LINHA. Ela nasceu para ser uma só (título à
   esquerda, controles à direita) e quebrava em duas por 67px: título 512 +
   controles 553 contra 998 de painel. Quebrada, o lado direito do título fica
   vazio de ponta a ponta e a lista de lotes desce 31px — foi o vão marcado na
   captura do dono (13/08/2026). O filtro não precisa de 180px para caber
   "COR3232/26D" e o seletor mostra o nome do depósito com folga em 12rem. */
.sep-item-cab #sep-filtro-lote{max-width:7.25rem}
.sep-item-cab #sep-deposito{max-width:12rem}
.sep-partes{margin-top:.5rem;background:var(--surf-2);border-radius:var(--radius);
  padding:.5rem .625rem}
.sep-partes__cab{font-size: var(--fonte-rotulo);text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-2);font-weight:500;margin:0 0 .25rem}
.sep-partes__lista{list-style:none;margin:0 0 1rem;padding:0;
  display:grid;grid-template-columns:1fr;gap:.125rem}
.sep-parte{display:flex;align-items:baseline;justify-content:space-between;
  gap:.75rem;padding:.0625rem 0;min-width:0}
.sep-parte__txt{font-size: var(--fonte-corpo);min-width:0;
}
.sep-parte__q{font-size: var(--fonte-corpo);color:var(--ink-2);flex:none}
.sep-parte--atual .sep-parte__txt{font-weight:500;color:var(--ink)}
.sep-parte--historico .sep-parte__txt,
.sep-parte--historico .sep-parte__q{color:var(--ink-3)}
/* Separação — entregas do item (#223). Uma linha por entrega (data com os selos
   "Atual"/"Atrasada", aberto, com lote, depois e a caixa "Separar também"), em
   colunas fixas para os números alinharem de uma linha para a outra. A atual
   leva o peso; o "Depois" que muda (cresce, consumida, reduz) leva o azul de
   ação. Sem moldura: é o mesmo fundo de `.sep-partes`. */
.sep-entregas{margin:0 0 .5rem}
.sep-entregas__lista{margin:0}
.sep-entregas__linha{display:grid;grid-template-columns:15rem repeat(3,7rem) minmax(0,1fr);
  align-items:center;column-gap:.75rem;padding:.125rem 0;min-width:0;
  font-size: var(--fonte-corpo);color:var(--ink-2)}
.sep-entregas__linha > span{min-width:0;}
.sep-entregas__linha > .num-tab:not(.sep-entregas__data){text-align:right}
.sep-entregas__linha--titulo{font-size: var(--fonte-rotulo);text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-3);font-weight:500;border-bottom:1px solid var(--line-3)}
.sep-entregas__linha--titulo > span:nth-child(n+2):nth-child(-n+4){text-align:right}
.sep-entregas__linha--atual{color:var(--ink);font-weight:500}
.sep-entregas__data{display:flex;align-items:center;gap:.375rem}
.sep-entregas__depois[data-efeito="cresce"],
.sep-entregas__depois[data-efeito="consumida"],
.sep-entregas__depois[data-efeito="reduz"]{color:var(--acc-ink);font-weight:500}
.sep-entregas__incluir{display:flex;align-items:center;gap:.375rem;padding-left:0;
  justify-self:start;margin-left:1rem;min-height:0;white-space:nowrap;font-weight:400;color:var(--ink)}
.sep-entregas__incluir .form-check-input{margin:0;float:none}
.sep-entregas__vazio{font-size: var(--fonte-corpo);color:var(--ink-3)}
/* Aberta do [Separar] da ordem de um dia (#273): a nota do recorte e a pista da
   entrega mais antiga que sai antes da do dia (a cascata #223 não muda). */
.sep-so-do-dia{margin:0 0 .5rem;font-size: var(--fonte-corpo);color:var(--ink-2)}
.sep-entregas__pista{padding:0 0 .125rem;font-size: var(--fonte-corpo);color:var(--ink-2)}
/* Pedido multilinha (#223): as linhas do pedido sob a entrega delas, nas mesmas
   colunas, recuadas e em tom secundário — a entrega é o cabeçalho do grupo. */
.sep-entregas__sublinha{display:grid;grid-template-columns:15rem repeat(3,7rem) minmax(0,1fr);
  align-items:center;column-gap:.75rem;padding:0;min-width:0;
  font-size: var(--fonte-pequena);color:var(--ink-3)}
.sep-entregas__sublinha > span{min-width:0;}
.sep-entregas__sublinha > span:first-child{padding-left:1rem}
.sep-entregas__sublinha > span:nth-child(2){text-align:right}
/* O código do lote passa de 7rem (COR3232-26H-260240610-5): ocupa "Com lote" e
   "Depois", alinhado à esquerda, para aparecer inteiro. */
.sep-entregas__lote{grid-column:3 / span 2}
/* A célula "Levar" da bobina: campo + botão "Fracionar" lado a lado. O campo
   tem largura própria porque dentro do flex o form-control (width:100%)
   colapsava a uma lasca quando o botão entrou ao lado. */
.sep-levar-par{display:flex;align-items:center;justify-content:flex-end;gap:.25rem}
.sep-levar-par .sep-levar{width:6.5rem;flex:0 0 auto}
/* O botão guarda a própria largura: enquanto a consulta corre o rótulo
   "Fracionar" dá lugar ao girador, e sem piso a célula encolheria e a tabela
   inteira pularia embaixo do cursor no meio do gesto. */
.sep-fracionar{min-width:5.5rem}
.sep-hist__t{font-size: var(--fonte-rotulo);text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-2);font-weight:500;margin:0 0 .25rem}
/* A linha do tempo do pedido: data | evento | quantidade, um evento por linha,
   em ordem cronológica. O fio à esquerda liga os eventos — é o que diz "isto é
   uma sequência" sem escrever a palavra. O "hoje" fecha em acento. */
.sep-tempo{list-style:none;margin:0 0 1.25rem;padding:0}
.sep-tempo__ev{display:flex;align-items:baseline;gap:.625rem;
  padding:.375rem 0 .375rem .875rem;position:relative;
  border-left:2px solid var(--line)}
.sep-tempo__ev::before{content:"";position:absolute;left:-5px;top:.8em;
  width:8px;height:8px;border-radius:var(--r-full);
  background:var(--surf);border:2px solid var(--ink-3)}
.sep-tempo__ev[data-tipo="nota"]::before{background:var(--positive-text);
  border-color:var(--positive-text)}
.sep-tempo__ev[data-tipo="hoje"]{border-left-color:transparent}
.sep-tempo__ev[data-tipo="hoje"]::before{background:var(--acc);border-color:var(--acc)}
.sep-tempo__data{flex:none;width:5.25rem;font-size: var(--fonte-corpo);color:var(--ink-3)}
.sep-tempo__meio{min-width:0;flex:1 1 auto;display:flex;flex-direction:column}
.sep-tempo__t{font-size: var(--fonte-corpo);font-weight:500;color:var(--ink)}
.sep-tempo__ev[data-tipo="hoje"] .sep-tempo__t{color:var(--acc)}
.sep-tempo__d{font-size: var(--fonte-corpo);color:var(--ink-2)}
.sep-tempo__q{flex:none;font-size: var(--fonte-corpo);font-weight:500;color:var(--ink)}

/* Separação · a observação do pedido na capa, em balão.
   Ela é INSTRUÇÃO de quem vendeu para quem carrega ("ENTREGAR SÓ PELA MANHÃ",
   "PEDIDO REFERENTE A NF QUE FOI ESTORNADA"). Em fita de dt/dd lia como mais um
   campo; o balão devolve o destaque que ela tinha. */
/* UM PARÁGRAFO NÃO É UM CAMPO. Em `flex:1 1 22rem;max-width:34rem` ela entrava
   na fita como mais um item — 544px de largura por 189 de altura — e esticava a
   LINHA INTEIRA para 266px, deixando um vão embaixo de todos os pares curtos: a
   capa ia a 364px, 43% da superfície, para um cabeçalho. Com `flex-basis:100%`
   ela cai na própria linha, ocupa a largura toda e o mesmo texto cabe em duas
   linhas em vez de cinco. */
/* A observação ocupa a SOBRA da fita, não uma fileira própria. Ela nasceu com
   `max-width:34rem`: 544px num vão de 1.478, o que a empurrava para cinco linhas
   e esticava a fita inteira para 266px. Depois foi para `flex-basis:100%` — uma
   fileira só dela, três linhas, com o lado direito da fita de campos vazio. Sem
   teto de largura ela fica NA MESMA fileira dos campos, consome o espaço que
   sobrava à direita deles e a capa cabe na altura de um bloco só.
   `flex-start` no alinhamento porque a fita alinha por `baseline`, e um bloco de
   várias linhas ao lado de pares de uma linha empurrava todos para baixo.
   Entrelinha de leitura, não de aviso curto: o `line-height:1.6` de `.nota` é
   feito para UMA frase. Vai nesta regra, não na `.sep-obs` solta — aquela vem
   ANTES de `.nota` no arquivo e, com a mesma especificidade, perdia calada. */
/* A advertência ocupa a faixa que sobrava à DIREITA DO CLIENTE, na primeira
   linha da capa; a fita de campos desce para a segunda, inteira. Medido no
   20318 a 1713px: com o balão dentro da fita, a fita ficava larga demais para
   caber ao lado do nome, descia junto e a primeira linha ia vazia de ponta a
   ponta — capa de 211px. Com o balão como irmão, capa de 164px.
   Entrelinha de leitura, não de aviso curto: o `line-height:1.6` de `.nota` é
   feito para UMA frase. Vai nesta regra, não na `.sep-obs` solta — aquela vem
   ANTES de `.nota` no arquivo e, com a mesma especificidade, perdia calada. */
/* A ADVERTÊNCIA MANDA NA ALTURA. Ela leva 2/5 da largura e o texto dela decide
   quantas linhas a capa tem; os campos se acomodam nos 3/5 restantes, em
   quantas fileiras couberem. Tentei antes fazê-la absorver a sobra de uma
   fileira (`grid-column:auto/-1`, depois `span 8`): com um lado auto a grade dá
   span 1 e o balão virava uma coluna magra de 40 linhas na ponta (capa de
   712px); com span fixo, a capa oscilava entre 205 e 270px conforme a janela,
   porque o span não sabe quantas colunas sobraram. */
/* O teto da advertência mora no ITEM, não na trilha: `fit-content()` na trilha
   colapsou a coluna para 66px e quebrou o recado em uma palavra por linha
   (medido). Com trilha `auto` a coluna mede o texto, e este teto impede que um
   recado longo coma a capa inteira. */
/* O teto mora na TRILHA (`fit-content(42%)` em `.wsurface__cap`), não aqui:
   ver o comentário lá. */
.wsurface__cap-obs{min-width:0}
.wsurface__cap-obs:empty{display:none}
/* A ADVERTÊNCIA ROLA DENTRO DA ALTURA QUE A CAPA TEM. Quem manda na altura são
   as duas fileiras de campos; o parágrafo se encaixa nelas e o excedente vem
   pelo arrastar. `position:absolute` é o que tira a altura dele da conta da
   grade — com `max-height` em rem o número seria chute, e sobraria faixa vazia
   quando o texto fosse curto ou corte quando a capa fosse alta. O piso existe
   para o balão não virar uma tarja de duas linhas num pedido de poucos campos. */
/* NA MESMA ALTURA DA CAPA: quem manda são os campos — o balão acompanha a
   fileira deles, nem um pixel a mais, e o texto excedente rola por dentro. O
   piso de 5.5rem que existia aqui era o que deixava o balão MAIS ALTO que os
   fatos ao lado, com a borda dele caindo abaixo da última fileira. */
/* O BALÃO VOLTOU PARA O FLUXO. Absoluto ele não tinha tamanho nenhum para a
   grade, então a coluna dele só podia ser uma FATIA FIXA da capa (metade) —
   era isso que pintava 654px de amarelo para 426px de frase, e espremia as
   fichas na metade restante. Em fluxo ele mede o texto (trilha `max-content`,
   teto de 30rem), e o teto de altura evita o efeito que o absoluto resolvia:
   um recado de dez linhas esticando a capa. */
/* 5.5rem cortava a terceira linha ao meio numa capa de duas fileiras (1400px):
   o recado é INSTRUÇÃO de quem vendeu, e um corte no meio da frase esconde
   justamente o final ("…não é permitida a entrada de pessoas com bermuda"). 8rem
   dão quatro linhas inteiras; recado maior que isso rola por dentro. */
.wsurface__cap-obs .sep-obs{max-height:8rem;overflow:auto}
.wsurface__cap-obs:empty{display:none}
.wsurface__cap-obs .sep-obs{margin:0;line-height:1.5}
.wsurface__cap-campos .sep-obs p{margin-bottom:.125rem}
.wsurface__cap-campo.sep-entrega dd{display:flex;align-items:center;gap:.25rem .375rem;flex-wrap:wrap}
/* A data cabe numa célula da capa, com o botão ao lado (form-control-sm e btn-sm de fábrica). */
.wsurface__cap .sep-entrega__data{width:8rem;max-width:100%;min-width:0}

/* ═══════════════════════════════════════════════════════════════════════════
   DISTRIBUIÇÃO DO FATURAMENTO  (/distribuicao-faturamento/)
   Barra empilhada por cliente + matriz cliente × mês.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Altura fixa e generosa: é ela que compra faixa visível para os clientes do
   meio do ranking. Medido — com 20 nomeados numa área de ~430px a menor faixa
   fica em 1,79px; abaixo disso deixa de ser clicável. */

/* A legenda é o que transforma "um tom de azul" em "o cliente X": com 20 blocos
   a rampa de um tom só não distingue vizinhos, e a identidade passa a vir daqui,
   do hover e do clique. Grid de colunas fluidas para caber 20 nomes sem virar
   parede de texto. */
.df-legenda{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));
  gap:2px 14px; margin-top:.75rem; padding-top:.75rem;
  border-top:1px solid var(--line); max-height:190px; overflow-y:auto;
}
.df-legenda__item{
  display:flex; align-items:center; gap:.45rem; width:100%; text-align:left;
  font-size: var(--fonte-corpo); color:var(--ink-2); background:none; border:0;
  padding:.2rem .25rem; border-radius:var(--r-sm); cursor:pointer;
}
.df-legenda__item:hover:not(:disabled){ background:var(--surf-2); color:var(--ink); }
.df-legenda__item:disabled{ cursor:default; }
.df-legenda__item:focus-visible{ outline:2px solid var(--chart-azul); outline-offset:1px; }
.df-legenda__item[aria-pressed="true"]{
  background:color-mix(in srgb, var(--chart-azul) 12%, var(--surf));
  color:var(--ink); font-weight:500;
}
.df-legenda__cor{ flex:none; width:13px; height:11px; border-radius:2px; }
.df-legenda__cor--outros{
  background:color-mix(in srgb, var(--chart-azul) 11%, var(--surf));
  border:1px solid color-mix(in srgb, var(--chart-azul) 28%, var(--surf));
}
.df-legenda__pct{ flex:none; margin-left:auto; color:var(--ink-3); font-variant-numeric:tabular-nums; }

/* Drill-down do mês: a pizza e sua legenda, e nada mais. O ranking completo já
   está na matriz da página; repeti-lo aqui era a mesma tabela duas vezes. */
.df-drill{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.15fr); gap:22px;
  align-items:center; }
@media (max-width:720px){ .df-drill{ grid-template-columns:minmax(0,1fr); } }
.df-drill__pizza{ position:relative; height:300px; }
.df-drill__legenda{ list-style:none; margin:0; padding:0; display:grid; gap:1px; }
.df-drill__legenda li{ display:grid; grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:center; gap:.5rem; padding:.3rem .35rem; border-radius:var(--r-sm);
  font-size: var(--fonte-corpo); }
.df-drill__legenda li:nth-child(odd){ background:var(--surf-2); }
.df-drill__cor{ width:11px; height:11px; border-radius:2px; flex:none; }
.df-drill__nome{ color:var(--ink-2); }
/* Valor e % nunca quebram: "R$ 1,858M" partido no meio deixa de ser número. */
.df-drill__valor{ white-space:nowrap; font-weight:500; }
.df-drill__pct{ white-space:nowrap; color:var(--ink-3); min-width:3.2rem; text-align:right; }

/* Mês clicável: o cabeçalho é a porta do drill, e precisa parecer uma. */
.df-mes{ cursor:pointer; }
.df-mes:hover{ color:var(--chart-azul); text-decoration:underline; }
.df-mes:focus-visible{ outline:2px solid var(--chart-azul); outline-offset:-2px; }

/* Cabeçalho de família marcável (colfilterMulti `grupoMarcavel`): pesa mais que o
   item e recua os filhos, para a hierarquia família ▸ produto ser lida de relance. */
.colfilter-multi__grupo{ font-weight:600; text-transform:uppercase; font-size: var(--bi-fs-micro);
  letter-spacing:.04em; margin-top:.35rem; }
.colfilter-multi__filho{ padding-left:1.5rem; }

/* Coluna de identificação congelada enquanto os meses rolam na horizontal.
   Sem isso, rolar até dez/26 deixa a linha órfã: números sem dono. */
.tbl-scroll--freeze-col .tbl-freeze{
  position:sticky; left:0; z-index:3; background:var(--surf);
  border-right:1px solid var(--line);
  min-width:230px; max-width:230px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.tbl-scroll--freeze-col thead .tbl-freeze,
.tbl-scroll--freeze-col tfoot .tbl-freeze{ z-index:4; background:var(--surf-2); }
.tbl-scroll--freeze-col tbody tr:hover .tbl-freeze{ background:var(--surf-2); }
.tbl-scroll--freeze-col tbody tr.table-active .tbl-freeze{ font-weight:600; }
.tbl-scroll--freeze-col tfoot td{ position:sticky; bottom:0; background:var(--surf-2); }
.tbl-scroll--freeze-col tbody tr{ cursor:pointer; }
.tbl-scroll--freeze-col tbody tr:focus-visible{ outline:2px solid var(--chart-azul); outline-offset:-2px; }

/* ============================================================
   CRM — DOCUMENTO DA PROPOSTA (impressão / PDF WeasyPrint)
   Réplica do layout da proposta comercial do Ploomes (gabarito:
   proposta 16.900-0, docs/planos/crm.md). Renderizado por
   bi/templates/bi/crm_proposta_pdf.html; mesmo HTML no preview
   e no PDF (weasyprint.CSS deste arquivo). Prefixo .prop-.
   ============================================================ */
@page {
  size: A4;
  margin: 30mm 12mm 40mm 12mm;
  @top-left { content: element(prop-cab); }
  @bottom-center { content: element(prop-rodape); }
}
.prop-doc{ font-family:'DejaVu Sans', Arial, sans-serif; font-size:8.5pt;
  color:#212529; line-height:1.32; }
.prop-cab{ position:running(prop-cab); display:flex;
  justify-content:space-between; align-items:flex-end; width:186mm; }
/* A logo do documento original ocupa quase um terço da faixa; 40mm a
   deixavam do tamanho de um selo. A arte tem 4626px de largura, então
   ampliar não perde nitidez. */
.prop-logo-img{ width:58mm; }
.prop-emp{ font-size:8pt; text-align:right; line-height:1.5; }
.prop-emp b{ font-size:8.5pt; }
.prop-faixa{ display:flex; justify-content:space-between; background:#4a4a4c;
  color:#fff; font-weight:700; font-size:9.5pt; padding:1.5mm 3mm; margin-bottom:2mm; }
/* Explicação do painel de condições quando ele abre sozinho. Fundo do acento
   em vez de cinza: cinza é a cor de quem não quer ser lido, e esta frase
   existe justamente para ser lida. */
[data-pagina="crm-deal"] .crm-aviso-suave{
  background: var(--crm-acento-fundo); border: 1px solid #d3e2d9;
  border-radius: 8px; padding: .7rem .9rem; margin: 0 0 1rem;
  font-size: var(--fonte-corpo); color: var(--crm-tinta-2); line-height: 1.5; }

/* ---------------------------------------------------------------------------
   Vocabulário do CRM que o Bootstrap não cobre. Existe porque estilo inline
   NÃO se usa aqui (regra do dono) e porque inline vence a folha: a regra que
   eu escrevi para o bloco de embalagem no telefone foi ignorada por um
   `justify-content` inline que estava no elemento. O que o Bootstrap cobre
   exatamente (mt-1, d-block, ms-auto, align-items-end…) usa o Bootstrap; o
   que não cobre está aqui, com nome.
   --------------------------------------------------------------------------- */
/* Larguras de campo dos formulários de cadastro. São medidas do CONTEÚDO
   (UF tem 2 letras, CEP tem 8 dígitos), por isso nome do campo e não número. */
[data-pagina^="crm"] .crm-campo-uf { flex: 0 0 4rem; }
[data-pagina^="crm"] .crm-campo-numero { flex: 0 0 5rem; }
[data-pagina^="crm"] .crm-campo-cep { flex: 0 0 7.5rem; }
[data-pagina^="crm"] .crm-campo-9 { flex: 0 1 9rem; }
[data-pagina^="crm"] .crm-campo-10 { flex: 0 0 10rem; }
[data-pagina^="crm"] .crm-campo-11 { flex: 0 1 11rem; }
/* Lupa escondida (cliente pessoa física, que não tem consulta pública) deixa
   o campo como último da linha — e o Bootstrap só arredonda a ponta direita do
   que é `:last-child`. Com `display:none` o botão continua sendo o último
   filho, então o canto ficava quadrado, encostado em nada. */
[data-pagina^="crm"] .input-group > .form-control:has(+ .crm-oculto) {
  border-top-right-radius: var(--bs-border-radius);
  border-bottom-right-radius: var(--bs-border-radius); }
[data-pagina^="crm"] .crm-campo-12 { flex: 0 1 12rem; }
[data-pagina^="crm"] .crm-campo-13 { flex: 0 1 13rem; }
[data-pagina^="crm"] .crm-largura-10 { max-width: 10rem; }
[data-pagina^="crm"] .crm-largura-16 { max-width: 16rem; }
[data-pagina^="crm"] .crm-largura-20 { max-width: 20rem; }
/* Pílula que é botão (o chip da embalagem reabre o bloco): mesma aparência de
   pílula, comportamento de botão. */
.crm-pilula-botao { border: 0; cursor: pointer; }
/* Lista de escolhas de um campo que aceita VÁRIAS (os trianguladores padrão do
   cadastro, 01/09/2026). Cada escolha é uma `.crm-pilula` com um ✕ dentro — o
   ✕ é o botão, a pílula não. */
[data-pagina^="crm"] .crm-fichas { display: flex; flex-wrap: wrap; gap: .35rem; }
/* O ✕ é o botão; a pílula não. Tamanho MÍNIMO real, não área invisível: a
   primeira tentativa estendia o alvo com um `::after` de 44px, e ele avançava
   sobre a ficha vizinha — clicar no começo da segunda podia tirar a primeira.
   Alvo fantasma que cobre o vizinho é pior que alvo pequeno. */
[data-pagina^="crm"] .crm-ficha-tirar { display: inline-flex; align-items: center;
  justify-content: center; min-width: 1.5rem; min-height: 1.5rem; border: 0;
  background: transparent; color: inherit; cursor: pointer; padding: 0;
  margin-left: .1rem; line-height: 1; opacity: .65; }
/* No TOQUE o alvo vai a 44px e a ficha cresce junto — é o certo: dedo não
   acerta 12px, e uma pílula mais alta no telefone não atrapalha nada. */
@media (pointer: coarse) {
  [data-pagina^="crm"] .crm-ficha-tirar { min-width: 2.75rem; min-height: 2.75rem; }
}
[data-pagina^="crm"] .crm-ficha-tirar:hover,
[data-pagina^="crm"] .crm-ficha-tirar:focus-visible { opacity: 1; }
/* Foco visível: o ✕ é operável por teclado e sem isto o anel do navegador
   sumia atrás da pílula. */
[data-pagina^="crm"] .crm-ficha-tirar:focus-visible { outline: 2px solid var(--acc-line);
  outline-offset: 2px; border-radius: 2px; }
/* Total do rodapé — o número que se lê de longe. */
[data-pagina="crm-deal"] .crm-numero-grande { font-size: var(--fonte-titulo); font-weight: 500; }
[data-pagina^="crm"] .crm-separador { margin: 1.5rem 0 1rem; }
[data-pagina^="crm"] .crm-recuo { margin: .25rem 0 0 1rem; }
[data-pagina^="crm"] .crm-linha-lista { padding: .5rem 0;
  border-top: 1px solid var(--crm-borda); }
.min-w-0 { min-width: 0; }
/* Largura dos painéis laterais, por peso do conteúdo. */
.crm-oc--estreita { --bs-offcanvas-width: 22rem; }
.crm-oc--media { --bs-offcanvas-width: 26rem; }
.crm-oc--larga { --bs-offcanvas-width: 30rem; }
/* O painel de cadastro usa o MESMO canvas da ficha (`#crm-modal-ficha`,
   abaixo): é o mesmo formulário de 34 campos, e em 30rem ele não cabe em
   disposição nenhuma — medido em 09/09/2026, 2.111px de conteúdo para 654 de
   dobra. `crm-oc--larga` continua no elemento para as telas que ainda o
   herdam; esta regra, mais específica, é quem manda. */
#crm-modal-novo { --bs-offcanvas-width: min(88rem, 96vw); }
/* Campo obrigatório. O asterisco é do RÓTULO, não do campo: quem lê a tela
   procura na etiqueta, e leitor de tela anuncia o `aria-required` do input
   sem tropeçar num caractere solto. A régua é a do SERVIDOR — só recebe
   estrela o que ele de fato recusa vazio. */
/* `campo-obrigatorio` é o nome de TODO o app (compras e BI usam o mesmo); o
   `crm-obrigatorio` continua valendo por já estar espalhado no CRM. */
.crm-obrigatorio::after,
.campo-obrigatorio::after { content: " *"; color: var(--crm-erro, #b3261e);
  font-weight: 500; }
/* Obrigatório do ERP: acende só quando o cadastro vai ao Senior (a classe do
   container é do JS, que lê `cliente.prospect` do servidor). No lead o servidor
   não recusa esses campos — asterisco ali seria estrela mentirosa. */
.crm-form-cliente--erp .crm-obrigatorio-erp::after {
  content: " *"; color: var(--crm-erro, #b3261e); font-weight: 500; }

/* Revisar mostra o documento inteiro: largura de papel, não de formulário. */
.crm-oc--documento { --bs-offcanvas-width: min(52rem, 96vw); }
[data-pagina="crm-deal"] .crm-oc-documento { padding: 0; display: flex; }
[data-pagina="crm-deal"] .crm-documento-previa { flex: 1; width: 100%;
  border: 0; background: #e9ecef; }
/* Espera do documento: ocupa o lugar do papel enquanto ele é gerado. Fundo
   igual ao do quadro para a troca não piscar de cor. */
[data-pagina="crm-deal"] .crm-documento-espera { flex: 1; display: flex;
  flex-direction: column; align-items: center; justify-content: center;
  gap: .75rem; background: #e9ecef; color: var(--crm-tinta-2, #6c757d);
  font-size: var(--fonte-corpo); }
[data-pagina="crm-deal"] .crm-documento-espera.crm-oculto { display: none; }

/* Roteiro da proposta: os passos, acionáveis. Diferente do trilho de etapas
   (indicador, não se clica), aqui cada passo LEVA ao lugar onde se resolve o
   que falta. O que está pronto fica discreto; o passo da vez é o único com
   peso — a tela responde "e agora?" sem ninguém perguntar.

   O respiro é do PRÓPRIO bloco (padding), não margem, e só EM CIMA: embaixo
   quem separa é o padding do corpo, que já vale 1,25rem. Somar os dois dava
   1px acima contra 36px abaixo — o roteiro nascia colado no trilho de etapas
   e solto do trabalho. */
[data-pagina="crm-deal"] .crm-roteiro{ display: flex; flex-wrap: wrap;
  gap: .4rem; margin: 0; padding-block: 1.25rem 0; flex: 0 0 auto; }
[data-pagina="crm-deal"] .crm-roteiro__passo{ display: flex; align-items: center;
  gap: .5rem; flex: 1 1 12rem; text-align: left; cursor: pointer;
  background: var(--crm-superficie); border: 1px solid var(--crm-borda);
  border-radius: 8px; padding: .5rem .7rem; color: var(--crm-tinta-2);
  font-size: var(--fonte-corpo); transition: border-color .15s ease, background .15s ease; }
[data-pagina="crm-deal"] .crm-roteiro__passo:hover{ border-color: var(--crm-acento); }
[data-pagina="crm-deal"] .crm-roteiro__n{ display: inline-flex;
  align-items: center; justify-content: center; flex: 0 0 1.4rem; height: 1.4rem;
  border-radius: 50%; background: #eaeeec; color: var(--crm-tinta-2);
  font-size: var(--fonte-pequena); font-weight: 500; }
[data-pagina="crm-deal"] .crm-roteiro__rot{ display: block; font-weight: 500;
  color: var(--crm-tinta); }
[data-pagina="crm-deal"] .crm-roteiro__falta{ display: block; font-size: var(--fonte-pequena);
  color: var(--crm-tinta-2); }
[data-pagina="crm-deal"] .crm-roteiro__passo--ok .crm-roteiro__n{
  background: var(--crm-acento); color: #fff; }
[data-pagina="crm-deal"] .crm-roteiro__passo--agora{
  border-color: var(--crm-acento); background: var(--crm-acento-fundo); }
[data-pagina="crm-deal"] .crm-roteiro__passo--agora .crm-roteiro__n{
  background: var(--crm-acento); color: #fff; }

/* Título do negócio: a primeira coisa depois da faixa preta, centralizado.
   É a linha que diz de QUE cotação se trata, e o cliente costuma ter mais de
   uma na mesa. Um ponto acima do corpo — chama sem gritar. */
.prop-obra{ font-size:9.5pt; font-weight:700; text-align:center;
  margin:0 0 2.5mm; }
.prop-vend{ font-size:8pt; margin-bottom:2.5mm; line-height:1.55; }
/* Quatro linhas empilhadas, como no documento real — em fita elas viravam
   uma linha só e o nome do empreendimento colava no telefone. */
.prop-vend > div{ display:block; }
.prop-tabela{ width:100%; border-collapse:collapse; font-size:8.5pt;
  /* fixed: sem isto as larguras abaixo são só sugestão e o navegador dá à
     coluna Produto o que sobra dos cabeçalhos longos ("Disponibilidade"),
     quebrando a descrição em três linhas. */
  table-layout:fixed; }
.prop-tabela th{ background:#e3e3e5; text-align:center; font-size:7.2pt;
  /* Respiro lateral curto: sao ate nove colunas em 186mm, e cada milimetro
     aqui decide se "Conteudo" cabe numa linha ou parte no meio. */
  font-weight:700; padding:2mm .8mm; border:.5pt solid #b9b9be;
  /* Cabeçalho de PALAVRA ÚNICA numa coluna estreita não quebra sozinho: ele
     transborda por cima da coluna vizinha, e foi assim que "Embalagem" saiu
     colado em "Conteúdo" na proposta da Sandra. Com isto ele parte. */
  /* `break-word` e NAO `anywhere`: o segundo parte dentro da palavra mesmo
     quando ela caberia inteira na linha seguinte, e escrevia "Valor por
     bobi-na". Este so parte quando a palavra sozinha nao cabe. */
  overflow-wrap:break-word; }
/* Larguras por CLASSE (não por nth-child: a coluna de previsão é condicional
   e os índices dançariam). Sem elas o código rouba espaço da descrição e
   "FOUR CORDOALHA CP 190 RB 9,5MM" quebra em duas linhas.
   São 186mm úteis (A4 menos 12mm de margem de cada lado); o que sobra depois
   destas nove vai para Produto, a única que precisa crescer. Cada número aqui
   foi medido contra um valor real, não estimado — em 24mm "R$ 125.000,00"
   quebrava entre o "R$" e o valor, e em 18mm a palavra "Quantidade" partia no
   meio ("Quantidad / e").
   Os dois totais (sem e com IPI) cabem porque o "R$" saiu das células e foi
   para o cabeçalho: cada coluna de dinheiro devolveu ~5mm, e são quatro.
   Sem o "R$" o valor virou uma palavra SEM ESPAÇO onde quebrar: em 18mm
   "2.600.646,40" (proposta da AGIS, 31/08/2026) não quebrava — transbordava
   4,5mm por cima da coluna vizinha, e o papel saía com os três valores
   embolados. Medido com o próprio WeasyPrint (DejaVu Sans 8,5pt): esse valor
   ocupa 20,0mm de texto, então a coluna de dinheiro precisa de 23mm (texto +
   2,4mm de respiro + a borda). Os 15mm vieram da descrição do produto (39mm
   → 26mm, autorizado pelo dono) e de código/conteúdo, que sobravam. Isso
   cobre até "9.999.999,99"; acima disso o valor volta a transbordar.
   CUIDADO ao editar este bloco: a barra em "s/ IPI" fechava o comentário no
   meio da frase, e o resto virava seletor — a regra `.c-item` logo abaixo era
   engolida pelo parser, a coluna `#` ficava sem largura e, com
   `table-layout:fixed`, herdava o espaço que era para ser da descrição do
   produto. Escreva "sem IPI" por extenso. */
.prop-tabela .c-item{ width:7mm; }
.prop-tabela .c-cod{ width:19mm; }
.prop-tabela .c-disp{ width:19mm; }
.prop-tabela .c-emb{ width:16mm; }
.prop-tabela .c-cont{ width:16mm; }
.prop-tabela .c-qtd{ width:19mm; }
.prop-tabela .c-preco{ width:14mm; }
.prop-tabela .c-vol{ width:23mm; }
/* O cento é dinheiro CURTO — "8,66" na caixa de 3.000, "259,71" na cotação
   cheia —, nunca o total de uma proposta. Por isso ele não herda os 23mm da
   coluna de volume: 16mm comportam "9.999,99" a 8,5pt e devolvem 7mm para a
   descrição do produto, que é a única coluna que cresce. */
.prop-tabela .c-cento{ width:16mm; }
.prop-tabela .c-total{ width:23mm; }
/* Alíquota do item (#587): "13,00" no máximo; os milímetros saem da
   descrição do produto, a única coluna que cresce. */
.prop-tabela .c-ipi{ width:11mm; }
/* Com a coluna de previsão são ONZE colunas em 186mm, e aí não existe
   milímetro para tirar de vizinho: apertar a de dinheiro quebra o valor,
   apertar a do produto empilha a descrição em oito linhas. A tabela inteira
   encolhe um ponto — o papel continua legível e todas as colunas respiram de
   novo. Antes eu trocava uma quebra por outra a cada ajuste. */
.prop-tabela--densa{ font-size:7.8pt; }
.prop-tabela--densa th{ font-size:6.6pt; padding:1.6mm .6mm; }
.prop-tabela--densa td{ padding:1.2mm 1.4mm; }
/* Medido no papel, não estimado: em 14mm o código de 8 dígitos partia em duas
   linhas ("300300 / 02") e em 12mm o cabeçalho "Volumes" virava "Volume / s".
   O que sobra depois destas dez vai para Produto, a única que cresce.
   Aqui o dinheiro precisa de 22mm (a 7,8pt "2.600.646,40" mede 18,4mm), e com
   onze colunas o milímetro sai de onde existe folga: previsão (texto livre,
   que já quebrava a data) e produto. */
.prop-tabela--densa .c-item{ width:6mm; }
.prop-tabela--densa .c-cod{ width:18mm; }
.prop-tabela--densa .c-disp{ width:14mm; }
.prop-tabela--densa .c-emb{ width:15mm; }
.prop-tabela--densa .c-cont{ width:15mm; }
.prop-tabela--densa .c-qtd{ width:17mm; }
.prop-tabela--densa .c-preco{ width:13mm; }
.prop-tabela--densa .c-vol{ width:22mm; }
.prop-tabela--densa .c-cento{ width:15mm; }
.prop-tabela--densa .c-total{ width:22mm; }
.prop-tabela--densa .c-ipi{ width:10mm; }
/* Preco de 4 casas (so acontece com frete diluido, onde o preco e o resultado
   de uma divisao e nao o que alguem digitou). Medido com a regua deste bloco
   em 02/09/2026: "1.297,0931" ocupa 17,2mm a 8,5pt e a celula precisa de
   20,0mm com o respiro e a borda; a 7,8pt sao 15,8mm e 18,6mm. Cobre ate
   "9.999,9999", que mede o mesmo (o separador de milhar entra e um digito
   sai).
   De onde vem: 3mm do valor por volume, a UNICA coluna com folga medida
   (23mm para "999.999,99", que pede 20,0mm), e 3mm da descricao do produto
   (26->23mm). Nenhuma outra tem de onde tirar — codigo, quantidade e os
   totais estao todos com menos de 1mm de sobra, e conteudo ja estoura.
   Por isso a classe e CONDICIONAL e nao a largura padrao: 2.9% dos precos da
   casa passam de duas casas, e apertar a descricao do produto — o que o
   cliente confere — nas outras 97% pagaria por um problema que elas nao tem.
   Quem decide e o servico (`tem_preco_longo`), nao o template. */
.prop-tabela--preco-longo .c-preco{ width:20mm; }
.prop-tabela--preco-longo .c-vol{ width:20mm; }
.prop-tabela--preco-longo.prop-tabela--densa .c-preco{ width:19mm; }
.prop-tabela--preco-longo.prop-tabela--densa .c-vol{ width:19mm; }
/* Célula de número e de código respiram menos nas laterais que a de texto —
   é onde cada milímetro decide se o valor cabe numa linha só. */
.prop-tabela td.num, .prop-tabela td.ctr{
  padding-left:1.2mm; padding-right:1.2mm; }
/* Quebra SÓ na disponibilidade, que é texto livre de até 40 caracteres
   ("logo após o carnaval") e transbordava por cima da descrição do produto.
   Nas outras células centradas o mesmo `break-word` partia o código do
   produto ("300300 / 02") e a data ("20/09/202 / 6"): ali o conteúdo tem
   tamanho conhecido e a coluna é dimensionada para ele. */
.prop-tabela td.c-disp{ overflow-wrap:break-word; }
/* O código é uma palavra só, sem espaço onde quebrar: com 14 caracteres ele
   transbordava POR CIMA da coluna vizinha (na proposta 10 ele invadia a linha
   da previsão). `anywhere` e não `break-word` porque aqui não existe "próxima
   linha melhor" — ou parte no meio, ou vaza. */
.prop-tabela td.c-cod{ overflow-wrap:anywhere; }
/* Grade fechada: linha entre TODOS os campos, não só entre as linhas. Com
   sete colunas de número, a borda vertical é o que separa "3.000" de
   "15.000" sem o leitor precisar mirar o cabeçalho. */
.prop-tabela td{ padding:1.4mm 2mm; border:.5pt solid #cfcfd2;
  vertical-align:top; }
/* Numero NAO leva nowrap: com 4.200.000 PC ou R$ 1.260.000,00 o nowrap nao
   aperta nada, ele TRANSBORDA por cima da coluna vizinha. Sem ele a celula
   quebra no unico espaco que existe ("R$" numa linha, o valor na outra), que
   e feio uma vez a cada mil propostas e legivel sempre. */
.prop-tabela .num{ text-align:right; font-variant-numeric:tabular-nums; }
.prop-tabela .ctr{ text-align:center; }
.prop-totais{ width:100%; border-collapse:collapse; font-size:8.5pt;
  margin-bottom:3mm; }
.prop-totais td{ padding:1.2mm 2mm; border:.5pt solid #d8d8dc; }
.prop-totais tr:nth-child(odd) td{ background:#ececee; }
.prop-totais .rot{ text-align:right; font-weight:700; }
.prop-totais .num{ text-align:right; font-variant-numeric:tabular-nums;
  width:30mm; }
/* A frase que explica o frete destacado: abre as Observações (reporte #4,
   15/09/2026), e sai em negrito porque diz quem cobra de quem — o cliente
   que a pular acha que a Four lhe fatura o frete. */
.prop-frete-aviso{ font-size:7.5pt; font-weight:700; line-height:1.35;
  margin:1mm 0; }
.prop-sec{ font-size:8.5pt; font-weight:700; border-bottom:1.5pt solid #9b1c2e;
  padding-bottom:.8mm; margin:2.5mm 0 1.5mm; }
.prop-grade{ width:100%; border-collapse:collapse; font-size:8.5pt; }
/* A ficha de faturamento ganha só a linha horizontal: fechar a grade aqui
   transformaria oito pares rótulo/valor num formulário de imposto. */
.prop-grade td{ padding:1.1mm 2mm; vertical-align:top;
  border-bottom:.5pt solid #e4e4e8; }
.prop-grade .rot{ font-weight:700; white-space:nowrap; width:34mm; }
/* Observação escrita PELO VENDEDOR: fundo amarelo, como quem passa marca-texto
   no papel. É a única linha do documento que não é padrão — nasce da conversa
   daquele negócio ("consulte nossas condições especiais para…") — e em itálico
   preto ela se perdia entre a EC 87 e as condições gerais, que o cliente já
   nem lê. O amarelo é o que faz o olho parar ali. */
.prop-obs-destaque{ font-style:italic; font-weight:700; font-size:8.5pt;
  margin:1mm 0; background:#fff3a3; padding:1.5mm 2mm;
  white-space:pre-wrap; }
.prop-obs{ font-size:6.8pt; color:#343a40; line-height:1.35;
  white-space:pre-wrap; }
/* Endereço de coleta em Araquari (#178/#279): só quando o cliente coleta. */
.prop-armazem{ font-size:7.5pt; line-height:1.4; margin:1mm 0 1.5mm; }
.prop-cond{ font-size:7.5pt; line-height:1.4; }
/* O rodapé sangra 6mm de cada lado da caixa de texto: são sete fotos de
   produto com legenda, e em 186mm as legendas ficavam ilegíveis. A arte tem
   2048px de largura — aguenta a ampliação. */
.prop-rodape{ position:running(prop-rodape); width:198mm; margin-left:-6mm; }
.prop-rodape img{ width:198mm; height:auto; }
/* Marca d'água da revisão superada. `position:fixed` no WeasyPrint repete em
   TODAS as páginas — é o mecanismo de marca d'água, não um bug. Fica atrás do
   conteúdo (z-index negativo) para não atrapalhar a leitura dos números. */
.prop-marca{ position:fixed; top:45%; left:0; right:0; z-index:-1;
  text-align:center; transform:rotate(-24deg); pointer-events:none;
  color:rgba(155,28,46,.16); }
.prop-marca__tit{ display:block; font-size:30pt; font-weight:700;
  letter-spacing:.06em; line-height:1; white-space:nowrap; }
.prop-marca__sub{ display:block; font-size:13pt; font-weight:700;
  letter-spacing:.12em; margin-top:3mm; }

/* ============================================================
   OCUPADO — sinal global de ação em andamento (biUtils.ocupado)
   Barra fina no topo enquanto uma escrita está no ar. Diferente do
   esqueleto de carregamento: o conteúdo continua à vista, só não
   aceita clique — assim ninguém dispara a mesma ação duas vezes.
   ============================================================ */
.bi-ocupado {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: 2000; pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%, var(--crm-acento, #1d4d38) 45%,
    var(--crm-acento, #1d4d38) 55%, transparent 100%);
  background-size: 240% 100%;
  animation: bi-ocupado-desliza 1.1s ease-in-out infinite;
}
@keyframes bi-ocupado-desliza {
  from { background-position: 120% 0; }
  to   { background-position: -20% 0; }
}
/* enquanto trabalha, a página não aceita novo clique (o cursor conta por quê) */
body.bi-ocupado-ativo { cursor: progress; }
body.bi-ocupado-ativo main, body.bi-ocupado-ativo .offcanvas {
  pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .bi-ocupado { animation: none; background: var(--crm-acento, #1d4d38); }
}

/* ============================================================
   CRM — DO ZERO (v3): A RAMPA DO FUNIL
   Telas /crm/ e /crm/deal/. Sistema próprio, sem chrome nem
   utilitários Bootstrap (a mecânica do offcanvas fica; o vestido é
   daqui). Tema claro. Assinatura: UM verde em QUATRO profundidades,
   uma por etapa — a cor codifica o avanço do deal (Prospecção clara
   → Fechamento profundo). Cabeçalho de estação é bloco sólido no
   tom da etapa; o stepper do deal usa a mesma rampa; dinheiro e CTA
   ficam no verde profundo. Tudo escopado por
   [data-pagina="crm"|"crm-deal"].
   ============================================================ */
/* A fila de cobrança (/acompanhamento-inadimplencia) adota esta MESMA
   linguagem, por decisão do dono do produto: uma paleta só, definida uma
   vez. Reuso do bloco de tokens, não cópia dos valores — se o verde mudar
   aqui, muda nas duas telas. A Agenda (`crm-agenda`) entra na mesma lista
   pelo mesmo motivo: casamento por IGUALDADE, nunca por prefixo
   (`[data-pagina^="crm"]`) — ver o incidente documentado em
   `bi/templates/bi/crm_produtividade.html` (o token some em silêncio e a
   borda do campo renderiza quase preta). */
[data-pagina="crm"], [data-pagina="crm-deal"], [data-pagina="crm-agenda"],
[data-pagina="crm-tabelas-preco"], [data-pagina="crm-clientes"],
[data-pagina="crm-representantes"], [data-pagina="crm-usuarios"],
[data-pagina="crm-classificacao"],
/* `.topbar` na lista porque ela é IRMÃ da `div[data-pagina]`, não filha: sem
   isto as `.crm-*` da barra (o selo do ERP, a lista da busca) ficam sem os
   tokens. Só classes `.crm-*` leem estes tokens; as outras telas não mudam. */
[data-pagina="acompanhamento_inadimplencia"], .topbar {
  --crm-fundo: #f4f6f5;
  --crm-superficie: #ffffff;
  --crm-tinta: #171a18;
  --crm-tinta-2: #4e544f;
  --crm-tinta-3: #6d746f;
  --crm-borda: #e2e6e3;
  --crm-borda-forte: #cfd5d1;
  /* rampa do funil: um verde, quatro profundidades (todas ≥4.5:1 com branco) */
  --crm-tom-1: #4f7a67;
  --crm-tom-2: #3f6b57;
  --crm-tom-3: #2e5c47;
  --crm-tom-4: #1d4d38;
  /* Perdido fica FORA da rampa: o verde codifica avanço, e a raia dos negócios
     perdidos pintada com ele diria que perder é o fim bom do funil. Grafite:
     registro fechado, não alarme (perder faz parte de vender; o vermelho
     gritaria a cada card). */
  --crm-tom-perdido: #5a615c;
  --crm-acento: var(--crm-tom-4);
  --crm-acento-fundo: #e9f2ec;
  /* Semântica: ALIAS do global, não valor próprio. Medido, a duplicata produzia
     divergência exatamente onde importa e nenhuma onde não importa: o vermelho
     saía #b42318 aqui e #ca2a26 em /inadimplencia/ — telas irmãs, uma o
     detalhamento da outra, dois prints discordando do que é "ruim"; o verde
     divergia em 1 de G e 1 de B, imperceptível. Um token duplicado que não
     produzia nem a diferença que justificaria duplicá-lo. A rampa autoral do
     funil (--crm-tom-1..4) segue própria: ela codifica a etapa, que é o dado. */
  --crm-ok: var(--positive-text);  --crm-ok-fundo: var(--positive-subtle);
  --crm-avi: var(--warning-text);  --crm-avi-fundo: var(--warning-subtle);
  --crm-mal: var(--negative-text); --crm-mal-fundo: var(--negative-subtle);
  /* Contêiner: nem tudo melhora esticando. Acima disto a linha de comando
     abria 1.400px de vão entre a busca e as medidas, e a tabela de itens
     dava 665px só para a descrição do produto. */
  --crm-largura-max: 110rem;
  /* Teto da coluna do funil. 272px é o piso do Trello (menor largura que
     ainda cabe título + valor + dois metadados) e ~352px é onde o card ainda
     lê como card. Nenhum kanban do mercado estica card além disso. */
  --crm-coluna-max: 22rem;
  --crm-raio: 10px;
  --crm-sombra: 0 1px 2px rgba(23, 26, 24, .05);
  --crm-sombra-2: 0 6px 20px rgba(23, 26, 24, .09);
  background: var(--crm-fundo);
  color: var(--crm-tinta);
  /* A altura vem do shell (`content--altura-cheia`): a tela ocupa a janela e
     quem rola é a coluna / o corpo do negócio, nunca a página. */
  min-height: 0;
}
/* cada raia do funil e cada etapa do stepper carregam o próprio tom */
[data-pagina="crm"] .crm-raia { --tom: var(--crm-tom-4); }
[data-pagina="crm"] .crm-raia[data-raia="prospeccao"] { --tom: var(--crm-tom-1); }
[data-pagina="crm"] .crm-raia[data-raia="negociacao"] { --tom: var(--crm-tom-2); }
[data-pagina="crm"] .crm-raia[data-raia="reserva"]    { --tom: var(--crm-tom-3); }
/* Adiado é estacionamento, não avanço: o tom CLAREIA depois da reserva (o
   tom-1 ficou livre quando a Prospecção saiu) para a raia não ler como um
   passo a mais rumo ao ganho. */
[data-pagina="crm"] .crm-raia[data-raia="adiado"]     { --tom: var(--crm-tom-1); }
/* A fila do Ploomes (08/09/2026) não é etapa de venda — é fila de
   redistribuição, e o tom NEUTRO diz isso antes de qualquer texto: nenhum dos
   quatro tons do funil, que marcam avanço rumo ao ganho. Cinza é o que sobra
   quando a coluna não afirma progresso nenhum. */
[data-pagina="crm"] .crm-raia[data-raia="importado"]  { --tom: #adb5bd; }
/* Arrastar card entre as raias abertas (02/09/2026). Só o card que o backend
   marcou (`destinos`) tem `draggable`; a raia que aceita o drop acende com o
   próprio tom. Sem transição no card arrastado: o fantasma do navegador já é
   o feedback, e opacidade na origem diz "isto está saindo daqui". */
[data-pagina="crm"] .crm-cartao[draggable="true"] { cursor: grab; }
[data-pagina="crm"] .crm-cartao--arrastando { opacity: .45; }
[data-pagina="crm"] .crm-raia--alvo .crm-raia__corpo {
  outline: 2px dashed var(--tom); outline-offset: -4px;
  background: color-mix(in srgb, var(--tom) 8%, transparent); }
[data-pagina="crm"] .crm-raia[data-raia="ganho"]      { --tom: var(--crm-tom-4); }
/* sem esta regra a raia dos perdidos herdaria o default de `.crm-raia` — o
   mesmo verde escuro dos ganhos */
[data-pagina="crm"] .crm-raia[data-raia="perdido"]    { --tom: var(--crm-tom-perdido); }

/* --- primitivas de layout (o que os utilitários do Bootstrap faziam) ---
   `crm-clientes` entrou em 26/08/2026, quando a lista ganhou a ficha como
   canvas por cima: sem ele, `.crm-oculto` não escondia (balões de erro
   vazios pintados na tela) e `.crm-linha` não era flex (espaçamento do
   formulário quebrado). Igualdade, nunca prefixo — ver o comentário do
   bloco de tokens. */
[data-pagina="crm"] .crm-linha, [data-pagina="crm-deal"] .crm-linha,
[data-pagina="crm-agenda"] .crm-linha, [data-pagina="crm-clientes"] .crm-linha {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
[data-pagina="crm"] .crm-cresce, [data-pagina="crm-deal"] .crm-cresce,
[data-pagina="crm-agenda"] .crm-cresce,
[data-pagina="crm-clientes"] .crm-cresce { flex: 1 1 auto; }
[data-pagina="crm"] .crm-oculto, [data-pagina="crm-deal"] .crm-oculto,
[data-pagina="crm-agenda"] .crm-oculto,
[data-pagina="crm-clientes"] .crm-oculto { display: none !important; }

/* Grupo dobrável do formulário de cliente ("Dados do CRM"): summary sem o
   marcador do navegador — o `.drill-plus` é o único sinal de abrir. */
.crm-form-grupo > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem; }
.crm-form-grupo > summary::-webkit-details-marker { display: none; }

/* ═══ CRM · CADASTRO DO CLIENTE EM COLUNAS ════════════════════════════════
   Os 34 campos de uma vez, sem acordeão e sem rolagem (dono, 09/09/2026).
   Antes: 2.111px de formulário para 654 de dobra, 23 campos atrás de dois
   `<details>` fechados, e o CNPJ — que sozinho preenche outros dez — a
   898px do topo.

   `columns` e não `grid`: `column-fill: balance` é o padrão, então o
   navegador iguala as alturas sozinho. Com grid seria preciso uma tabela de
   distribuição em JS, que teria de ser refeita a cada grupo novo.

   O nome é `crm-form-bloco`, e não `crm-form-grupo`: esse já existe, como
   etiqueta de seção do painel do negócio (`negocio.js`) e com borda e recuo
   próprios em `[data-pagina="crm-deal"]` — que é uma das duas páginas que
   incluem este formulário. Reaproveitar traria a borda de lá para cá.
   ============================================================ */
/* 13,5rem e não os 17 do mockup: com o bloco das pessoas dentro do
   formulário (pedido do dono, 09/09/2026) o conteúdo cresceu, e trilho mais
   estreito é mais trilho. Medido nos dez monitores: 17rem dava QUATRO colunas
   em todos e sobrava campo fora da dobra em quatro deles; 13,5 dá CINCO de
   1280 para cima. É o MESMO valor da faixa estreita — um número só para a
   tela inteira, em vez de dois para manter em dia. */
.crm-form-colunas { columns: 13.5rem; column-gap: 1.15rem; }
.crm-form-bloco { margin-bottom: .65rem; break-inside: avoid; }
.crm-form-bloco__nome {
  font-size: var(--fonte-rotulo); text-transform: uppercase; letter-spacing: .06em;
  color: var(--crm-tinta-3); font-weight: 500; line-height: 1.2;
  padding-bottom: .25rem; margin-bottom: .45rem;
  border-bottom: 1px solid var(--crm-borda);
}
.crm-form-campo { margin-bottom: .35rem; }

/* "Trabalha com": sete opções curtas em btn-check de fábrica — cabem em duas
   ou três linhas, e o que está marcado se lê de longe (dono, 09/09/2026). */
.crm-form-chips { display: flex; flex-wrap: wrap; gap: .25rem; }
.crm-form-colunas .form-label {
  display: flex; align-items: baseline; gap: .4rem;
  font-size: var(--fonte-pequena); line-height: 1.2; margin-bottom: .08rem;
  color: var(--crm-tinta-2);
}
.crm-form-colunas .form-text { font-size: var(--fonte-pequena); line-height: 1.2; margin-top: .1rem; }
.crm-form-colunas .crm-linha { gap: .45rem; margin-bottom: .35rem; }

/* #177: seletor de país do telefone. Compacto à esquerda do número; a lista
   aberta mostra bandeira, nome e DDI. A altura é a do form-select-sm. */
[data-pagina^="crm"] .crm-telefone > .crm-telefone-pais {
  flex: 0 0 7.5rem; width: 7.5rem;
  padding-right: 1.5rem;
}
/* Na coluna estreita das pessoas (7rem por campo), seletor + número não cabem
   numa célula: o telefone ocupa a linha inteira. */
[data-pagina^="crm"] .crm-form-contato__campos > div:has(> .crm-telefone) { grid-column: 1 / -1; }

/* #177: bandeira no Windows (Chrome/Edge desenham o emoji como letras). A fonte
   só cobre os indicadores regionais; o resto do texto segue na fonte de sempre. */
@font-face {
  font-family: "Twemoji Country Flags";
  unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E007F;
  src: url("https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1.10/dist/TwemojiCountryFlags.woff2") format("woff2");
  font-display: swap;
}
[data-pagina^="crm"] .crm-telefone-pais,
[data-pagina^="crm"] .cl-fone,
#crm-modal-ficha .fc-fone {
  font-family: "Twemoji Country Flags", var(--sans);
}

/* O CNPJ é o motor do formulário: dez dos 34 campos saem da consulta dele.
   Destaque de POSIÇÃO (primeiro da primeira coluna) e de moldura, uma vez só
   na tela — dois destaques e nenhum destaca. */
.crm-form-motor {
  background: var(--crm-acento-fundo); border: 1px solid #c5ded0;
  border-radius: 8px; padding: .5rem .65rem .55rem; margin-bottom: .6rem;
  break-inside: avoid;
}
.crm-form-motor__nota {
  font-size: var(--fonte-pequena); line-height: 1.2; color: var(--crm-acento);
  margin-top: .35rem; font-weight: 500;
}

/* O botão mora NO RÓTULO do campo de origem: é dali que a cópia sai, e a
   pessoa lê "E-mail do contato → usar este nos três" numa varredura só.

   LINK, não pastilha (pedido do dono, 09/09/2026): a pastilha de fundo verde
   encostava na caixa do campo e virava um bloco a mais na coluna. Texto de
   acento sublinhado carrega a mesma promessa de "isto é clicável" sem ocupar
   área — e cinza sem sublinhado lia como legenda do
   campo, porque cinza nesta casa é a cor de desabilitado. */
.crm-form-colunas .crm-form-replicar,
.crm-form-colunas .crm-form-redistribuir {
  color: var(--crm-acento); background: none; border: 0; border-radius: 0;
  text-decoration: underline; text-underline-offset: .15em;
  font-weight: 500;
}
.crm-form-colunas .crm-form-replicar:hover,
.crm-form-colunas .crm-form-replicar:focus-visible,
.crm-form-colunas .crm-form-redistribuir:hover,
.crm-form-colunas .crm-form-redistribuir:focus-visible {
  color: var(--crm-tinta); background: none; text-decoration-thickness: 2px;
}
.crm-form-colunas .crm-form-replicar {
  margin-left: auto; font-size: var(--fonte-pequena); padding: 0;
}

/* Nasce onde o problema está e some quando ele acaba. Sem `margin-left:auto`:
   ele pertence ao campo de cima, não ao canto do cartão. */
.crm-form-colunas .crm-form-redistribuir {
  font-size: var(--fonte-pequena); padding: 0; margin-top: .2rem; align-self: flex-start;
}

/* As PESSOAS de contato: bloco do PAINEL, fora do formulário do cadastro
   (10/09/2026). Dentro dele — onde estiveram por um dia — o bloco herdava a
   invisibilidade do `#nd-prospect`, que só abre em "Cadastrar cliente novo":
   quem escolhia um cliente existente via o negócio ser recusado por falta de
   contato sem ter onde digitá-lo.

   As classes ficam as do formulário de propósito: é a mesma ESCALA de campo e
   rótulo do cadastro logo acima. Sem isto a pessoa herdava o tamanho solto do
   Bootstrap e lia como outra tela colada no painel. */
.crm-form-bloco--pessoas {
  border-top: 2px solid var(--crm-borda-forte); padding-top: .5rem;
  margin-top: .35rem;
}
.crm-form-pessoa__linha { position: relative; }
.crm-form-pessoa__linha + .crm-form-pessoa__linha {
  border-top: 1px dashed var(--crm-borda); padding-top: .4rem; margin-top: .4rem;
}
/* O ✕ só existe da linha 1 em diante — não dá para o formulário ficar com
   zero pessoas. Fora da grade, encostado à direita, para não roubar coluna de
   campo nenhum. */
.crm-form-pessoa__tirar { position: absolute; top: .1rem; right: 0; }
.crm-form-pessoa__linha + .crm-form-pessoa__linha .crm-form-contato__campos {
  padding-right: 1.6rem;
}

/* A pessoa usa a MESMA escala do cadastro acima. Sem isto ela herdava o
   tamanho solto do Bootstrap — campo de 38px contra 32, rótulo de 14 contra
   12 — e lia como outra tela colada no fim desta. O gancho é o bloco, que só
   existe no painel de cadastro: no painel do negócio (30rem) o MESMO
   componente continua como estava. */
.crm-form-bloco--pessoas .form-label {
  font-size: var(--fonte-pequena); line-height: 1.2; margin-bottom: .08rem;
  color: var(--crm-tinta-2);
}
.crm-form-bloco--pessoas .form-text { font-size: var(--fonte-pequena); line-height: 1.2; margin-top: .1rem; }

/* Os cinco campos numa linha só, com largura por PESO do conteúdo: nome e
   e-mail são longos, cargo é uma lista curta, telefone tem tamanho fixo e
   aniversário é uma data. Antes eram duas linhas de flex e o nome esticava
   por 1.065px — um campo enorme e vazio para caber "Maria Silva". */
/* Um campo por linha: o bloco vive num trilho de 216 a 272px. `auto-fit`
   e não `1fr` fixo porque o mesmo componente também é montado no painel do
   negócio, mais largo — lá ele volta a caber lado a lado sozinho. */
.crm-form-bloco--pessoas .crm-form-contato__campos {
  display: grid; gap: .1rem .55rem; align-items: end;
  /* 7rem: num trilho de 272px cabem DOIS campos por linha, e a pessoa deixa
     de custar cinco linhas inteiras. Abaixo disso o rótulo quebra. */
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
}
@media (max-width: 1200px), (max-height: 820px) {
  .crm-form-pessoa { padding-top: .6rem; margin-top: .7rem; }
}



/* Canvas estreito (1152 e 1024) é o caso mais duro: com trilhos de 17rem
   cabem TRÊS, e três colunas não seguram 34 campos em 654px de dobra — medido,
   712 contra 654. A saída é mais trilhos, mais estreitos, com os pares
   desfeitos: dois campos lado a lado não cabem num trilho estreito, um cabe.
   Desempilhar custa altura, mas a coluna a mais paga com folga.

   13,5rem foi medido, não escolhido: com 15rem o trilho mede 258px e 983
   ainda dá TRÊS — desempilhava os pares e pagava a altura sem ganhar a
   coluna. Com 13,5rem (234px) dá quatro em 1024 e em 1152.

   O gatilho é 1200 e não 1120 porque a media query lê a JANELA e o formulário
   mora no canvas, que é 96vw: em 1152×864 a janela passava dos 1120 e a
   altura passava dos 820, então nenhuma das duas faixas pegava — o canvas de
   1106 ficava com trilhos de 17rem e ritmo largo, e três campos caíam fora
   (medido: 809 de bloco para 750 de dobra). */
@media (max-width: 1200px) {
  .crm-form-colunas { columns: 10.5rem; }
  .crm-form-colunas .crm-linha { display: block; }
  .crm-form-colunas .crm-linha > * + * { margin-top: .2rem; }
  /* O par tipo-pessoa + CNPJ do motor continua LADO A LADO: são dois campos
     curtos, e é o bloco que abre a tela. */
  .crm-form-motor .crm-linha { display: flex; }
  .crm-form-motor .crm-linha > * + * { margin-top: 0; }
}

/* Dois gatilhos para o MESMO aperto do RITMO, ambos medidos: canvas estreito
   e janela baixa. O teto de altura é 820 e não a altura da janela porque a
   dobra não é a janela: em 1366×768 a janela tem 768 e a dobra tem 654 — o
   cabeçalho, o rodapé e o preâmbulo do painel comem 114. Aperta o respiro,
   nunca esconde campo: o defeito que esta reforma corrige é campo escondido. */
@media (max-width: 1200px), (max-height: 820px) {
  /* Na faixa apertada o BLOCO pode ser partido entre duas colunas, e é essa a
     mudança que mais rende: seis pedaços indivisíveis (cinco blocos mais o
     motor do CNPJ) em quatro colunas desperdiçam ~250px de equilíbrio, porque
     o navegador tem de fechar a coluna quando o próximo pedaço não cabe
     inteiro. Partir custa continuidade de leitura; não partir custava campo
     fora da dobra, que é o defeito que esta reforma existe para corrigir.

     O que NUNCA parte: o campo do seu rótulo (`crm-form-campo`, `crm-linha`),
     o rótulo do bloco do primeiro campo dele (`break-after: avoid`) e o motor
     do CNPJ, que é um bloco de destaque de quatro linhas. */
  /* Partir custa continuidade — o bloco pode fechar uma coluna e continuar na
     seguinte sem repetir o cabeçalho. Medi as duas saídas: proibindo partir,
     seis pedaços indivisíveis em quatro colunas desperdiçam ~250px de
     equilíbrio e voltam a sobrar campos fora da dobra (613 de bloco para 654
     em 1366, quatro campos fora em 1280×720). Partindo, sobra folga em todos.
     Entre continuação sem cabeçalho e campo escondido, a regra do dono decide:
     campo escondido é campo esquecido, e o rótulo de cada campo já diz o que
     ele é ("Endereço", "Bairro", "Cidade" não precisam do título do grupo). */
  .crm-form-bloco { break-inside: auto; }
  .crm-form-bloco__nome { break-after: avoid; }
  .crm-form-campo, .crm-form-colunas .crm-linha { break-inside: avoid; }
  .crm-form-bloco { margin-bottom: .3rem; }
  .crm-form-bloco__nome { padding-bottom: .15rem; margin-bottom: .3rem; }
  .crm-form-campo { margin-bottom: .15rem; }
  .crm-form-colunas .form-text { line-height: 1.2; }
  /* O grupo de caixas de seleção respira menos que os campos: são rótulos
     curtos numa linha só, e o respiro deles era o mesmo de um campo com
     rótulo em cima. */
  .crm-form-colunas .form-check { margin-bottom: 0; min-height: 1.25rem; }
  .crm-form-motor__nota { line-height: 1.2; }
  .crm-form-colunas .crm-linha { margin-bottom: .2rem; }
  .crm-form-colunas .form-label { line-height: 1.2; }
  .crm-form-motor { padding: .45rem .6rem .5rem; margin-bottom: .45rem; }
}

/* --- tipografia --- */
.crm-rotulo { font-size: var(--fonte-pequena); font-weight: 400; color: var(--crm-tinta-3);
  letter-spacing: .01em; }
/* Nota que PRECISA ser lida (referências da condição de pagamento que
   divergem, enquadramento fora do herdado). O `text-warning` do Bootstrap
   (#ffc107) é o pior amarelo do fundo branco em corpo miúdo; o token da casa
   já é a tinta de aviso legível. */
.crm-rotulo--avi { color: var(--crm-avi); }
.crm-numero { font-variant-numeric: tabular-nums lining-nums;
  font-weight: 500; letter-spacing: -.015em; }
/* Campo de PERCENTUAL (comissão, IPI): o sinal fica dentro do campo, à
   direita. O número sozinho não dizia a unidade — o vendedor digitava "3" ou
   "3%" sem saber qual a tela esperava (relato do dono, 25/08/2026). O sinal é
   só leitura: a máscara decimal já descarta o "%" que alguém digite, e o que
   viaja ao servidor continua sendo o número. Não usa `input-group` porque a
   coluna tem 80px e a borda extra do addon comeria o campo. */
.crm-pct { position: relative; display: block; }
.crm-pct > .form-control { padding-right: 1.3rem; }
.crm-pct::after { content: '%'; position: absolute; right: .4rem; top: 50%;
  transform: translateY(-50%); pointer-events: none;
  font-size: var(--fonte-pequena); color: var(--crm-tinta-3); }
/* TÍTULO DE SEÇÃO — caixa alta. Toda a interface já rotula em caixa alta
   (etapa, coluna de tabela, campo da capa); o título do painel era o único
   em caixa mista, o que fazia ele parecer conteúdo em vez de estrutura.
   Caixa alta pede tracking positivo e peso maior para não fechar. */
.crm-titulo { font-size: var(--fonte-corpo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .08em; color: var(--crm-tinta); }
/* PERGUNTA — a faixa de confirmação faz uma pergunta em frase inteira, e
   frase inteira em caixa alta lê-se pior (e grita). Fica em caixa mista. */
.crm-pergunta { font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -.01em;
  color: var(--crm-tinta); }
.crm-etiqueta { font-size: var(--fonte-rotulo); font-weight: 500; color: var(--crm-tinta-3);
  text-transform: uppercase; letter-spacing: .1em; }
/* Etiqueta usada como rótulo de campo é sempre bloco com respiro embaixo —
   isso estava repetido em 14 `style=` inline nos dois formulários. */
[data-pagina="crm"] label.crm-etiqueta,
[data-pagina="crm-deal"] label.crm-etiqueta { display: block; margin-bottom: .3rem; }
.crm-forte { font-weight: 500; letter-spacing: -.01em; }

/* --- superfícies --- */
/* UMA superfície de card no CRM. `.crm-painel` é o mesmo cartão com recuo
   interno — eram duas declarações idênticas que já divergiam por descuido. */
.crm-cartao, .crm-painel { background: var(--crm-superficie);
  border: 1px solid var(--crm-borda); border-radius: var(--crm-raio);
  box-shadow: var(--crm-sombra); }
.crm-painel { padding: 1rem 1.15rem; }

/* --- selos de estado (cantos 6px: selo, não cápsula) --- */
.crm-pilula { display: inline-flex; align-items: center; gap: .3rem;
  padding: .1rem .45rem; border-radius: 6px; font-size: var(--fonte-pequena);
  font-weight: 500; white-space: nowrap; }
.crm-pilula--ok     { background: var(--crm-ok-fundo);     color: var(--crm-ok); }
/* #220: a pílula de estoque que abre a ficha não ganha sublinhado de link. */
.crm-pilula-link { text-decoration: none; }
.crm-pilula-link:hover .crm-pilula, .crm-pilula-link:focus-visible .crm-pilula { outline: 1px solid currentColor; }
.crm-pilula--aviso  { background: var(--crm-avi-fundo);    color: var(--crm-avi); }
.crm-pilula--erro   { background: var(--crm-mal-fundo);    color: var(--crm-mal); }
.crm-pilula--acento { background: var(--crm-acento-fundo); color: var(--crm-acento); }
.crm-pilula--neutra { background: #eaeeec; color: var(--crm-tinta-2); }
/* A borda entra PARA DENTRO: sem descontar o 1px, a única pílula com traço
   ficava 2px mais alta que as vizinhas e o alinhamento da linha dançava. */
.crm-pilula--tracejada { background: transparent;
  border: 1px dashed var(--crm-borda-forte); color: var(--crm-tinta-2);
  padding: calc(.1rem - 1px) calc(.45rem - 1px); }
/* Espera de um fato que ainda vem do servidor (o saldo de estoque do item
   recém-escolhido). O pulso é o que separa "estou consultando" de um rótulo
   parado — sem ele, a pílula tracejada parecia mais um estado final. */
.crm-pilula--pulsa { animation: crm-doc-pulsa 1.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .crm-pilula--pulsa { animation: none; }
}

/* CRM · selo de prospect (cliente sem código no Senior) */
.crm-selo--prospect { background: #fff3cd; color: #664d03; border: 1px solid #ffe69c;
  border-radius: .25rem; font-size: var(--fonte-pequena); padding: 0 .35rem; margin-left: .35rem; }

/* --- controles --- */
[data-pagina="crm"] .form-label, [data-pagina="crm-deal"] .form-label {
  font-size: var(--fonte-corpo); font-weight: 500; margin-bottom: .3rem; }
[data-pagina="crm"] .form-text, [data-pagina="crm-deal"] .form-text {
  font-size: var(--fonte-corpo); color: var(--crm-tinta-3); }

/* busca com lupa dentro do campo */
/* A busca do funil ENCOLHE, não cresce, e cabe em 16rem. Ela carregava
   `.crm-cresce` + `.crm-largura-20` e ficava com 320px ao lado de uma fita de
   medidas de 660px: a barra somava 1424px em 1352 disponíveis e "Novo
   negócio" caía numa segunda linha. A folga era ZERO — bastaram dez pixels a
   mais no rótulo de um botão para a linha estourar. 16rem (256px) sobra para
   o placeholder, que mede 208px. */
[data-pagina="crm"] .crm-comando > .crm-busca { flex: 0 1 16rem; max-width: 16rem; }
/* As duas ações andam juntas e ficam à direita mesmo quando a linha quebra —
   `margin-left:auto` vale por LINHA no flex, então na segunda ela continua
   encostada na direita em vez de nascer à esquerda. */
[data-pagina="crm"] .crm-comando__acoes { display: flex; align-items: center;
  gap: var(--crm-e2); margin-left: auto; }
/* PREFIXO, não igualdade: os canvas de histórico e de documentos (com as
   buscas deles) são incluídos também pela lista de clientes, que é
   `data-pagina="crm-clientes"`. Com `="crm"` as três regras não casavam lá, o
   `.crm-busca` deixava de ser contexto de posicionamento e a lupa voltava ao
   fluxo — renderizava como bloco ACIMA do campo, que perdia o recuo. Medido
   em 03/09/2026 nas duas buscas da tela Clientes. `^=` é o mesmo casamento
   que este arquivo já usa em outros 54 lugares. */
[data-pagina^="crm"] .crm-busca { position: relative; }
[data-pagina^="crm"] .crm-busca > i { position: absolute; left: .8rem; top: 50%;
  transform: translateY(-50%); color: var(--crm-tinta-3); font-size: var(--fonte-corpo);
  pointer-events: none; }
[data-pagina^="crm"] .crm-busca > .form-control { padding-left: 2.1rem; }


/* Foco visível em TODA ação — antes só quatro seletores tinham, e Ganhar,
   Perder e Enviar proposta (as irreversíveis) estavam entre os que não. */
[data-pagina="crm"] .crm-cartao__acao:focus-visible,
[data-pagina="crm"] .crm-raia__cabo:focus-visible,
[data-pagina="crm"] .crm-lista__item:focus-visible,
[data-pagina="crm-deal"] .crm-lista__item:focus-visible {
  outline: 2px solid var(--crm-acento); outline-offset: 2px; }

/* --- medidas (painel de instrumento na linha de comando) --- */
.crm-medidas { display: flex; flex-wrap: wrap; margin: 0; }
.crm-medidas .crm-medida { display: flex; flex-direction: column; gap: .06rem;
  padding: 0 1.35rem; border-left: 1px solid var(--crm-borda); }
.crm-medidas .crm-medida:first-child { border-left: 0; padding-left: 0; }
.crm-medidas .crm-medida dt { font-size: var(--fonte-rotulo); font-weight: 500;
  color: var(--crm-tinta-3); text-transform: uppercase; letter-spacing: .1em; }
.crm-medidas .crm-medida dd { margin: 0; font-size: var(--fonte-destaque); line-height: 1.2;
  font-variant-numeric: tabular-nums; font-weight: 500; letter-spacing: -.02em; }
@media (max-width: 991.98px) {
  [data-pagina="crm"] .crm-medidas { display: none; }
}

/* ------------------------------------------------------------
   FUNIL — board em grid, estações com TRILHO DE SEGMENTOS
   ------------------------------------------------------------ */
/* O board tem QUATRO etapas fixas — não dá para usar largura sobrando criando
   coluna nova. E card largo não é card melhor: em 2560px cada um passava de
   580px para três linhas de texto, virando caixa esticada com metade vazia.
   A coluna ganha um teto e a sobra vira margem; acima de 1600px a sobra vira
   o painel de follow-ups à direita, que antes empurrava o board para baixo. */
/* CINCO colunas desde 02/09/2026 — Adiados saiu de dentro da Reserva (ver
   `ETAPAS` em crm/services/crm.py). Foram quatro desde 23/08 (Finalizado
   virou Ganhos + Perdidos) e três entre 08/08 e 23/08, quando a Prospecção
   saiu. O número acompanha `ETAPAS`: mudou lá, muda aqui. O `minmax(0, …)`
   é o que deixa as cinco colunas encolherem abaixo do teto numa janela
   estreita, em vez de estourarem a largura da tela. */
[data-pagina="crm"] .crm-board { display: grid; gap: 1rem;
  /* Seis desde 08/09/2026: a fila do Ploomes entrou na frente das cinco. */
  grid-template-columns: repeat(6, minmax(0, var(--crm-coluna-max)));
  /* O contêiner já tem a largura exata das colunas, então alinhar ao início
     mantém board e barra de comando na mesma vertical. */
  /* `align-content` PRECISA esticar: com `start` a linha da grade empacota no
     topo e a coluna nunca ganha altura — logo, nunca rola. Era metade da causa
     do board de 226px numa tela de 929px (a outra metade é o `align-items` da
     .crm-tela, logo abaixo). */
  justify-content: start; align-content: stretch; min-height: 0; }
@media (max-width: 1199.98px) {
  /* O teto vale aqui também: em duas colunas a 1199px o card chegava a
     528px — pior que no layout de quatro. */
  [data-pagina="crm"] .crm-board {
    grid-template-columns: repeat(2, minmax(0, var(--crm-coluna-max))); }
}
@media (max-width: 767.98px) {
  [data-pagina="crm"] .crm-board { grid-template-columns: minmax(0, 1fr); gap: .65rem; }
}


/* A tela do funil: board + follow-ups. Até 1599px eles se empilham (o painel
   só existe quando há compromisso, então não rouba espaço à toa); daí para
   cima o painel vira a coluna da direita, ocupando a sobra que o board não
   usa. */
/* Contêiner das duas telas — a linha de comando e o board dividem o mesmo
   limite, senão as medidas fogem para o canto e o board fica sozinho no meio. */
/* O funil não usa o contêiner geral: ele tem a largura NATURAL das cinco
   colunas (5 × 22rem + 4 gaps). Assim a barra de comando e o board terminam
   no mesmo lugar — board centrado com a barra esticada ficava torto. */
[data-pagina="crm"] .crm-comando,
[data-pagina="crm"] .crm-tela {
  max-width: calc(5 * var(--crm-coluna-max) + 4rem);
  margin-inline: auto; width: 100%; }
/* O feed de ações era a coluna fixa da direita (com faixa RESERVADA para o
   board não mudar de tamanho a cada tecla da busca). Virou o drawer
   #crm-modal-fups (pedido do dono, 25/08/2026) — o board tem a largura toda
   e a tela volta a uma coluna só. */
[data-pagina="crm"] .crm-tela { display: grid; gap: 1rem;
  grid-template-columns: minmax(0, 1fr); align-items: stretch; }

/* laje contida com os cards: leve tintura do tom da etapa */
[data-pagina="crm"] .crm-coluna {
  background: color-mix(in srgb, var(--tom) 7%, #fff); border-radius: 12px;
  padding: .6rem; display: flex; flex-direction: column; gap: .6rem;
  min-height: 13rem; }
/* Painel sem nada a listar: para de esticar até o rodapé. */
[data-pagina="crm"] .crm-painel--hug { align-self: start; }

/* Busca sem nenhum resultado: uma faixa no lugar do board inteiro. Ocupa as
   quatro trilhas para não deslocar a grade, e não estica: o vazio não merece
   a altura da tela. */
[data-pagina="crm"] .crm-board__vazio { grid-column: 1 / -1; align-self: start;
  background: var(--crm-superficie); border: 1px dashed var(--crm-borda);
  border-radius: 12px; padding: 2rem 1rem; text-align: center;
  color: var(--crm-tinta-2); font-size: var(--fonte-corpo); }
/* A frase começa ONDE O CONTEÚDO COMEÇARIA, não no meio da coluna: centrada
   verticalmente num vão de 724px ela flutuava longe do cabeçalho que explica,
   e o olho tinha de descer meia tela para achar a resposta. `flex:1` mantinha
   a caixa esticada até o fim da raia só para centralizar. */
/* Explicativo da coluna vazia, um degrau menor (passe de compacidade,
   28/08/2026): é rodapé de raia sem negócio, não corpo de texto. */
[data-pagina="crm"] .crm-coluna__vazio { color: var(--crm-tinta-3);
  font-size: var(--fonte-pequena); padding: var(--crm-e2) var(--crm-e3) 0;
  line-height: 1.5; text-wrap: pretty; }

/* card do deal — passe de compacidade (28/08/2026, aprovado): padding e
   margens ~30% mais curtos em toda a pilha do cartão. */
[data-pagina="crm"] .crm-coluna .crm-cartao { overflow: hidden;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
[data-pagina="crm"] .crm-coluna .crm-cartao:hover {
  border-color: var(--crm-borda-forte); box-shadow: var(--crm-sombra-2);
  transform: translateY(-1px); }
[data-pagina="crm"] .crm-cartao__corpo { display: block; padding: .55rem .7rem;
  color: inherit; text-decoration: none; }
[data-pagina="crm"] .crm-cartao__corpo:hover { color: inherit; }
[data-pagina="crm"] .crm-cartao__corpo:focus-visible {
  outline: 2px solid var(--crm-acento); outline-offset: -2px; }
[data-pagina="crm"] .crm-cartao__nome { font-size: var(--fonte-corpo); font-weight: 500;
  letter-spacing: -.01em; line-height: 1.2;
 }
/* `min-width:0` nos selos: um único selo mais largo que o cartão (nome de
   etapa comprido) travava a fileira no tamanho do conteúdo e vazava por
   cima da borda mesmo com `flex-wrap`, medido 262px de conteúdo em 235px de
   cartão. Com ele o selo quebra em vez de estourar. */
[data-pagina="crm"] .crm-cartao__selos { display: flex; flex-wrap: wrap;
  gap: .2rem; margin-top: .2rem; min-width: 0; }
[data-pagina="crm"] .crm-cartao__selos > * { min-width: 0; }
/* `min-width:0` sozinho não bastava: o selo LONGO ("Pedido 20974 · Não
   fechado no Senior · HML2") é quem estoura, não a fileira — `.crm-pilula`
   herda `white-space:nowrap` do global. Texto que TEM que ser lido por
   inteiro (número do pedido + estado) quebra em duas linhas em vez de
   vazar; não trunca (28/08/2026, medido 255>241). Mesma causa no delta de
   preço da tabela de itens — consertada junto. */
[data-pagina="crm"] .crm-cartao__selos .crm-pilula,
[data-pagina="crm-deal"] .crm-tabela .crm-pilula {
  white-space: normal; min-width: 0; }
[data-pagina="crm"] .crm-cartao__valor { font-size: var(--fonte-corpo); font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; margin-top: .3rem;
  color: var(--tom); }
[data-pagina="crm"] .crm-cartao__rodape { display: flex; align-items: center;
  gap: .4rem; border-top: 1px solid var(--crm-borda); padding: .25rem .7rem; }
/* Link, não botão: "Marcar previsão" pesava como uma banda própria (peso de
   botão, fundo no hover) numa fileira que já é o rodapé compacto — a MESMA
   fileira do avatar. Sublinhado e sem fundo lê como ação secundária, do
   tamanho da linha em que já mora. */
[data-pagina="crm"] .crm-cartao__acao { margin-left: auto; border: 0;
  background: none; color: var(--crm-acento); font-size: var(--fonte-pequena);
  font-weight: 500; text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer; padding: .1rem .15rem; }
[data-pagina="crm"] .crm-cartao__acao:hover { opacity: .8; }
.crm-avatar { width: 1.45rem; height: 1.45rem; border-radius: 50%; flex: none;
  background: #e2e2e6; color: var(--crm-tinta-2); display: inline-flex;
  align-items: center; justify-content: center; font-size: var(--fonte-pequena);
  font-weight: 500; letter-spacing: .02em; }

/* UM cabeçalho por raia — o bloco sólido no tom da etapa. Era declarado duas
   vezes com os MESMOS três dados: `.crm-estacao` da tabuleta larga e
   `.crm-raia__cabo` do telefone. Agora é o mesmo elemento: no telefone ele
   também colapsa a raia (daí ser <button>), na tabuleta é só o rótulo. */
[data-pagina="crm"] .crm-raia__cabo { display: flex; align-items: center;
  gap: .5rem; width: 100%; appearance: none; text-align: left;
  background: var(--tom); color: #fff; border: 0; border-radius: 8px;
  padding: .5rem .75rem; margin-bottom: .55rem; cursor: default; }
[data-pagina="crm"] .crm-raia__nome { font-size: var(--fonte-rotulo); font-weight: 500;
  color: #fff; text-transform: uppercase; letter-spacing: .1em; }
[data-pagina="crm"] .crm-raia__conta { font-size: var(--fonte-pequena); font-weight: 500;
  color: #fff; font-variant-numeric: tabular-nums;
  border: 1px solid rgba(255, 255, 255, .55); border-radius: var(--raio-chip);
  padding: 0 .38rem; line-height: 1.5; }
/* Ganho e perdido no cabeçalho da raia terminal: é a composição do número ao
   lado, não uma segunda medida — por isso texto de apoio, no branco da faixa
   com opacidade, e não outra pílula competindo com a contagem. */
[data-pagina="crm"] .crm-raia__detalhe { font-size: var(--fonte-pequena);
  font-weight: 500; color: #fff; opacity: .85; }
/* "e mais 1916": o resto que o teto da fila não desceu. Discreto de
   propósito — é ressalva do cabeçalho, não um segundo número competindo com a
   contagem. */
[data-pagina="crm"] .crm-raia__ocultos { font-size: var(--fonte-pequena); color: #6c757d;
  white-space: nowrap; }
[data-pagina="crm"] .crm-raia__soma { margin-left: auto; font-size: var(--fonte-corpo);
  font-weight: 500; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
/* o marcador (`.drill-plus`, + ↔ −) é do colapso, que só existe no telefone;
   branco porque o cabo da raia é escuro. Estado pelo aria-expanded do cabo. */
[data-pagina="crm"] .crm-raia__cabo .drill-plus { display: none; }
@media (max-width: 767.98px) {
  [data-pagina="crm"] .crm-raia__cabo { cursor: pointer; margin-bottom: 0; }
  [data-pagina="crm"] .crm-raia__cabo .drill-plus {
    display: inline-flex; margin-left: .5rem; color: #fff; }
  /* Quem empurra o marcador para a direita é a soma (`margin-left: auto`).
     Perdidos não tem soma — de propósito —, e sem isto o "+" daquela raia
     ficaria colado na contagem, no meio da faixa. */
  [data-pagina="crm"] .crm-raia__cabo:not(:has(.crm-raia__soma)) .drill-plus {
    margin-left: auto; }
  [data-pagina="crm"] .crm-raia__corpo { display: none; }
  [data-pagina="crm"] .crm-raia--aberta .crm-raia__corpo { display: block;
    margin-top: .55rem; }
}

/* --- follow-ups --- */
[data-pagina="crm"] .crm-fups li { display: flex; flex-wrap: wrap;
  align-items: center; gap: .5rem; padding: .45rem 0; }
[data-pagina="crm"] .crm-fups li + li { border-top: 1px solid var(--crm-borda); }
/* Botão flutuante das próximas ações: o compromisso do dia à vista em
   qualquer rolagem. É o btn-primary de fábrica; aqui só a flutuação e a
   sombra. Abaixo do offcanvas do Bootstrap (1045), acima de
   todo o resto da página. */
[data-pagina="crm"] .crm-fab { position: fixed;
  right: var(--crm-respiro-x, 1.5rem); bottom: 1.5rem; z-index: 1030;
  box-shadow: 0 6px 20px rgba(23, 26, 24, .28); }
[data-pagina="crm"] .crm-fab:hover { transform: translateY(-1px); }
/* A contagem no verde: texto claro; a pílula de atraso continua vermelha. */
[data-pagina="crm"] .crm-fab #crm-fups-n { display: inline-flex; gap: .4rem; }
[data-pagina="crm"] .crm-fab #crm-fups-n > span:not([class*="pilula"]) {
  opacity: .85; }

/* ------------------------------------------------------------
   DEAL — página própria: capa, trilho, corpo (rail + main),
   rodapé de decisão grudado. Sem wsurface.
   ------------------------------------------------------------ */
[data-pagina="crm-deal"] .crm-pagina { display: flex; flex-direction: column;
  gap: 0; min-height: 0; flex: 1 1 auto; }
/* A capa é a grade de 12 do Bootstrap (row/col, montada no JS). Nenhuma regra
   de layout aqui: as larguras são das colunas, e o CSS cuida só do que o
   Bootstrap não tem — a pele da faixa, o nome do cliente e o resumo. */
[data-pagina="crm-deal"] .crm-capa { background: var(--crm-superficie);
  border-bottom: 1px solid var(--crm-borda); padding-block: .5rem .45rem; }
[data-pagina="crm-deal"] .crm-capa .crm-etiqueta { display: block;
  margin-bottom: .2rem; }
/* Campo com botão colado (contato + Ligar): o select cede, o botão não —
   sem `nowrap` o select tomava a coluna inteira e o Ligar caía para a linha
   de baixo, esticando a capa em 40px. */
[data-pagina="crm-deal"] .crm-capa .crm-linha { flex-wrap: nowrap; }
[data-pagina="crm-deal"] .crm-capa .crm-linha > .form-select { min-width: 0; }
[data-pagina="crm-deal"] .crm-capa .crm-linha > .btn { white-space: nowrap; }
/* Resumo do que está guardado no painel de detalhes: leitura, não campo. Em
   três linhas e não duas — nomear cada valor (Task 4) engordou a fita o
   bastante para cortar a validade em 142 das 220 condições do catálogo com
   frete destacado. */
[data-pagina="crm-deal"] .crm-resumo { font-size: var(--fonte-corpo);
  color: var(--crm-tinta-2);
 }
/* Prévia da assinatura no painel de envio: papel, não campo — fundo branco,
   contorno leve e a arte encolhida para caber nos 30rem do painel. */
[data-pagina="crm-deal"] .crm-assinatura-previa { background: #fff;
  border: 1px solid var(--crm-borda); border-radius: 8px;
  padding: .7rem .8rem; overflow-x: auto; }
[data-pagina="crm-deal"] .crm-assinatura-previa img { max-width: 100%;
  height: auto; }
[data-pagina="crm-deal"] .crm-assinatura-previa p { margin: 0 0 .5rem; }
/* Formulário do painel lateral: uma coluna, campos empilhados. Em duas
   colunas num painel de 26rem nenhum campo caberia inteiro. */
[data-pagina="crm-deal"] .crm-form-lista { display: grid; gap: .85rem;
  margin: 0; }
[data-pagina="crm-deal"] .crm-form-lista dt { font-size: var(--fonte-rotulo);
  font-weight: 500; color: var(--crm-tinta-3); text-transform: uppercase;
  letter-spacing: .1em; }
[data-pagina="crm-deal"] .crm-form-lista dd { margin: .25rem 0 0; }
/* Título de bloco dentro do painel: separa o que vai para o pedido do que
   sai impresso. Linha em cima, e nenhuma no primeiro. */
[data-pagina="crm-deal"] .crm-form-grupo { padding-top: .85rem;
  border-top: 1px solid var(--crm-borda); }
[data-pagina="crm-deal"] .crm-form-grupo:first-child { padding-top: 0;
  border-top: 0; }
[data-pagina="crm-deal"] .crm-form-lista .form-control,
[data-pagina="crm-deal"] .crm-form-lista .form-select,
[data-pagina="crm-deal"] .crm-form-lista .crm-combo { width: 100%; }
[data-pagina="crm-deal"] .crm-form-lista textarea.form-control {
  min-height: 5.5rem; resize: vertical; }
/* Bloco de frete: os seis campos numa LINHA SÓ, colunas iguais (pedido do
   dono, 25/08/2026 — simetria acima de tudo). Rótulo curto cabe na coluna;
   a explicação mora na nota embaixo. O rótulo reserva duas linhas para o
   caso de quebra no notebook denso — os controles nascem alinhados. */
[data-pagina="crm-deal"] .crm-form-lista--frete {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1.1rem 1.25rem; align-items: start; }
[data-pagina="crm-deal"] .crm-form-lista--frete dt {
  min-height: 2.4em; display: flex; align-items: flex-end; }
[data-pagina="crm-deal"] .crm-form-lista--frete .crm-campo-un { display: flex; }
[data-pagina="crm-deal"] .crm-form-lista--frete .crm-campo-un .form-control {
  flex: 1; }
@media (max-width: 1100px) {
  [data-pagina="crm-deal"] .crm-form-lista--frete {
    grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  [data-pagina="crm-deal"] .crm-form-lista--frete {
    grid-template-columns: minmax(0, 1fr); }
  [data-pagina="crm-deal"] .crm-form-lista--frete dt { min-height: 0; }
}
[data-pagina="crm-deal"] .crm-conta-nome { font-size: var(--fonte-titulo); font-weight: 500;
  letter-spacing: -.02em; }
[data-pagina="crm-deal"] .crm-capa-obs:empty { display: none; }
[data-pagina="crm-deal"] .crm-capa-obs { margin-top: .6rem; }
/* Recado do cadastro do cliente: `pre-line` porque o vendedor escreveu em
   linhas ("SCORE 810" embaixo de "SEM RESTRIÇÕES") e emendar tudo numa
   frase só perde a leitura que ele montou. */
[data-pagina="crm-deal"] .crm-obs-cliente { white-space: pre-line; }
/* Recado comprido não pode empurrar o formulário de proposta/produtos para
   fora da tela (dropdown de busca de produto abria fora da viewport,
   28/08/2026). Mesmo mecanismo do `.wsurface__cap`/`.wsurface__cap-obs` da
   separação (canônico, custom.css ~8100/~8749): a fatia da observação
   MEDE O TEXTO (`fit-content`) até um teto, os campos ficam com o resto da
   linha, e sem observação a coluna some — CRM-prefixado porque `#dl-campos`
   é grade Bootstrap própria, não o `.wsurface__cap-esq` empacotado. */
[data-pagina="crm-deal"] .crm-capa-linha { display: grid;
  grid-template-columns: minmax(0,1fr) fit-content(42%);
  align-items: start; gap: .375rem .875rem; }
[data-pagina="crm-deal"] .crm-capa-linha:has(> .crm-cap-obs-cliente:empty) {
  grid-template-columns: minmax(0,1fr); }
[data-pagina="crm-deal"] .crm-cap-obs-cliente:empty { display: none; }
/* A caixa MANDA na própria altura, não na da linha: teto de 8rem (mesmo da
   separação) com rolagem interna para o excedente — sem isso um recado
   comprido esticaria a capa inteira. Dois blocos (pedido/nota) empilham
   dentro dela, sem clamp individual: quem rola é a caixa toda. Compacta:
   nota lateral, não hero. */
[data-pagina="crm-deal"] .crm-cap-obs-cliente { min-width: 0; max-height: 8rem;
  overflow: auto; padding: .5rem .7rem; border-radius: 8px;
  border: 1px solid #f0d9a7; background: var(--crm-avi-fundo);
  font-size: var(--fonte-corpo); line-height: 1.2; }
[data-pagina="crm-deal"] .crm-cap-obs-cliente b { display: block; font-size: var(--fonte-pequena); }
[data-pagina="crm-deal"] .crm-cap-obs-cliente .crm-rotulo { font-size: var(--fonte-pequena); }

/* O stepper de etapas (`.crm-etapas`/`.crm-etapa`) foi removido em 10/08/2026
   junto com o markup: 56px de altura repetindo a faixa de estado. Ver o
   comentário em `crm/templates/crm/negocio.html`. As ~40 linhas de regra que
   moravam aqui saíram com ele — CSS sem markup é peso que ninguém cobra. */

/* corpo: trilho de contexto + trabalho */
/* O trilho era 17rem fixo enquanto a tabela ia a 2.100px — a descrição do
   produto sozinha ficava com 665px. Agora o trilho acompanha um pouco e o
   corpo respeita o contêiner. */
/* O acompanhamento deixou de ser contexto e virou a NEGOCIAÇÃO inteira
   (rodadas + conversas na mesma linha), então ganhou largura: 20rem apertava
   uma rodada com valor e ação em três linhas. A tabela de itens continua no
   centro porque é campo de trabalho — é nela que se digita. */
[data-pagina="crm-deal"] .crm-corpo { display: grid;
  grid-template-columns: minmax(20rem, 25rem) minmax(0, 1fr); gap: 1.25rem;
  /* Respiro lateral em variável (era 1.25rem fixo): a barra de rolagem do
     corpo mora colada na borda direita e o sidebar na esquerda — canto
     arredondado de card a 13px deles parecia grudado. Capa/roteiro/rodapé
     usam a MESMA variável para o conteúdo seguir alinhado. */
  padding: 1.25rem var(--crm-respiro-x, 2rem); align-items: start; flex: 1;
  max-width: var(--crm-largura-max); margin-inline: auto; width: 100%; }
/* A faixa (fundo branco, borda) continua atravessando a tela — é ela que
   separa as camadas —, mas o CONTEÚDO respeita o mesmo contêiner do corpo.
   Sem isto, em 2560px o seletor de representante ficava com 1.000px e o
   "Pedido no Senior" ia parar a um palmo da borda, longe do resto. */
[data-pagina="crm-deal"] .crm-capa,
[data-pagina="crm-deal"] .crm-roteiro,
[data-pagina="crm-deal"] .crm-rodape {
  padding-inline: max(var(--crm-respiro-x, 2rem),
                      calc((100% - var(--crm-largura-max)) / 2)); }
/* O respiro cresce com a tela: canto de 10px precisa de chão para não
   parecer grudado no sidebar e na barra de rolagem. A régua vale para o
   corpo E para capa/roteiro/rodapé — um número só, sempre alinhados. O modo
   denso de notebook (≤1600) aperta, mas não gruda; celular volta ao .8rem. */
[data-pagina^="crm"], [data-pagina="separacao_faturamento"][data-tela="programacao"] { --crm-respiro-x: 3rem; }
@media (max-width: 1600px) {
  [data-pagina^="crm"], [data-pagina="separacao_faturamento"][data-tela="programacao"] { --crm-respiro-x: 1.5rem; }
}
@media (max-width: 991.98px) {
  [data-pagina^="crm"], [data-pagina="separacao_faturamento"][data-tela="programacao"] { --crm-respiro-x: .8rem; }
}
/* A régua vale para TODO o CRM (pedido do dono, 25/08/2026): o recuo do
   .content sai da frente e cada página CRM respira pela variável. O funil
   e o negócio têm regra própria (abaixo, na seção de altura cheia). */
.content:has(> .page[data-pagina^="crm"]) { padding-inline: 0; }
/* A Programação de Faturamento (#323, 09/10/2026) respira pela mesma régua: a página
   herda o `padding: y 0 b` da folha de Pedidos (seção da paleta --pedido-*) e, sem
   esta regra, ficava com 0 px nos lados — 16 px da tabela embaixo da barra lateral. */
.content > .page[data-pagina^="crm"],
.content > .page[data-pagina="separacao_faturamento"][data-tela="programacao"] {
  padding-inline: var(--crm-respiro-x, var(--content-pad-x)); }
/* Montando a proposta, o acompanhamento sai: a tabela de itens é a superfície
   de trabalho e ganha a tela inteira. A conversa com o cliente volta a
   importar antes (prospecção) e depois (proposta pronta) — durante, ela só
   estreita a coluna em que se digita. */
[data-pagina="crm-deal"] .crm-corpo--montando { grid-template-columns: minmax(0, 1fr); }
[data-pagina="crm-deal"] .crm-corpo--montando .crm-trilho { display: none; }
@media (max-width: 991.98px) {
  [data-pagina="crm-deal"] .crm-corpo { grid-template-columns: minmax(0, 1fr);
    padding: .8rem; gap: .8rem; }
}
/* Acompanhamento: superfície própria, cabeçalho que não rola e a lista
   rolando por dentro. Antes era texto solto sobre o canvas, ao lado de cards —
   parecia sobra de layout, e a lista empurrava a página inteira. */
[data-pagina="crm-deal"] .crm-trilho { position: sticky; top: 0;
  align-self: stretch; min-height: 0; max-height: 100%;
  display: flex; flex-direction: column;
  background: var(--crm-superficie); border: 1px solid var(--crm-borda);
  border-radius: var(--crm-raio); box-shadow: var(--crm-sombra);
  /* MESMO recuo do `.crm-painel` ao lado. Eram .9rem/1rem contra 1rem/1.15rem:
     dois cartões vizinhos com o texto em alturas e recuos diferentes, o que
     fazia a borda esquerda passear ao descer a tela (medido: 5 valores
     distintos no celular, entre 13px e 30px). */
  padding: 1rem 1.15rem; }
[data-pagina="crm-deal"] .crm-trilho > .crm-linha { flex: 0 0 auto; }
[data-pagina="crm-deal"] .crm-tempo { flex: 1 1 auto; min-height: 0;
  overflow-y: auto; padding-right: .2rem; }
/* Ações da proposta em linha, dentro do card dela. Quebra em duas linhas
   quando não couber. (A fita de revisões morreu: as rodadas vivem na linha
   do tempo, junto das conversas que as provocaram.) */
/* ESCALA DE ESPAÇO DO CRM. Medido em 08/08/2026 na tela do negócio: 12 valores
   distintos de `gap`, e os quatro mais usados eram 6,4px / 4,8px / 11,2px /
   9,6px — decimais de rem escolhidos um a um. Onze deles cabiam na faixa de
   1,6 a 12px, onde a diferença não é perceptível: o espaço deixava de dizer o
   que está junto e o que está separado. Base 4pt; regra nova ou tocada usa
   estes tokens, e a diferença entre dois passos é sempre visível. */
[data-pagina^="crm"] {
  --crm-e1: 4px;    /* dentro de um grupo: botões irmãos, rótulo e valor */
  --crm-e2: 8px;
  --crm-e3: 12px;
  --crm-e4: 16px;   /* entre blocos de um mesmo painel */
  --crm-e5: 24px;   /* entre GRUPOS de intenção diferente */
  --crm-e6: 32px;
}

/* A barra da proposta são dois grupos, e a separação entre eles é a
   informação: o que se faz COM o papel (ler, baixar, mandar) e o que MEXE
   nele. Apertado dentro, generoso entre — 4px contra 24px. Antes eram cinco
   ações a 6,4px umas das outras, uma fileira que no squint virava mancha. */
/* `flex-end` para a fileira que QUEBRA continuar encostada à direita: sem
   isto o segundo grupo caía na linha de baixo alinhado à esquerda, e os dois
   blocos de ação deixavam de se ler como um bloco só. */
[data-pagina="crm-deal"] .crm-proposta-acoes { flex-wrap: wrap;
  justify-content: flex-end; gap: var(--crm-e3) var(--crm-e5); }
[data-pagina="crm-deal"] .crm-acoes-grupo { display: inline-flex;
  align-items: center; flex-wrap: wrap; gap: var(--crm-e1); }
/* Grupo cujos botões estão todos escondidos (a sessão de edição esconde as
   ações do documento) não deixa um vão de 24px para trás. */
[data-pagina="crm-deal"] .crm-acoes-grupo:not(:has(> :not(.crm-oculto))) {
  display: none; }
@media (max-width: 991.98px) {
  [data-pagina="crm-deal"] .crm-trilho { position: static; }
}

/* ações da proposta no trilho: lista quieta */
/* próximo passo: a única superfície tingida */
[data-pagina="crm-deal"] .crm-passo { background: var(--crm-acento-fundo);
  border: 1px solid #d3e2d9; border-radius: var(--crm-raio);
  padding: .55rem .9rem; display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem 1rem; margin-bottom: 1rem; }
[data-pagina="crm-deal"] .crm-passo__etiqueta { font-size: var(--fonte-rotulo);
  font-weight: 500; color: var(--crm-acento); text-transform: uppercase;
  letter-spacing: .08em; flex: none; }
[data-pagina="crm-deal"] .crm-passo__texto { flex: 1 1 14rem; font-size: var(--fonte-corpo);
  color: var(--crm-tinta); }
/* Silêncio que passou do limiar: a faixa troca de tom. Verde é "está tudo no
   trilho"; aqui não está — a proposta está parada na mão do cliente. */
[data-pagina="crm-deal"] .crm-passo[data-cobrando] { background: var(--crm-mal-fundo);
  border-color: color-mix(in srgb, var(--crm-mal) 25%, #fff); }

/* A rodada da negociação tem PESO na linha do tempo: é o marco que passa a
   bola. Conversa é texto corrido; rodada é linha com valor e PDF. */
[data-pagina="crm-deal"] .crm-tempo__rodada { display: flex; align-items: center;
  flex-wrap: wrap; gap: .3rem .6rem; margin: .1rem 0 .2rem; }
[data-pagina="crm-deal"] .crm-tempo--rodada .crm-tempo__no {
  background: var(--crm-acento); box-shadow: 0 0 0 3px var(--crm-acento-fundo); }

/* tabela de itens */
.crm-tabela { width: 100%; border-collapse: collapse; }
.crm-tabela th { font-size: var(--fonte-rotulo); font-weight: 500; color: var(--crm-tinta-3);
  text-transform: uppercase; letter-spacing: .1em; text-align: left;
  padding: .5rem .75rem; border-bottom: 1px solid var(--crm-borda); }
.crm-tabela td { padding: .7rem .75rem; border-bottom: 1px solid var(--crm-borda);
  vertical-align: top; font-size: var(--fonte-corpo); }
.crm-tabela tbody tr:last-child td { border-bottom: 0; }
.crm-tabela .num { text-align: right; font-variant-numeric: tabular-nums; }
/* #335: itens orçados da proposta — uma linha, o resto na dica (title). */
.crm-tabela td[data-itens] { cursor: help; }
.crm-tabela .fc-itens { display: flex; gap: .3rem; max-width: 22rem; white-space: nowrap; }
.crm-tabela .fc-itens__primeiro { min-width: 0; }
.crm-tabela .fc-itens__mais { flex: none; color: var(--crm-tinta-3); }
/* Colunas NUMÉRICAS não precisam do mesmo respiro horizontal do texto
   (passe de compacidade, 28/08/2026) — "1,5%" e "R$ 7,49" não têm com o que
   colidir de perto. Menos padding aqui é o que sobra para a tabela caber em
   1366px sem rolagem interna. */
[data-pagina="crm-deal"] .crm-tabela .num { padding-inline: .4rem; }
.crm-tabela .num .form-control, .crm-tabela .num .form-select {
  max-width: 7.5rem; margin-left: auto; }
/* O select de tabela não tem mais largura própria (decisão do dono, 10/08):
   vale a mesma dos outros campos da linha, os 7,5rem da regra acima. A opção
   fechada foi encurtada para caber nela — "0421 · R$ 7,49" em vez do rótulo
   inteiro do backend, que vive no `title` e na lista aberta. */
.crm-tabela tfoot td { border-top: 1px solid var(--crm-borda-forte);
  border-bottom: 0; font-variant-numeric: tabular-nums; }
/* A EMBALAGEM É COLUNA, como qualquer outro dado do item. Foi, nesta ordem:
   um balão tingido sobre a tabela (campos sem cabeçalho, era preciso
   reaprender o que era cada um), uma segunda <tr> alinhada coluna a coluna,
   e uma célula única entre Preço e Total — três formas de esconder três
   campos atrás de um gesto. Em 10/08 o dono decidiu o fim do gesto: três
   colunas fixas depois do Preço, vazias quando o item não se embala. Sem
   fundo tingido e sem borda própria: a coluna já é o que separa, e o
   cabeçalho já é o que nomeia. */

/* timeline com fio: o fio nasce no marcador e vai até o próximo, e a última
   entrada não puxa fio para o vazio. */
.crm-tempo { list-style: none; margin: 0; padding: 0; }
/* RITMO DA LINHA DO TEMPO. Toda entrada tinha o mesmo padding e o mesmo nó: no
   teste de squint a coluna era uma escada uniforme, e "Rodada 1 · R$ 22.198,75
   · entregue ao cliente" pesava exatamente o mesmo que "Descarga: vazio → Não
   se aplica". Medido no negócio 27: 12 de 12 entradas automáticas, sete delas
   no MESMO segundo (um Salvar do painel de detalhes). O que aconteceu de
   verdade ganha ar e nó cheio; o diff de campo encolhe e clareia. */
.crm-tempo > li { display: grid; grid-template-columns: .55rem 1fr;
  gap: var(--crm-e2); padding-bottom: var(--crm-e4); position: relative; }
.crm-tempo > li.crm-tempo--auto { padding-bottom: var(--crm-e2); }
.crm-tempo > li.crm-tempo--auto .crm-tempo__texto { color: var(--crm-tinta-2); }
.crm-tempo > li.crm-tempo--auto .crm-tempo__no { width: .35rem; height: .35rem;
  margin-top: .5rem; border-width: 1px; }
/* O ar entra ANTES do que interrompe a sequência de automáticos: é ali que a
   história volta a ser de gente. */
.crm-tempo > li.crm-tempo--auto + li:not(.crm-tempo--auto) {
  padding-top: var(--crm-e3); }
/* O resumo do gesto: a linha diz quantos campos mudaram e o diff abre por
   baixo. `<details>` nativo — não há estado a guardar nem JS a escrever. */
/* padding-block: 21px de altura ficava abaixo do piso de 24px do WCAG 2.5.8
   (AA) — o único alvo da tela fora da régua. */
[data-pagina="crm-deal"] .crm-tempo__detalhe > summary { font-size: var(--fonte-corpo); cursor: pointer;
  color: var(--crm-tinta-2); list-style: none; padding-block: 2px;
  display: flex; align-items: center; gap: .35rem; }
/* O marcador do navegador ficava pendurado para fora, cortado pela linha do
   tempo; o `.drill-plus` canônico entra no fluxo da frase. */
.crm-tempo__detalhe > summary::-webkit-details-marker { display: none; }
.crm-tempo__detalhe > summary:hover { color: var(--crm-tinta); }
.crm-tempo__detalhe > summary:focus-visible { outline: 2px solid var(--crm-acento);
  outline-offset: 2px; border-radius: 3px; }
.crm-tempo__detalhe > ul { margin: var(--crm-e1) 0 0; padding-left: var(--crm-e4);
  font-size: var(--fonte-corpo); color: var(--crm-tinta-2); }
.crm-tempo__detalhe > ul > li { margin-top: 2px; }
.crm-tempo > li:not(:last-child)::before { content: ''; position: absolute;
  left: calc(.275rem - .5px); top: 1.05rem; bottom: -.05rem; width: 1px;
  background: var(--crm-borda); }
.crm-tempo > li.crm-tempo--solto { display: block; }
.crm-tempo > li.crm-tempo--solto::before { display: none; }
.crm-tempo .crm-tempo__no { width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--crm-superficie); border: 2px solid var(--crm-borda-forte);
  margin-top: .42rem; box-sizing: border-box; }
/* Compromisso futuro é o único cheio: ele é o que ainda pede ação. */
.crm-tempo > li.crm-tempo--futuro .crm-tempo__no { background: var(--crm-acento);
  border-color: var(--crm-acento); }
.crm-tempo .crm-tempo__quando { font-size: var(--fonte-pequena); font-weight: 500;
  color: var(--crm-tinta-3); }
.crm-tempo .crm-tempo__texto { font-size: var(--fonte-corpo); margin-top: .05rem; }
.crm-tempo .crm-tempo__quem { font-size: var(--fonte-pequena); color: var(--crm-tinta-3);
  margin-top: .1rem; }

.crm-selo--acervo { background: var(--crm-superficie-2, #f1f3f5);
  color: var(--crm-tinta-2); border: 1px solid var(--crm-borda); }

/* Anexos da conversa (registrar contato). Duas telas os desenham — a linha do
   tempo do negócio e o histórico do cliente — com o mesmo HTML, por isso a
   regra não é escopada por página. O tocador de áudio fica estreito de
   propósito: é um anexo dentro de uma linha, não o assunto dela. */
.crm-tempo__anexos { display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem .5rem; margin-top: .35rem; }
.crm-anexo { display: inline-flex; align-items: center; gap: .35rem;
  max-width: 100%; padding: .18rem .5rem; border: 1px solid var(--crm-borda);
  border-radius: var(--raio-chip); background: var(--crm-superficie-2, #f8f9fa);
  font-size: var(--fonte-pequena); color: var(--crm-tinta-2);
  text-decoration: none; }
.crm-anexo:hover { border-color: var(--crm-acento); color: var(--crm-tinta); }
/* O nome corta com reticências; o title completo fica no atributo. Sem isto um
   arquivo de 184 caracteres (existem, vieram do Ploomes) empurra a linha. */
.crm-anexo__nome { max-width: 16rem;
 }
.crm-anexo-audio { max-width: 20rem; width: 100%; height: 2rem; }

/* rodapé de decisão grudado */
[data-pagina="crm-deal"] .crm-rodape { position: sticky; bottom: 0; z-index: 20;
  background: var(--crm-superficie); border-top: 1px solid var(--crm-borda);
  padding-block: .7rem; display: flex; flex-wrap: wrap; align-items: center;
  gap: .6rem 1rem; }
[data-pagina="crm-deal"] .crm-rodape__acoes { margin-left: auto; display: flex;
  flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: .5rem; }
/* avisos moram no rodapé, na linha acima dos botões; vazio não ocupa linha */
[data-pagina="crm-deal"] .crm-rodape__avisos { flex: 1 1 100%; }
[data-pagina="crm-deal"] .crm-rodape__avisos:empty { display: none; }
[data-pagina="crm-deal"] .crm-rodape__avisos .crm-aviso { margin-bottom: .35rem; }

/* A barra é a ÚNICA superfície de ação da tela desde 11/08 — dez botões onde
   antes havia quatro grupos espalhados por quatro bordas. Sem menu "mais":
   decisão do dono, tudo à mostra. Para caber numa fileira a 1366 (a resolução
   real da frota) os botões daqui vão SEM ícone. O ícone valia ~20px por botão e não dizia nada que o
   rótulo já não diga — um lápis ao lado de "Editar proposta" é decoração com
   custo de largura. Ícone SEM rótulo seria o anti-referente nº 1 do produto
   (ERP legado); não é o caso aqui, os rótulos ficam. */
[data-pagina="crm-deal"] .crm-rodape__acoes .fa-solid,
[data-pagina="crm-deal"] .crm-rodape__acoes .fa-regular { display: none; }

/* A barra é grudada, então ela COBRE o fim da página — o acompanhamento
   ficava debaixo dela numa tela de 768px de altura, e tabular até lá levava o
   foco para fora de vista. O respiro é do tamanho dela. */
[data-pagina="crm-deal"] .crm-corpo { padding-bottom: 3.5rem; }

/* --- avisos --- */
.crm-aviso { background: var(--crm-superficie); border: 1px solid var(--crm-borda);
  border-radius: 8px; padding: .65rem .9rem; font-size: var(--fonte-corpo);
  display: flex; gap: .6rem; align-items: flex-start; margin-bottom: .75rem; }
.crm-aviso--ok   { border-color: #b7e2c5; background: var(--crm-ok-fundo); }
.crm-aviso--avi  { border-color: #f0d9a7; background: var(--crm-avi-fundo); }
.crm-aviso--erro { border-color: #f2c6c0; background: var(--crm-mal-fundo); }
/* Faixa do negócio ganho (#273): colunas rótulo/valor; escopo da ficha. */
[data-pagina="crm-deal"] .crm-faixa-pedido__colunas { display: flex; flex-wrap: wrap;
  align-items: flex-end; column-gap: 2rem; row-gap: .4rem; }
[data-pagina="crm-deal"] .crm-faixa-pedido__coluna { display: flex; flex-direction: column; }
/* O "ruim" da paleta do CRM (`--crm-mal`, alias do global `--negative-text`), sem cor fixa. */
[data-pagina="crm-deal"] .crm-faixa-pedido__atrasada { color: var(--crm-mal); font-weight: 500; }

/* Toast flutuante com "Desfazer" (reporte #146, excluir conversa): vive FORA
   da lista que `crm:conversa-alterada` redesenha — a lista some/recarrega, o
   toast (e o botão de desfazer) precisa sobreviver a isso. `position: fixed`
   de propósito: `conversa.js` é compartilhado por ficha e canvas, e nenhum
   dos dois tem uma área de aviso própria que o outro também alcance. */
.crm-toast-desfazer { position: fixed; bottom: 1.25rem; left: 50%; transform: translateX(-50%);
  z-index: 1080; box-shadow: var(--crm-sombra-2); max-width: 26rem; margin: 0; }

/* --- estados vazios --- */
.crm-vazio { color: var(--crm-tinta-3); font-size: var(--fonte-corpo); padding: 1.2rem .5rem; }

/* --- listas de sugestão (autocomplete) --- */
[data-pagina="crm"] .crm-lista, [data-pagina="crm-deal"] .crm-lista {
  background: var(--crm-superficie); border: 1px solid var(--crm-borda);
  border-radius: 10px; box-shadow: var(--crm-sombra-2); overflow: hidden;
  overflow-y: auto; }
[data-pagina="crm"] .crm-lista__item, [data-pagina="crm-deal"] .crm-lista__item {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  border-bottom: 1px solid var(--crm-borda); padding: .6rem .85rem;
  font-size: var(--fonte-corpo); color: var(--crm-tinta); cursor: pointer; }
[data-pagina="crm"] .crm-lista__item:last-child,
[data-pagina="crm-deal"] .crm-lista__item:last-child { border-bottom: 0; }
[data-pagina="crm"] .crm-lista__item:hover,
[data-pagina="crm"] .crm-lista__item:focus,
[data-pagina="crm-deal"] .crm-lista__item:hover,
[data-pagina="crm-deal"] .crm-lista__item:focus { background: var(--crm-fundo); }
[data-pagina="crm"] .crm-lista--flutua, [data-pagina="crm-deal"] .crm-lista--flutua {
  position: absolute; left: 0; right: 0; z-index: 1060; max-height: 16rem; }

/* --- offcanvas: painel do sistema ---
   `crm-clientes` entra na lista em 01/09/2026: a lista de clientes/leads
   inclui os MESMOS canvas (ficha, histórico, documentos, negócios) desde
   26/08, e sem esta linha eles caíam no padding padrão do Bootstrap — a mesma
   ficha tinha margem diferente conforme a tela de onde era aberta. Por
   IGUALDADE e nunca por prefixo, como o resto do skin do CRM (ver o incidente
   em `bi/templates/bi/crm_produtividade.html`). */
[data-pagina="crm"] .offcanvas, [data-pagina="crm-deal"] .offcanvas,
[data-pagina="crm-clientes"] .offcanvas {
  border-left: 0; box-shadow: -12px 0 48px rgba(26, 26, 30, .16); }
[data-pagina="crm"] .offcanvas-header, [data-pagina="crm-deal"] .offcanvas-header,
[data-pagina="crm-clientes"] .offcanvas-header {
  padding: 1rem 1.25rem; }
[data-pagina="crm"] .offcanvas-body, [data-pagina="crm-deal"] .offcanvas-body,
[data-pagina="crm-clientes"] .offcanvas-body {
  padding: 1rem 1.25rem; }
[data-pagina="crm"] .crm-oc-rodape, [data-pagina="crm-deal"] .crm-oc-rodape,
[data-pagina="crm-clientes"] .crm-oc-rodape {
  display: flex; gap: .6rem; padding: .9rem 1.25rem;
  border-top: 1px solid var(--crm-borda); }
[data-pagina="crm"] .crm-oc-rodape > *, [data-pagina="crm-deal"] .crm-oc-rodape > *,
[data-pagina="crm-clientes"] .crm-oc-rodape > * {
  flex: 1 1 0; }

/* --- toque e movimento --- */
@media (pointer: coarse) {
  [data-pagina="crm"] .form-control, [data-pagina="crm"] .form-select,
  [data-pagina="crm-deal"] .form-control, [data-pagina="crm-deal"] .form-select {
    min-height: 2.75rem; }
}
@media (prefers-reduced-motion: reduce) {
  [data-pagina="crm"] *, [data-pagina="crm-deal"] * { transition: none !important; }
}

/* colunas de apoio da tabela: somem em telas menores */
@media (max-width: 767.98px) {
  [data-pagina="crm-deal"] .crm-col-md { display: none; }
}
@media (max-width: 991.98px) {
  [data-pagina="crm-deal"] .crm-col-lg { display: none; }
}
/* As três colunas de embalagem somem quando NENHUM item da proposta tem
   embalagem preenchida (decisão do dono, 11/08/2026) — 685 dos 740 produtos
   do catálogo não se embalam, e a maioria das propostas oferecia três
   colunas em branco. Quem decide o fato é o backend
   (`tem_item_com_embalagem`, `crm.py` `_serializar_proposta`); a classe
   `.crm-sem-embalagem` na tabela é aplicada por `renderItens` (itens.js),
   já combinada com o estado de EDIÇÃO — em edição ela nunca entra, porque
   escondê-las ali impediria preencher a embalagem pela primeira vez. Sem
   `@media` aqui de propósito: a regra vale em qualquer largura, inclusive
   no cartão do celular — três classes (id + duas classes) para vencer o
   `#dl-itens td { display: flex }` genérico do cartão (uma classe a menos:
   já aconteceu nesta tela uma regra mais fraca perder por engano). */
[data-pagina="crm-deal"] #dl-itens.crm-sem-embalagem .crm-col-embalagem { display: none; }
[data-pagina="crm-deal"] .crm-tabela .num .form-control { text-align: right; }
/* Sem `min-width` aqui, `table-layout:auto` (herdado) redistribui a coluna
   pelo que sobra: fechada a embalagem ela cabe folgada, mas assim que o
   bloco abre (nova coluna ao lado pedindo espaço) o navegador reduz esta
   coluna e "Tabela 0002 · 5,30" volta a cortar em "5…" — medido ao vivo, o
   max-width do select (acima) não segura sozinho quando outra coluna
   disputa a MESMA largura total da tabela. */
/* A coluna acompanha o campo (11/08/2026): com o seletor em 19ch, os 13rem de
   antes deixavam ~60px de sobra à direita do campo, e a coluna larga com o
   campo estreito dentro é o mesmo desalinho que os 13rem tinham vindo
   corrigir, invertido. 10,5rem = o campo mais o respiro da célula. */
[data-pagina="crm-deal"] .crm-tabela .crm-col-lg { min-width: 10.5rem; }
/* O seletor cabe o par que IDENTIFICA a tabela — código e preço —, não o
   rótulo inteiro (decisão do dono, 11/08/2026, revendo o "ocupa a coluna
   inteira" de 10/08). Medido: com o nome dentro, o campo abria 447px e a
   coluna crescia atrás dele. Os 19ch somam "0002 · R$ 7,49" mais a seta.
   O nome não se perde: a lista ABERTA se dimensiona pelo conteúdo, e cada
   opção leva `title` com a frase inteira. */
[data-pagina="crm-deal"] .crm-tabela .num .crm-tabela-item { max-width: 19ch; }
/* Alinhar o que NÃO é campo com o texto de quem é. Duas tentativas:
   `vertical-align: middle` na célula centrava tudo — e aí a célula que
   ganha um comentário embaixo (o delta do preço base, a conversão da
   embalagem) fica mais alta, o meio dela sobe, e o campo daquela coluna
   descola dos vizinhos. O comentário é EVENTUAL; o desalinho que ele
   causava, não.
   Então: célula alinhada pelo TOPO (o comentário cresce para baixo, sem
   mexer em nada) e o valor desce os 7px que põem sua linha de texto na
   mesma altura do texto dentro do campo — 35px de campo centram o texto
   em 17,5px; 21px de pílula centram em 10,5px; a diferença é a margem.
   Só em edição: os `data-previa-*` não existem fora dela, e sem campo ao
   lado não há com o que alinhar. */
[data-pagina="crm-deal"] #dl-itens tbody [data-previa-estoque],
[data-pagina="crm-deal"] #dl-itens tbody [data-previa-total],
[data-pagina="crm-deal"] #dl-itens tbody [data-remover] { margin-top: .45rem; }
[data-pagina="crm-deal"] #dl-itens tbody [data-previa-estoque],
[data-pagina="crm-deal"] #dl-itens tbody [data-previa-total] {
  display: inline-block; }

/* ------------------------------------------------------------
   TELEFONE — densidade: sem altura mínima fantasma no funil,
   capa do deal em grade compacta, stepper enxuto, trilho da
   proposta DEPOIS do trabalho principal.
   ------------------------------------------------------------ */
@media (max-width: 767.98px) {
  /* funil: a laje encolhe até o conteúdo — nada de ar fantasma */
  [data-pagina="crm"] .crm-coluna { min-height: 0; }
  [data-pagina="crm"] .crm-raia__cabo { padding: .55rem .6rem; }

  /* capa do deal: as colunas do Bootstrap já empilham (col-12); aqui só a
     densidade — e os dois botões de editar dividem a linha em vez de sair
     pela borda. */
  [data-pagina="crm-deal"] .crm-capa { padding: .7rem .8rem .6rem; }
  [data-pagina="crm-deal"] .crm-capa .row > .col-auto:last-child { flex: 1 1 100%; }
  [data-pagina="crm-deal"] .crm-capa .row > .col-auto:last-child > .btn {
    flex: 1 1 0; justify-content: center; }
  [data-pagina="crm-deal"] .crm-conta-nome { font-size: 1rem; }

  /* O roteiro tinha ficado de fora: seguia com o recuo de desktop (20px)
     enquanto capa, etapas, corpo e rodapé encolhiam para 12,8px — era ele o
     degrau que sobrava na borda esquerda ao rolar a tela. */
  [data-pagina="crm-deal"] .crm-roteiro { padding-inline: .8rem; }

  /* corpo: trabalho primeiro, trilho da proposta depois */
  [data-pagina="crm-deal"] .crm-corpo { padding: .8rem; gap: .8rem; }
  [data-pagina="crm-deal"] .crm-trilho { order: 2; padding: .85rem .8rem; }
  [data-pagina="crm-deal"] .crm-painel { padding: .85rem .8rem; }
  [data-pagina="crm-deal"] .crm-rodape { padding: .6rem .8rem; }

  /* iOS: input com fonte < 16px dispara ZOOM automático ao focar — o
     zoom desloca o rodapé sticky pro meio da tela e o conteúdo vaza
     por trás. 1rem = 16px mata o zoom na raiz. */
  [data-pagina="crm"] .form-control, [data-pagina="crm"] .form-select,
  [data-pagina="crm-deal"] .form-control, [data-pagina="crm-deal"] .form-select {
    font-size: 1rem; }

  /* tabela de itens: células e inputs mais enxutos pro TOTAL caber */
  [data-pagina="crm-deal"] .crm-tabela th { padding: .45rem .3rem; }
  [data-pagina="crm-deal"] .crm-tabela td { padding: .55rem .3rem;
    font-size: var(--bi-fs-compact); }
  [data-pagina="crm-deal"] .crm-tabela td:empty { padding: 0; }
  [data-pagina="crm-deal"] .crm-tabela .num .form-control,
  [data-pagina="crm-deal"] .crm-tabela .num .form-select { max-width: 5.4rem; }
  /* descrição do produto não vira parágrafo: 2 linhas e reticências */

  /* teclado aberto (edição de item) esconde o rodapé de decisão —
     classe posta pelo JS no focusin/focusout da tabela */
  [data-pagina="crm-deal"] .crm-rodape--editando { display: none; }

  /* Rodapé de decisão no telefone: FIXO, não sticky. O sticky depende da
     altura do container, e no Safari do iPhone essa altura muda quando a
     barra de URL recolhe — o banner "descolava" e ficava no meio da rolagem.
     Fixo + safe-area encosta na borda de baixo sempre; a página ganha um
     colchão do mesmo tamanho pra última linha não ficar por baixo dele. */
  [data-pagina="crm-deal"] .crm-rodape {
    position: fixed; left: 0; right: 0; bottom: 0;
    padding-bottom: calc(.6rem + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -1px 12px rgba(23, 26, 24, .1); }
  [data-pagina="crm-deal"] .crm-pagina {
    padding-bottom: calc(7rem + env(safe-area-inset-bottom, 0px)); }
  /* a faixa de confirmação toma o lugar do rodapé — mesma âncora */
  [data-pagina="crm-deal"] #dl-confirmacao { align-items: flex-start; }
  [data-pagina="crm-deal"] #dl-confirmacao .crm-rodape__acoes { width: 100%; }
  [data-pagina="crm-deal"] #dl-confirmacao .crm-rodape__acoes > * { flex: 1 1 0; }

  /* no telefone o painel é folha de tela cheia */
  [data-pagina="crm"] .offcanvas, [data-pagina="crm-deal"] .offcanvas {
    --bs-offcanvas-width: 100%; }
}

/* #427, #524: tempo calculado de separação e transporte ("Separar material em"), componente comum do
   negócio do CRM e da Proposta nova do portal — o aviso (separação hoje ou no passado) é texto de
   atenção, nunca âmbar. */
.previa-separacao__aviso { color: var(--warning-text); }

/* OFFCANVAS FECHADO NÃO PODE FICAR ESTACIONADO FORA DA TELA (toque).
   O Bootstrap guarda o painel com `translateX(100%)`: um box da largura
   da tela parado logo à direita dela. O Safari do iPhone/iPad conta esse
   box na largura do conteúdo ao calcular a escala INICIAL — a página abre
   com zoom-out e aceita arrastar de lado. (No Chromium o `overflow-x:
   clip` do html mascara o sintoma, por isso não aparecia nas medições.)
   Até 1199px o painel não usa transform: aparece e some por opacidade.
   No desktop (≥1200px, sem escala automática) o slide lateral fica. */
@media (max-width: 1199.98px) {
  [data-pagina="crm"] .offcanvas, [data-pagina="crm-deal"] .offcanvas {
    transform: none !important;
    transition: opacity .2s ease; opacity: 1; }
  [data-pagina="crm"] .offcanvas:not(.show):not(.showing),
  [data-pagina="crm-deal"] .offcanvas:not(.show):not(.showing) { opacity: 0; }
}

/* deal frio: parado na etapa acima do limiar (classificado no backend) —
   o card inteiro esquenta pro âmbar, escaneável descendo a raia */
[data-pagina="crm"] .crm-cartao--frio { border-color: #ecc94b66;
  background: #fffdf4; }
[data-pagina="crm"] .crm-cartao--frio .crm-cartao__rodape {
  border-top-color: #f0e6c0; }

/* ------------------------------------------------------------
   NOTEBOOK DE 1366×768 — a tela real do comercial.
   Medido em 10/08/2026 no negócio 27, nessa viewport: 462px de altura
   consumidos ANTES da primeira linha de item (60% da tela) e a tabela
   vazando 327px pela direita, com "Total" e "Ações" fora da janela. Dois
   itens visíveis em leitura, 1,4 em edição — e a linha de item medindo
   166px, das quais a maior parte era texto quebrando em coluna estreita.

   O que se resolve aqui é ALTURA e LARGURA ao mesmo tempo, e por deleção
   antes de encolhimento: a faixa de etapas saiu (template), os rótulos da
   capa saíram (JS) e o trilho de acompanhamento desce em vez de disputar a
   largura. O que sobra é densidade — um passo, não uma tela em miniatura.
   ------------------------------------------------------------ */

/* --- 1. O trilho DESCE, não some (≤ 1600px) ---
   Em leitura o acompanhamento ocupava 400px de largura à esquerda: exatamente
   o que a tabela vazava pela direita. Ele é CONTEXTO e a proposta é o
   trabalho, então abaixo do desktop largo ele vai para depois — o mesmo
   movimento que o telefone já fazia (`order: 2`), agora começando onde a
   disputa começa. Nada é escondido: rolar o corpo continua chegando nele. */
@media (max-width: 1600px) {
  [data-pagina="crm-deal"] .crm-corpo { grid-template-columns: minmax(0, 1fr); }
  [data-pagina="crm-deal"] .crm-trilho { order: 2; position: static;
    max-height: 32rem;
    /* `stretch` (herdado do modo lado a lado) numa linha de grade só dele:
       a linha media o trilho pelo mínimo da lista (`min-height: 0` +
       overflow), e o acompanhamento nascia com 31px e rolagem interna —
       uma entrada visível (medido no negócio 27 a 1600px). `start` deixa o
       trilho medir o conteúdo até os 32rem. */
    align-self: start; }
}

/* --- 2. Densidade: um passo, dentro do CRM só ---
   `[data-pagina^="crm"]` cobre funil e negócio e nada mais: `custom.css` é
   lido por ~28 páginas, e mexer em token global vazaria no app inteiro. */
@media (max-width: 1600px) {
  [data-pagina^="crm"] .crm-capa { padding-block: .55rem; }
  [data-pagina^="crm"] .crm-painel { padding: .8rem .9rem; }
  /* Denso na VERTICAL; na horizontal vale a régua de respiro (o fallback
     .8rem cobre o funil, que não declara a variável). */
  [data-pagina^="crm"] .crm-corpo {
    padding: .8rem var(--crm-respiro-x, .8rem); gap: .8rem; }
  [data-pagina^="crm"] .crm-rodape { padding-block: .5rem; }
}

/* --- 3. A tabela de itens tem largura DECLARADA ---
   Mesma disciplina do documento em PDF (`.prop-tabela`), pelo mesmo motivo:
   com `layout: auto` a pílula de estoque ("591.834,215 KG") e o seletor de
   tabela puxavam a largura, e sobravam 95px para o nome do produto — que é o
   que se lê. Cada número abaixo foi conferido contra conteúdo real na tela,
   não estimado.

   REFEITO em 21/08/2026, com a coluna da COMISSÃO: as larguras são declaradas
   por POSIÇÃO, então a coluna nova empurrou todas as seguintes uma casa e o
   TOTAL — a última com largura declarada — ficou sem nenhuma e colapsou para
   zero em 1366×768. Medido: a tabela pedia 1.263px numa faixa de 1.236px. Os
   6rem da comissão foram tirados de onde havia gordura, e o Produto encolheu
   por decisão do dono (o nome longo agora corta com reticências, e a frase
   inteira fica no `title`). Somam 76,25rem = 1.220px — e a
   régua é a CASCA que rola (1.222px), não a tabela: 1.228px cabiam na tabela
   e ainda assim acendiam a barra de rolagem do contêiner por 6px. */
/* REFEITO em 28/08/2026: as três colunas de embalagem (posições 8-10)
   viraram UMA (posição 8) — o TOTAL e as AÇÕES sobem uma casa cada (9 e
   10/last). Mesma disciplina de sempre: largura por POSIÇÃO, então quem
   mexe na ordem tem que refazer a soma. Embalagem ganha mais espaço que a
   antiga coluna "Tipo" sozinha (agora carrega a frase inteira ou os três
   controles agrupados), e o TOTAL ganha largura DECLARADA pela primeira vez
   — antes ela contava com a sobra, e foi exatamente isso que a fez colapsar
   em 21/08 quando a Comissão entrou. Soma: 73,75rem = 1.180px, contra os
   ~83rem (Total incluso) da versão de 12 colunas — folga de sobra para
   1366px. */
@media (min-width: 992px) and (max-width: 1600px) {
  [data-pagina="crm-deal"] #dl-itens { table-layout: fixed; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(1) { width: 11rem; }
  [data-pagina="crm-deal"] #dl-itens th.crm-col-md { width: 6rem; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(3) { width: 8rem; }
  [data-pagina="crm-deal"] #dl-itens th.crm-col-lg { width: 10.5rem;
    min-width: 0; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(5) { width: 7.5rem; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(6) { width: 6rem; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(7) { width: 6rem; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(8) { width: 9rem; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(9) { width: 7rem; }
  [data-pagina="crm-deal"] #dl-itens th:last-child { width: 2.75rem; }
  [data-pagina="crm-deal"] .crm-tabela th { padding: .4rem .5rem; }
  [data-pagina="crm-deal"] .crm-tabela td { padding: .45rem .5rem; }
  /* "EMBALAGENS" é UMA palavra de 10 letras: a 12px com 1,2px de espaçamento
     ela pede 98px, e a coluna tem 80. Palavra não quebra — ela vazava por
     cima da vizinha ("EMBALAGENSEMBALAGEM" na medição de 1366×768). Menos
     corpo e menos espaçamento SÓ nesta faixa: o cabeçalho continua em caixa
     alta, e passa a caber. */
  [data-pagina="crm-deal"] .crm-tabela th { letter-spacing: .04em; }

  /* `layout: fixed` NÃO recorta: conteúdo maior que a coluna declarada vaza
     POR CIMA da vizinha em vez de alargá-la, e foi o que aconteceu na
     primeira medição — o "KG" ao lado da quantidade caía dentro do seletor de
     tabela, e o do volume por cima do total. Com `auto` esse mesmo excesso
     roubava a largura do nome do produto; o vazamento é o preço de declarar
     largura, e quem o paga é esta regra. Cada filho da célula fica preso à
     célula, e o campo ENCOLHE em vez de empurrar o sufixo para fora. */
  [data-pagina="crm-deal"] #dl-itens td > * { max-width: 100%; }
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un { max-width: 100%; }
  /* `min-width: 0` é o que permite encolher: sem ele o `flex` respeita a
     largura mínima do conteúdo do input e o encolhimento não acontece. */
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un > .form-control {
    width: auto; flex: 1 1 auto; min-width: 0; }
  /* A UNIDADE não encolhe: quem cede espaço é o campo. Deixada com o
     `flex-shrink` padrão ela virava "K" em vez de "KG" — e uma unidade pela
     metade ao lado de "3.000" é pior que o vazamento que a regra acima
     consertou: dá para ler 3.000 K como outra coisa. */
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un > .crm-rotulo {
    flex: 0 0 auto; }
  [data-pagina="crm-deal"] #dl-itens [data-previa-conversao],
  [data-pagina="crm-deal"] #dl-itens [data-previa-delta] { max-width: 100%; }
}

/* --- 3-b. ACIMA de 1600px a mesma disciplina, em PROPORÇÃO ---
   O bloco acima parava em 1600px, e daí para cima a tabela voltava ao
   `layout: auto` SEM largura declarada: bastava uma frase longa numa célula —
   a conversão da embalagem, "5.000 KG = 1 bobina × 5.000 KG · R$ 27.500,00 por
   bobina" — para ela pedir mais que o contêiner e acender barra de rolagem
   horizontal num monitor grande, com a coluna TOTAL cortada (defeito relatado
   pelo dono, 25/08/2026).
   Aqui a largura é PERCENTUAL, não rem: o espaço extra do monitor se reparte
   entre as colunas em vez de sobrar para uma frase esticar. As proporções são
   as mesmas que os rem do bloco anterior produzem a 1366 (medidas na tela,
   somam 100%). Abaixo de 1601px nada muda: lá o problema é caber, e caber
   pede número absoluto.
   REFEITO em 28/08/2026 junto com o bloco de cima: posições 8-10 (as três
   colunas de embalagem) viraram a posição 8 só, com mais % que a antiga
   "Tipo" sozinha; Total e Ações sobem para 9 e 10/last, com Total ganhando
   % DECLARADA (não sobra) pela mesma razão do bloco anterior. Soma
   continua 100%. */
@media (min-width: 1601px) {
  [data-pagina="crm-deal"] #dl-itens { table-layout: fixed; width: 100%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(1) { width: 13%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(2) { width: 7%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(3) { width: 9.5%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(4) { width: 12.5%; min-width: 0; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(5) { width: 9%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(6) { width: 7%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(7) { width: 7%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(8) { width: 20%; }
  [data-pagina="crm-deal"] #dl-itens th:nth-child(9) { width: 11%; }
  [data-pagina="crm-deal"] #dl-itens th:last-child { width: 4%; }
}

/* As regras de CONTENÇÃO valem de 992px para cima, nas duas faixas: é
   `table-layout: fixed` que as exige (conteúdo maior que a coluna vaza por
   cima da vizinha em vez de alargá-la), e agora as duas faixas o usam. Estavam
   presas ao bloco de 992–1600 e, acima de 1600, a frase da conversão saía sem
   freio. */
@media (min-width: 992px) {
  /* A coluna de AÇÕES não se esconde atrás da rolagem: na faixa de rem
     (992–1600) a tabela em edição estoura o contêiner (23px a 1366, 189px a
     1200 — foi assim que o zoom negativo da Letícia sumiu com o X de
     remover) e a última coluna ia junto. Sticky na borda direita: visível
     em qualquer largura efetiva, com ou sem rolagem. */
  [data-pagina="crm-deal"] #dl-itens th:last-child,
  [data-pagina="crm-deal"] #dl-itens td:last-child {
    position: sticky; right: 0; background: #fff; }
  [data-pagina="crm-deal"] #dl-itens td > * { max-width: 100%; }
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un { max-width: 100%; }
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un > .form-control {
    width: auto; flex: 1 1 auto; min-width: 0; }
  [data-pagina="crm-deal"] #dl-itens .crm-campo-un > .crm-rotulo {
    flex: 0 0 auto; }
  [data-pagina="crm-deal"] #dl-itens [data-previa-conversao],
  [data-pagina="crm-deal"] #dl-itens [data-previa-delta] { max-width: 100%; }
}

/* --- 4. A LINHA de item: 166px eram três textos quebrando ---
   Nome do produto em 4 linhas, o gatilho da previsão em 3 e a frase de
   conversão em 5. Nenhum deles precisa de mais de uma ou duas linhas: o que
   não couber vai para o `title`, que é onde texto longo pertence numa
   tabela. Vale em toda largura — o desperdício não era do notebook. */
/* A SEGUNDA LINHA IMAGINÁRIA (pedido do dono, 25/08/2026). As legendas sob os
   campos — referência da tabela, aviso de piso, variação do preço, IPI do
   cadastro, conversão da embalagem — nasciam cada uma colada no próprio
   campo, e como cada célula tem altura própria elas ficavam em alturas
   diferentes: "preço tabela, variação, ipi alinhados no topo, embalagem no
   fundo". Aqui todas viram camadas absolutas ancoradas na MESMA altura
   (`--crm-linha2`), formando uma linha de comentários com as mesmas
   propriedades sob a linha de campos; o `padding-bottom` do td reserva a
   banda que o absoluto não reserva.
   Só na linha EM EDIÇÃO (`tr:has(.form-control)`) e só em tela de tabela:
   em leitura as células são texto de uma linha, e no telefone a linha é um
   cartão empilhado. */
@media (min-width: 992px) {
  [data-pagina="crm-deal"] #dl-itens tbody { --crm-linha2: 3.2rem; }
  /* :not(:last-child): a célula de AÇÕES fica de fora — ela é sticky (regra
     acima) e `position: relative` aqui a soltava da borda, escondendo o X
     de remover atrás da rolagem. Legenda nunca mora nela. */
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) > td:not(:last-child) {
    position: relative; padding-bottom: 2.9rem; }
  /* Cada legenda pelo SEU seletor, nunca um `td > .crm-rotulo` genérico: o
     nome do produto também é `.crm-rotulo` filho de td, e o genérico o
     arrancava para a linha de baixo. O `!important` do margin vence o
     `.mt-1` do wrapper da variação, que também é !important. */
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) [data-previa-ipi-item] > .crm-rotulo,
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) [data-previa-comissao] > .crm-rotulo,
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) > td > [data-previa-delta],
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) > td > [data-previa-aviso],
  [data-pagina="crm-deal"] #dl-itens tbody tr:has(.form-control) [data-previa-tabela] > .crm-rotulo {
    position: absolute; top: var(--crm-linha2); left: .5rem; right: .5rem;
    margin-top: 0 !important; }
  /* A conversão da embalagem CORRIA sob as colunas vizinhas ("Qtd", "Total")
     de propósito (`max-width: 34rem`, sem `right`) — pré-28/08/2026, quando
     elas só tinham conteúdo na primeira linha e a folga era inofensiva. Não
     é mais: a coluna Total ganhou o selo do frete diluído na SEGUNDA linha
     (`itens.js` `badgeComFrete`), e a legenda passava por cima dele (achado
     ao vivo, deal 73, 1500px — 164px de vazamento medidos: legenda indo até
     1443, a própria célula da Embalagem terminando em 1279). `right: .5rem`
     tranca a legenda na SUA célula, como as outras desta banda; o texto que
     não couber corta em reticências (`overflow`/`text-overflow` abaixo). */
  [data-pagina="crm-deal"] #dl-itens [data-previa-conversao] {
    position: absolute; top: var(--crm-linha2); left: .5rem; right: .5rem;
    margin-top: 0; display: block;
 z-index: 1; }
}
@media (min-width: 992px) and (max-width: 1600px) {
  /* Os controles são um degrau mais baixos nesta faixa (min-height 2rem):
     a linha imaginária sobe junto. */
  [data-pagina="crm-deal"] #dl-itens tbody { --crm-linha2: 2.9rem; }
}
/* A LEGENDA DA COLUNA DE EMBALAGEM VOLTA AO FLUXO (01/09/2026).
   A "segunda linha imaginária" acima é `position:absolute`, e para as outras
   colunas ela está certa: elas têm UM controle, e a faixa de baixo está
   livre. Esta coluna não: a embalagem tem três controles e o cento tem dois,
   e em 149px (medidos ao vivo no deal 73 a 1366px) eles não cabem lado a
   lado — quebram, ocupam a segunda faixa, e a legenda absoluta era desenhada
   POR CIMA do segundo campo. Medido: campo em y 495..528, legenda em
   502..520. Estava assim na embalagem antes deste passe ("5.000 KG = 10
   bobinas…" escrito sobre o campo de volumes) e o cento herdaria o mesmo.
   Nenhum teste via — o DOM estava correto; quem mostrou foi a foto.
   Em fluxo normal a legenda desce para depois dos campos. Ela deixa de
   alinhar com as das colunas vizinhas, e é o preço certo a pagar: legenda
   desalinhada se lê, legenda por cima de um campo não.
   E ela QUEBRA em vez de cortar (pedido do dono, 01/09): "5.000 KG = 10
   bobinas × 500 KG · R$ 250.000,0…" com reticências escondia justamente o
   número que a legenda existe para dar. */
[data-pagina="crm-deal"] #dl-itens .crm-col-embalagem [data-previa-conversao] {
  position: static; margin-top: .25rem; white-space: normal;
  overflow: visible; }
/* O seletor de tabela carrega o NOME dela (10/08/2026), e o texto é mais longo
   que a coluna de propósito: quem identifica é o código e o preço, que vêm
   antes, e o nome corta com reticências.
   Fechado, o campo cabe só o par que identifica — "0002 · R$ 7,49" são 15
   caracteres, e os 19ch abaixo somam a seta do `<select>` (decisão do dono,
   11/08/2026: o botão não precisa da largura do nome). O nome inteiro
   continua alcançável de dois jeitos, sem custo de espaço: a lista ABERTA o
   mostra (o popup nativo se dimensiona pelo conteúdo, não pelo campo) e o
   `title` de cada opção entrega a frase inteira ao passar o mouse.
   Tentou-se trocar estas três declarações pelo `.text-truncate` do Bootstrap
   (11/08/2026). Não serve: na legenda existe um `-webkit-line-clamp: 2` logo
   abaixo, e o utility do BS forçaria UMA linha, mudando o que a célula mostra;
   no `<select>` ele não muda nada, porque o widget nativo já elide sozinho. A
   MEDIDA, essa, o BS não tem como expressar — `w-auto` devolve a largura do
   conteúdo, que é exatamente o que se quer evitar aqui. */
[data-pagina="crm-deal"] .crm-tabela-item,
[data-pagina="crm-deal"] .crm-tabela-legenda { max-width: 19ch;
 }

/* A COLUNA DA COMISSÃO NÃO PRECISA DOS 7,5rem dos outros campos da linha: ela
   mostra "1,5%" ou "Outro", nunca uma frase. Medido a 1366×768 com a coluna
   nova (21/08/2026): a tabela somava 1.263px em 1.236px disponíveis, e quem
   colapsava era o TOTAL — 27px de excesso apagavam da tela o número que fecha
   a linha. Estreitar aqui devolve mais do que os 27. */
[data-pagina="crm-deal"] .crm-tabela .num .crm-comissao-item { max-width: 6rem; }

/* E o TOTAL nunca é quem some. Ele não tem largura própria (a tabela reparte o
   que sobra), então qualquer coluna que cresça o espreme primeiro — foi o que
   aconteceu acima. Piso + `nowrap`: se faltar espaço, a tabela rola e as
   colunas de embalagem é que saem da vista, não o valor da linha. */
[data-pagina="crm-deal"] .crm-tabela .crm-col-total { min-width: 7rem; white-space: nowrap; }

/* Selo "R$ X c/ frete" no TOTAL: o `nowrap` que segura o número da linha
   (regra acima) valia por herança para o selo também, e `.crm-pilula` (a
   família toda) já é `nowrap` por padrão. Um valor grande ("R$
   1.291.625,00 c/ frete") é mais largo que os 7rem da coluna declarada, e
   sem quebra o excesso VAZAVA por cima da coluna vizinha (Embalagem, à
   esquerda — `.num` alinha à direita, e o texto que sobra escapa pela
   esquerda da célula). Achado ao vivo no deal 73, 1500px, frete diluído.
   Só este selo quebra linha; as pílulas curtas do resto da tabela (delta,
   estoque) continuam numa linha só. */
[data-pagina="crm-deal"] #dl-itens .crm-pilula--frete { white-space: normal; }

/* O NOME DO PRODUTO QUEBRA EM LINHAS (decisão do dono, 01/09/2026 — reverte a
   de 21/08, que o punha em UMA linha com reticências).
   O motivo de então era altura: "CORDOALHA ENGRAXADA 12,7MM CP-190 RB" em duas
   linhas dobrava a linha inteira da tabela. O que mudou é que o corte passou a
   esconder o que distingue um item do outro — os seis fixadores só se
   diferenciam no fim da descrição ("TCP1 ... (CX C 3000PC)" contra "TCP4 ...
   (CX C 100PC)"), e cortados em 183px medidos a 1366px eles viram a mesma
   linha na tela. Reticências que escondem a diferença entre dois produtos
   custam mais que a altura que economizam. */
[data-pagina="crm-deal"] #dl-itens td .crm-produto-nome {
  display: block; white-space: normal;
  overflow: visible; overflow-wrap: anywhere; }

/* A LINHA DE ADICIONAR PRODUTO não é um formulário — é um convite. Ela ocupava
   a largura inteira da tabela com um campo de 33px de altura, e pesava mais na
   tela do que qualquer item já incluído. Campo miúdo e curto (decisão do dono,
   21/08): o texto do placeholder cabe, e a linha para de competir com o que a
   tabela tem para mostrar. */
[data-pagina="crm-deal"] #dl-itens td > #dl-add-busca { max-width: 34rem; }

/* --- 5. Funil: a barra de comando cabe em UMA linha, e o card encolhe ---
   Medido a 1366×768: a barra somava mais que os 1.278px disponíveis e
   quebrava em duas — a fileira de botões caía sozinha embaixo, e o primeiro
   card começava só aos 230px. O comentário do template já previa a conta
   ("somam 1369 numa linha de 1352"); aqui ela fecha, encolhendo o campo de
   busca, que é o único elemento da barra cuja largura era arbitrária.
   O card ia a 174–200px para cinco fatos: o que come a altura é o recuo, a
   entrelinha do título e a faixa do rodapé, não o conteúdo. */
@media (max-width: 1600px) {
  [data-pagina="crm"] .crm-comando { margin-bottom: .75rem !important; }
  /* A busca ficou com a largura de origem: encolhê-la foi tentativa de fazer
     a barra caber ANTES de descobrir que o que não cabia eram duas medidas
     repetindo o board. Cortado o excesso, não há por que apertar o campo. */
  /* Medido: as quatro medidas somavam 708px dos 1.278 disponíveis, e eram
     ELAS que empurravam a fileira de botões para a segunda linha. Quem
     ocupava a largura era o RÓTULO ("Negócios abertos" em 14px), não o
     número — e rótulo de indicador é legenda, não dado. Em micro eles somam
     ~470px e a barra fecha numa linha só, sem tocar no valor, que continua
     no corpo de leitura. */
  [data-pagina="crm"] .crm-medidas { gap: .65rem; }
  /* O rótulo é CAIXA ALTA com 1,2px de espaçamento entre letras: são as duas
     coisas que fazem "NEGÓCIOS ABERTOS" medir 133px. Reduzir o corpo sozinho
     não moveu nada (medido: 708 → 691px) — o espaçamento é que carrega a
     largura, e num rótulo de indicador ele é decoração. */
  [data-pagina="crm"] .crm-medida { padding-right: .3rem; }
  [data-pagina="crm"] .crm-medida dt { letter-spacing: .4px; }
  /* O card do funil: 217px para cinco fatos. O conteúdo mede 118px — o resto
     era respiro entre linhas que não separam grupo nenhum (nome, cidade,
     selo, proposta e valor são a MESMA coisa: a identidade do negócio). */
  [data-pagina="crm"] .crm-cartao { padding: .55rem .65rem; }
  /* `gap` não existe aqui: `.crm-cartao__corpo` é `display: block` (medido —
     a regra anterior de gap não fazia nada). Quem separa são as margens dos
     filhos, e são elas que encolhem. */
  [data-pagina="crm"] .crm-cartao__nome { line-height: 1.2; }
  [data-pagina="crm"] .crm-cartao__selos { margin-top: .15rem; }
  [data-pagina="crm"] .crm-cartao__valor { margin-top: .25rem; }
  [data-pagina="crm"] .crm-cartao__rodape { padding-block: .35rem; }
  [data-pagina="crm"] .crm-raia__cabo { padding: .45rem .6rem; }
}

/* Onde + o quê, numa linha só. Trava em UMA linha em qualquer largura: o
   subtítulo vai de "FBS CONSTRUCAO" a "proposta P-2026-0027 · rev. 1 ·
   entregue", e sem a trava o card voltaria a ter duas linhas exatamente nos
   negócios que já têm proposta — os que mais aparecem no board. */

/* --- 6. Rótulos da capa em MICRO, não ausentes ---
   Tirá-los devolveu 20px e custou reconhecimento: campo preenchido sem rótulo
   não diz o que é. Eles chegaram a ficar em 10px para o ganho de altura ser
   quase inteiro — e 10px é texto fora da escala do sistema, cujo piso é 12px
   e não tem exceção para "só um pouquinho menor". Voltaram para o degrau
   Label (12px); a entrelinha 1 e os 2px de respiro seguram a altura. */
[data-pagina="crm-deal"] .crm-capa-campos .crm-etiqueta {
  font-size: var(--fonte-pequena); line-height: 1; letter-spacing: .04em;
  margin-bottom: 2px; }

/* --- 7. O resumo das condições, na capa, é UMA linha ---
   Cinco partes ("Pagamento 21/28/35 · Frete CIF · …") quebravam em três
   linhas e faziam sozinhas a segunda faixa da capa ter 73px. A frase inteira
   fica no `title`; o que a capa responde é se há algo combinado. */
/* A linha QUEBRA, não trunca. Ela cortava em "Frete destacado R$ 1…" com o
   valor só no `title` — inalcançável no toque, e o comercial que está na
   ligação não lê o frete que ele mesmo negociou. Número que a tela mostra tem
   que ser legível NA tela: esconder dinheiro atrás de hover contraria a regra
   de auditoria da casa, e as duas linhas que isso custa cabem. */
[data-pagina="crm-deal"] .crm-resumo__linha { display: block;
  white-space: normal; overflow: visible; }

/* ------------------------------------------------------------
   A TELA CABE NA JANELA (ambas as páginas do CRM).
   O shell dá a altura (`content--altura-cheia`: .main com height fixa e
   overflow hidden). Aqui só se diz QUEM rola: no funil, cada coluna do
   kanban; no negócio, o corpo. A página em si nunca rola — perder a barra
   de comando e o rodapé de decisão ao rolar era o custo de deixar rolar.
   ------------------------------------------------------------ */
[data-pagina="crm"] .crm-tela { flex: 1 1 auto; min-height: 0; }
[data-pagina="crm"] .crm-comando { flex: 0 0 auto; }

/* Só a partir de md o board é grade de colunas — abaixo disso as raias
   são um acordeão e quem rola é a tela inteira. */
@media (min-width: 768px) {
  [data-pagina="crm"] .crm-board { min-height: 0; align-items: stretch; }
  [data-pagina="crm"] .crm-raia { display: flex; flex-direction: column;
    min-height: 0; }
  [data-pagina="crm"] .crm-raia__corpo { display: flex; flex-direction: column;
    min-height: 0; flex: 1 1 auto; }
  [data-pagina="crm"] .crm-coluna { flex: 1 1 auto; min-height: 0;
    overflow-y: auto; }
  /* Card NÃO encolhe. Sem isto a coluna flex espreme os cards para caber na
     altura disponível e o `overflow-y: auto` nunca dispara: 13 cards ficavam
     nos mesmos 885px, cada um mais fino, e a rolagem simplesmente não existia. */
  [data-pagina="crm"] .crm-coluna > .crm-cartao { flex: 0 0 auto; }
  [data-pagina="crm"] .crm-tela { overflow: hidden; }
  /* O painel de follow-ups é a segunda coluna: rola sozinho também. */
  [data-pagina="crm"] .crm-tela > .crm-painel { min-height: 0; overflow-y: auto; }
}
@media (max-width: 767.98px) {
  [data-pagina="crm"] .crm-tela { overflow-y: auto; }
}

/* Negócio: capa e rodapé ficam parados; o corpo rola. */
[data-pagina="crm-deal"] .crm-capa,
[data-pagina="crm-deal"] .crm-rodape { flex: 0 0 auto; }
[data-pagina="crm-deal"] .crm-corpo { flex: 1 1 auto; min-height: 0;
  overflow-y: auto; }

/* Campo buscável (crm-combo.js): a lista flutua ancorada no campo. */
[data-pagina="crm"] .crm-combo,
[data-pagina="crm-deal"] .crm-combo { position: relative; display: block; }

/* Prévia do rascunho em voo: os números derivados esmaecem no instante da
   digitação e voltam quando o servidor responde — sem isto o total da conta
   ANTERIOR parecia ser o da digitação atual. */
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-total],
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-frete-total],
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-qtd],
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-tabela],
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-delta],
[data-pagina="crm-deal"] .crm-previa-pendente .crm-conversao__txt,
[data-pagina="crm-deal"] .crm-previa-pendente tfoot {
  opacity: .35;
  transition: opacity .15s ease;
}
/* A gangorra é conta do SERVIDOR: mexer na quantidade, no nº de volumes ou
   no conteúdo manda a linha inteira para lá e espera. Esmaecer o número
   velho diz "isto não vale mais"; o giro ao lado da conversão diz "estou
   contando" — sem ele, a espera se parecia com tela travada. Fica na
   legenda porque é ali que se lê o resultado da gangorra. */
[data-pagina="crm-deal"] .crm-previa-pendente [data-previa-conversao]::after {
  content: ''; display: inline-block; vertical-align: -1px;
  width: .7rem; height: .7rem; margin-left: .45rem;
  border: 2px solid var(--crm-acento); border-right-color: transparent;
  border-radius: 50%; animation: crm-girando .6s linear infinite; }
@keyframes crm-girando { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  [data-pagina="crm-deal"] .crm-previa-pendente [data-previa-conversao]::after {
    animation: none; border-right-color: var(--crm-borda); }
}

/* Montar a proposta é a própria tabela: a última linha procura o produto e os
   achados entram como linhas logo abaixo (lista flutuante era cortada pelo
   contêiner que rola). */
/* Recuo miúdo (21/08): a linha era um convite com peso de formulário. */
[data-pagina="crm-deal"] .crm-linha-nova > td { padding-block: .35rem; }
[data-pagina="crm-deal"] .crm-linha-achado { cursor: pointer; }
[data-pagina="crm-deal"] .crm-linha-achado > td { padding-left: 1.5rem; }
[data-pagina="crm-deal"] .crm-linha-achado:hover > td,
[data-pagina="crm-deal"] .crm-linha-achado:focus > td {
  background: var(--crm-acento-fraco, rgba(23, 26, 24, .05));
}

/* Unidade colada no número (KG ao lado do campo, não embaixo dele): abaixo
   do campo ela era lida como legenda de outra coisa. */
[data-pagina="crm-deal"] .crm-campo-un { display: inline-flex; align-items: center;
  gap: .4rem; justify-content: flex-end; }
[data-pagina="crm-deal"] .crm-campo-un > .form-control { width: 7.5rem; text-align: right; }

/* Lista de escolha com marca à direita (contatos do cliente no "Novo
   negócio"): o item continua sendo `.crm-lista__item`, mas com duas colunas —
   a ficha à esquerda, o sinal de escolhida à direita. Em bloco, a marca caía
   numa linha própria e parecia mais um dado da pessoa. */
[data-pagina="crm"] .crm-lista--escolha .crm-lista__item {
  display: flex; align-items: center; gap: .6rem;
}
[data-pagina="crm"] .crm-lista--escolha [aria-selected="true"] {
  background: var(--crm-acento-fraco, rgba(23, 26, 24, .05));
}

/* Esperando o servidor sem apagar a tela: o conteúdo que ainda é o ANTERIOR
   esmaece até a resposta chegar. É o mesmo vocabulário da prévia do rascunho
   no negócio — dizer "isto ainda não é a sua resposta" em vez de exibir dado
   velho com cara de novo. */
[data-pagina="crm"] .crm-aguardando,
[data-pagina="crm-deal"] .crm-aguardando {
  opacity: .45; transition: opacity .15s ease; pointer-events: none;
}

/* Documento da proposta: coluna direita do bloco do vendedor (representante),
   como no documento que o Ploomes emite. */
.prop-vend-dir{ text-align:right; }

/* Selo das normas na proposta de cordoalha — some junto com a condição 5
   quando a proposta não tem cordoalha. */
.prop-selo{ margin-top:2mm; }
.prop-selo img{ height:14mm; }

/* Negócio no celular: a página inteira rola, em vez da capa comer a tela.
   Com os termos do documento editáveis, a capa passou de 6 para 14 campos —
   empilhados em 390px ela ocupava 639px dos 844 e sobravam 26px para a
   proposta e o acompanhamento, que são o trabalho. Numa tela estreita a
   rolagem única é o gesto natural; a altura cheia continua valendo do tablet
   para cima, onde a capa é uma fita e não uma coluna. */
@media (max-width: 767.98px) {
  .main:has(> .content--altura-cheia):has([data-pagina="crm-deal"]) {
    height: auto; overflow: visible;
  }
  [data-pagina="crm-deal"] .crm-corpo { overflow-y: visible; }
  /* O rodapé de decisão para de flutuar e fecha a página: preso ao pé numa
     página que rola, ele cobriria os últimos itens da proposta. */
  [data-pagina="crm-deal"] .crm-rodape { position: static; }
}

/* Itens da proposta no celular: cartão, não tabela que rola de lado.
   Sete colunas em 337px espremiam o campo de preço a 41px — largo o
   bastante para mostrar "5,3" cortado e estreito demais para digitar. O
   padrão de rolar na horizontal serve para LER uma tabela; aqui se escreve,
   e escrever num campo que está meio fora da tela não é possível.
   Cada item vira um bloco com rótulo à esquerda e valor à direita. */
@media (max-width: 767.98px) {
  [data-pagina="crm-deal"] #dl-itens thead { display: none; }
  [data-pagina="crm-deal"] #dl-itens,
  [data-pagina="crm-deal"] #dl-itens tbody,
  [data-pagina="crm-deal"] #dl-itens tfoot,
  [data-pagina="crm-deal"] #dl-itens tr { display: block; width: 100%; }
  [data-pagina="crm-deal"] #dl-itens tbody tr {
    border: 1px solid var(--crm-borda); border-radius: 8px;
    padding: .6rem .75rem; margin-bottom: .6rem;
  }
  [data-pagina="crm-deal"] #dl-itens td {
    display: flex; align-items: center; justify-content: space-between;
    gap: .75rem; width: 100%; padding: .3rem 0; border: 0; text-align: right;
  }
  /* A primeira célula é o produto: nome inteiro, sem rótulo e sem alinhar
     à direita — é o título do cartão. */
  [data-pagina="crm-deal"] #dl-itens td:first-child {
    display: block; text-align: left; padding-bottom: .5rem;
  }
  [data-pagina="crm-deal"] #dl-itens td[data-rotulo]::before {
    content: attr(data-rotulo); color: var(--crm-tinta-2);
    font-size: var(--bi-fs-compact); text-transform: uppercase; letter-spacing: .06em;
    text-align: left; flex: 0 0 auto;
  }
  /* Célula vazia (a das ações quando não se edita) não vira linha em branco. */
  [data-pagina="crm-deal"] #dl-itens td:empty { display: none; }
  /* No cartão, o campo tem a largura toda que sobra do rótulo — menos a
     busca de produto, que é a linha inteira e não tem rótulo ao lado. */
  [data-pagina="crm-deal"] #dl-itens td[data-rotulo] .form-control { max-width: 10rem; }
  [data-pagina="crm-deal"] #dl-add-corpo td { display: block; padding: .2rem 0; }
  [data-pagina="crm-deal"] #dl-add-busca { max-width: none; width: 100%; }
  /* Achado de produto: linha inteira, texto à esquerda, alvo alto. */
  [data-pagina="crm-deal"] .crm-linha-achado > td {
    display: block; text-align: left; padding: .55rem .75rem; }
  [data-pagina="crm-deal"] .crm-campo-un > .form-control { width: 7rem; }
  /* Coluna de embalagem (10/08, entre Preço e Total): sem rótulo (cabeçalho
     oculto — a coluna fica em branco na maioria das linhas) e sem um único
     "valor" para emparelhar com label nenhum — é uma pilha de até quatro
     blocos já rotulados por si (tipo, nº de volumes, conteúdo, ações). O
     `display:flex; justify-content:space-between` genérico da célula
     serve para PAR rótulo→valor; aqui não há par, e ele espalhava os blocos
     rente às bordas do cartão, cortando os do meio. Bloco puro empilha os
     filhos na ordem natural, sem flex nenhum. */
  /* As colunas de apoio deixam de ser escondidas: como cartão, elas cabem. */
  [data-pagina="crm-deal"] #dl-itens td.crm-col-md,
  [data-pagina="crm-deal"] #dl-itens td.crm-col-lg { display: flex; }
  /* Rodapé de totais: mesma leitura de rótulo e valor. */
  [data-pagina="crm-deal"] #dl-itens tfoot tr { display: flex;
    justify-content: space-between; padding: .2rem .75rem; }
  [data-pagina="crm-deal"] #dl-itens tfoot td:empty { display: none; }
}

/* O "X" de fechar painel e modal: 16×16 no sistema inteiro, abaixo dos 24px
   que a WCAG 2.5.8 pede para alvo de toque. A causa não era o Bootstrap —
   ele desenha o botão com `content-box` (16px de ícone + 8px de padding =
   32px de alvo); a regra global de `border-box` do projeto fez o padding
   comer o próprio tamanho. Devolver a caixa que o componente espera
   restaura os 32px SEM mexer no ícone nem no espaçamento visual. */
.btn-close {
  box-sizing: content-box;
  min-width: 1em;
  min-height: 1em;
}

/* ── BOARD DE COBRANÇA (/acompanhamento-inadimplencia) ───────────────────────
   Reescrita total (spec docs/superpowers/specs/2026-08-07-inadimplencia-frontend-fromzero-design.md):
   kanban horizontal, decisão do dono ("Vamos de kanban") sobre um benchmark
   que apontava fila agrupada — ver o `## Escopo` do spec para o registro.
   Fidelidade de estilo é QUASE PIXEL-PERFECT ao mockup normativo (mesma pasta,
   `2026-08-07-inadimplencia-fromzero-mockup.html`): larguras, gaps, paddings,
   radii, cores e tipografia em px vêm de lá, literais. Os tokens abstratos do
   mockup (--bg, --surface, --ink*, --line, --amber*, --red*) mapeiam 1:1 nos
   tokens FCDS já existentes (--bg, --surf, --ink*, --line, --warning*,
   --negative*); botões e campos são os do Bootstrap de fábrica (#454). */

/* ── ORDENAÇÃO E CONTAGEM NO TOPBAR (#511) ─────────────────────────────────────── */
/* Ficavam numa faixa própria abaixo do cabeçalho. Dois controles não pagam uma
   faixa de 39px num board cuja métrica é quantos cartões cabem na tela. */
.inad-ordenar{flex:0 0 auto;margin:0}
/* `width:auto` num <select> mede a MAIOR opção: toda opção aparece inteira, sem teto (#454). */
.inad-ordenar .form-select{width:auto}
/* O seletor de representante é irmão da ordenação na mesma faixa flex: sem o
   `0 0 auto` ele encolhe até o gatilho cortar o próprio rótulo. */
.inad-representante{flex:0 0 auto}
/* As contagens e o percentual da carteira, como leitura (não botão), no fim da faixa
   do topo (#511). Não encolhem: texto cortado não vale; quem cede são os filtros. */
.inad-contadores{display:flex;align-items:center;gap:.75rem;flex:0 0 auto;margin-left:.5rem}
.inad-contadores .inad-contagem{font-size:var(--fonte-pequena);color:var(--ink-3);white-space:nowrap;line-height:1.2}

/* ── O BOARD ──────────────────────────────────────────────────────────────
   Mockup literal: coluna flex-basis 292px, gap 14px, raio 12px, cartão 9px,
   sombra rasa (`0 1px 2px rgba(15,23,42,.06)` — exceção sancionada à regra
   "zero sombra de repouso" do app: esta página já era a exceção CRM antes
   desta reescrita, e o dono pediu fidelidade quase pixel-perfect ao mockup).
   `overflow-x:auto` mora SÓ no board — a página nunca rola de lado (spec §4).
   A altura vem do shell (`content--altura-cheia`): `.page` já é uma coluna
   flex até o fim da janela, e o board herda o resto dela — é o que amarra a
   rolagem vertical de cada coluna à VIEWPORT sem um número mágico de px
   (spec §1), em vez do `max-height:840px` fixo do mockup. */
.inad-board{display:flex;gap:14px;overflow-x:auto;padding-bottom:14px;
  flex:1 1 auto;min-height:0}
/* `min-width:0` NÃO é decorativo: sem ele o `min-width:auto` do flex item
   trava a coluna no min-content, que aqui é a DESCRIÇÃO (`white-space:nowrap`)
   — a largura passava a ser ditada pelo comprimento da frase, não pela carga.
   Medido em 1536px antes do fix: 436/380/441/577/398/292/428px, e a mais larga
   era "Enviar", com ZERO cartões e a frase mais comprida; board de 3036px para
   1456 visíveis, mais da metade fora da tela rolando para mostrar vazio. O
   `text-overflow:ellipsis` da descrição nunca disparava porque o pai crescia.
   (Mesmo bug, mesmo fix, comentado na seção do CRM mais abaixo.)
   DOIS PATAMARES, `flex:0 0` nos dois: `flex:1 1 320px` com `min-width:0`
   recém-posto faz o único item encolhível absorver o déficit inteiro e a
   coluna vai a 20px em 1280. */
/* ── A FOLHA (rebrand 09/08/2026) ──────────────────────────────────────────
   A coluna era uma caixa cinza com cartões brancos flutuando dentro: caixa
   dentro de caixa, sombra em cada cartão, 8px de vão entre eles. É o grid de
   cartões idênticos que todo board de SaaS repete — e num board de 110 itens
   ele cobra ~19px por item só em borda, vão e sombra, sem dizer nada.
   Agora a coluna é uma FOLHA (superfície branca, hairline, um raio só) e cada
   cobrança é uma LINHA dessa folha, separada por fio. É a linguagem do extrato
   que o operador já lê no ERP ao lado — sem virar o grid cinza do ERP, porque
   a folha tem respiro, tipografia com hierarquia e cor racionada a significado.
   O canvas frio do shell (--surface-app) continua atrás; nada de creme. */
.inad-coluna{min-width:0;background:var(--surf);border:1px solid var(--line);
  border-radius:10px;padding:0;display:flex;flex-direction:column;min-height:0;
  overflow:hidden}
/* LARGURA FIXA, e a rolagem lateral do board abaixo de 1536 é aceita (decisão
   do dono, 09/08): sete fases não cabem numa tela de notebook sem espremer a
   linha a ponto de o nome do cliente quebrar em três. A coluna com carga
   mantém os 320px do desenho; a vazia encolhe de 180 para 140 — ela só precisa
   do nome da fase e do zero, e cada 40px devolvidos são 40px a menos de
   rolagem para chegar na fase que tem trabalho. */
/* SETE COLUNAS IGUAIS, dividindo a viewport (decisão do dono, 10/08/2026). Os
   dois patamares por carga (320px com cartão, 96px vazia) saíram: o funil é uma
   régua, e régua com passo variável faz o olho comparar tamanho de coluna em
   vez de comparar carga — o número e o subtotal já dizem quanto há em cada
   fase. `flex:1 1 0` (base ZERO, não `auto`) é o que reparte a largura em
   partes iguais independentemente do conteúdo; `min-width` segura o piso e
   devolve a rolagem horizontal em tela estreita, onde 7 colunas não cabem sem
   virar tira. `min-width:0` continua obrigatório contra o `min-content` do
   flex — sem ele a descrição no `title` volta a ditar largura. */
/* 250px DE PISO, todas iguais (decisão do dono, 12/08/2026). O `flex:1 1 0`
   anterior repartia a viewport por um número de colunas que ninguém escolheu —
   o funil cresceu de 7 para 9 (e vai a 11 com a prorrogação) e a conta nunca
   foi refeita: medido a 1536px, dava 168px por coluna, com o nome do cliente
   truncado e o "também em" cortado no meio da palavra. E já rolava 88px, curto
   demais para o olho perceber que havia mais coluna à direita.
   Base igual + crescimento igual = largura igual, então a régua do funil
   continua de passo constante (decisão de 10/08) enquanto o piso devolve a
   largura fixa e a rolagem franca (decisão de 09/08). */
.inad-coluna[data-carga]{flex:1 0 250px;min-width:250px}
/* Grade fixa em vez de flex-wrap: sem ela os cabeçalhos desalinham entre si
   conforme a coluna estreita (medidos 58/72/97/113px de altura), e o
   desalinhamento aparece sozinho no dia em que as colunas encherem. */
/* `flex:none` NÃO é redundante: a coluna é um flex container vertical e o
   cabeçalho é item dele — medido ao vivo, a coluna com 109 cartões ESPREMIA o
   próprio cabeçalho de 93px para os 86px do `min-height`, enquanto a coluna
   com 3 cartões ficava nos 93. Era o desalinhamento que a grade veio evitar,
   reintroduzido pela carga. */
/* Duas linhas, não três: a descrição da fase saiu do fluxo e virou `title` do
   próprio cabeçalho (ela custava 30px dos 93px e repetia a mesma narração nas
   sete colunas). `min-height` cai junto — a grade continua garantindo que os
   sete cabeçalhos tenham a MESMA altura, que é o que alinha o topo dos
   cartões entre colunas vizinhas. */
/* Cabeçalho da folha: gruda no topo enquanto a coluna rola (com 109 linhas, o
   operador perdia de vista em qual fase estava e quanto ela vale) e fecha com
   um fio, que é o que faz a folha ler como folha. */
/* 64px, não 56: o `min-height` existia para igualar os sete cabeçalhos, mas
   media o piso errado — a coluna COM carga tem subtotal e mede 64, a vazia não
   tem e parava nos 56 (medido a 1536px: 64/64/64/56/56/56/56). Oito pixels de
   desalinhamento entre folhas vizinhas no topo do funil, justamente onde o olho
   compara as fases. Com o piso na altura real, as sete réguas começam juntas. */
.inad-coluna__cabeca{display:grid;grid-template-columns:1fr auto;
  grid-template-areas:"t n" "s s";row-gap:2px;align-items:baseline;
  align-content:start;min-height:64px;padding:10px 12px;flex:none;
  position:sticky;top:0;z-index:1;background:var(--surf);
  border-bottom:1px solid var(--line)}
.inad-coluna__titulo{grid-area:t;font-size:var(--fonte-corpo);font-weight:500;margin:0}
/* O DINHEIRO ERA O ELEMENTO MAIS FRACO do cabeçalho: "107" vinha em 700 e
   "R$ 5.921.223,62" em 400/--ink-3. Invertido — o subtotal manda, a contagem
   vira sufixo. `tabular-nums` para as colunas alinharem verticalmente. */
.inad-coluna__contagem{grid-area:n;color:var(--ink-3);font-size:var(--fonte-pequena);font-weight:500;
  font-variant-numeric:tabular-nums}
/* O subtotal é a manchete da folha — 15px contra os 13,5 do nome da fase. Na
   linguagem de extrato quem responde "quanto tem aqui" vem primeiro; a fase
   é o rótulo da coluna, não o dado. */
.inad-coluna__subtotal{grid-area:s;margin-left:0;color:var(--ink);font-size:var(--fonte-corpo);
  font-weight:500;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums lining-nums}
/* O toggle ▲/▼ de direção POR COLUNA saiu daqui (08/08): a ordenação virou uma
   escolha só, no seletor da faixa, com a direção escrita por extenso na opção.
   Sete botões de 24×24 dentro dos cabeçalhos diziam a mesma coisa que a faixa
   agora diz uma vez — e diziam por glifo. */
/* "Enviar" é a única fase que não pode esperar — âmbar no título e na
   contagem (spec §1), a mesma família de cor dos chips de alerta do cartão. */
.inad-coluna--urgente .inad-coluna__titulo{color:var(--warning-text)}
/* NUNCA SÓ POR COR (PRODUCT.md §Acessibilidade): a urgência de "Enviar" era
   apenas o tom âmbar do título — invisível para quem não distingue âmbar de
   cinza, que é justamente o eixo vermelho/âmbar/verde onde há daltônicos no
   time. A contagem vira pílula preenchida: forma e peso dizem o mesmo que a
   cor, e o número continua legível. */
.inad-coluna--urgente .inad-coluna__contagem{background:var(--warning-subtle);
  color:var(--warning-text);border-radius: var(--raio-chip);padding:0 .4rem;font-weight:500}
/* TRACEJADO = SEM CARTÃO, e não "coluna terminal": o tratamento era exclusivo
   das Encerradas, mas o que ele diz ("aqui não há o que fazer agora") vale
   para qualquer coluna vazia — generalizado, a terminal deixa de precisar de
   estilo próprio e volta a parecer as outras no dia em que tiver carga. */
.inad-coluna[data-carga="vazia"]{background:transparent;border:1px dashed var(--line-3)}
.inad-coluna[data-carga="vazia"] .inad-coluna__cabeca{background:transparent;border-bottom:0}
.inad-coluna[data-carga="vazia"] .inad-coluna__titulo{color:var(--ink-3);font-size:var(--fonte-corpo)}
/* SOB RECORTE DE TERMO A COLUNA VAZIA SAI (09/09/2026). Ela não encolhe — todas
   valem `flex:1 0 250px` —, e é isso que tinha derrubado o filtro do board em
   04/09: buscando "cleverton" na carteira real os 3 casados nasciam em x=73,
   1393 e 2185 numa viewport de 1744, com 10 colunas vazias de 250px entre eles,
   e o terceiro ficava fora da tela. Sem as vazias sobram 3 colunas (750px) e os
   3 aparecem juntos. Só sob `termo`: sob `cliente` a coluna vazia carrega a
   frase "Nenhuma cobrança deste cliente nesta fase", que é a resposta à
   pergunta que o operador fez — e sem recorte a régua do funil fica inteira,
   de passo constante (decisão de 10/08). O `data-recorte` é escrito pelo JS em
   `renderizarBoard`. */
.inad-board[data-recorte="termo"] .inad-coluna[data-carga="vazia"]{display:none}
/* `padding:4px` (10/08/2026): com o contorno de volta em cada cartão, sem este
   respiro a borda do cartão encostava na borda da coluna e as duas viravam um
   fio grosso só. */
.inad-coluna__cartoes{display:flex;flex-direction:column;overflow-y:auto;min-height:0;padding:4px}
/* Só sobra a frase da BUSCA ("Nenhum cliente encontrado.") — o "Nenhum cliente
   nesta fase." saiu: a tela parava para narrar um vazio que o `0` do
   cabeçalho já anuncia. */
.inad-coluna__vazia{padding:.75rem .5rem;text-align:center;color:var(--ink-3);font-size:var(--fonte-pequena)}

/* ── O CARTÃO ─────────────────────────────────────────────────────────────── */
/* RITMO: dois valores só — 4px dentro do grupo, 10px entre grupos. Antes eram
   5/2/6/6/9px, uma escadinha sem intenção. */
/* A LINHA DA FOLHA (rebrand 09/08/2026): sem borda própria, sem raio, sem
   sombra e sem vão — o que separa uma cobrança da seguinte é um fio, como num
   extrato. Só o que sobrou de "cartão" foi o nome da classe (o JS e os testes
   dependem dele; renomear seria diff de centenas de linhas sem ganho).
   Devolveu ~19px por item (borda 2px + vão 8px + sombra + raio) num board de
   110: é altura que vira linha visível em vez de moldura. */
/* CONTORNO FECHADO EM CADA CARTÃO (ordem do dono, 10/08/2026). O fio único
   entre linhas — a "folha de extrato" descrita acima — separava um cartão do
   seguinte mas não dizia onde ele COMEÇA e onde ACABA: numa coluna de 96
   linhas o olho perdia o par nome+valor. Volta a borda inteira, no tom mais
   escuro da família (`--line-3`), com 4px de vão para que o contorno de um
   não encoste no do outro. Custo medido e aceito: ~5px por cartão. */
.inad-card{background:var(--surf);border:1px solid var(--line-3);border-radius:0;
  padding:9px 12px;box-shadow:none;text-align:left;width:100%;
  line-height:1.5;display:flex;flex-direction:column;gap:4px;
  transition:background .12s,border-color .12s}

/* Modal "Registrar cobrança": a linha indisponível pela regra do escopo
   homogêneo (descontado e negociável não dividem cobrança — ADR-0007, emenda de
   17/08/2026). A caixa `disabled` sozinha não se distinguia da disponível num
   relance, medido ao vivo no cartão da CONSTRUCITY: seis linhas, quatro
   descontadas, e o olho não achava quais tinham saído de jogo. Escopo de
   página, nenhum token tocado. */
.cobranca-criar-linha--fora{opacity:.42}
.cobranca-criar-linha--fora td{text-decoration:line-through;
  text-decoration-color:var(--line-3)}
.inad-card + .inad-card{margin-top:4px}
/* Clicável: a linha inteira abre a cobrança, então precisa dizer isso ao
   passar o mouse — sem a moldura do cartão, o hover é o que resta de
   afordância. `--surf-2` é o mesmo tom das superfícies secundárias do app. */
.inad-card:hover{background:var(--surf-2);cursor:pointer}
.inad-card:focus-visible{outline:2px solid var(--acc);outline-offset:-2px}
/* `line-height:1.45` acima é literal do `body{font:14px/1.45 ...}` do mockup —
   sem ela o cartão herda o 1.5 do reset do Bootstrap, e cada elemento sem
   line-height próprio (valor/meta/situação) fica ~0.6px mais alto; num board
   de 5+ cartões empilhados isso se acumula em desvio visível de várias
   dezenas de px no pixel-diff (task 5, verificado por medição). */
/* LINHA 1: nome à esquerda, dinheiro à direita — e o dinheiro LIDERA. Antes o
   valor era 14px/700 contra um nome 13px/600 em caixa alta ocupando duas
   linhas: razão 1,077, isto é, empate. O nome desce a 12px/500/--ink-2 e o
   valor sobe a 18px/700; o nome ganha clamp de 2 linhas (o de 3+ linhas
   empurrava o cartão inteiro), com o nome completo no `title`. */
/* `align-items:start`, não `baseline`: medido ao vivo, 92 dos 112 cartões têm
   nome de duas linhas, e alinhar o valor de 18px pela PRIMEIRA linha de base
   do nome empurrava a caixa 6px para baixo em cada um deles (38px de linha 1
   contra os 32px do nome). Com `start` o dinheiro encosta no topo — que é
   onde o olho o procura — e a linha volta a medir o que o nome mede. */
/* NOME EM CIMA, VALOR EMBAIXO (10/08/2026, quando as sete colunas passaram a
   dividir a viewport em partes iguais). Lado a lado, o valor levava 119px fixos
   dos ~196 de uma coluna a 1536px e o nome sobrava com 60px: "CONSTRUCITY OLEO
   E GAS ENGENHARIA" virava "CONSTR OLEO …" em duas linhas de seis letras. Um
   layout só, não dois: empilhado, o nome tem a linha inteira e o valor continua
   alinhado verticalmente entre os cartões, que é o que o olho usa para
   comparar. */
.inad-card__topo{display:flex;flex-direction:column;align-items:stretch;gap:2px}
.inad-card__cliente{font-weight:500;font-size:var(--fonte-pequena);line-height:1.2;color:var(--ink-2);
  min-width:0;
}
/* O código do homônimo anda colado ao nome porque é parte do identificador,
   não um dado à parte. Só nasce quando o serviço marca `nome_ambiguo`. */
.inad-card__codigo{font-size:var(--fonte-pequena);color:var(--ink-3);font-variant-numeric:tabular-nums;
  margin-left:.3rem}
.inad-card__empresa{display:inline-block;margin-left:6px;font-size:var(--fonte-pequena);font-weight:500;
  color:var(--ink-3);border:1px solid var(--line);border-radius:4px;padding:0 5px;
  vertical-align:1px}
/* "também em Em negociação": um cliente com cobrança aberta E título solto
   rende dois cartões, e sem esta linha o segundo lê como duplicata. */
/* `nowrap` sem `overflow` cortava no meio da palavra: medido em 12/08/2026 o
   cartão do CLEVERTON exibia "também em Com assessoria/S". A linha é uma frase
   curta que pode não caber na coluna de 250px — reticencia, não decepa.
   `min-width:0` é obrigatório: o pai é flex e sem ele o `min-content` do texto
   impede o encolhimento e o `text-overflow` nunca dispara. */
.inad-card__tambem{font-size:var(--fonte-pequena);color:var(--ink-3);
min-width:0}
.inad-card__valor{flex:none;font-weight:500;font-size:var(--fonte-destaque);line-height:1.2;
  font-variant-numeric:tabular-nums lining-nums;text-align:right}
/* O TOTAL VENCIDO DO CLIENTE, embaixo do valor do cartão e em segundo plano: o
   número grande continua sendo o do recorte que o cartão representa, e este é a
   referência que o operador confere contra o Sênior (12/08/2026). Bloco próprio
   para não competir com o de cima na mesma linha de 250px. */
.inad-card__valor-total{display:block;font-weight:500;font-size:var(--fonte-pequena);
  color:var(--ink-3);line-height:1.2}
/* LINHA 2: o fato DAQUELA fase. O atraso/dia em --ink-2 e o resto em --ink-3
   não cabem numa classe só (é uma frase montada), então a linha inteira fica
   em --ink-2 e o que está vencido/liberado vira `--alerta` — antes "vencido há
   201 dias" tinha exatamente o mesmo peso de "últ. contato 09/07". */
.inad-card__fato{color:var(--ink-2);font-size:var(--fonte-pequena);line-height:1.2}
.inad-card__fato--alerta{color:var(--negative-text);font-weight:500}
/* A IDADE DA DÍVIDA VIRA COR (08/08). Era a única variável que muda de cartão
   para cartão na primeira coluna — 1 dia e 576 dias saíam no mesmo cinza de
   12px, e o olho não tinha como triar 206 cartões sem ler número por número.
   Duas cores, não oito: até 90 dias é rotina e fica em cinza; 91–360 é atenção;
   361+ é o dinheiro que provavelmente já não volta. A cor NUNCA é o único
   sinal — o número de dias e a faixa canônica no `title` dizem o mesmo. */
.inad-card__fato--atencao{color:var(--warning-text)}
.inad-card__fato--critico{color:var(--negative-text);font-weight:500}
/* UMA FAIXA, DUAS LEITURAS: o fato da fase à esquerda, a situação à direita.
   Eram duas linhas empilhadas, e a de baixo dizia "Sem contato" em 204 dos 209
   cartões — 19px por linha gastos num rótulo que quase nunca varia. Lado a
   lado, a linha some quando não há chip, e a pílula segue visível para o caso
   em que ela de fato diz algo (promessa quebrada, jurídico liberado).
   `wrap` porque em coluna estreita a pílula desce sozinha em vez de espremer
   o fato. */
.inad-card__linha{display:flex;align-items:baseline;justify-content:space-between;
  gap:.4rem;flex-wrap:wrap;min-width:0}
.inad-card__linha .inad-card__fato{min-width:0;flex:1 1 auto}
/* `flex:0 1 auto` + `min-width:0` (10/08/2026): com `0 0 auto` o bloco não
   encolhia nem quebrava, e a oitava coluna (Encontro de contas) estreitou a
   régua de 196 para 170px — "Aguardando · 1 de 2 promessas" passou a vazar 21px
   para fora do cartão, cortando "promessas" no meio da palavra (medido).
   Podendo encolher, o placar desce para a própria linha em vez de sangrar. */
.inad-card__situacao{display:flex;align-items:baseline;gap:.3rem;flex-wrap:wrap;
  flex:0 1 auto;min-width:0;justify-content:flex-end}
.inad-card__pilula{flex:none;padding:.05rem .4rem;border-radius: var(--raio-chip);font-size:var(--fonte-pequena);
  line-height:16px;font-weight:500;white-space:nowrap;background:var(--surf-2);color:var(--ink-2)}
/* `line-height:15.8px` acima: a pílula não existe no mockup (que só tem
   `.sit` em texto corrido, 12px) — spec §1 pede a pílula mesmo assim. Sem a
   declaração ela herda 1.45 do `.inad-card`, ficando ~0.6px mais baixa que a
   linha `.sit` do mockup por cartão; medido no pixel-diff (task 5), esse era
   o ÚNICO elemento do cartão ainda fora do alinhamento depois dos ajustes
   acima — 0,6px por cartão acumula visivelmente ao longo da coluna. */
.inad-card__pilula--neutro{background:var(--surf-2);color:var(--ink-2)}
.inad-card__pilula--quebrada{background:var(--negative-subtle);color:var(--negative-text)}
.inad-card__pilula--novo{background:var(--warning-subtle);color:var(--warning-text)}
.inad-card__pilula--aguardando{background:var(--info-subtle);color:var(--info-text)}
/* Os chips ficam na MESMA linha da pílula (linha 3), não numa quarta linha
   própria — o `margin-top:6px` que os empurrava saiu junto do `.inad-card__
   acao`. O `<span>` que fingia ser botão (`.inad-card__botao`) foi REMOVIDO:
   era um falso alvo repetido em cada um dos 110 cartões dentro de um cartão
   que já é inteiro clicável, e custava 35px de altura por cartão. O verbo que
   ele mostrava vive agora no `aria-label` do cartão. */
.inad-chip{display:inline-block;font-size:var(--fonte-pequena);font-weight:500;border-radius:5px;
  padding:1px 7px}
.inad-chip--amber{background:var(--warning-subtle);color:var(--warning-text)}
.inad-chip--red{background:var(--negative-subtle);color:var(--negative-text)}
/* NEUTRO: o chip que INFORMA em vez de alertar (comprovante tem/falta,
   12/08/2026). O comprovante é opcional — pintar "sem comprovante" de âmbar
   poria um aviso de atenção em quase todo cartão do board. */
.inad-chip--slate{background:var(--surf-3);color:var(--ink-2)}
/* O QUE O CLIENTE DISSE, em área própria. Era uma linha de 11px em `--ink-3`
   com reticências — a frase mais importante da conversa tratada como rodapé,
   e ilegível justamente na coluna onde a conversa está viva (ordem do dono,
   08/08). Agora é um bloco citado: fundo `--surf-2`, tinta `--ink-2`, duas
   linhas antes de cortar. Só nasce quando há observação, então o cartão só
   paga a altura quando há o que ler. Vem INTEIRA do serviço — quem corta é o
   `line-clamp` e o texto todo fica no `title`; não há limite que o JS conheça. */
/* O corte mora no FILHO, não na caixa: `overflow:hidden` recorta na caixa de
   PADDING, então uma terceira linha vazava para dentro do respiro de baixo,
   meio cortada, visível (medido em observação real de 211 caracteres). Com o
   `-webkit-box` no span, o corte acontece antes do padding começar. */
/* A FALA DO CLIENTE TEM COR PRÓPRIA — e é a do `info`, não a do alerta: o que
   ele disse não é bom nem ruim, é a evidência mais fresca que a cobrança tem.
   O bloco era cinza sobre cinza (--surf-2 no cartão branco) e sumia dentro da
   miudeza. Texto em `--info-text` (tom mais escuro da MESMA matiz do fundo, não
   cinza sobre colorido, que lava).
   AS ASPAS SAÍRAM: o glifo decorativo custava 13px de recuo em toda linha da
   citação para dizer o que a assinatura agora diz com dado — quem falou e
   quando. Ornamento fora, atribuição dentro. */
.inad-card__obs{min-width:0;font-size:var(--fonte-pequena);line-height:1.5;color:var(--info-text);
  background:var(--info-subtle);border:1px solid color-mix(in srgb, var(--info) 22%, var(--surf));
  border-radius:6px;padding:5px 7px}
.inad-card__obs-texto{
}
/* A assinatura é metadado da citação, não a citação: fica um degrau abaixo em
   TAMANHO — e só nele. Clarear a cor (medido: `--info-text` a 82% do fundo caía
   para 3,39:1) reprovaria em AA num texto de 10,5px; a hierarquia sai de graça
   pelo tamanho, sem pagar em legibilidade. */
.inad-card__obs-fonte{display:block;margin-top:2px;font-size:var(--fonte-pequena);line-height:1.2;
  font-variant-numeric:tabular-nums}

/* O ATALHO PARA O HISTÓRICO (31/08/2026), no lugar da citação emprestada.
   Discreto de propósito: é uma porta, não um aviso — quem tem citação própria
   não o recebe, e nos que recebem ele ocupa a linha que a citação desocupou.
   Sem fundo nem borda para não competir com a caixa da citação dos cartões
   vizinhos na mesma coluna; a afordância vem do sublinhado ao passar o mouse.
   `text-align:left` porque `button` centraliza por padrão e o cartão inteiro é
   alinhado à esquerda. */
.inad-card__historico{align-self:flex-start;padding:0;border:0;background:none;
  font-size:var(--fonte-pequena);line-height:1.2;color:var(--ink-3);text-align:left;
  font-variant-numeric:tabular-nums;cursor:pointer}
.inad-card__historico:hover,.inad-card__historico:focus-visible{
  color:var(--ink);text-decoration:underline}

/* ── GRADE DE ENCAMINHAMENTOS (14/08/2026) ────────────────────────────────── */
/* Para onde a dívida já foi e quando — Serasa, Consulth, protesto, jurídico.
   `<dl>` e não tabela: são pares termo/valor, não uma matriz — e a semântica de
   lista de definição é o que faz o leitor de tela anunciar "Enviada para
   Serasa: 12/08" como um par, em vez de duas células soltas.
   MUDO POR PADRÃO, como o resto dos metadados do cartão: a grade é referência
   de consulta, não alerta — quem precisa de atenção já tem a pílula e o fato.
   `tabular-nums` alinha as datas em coluna sem precisar de grid: em fonte
   proporcional, `12/08` e `01/11` não fecham à direita e a coluna serrilha. */
.inad-card__encaminhamentos{margin:0;font-size:var(--fonte-pequena);line-height:1.2;
  color:var(--ink-2);border-top:1px dashed var(--line);padding-top:5px}
.inad-card__encaminhamento{display:flex;align-items:baseline;gap:6px;
  justify-content:space-between}
.inad-card__encaminhamento + .inad-card__encaminhamento{margin-top:2px}
/* O NOME DO DESTINO NÃO PODE SER CORTADO — é o dado que a grade existe para
   dar. A primeira versão punha `text-overflow:ellipsis` no termo para proteger
   a data, e na largura real da coluna do board isso virou "Enviada para
   Prote…" (medido em 14/08/2026, cartão da LMD): o operador ficava sem saber se
   foi protesto ou outra coisa, que é a pergunta inteira.
   Agora o termo QUEBRA e a data (largura fixa, `flex:none`) continua onde
   está — duas linhas ocasionais custam menos que uma palavra escondida. */
.inad-card__encaminhamento dt{min-width:0;font-weight:500}
.inad-card__encaminhamento dd{margin:0;flex:none;font-variant-numeric:tabular-nums}
/* "há quanto tempo" é o segundo grau da mesma informação que a data já dá —
   fica um degrau abaixo, entre parênteses, sem virar uma terceira coluna. */
.inad-card__encaminhamento-dias{margin-left:4px;color:var(--ink-3)}
.inad-card__encaminhamento-dias::before{content:"("}
.inad-card__encaminhamento-dias::after{content:")"}

/* ── RESPONSIVO (spec §4) ─────────────────────────────────────────────────── */
/* ≤760px: o board deixa de ser kanban e vira pilha vertical de seções por
   fase, na mesma ordem do fluxo — único formato viável em tela estreita (o
   dono aceitou o custo de scroll horizontal no notebook, não no celular). O
   shell já devolve `.main`/`.content--altura-cheia` para fluxo normal nesta
   largura; aqui só o board precisa parar de ser flex-row com altura amarrada. */
@media (max-width:760px){
  .inad-board{flex-direction:column;overflow-x:visible;flex:0 0 auto}
  /* `[data-carga]` (0,2,0), não `.inad-coluna` (0,1,0): media query NÃO soma
     especificidade, então a regra de classe pura PERDIA dos dois patamares
     `.inad-coluna:not([data-carga="vazia"])`/`[data-carga="vazia"]` lá de cima
     e o `flex-basis` virava ALTURA na pilha vertical — coluna de 320px para
     13.689px de conteúdo, com o resto dos cartões inalcançável. Empatando em
     0,2,0 esta ganha por ordem de fonte. O JS emite `data-carga` em toda
     coluna, então o seletor casa sempre. */
  .inad-coluna[data-carga]{flex:0 0 auto}
  .inad-coluna__cartoes{overflow-y:visible}
}

/* ALVOS DE TOQUE DO PAINEL (10/08/2026), na largura onde o dedo é o ponteiro.
   Botões e campos ficam no -sm de fábrica, como no desktop (#454).
   Links de e-mail na ficha ficam como estão: são links dentro de uma frase,
   que a própria WCAG 2.5.8 dispensa do alvo mínimo — engordá-los quebraria a
   linha "victor@… , nfe@…" em duas. */
@media (max-width:760px){
  /* O link destrutivo com área de toque sem virar botão. */
  .inad-painel .btn-link{display:inline-flex;align-items:center;justify-content:center;
    min-height:44px;min-width:44px}
  /* Os e-mails da ficha param de ser dois links colados numa linha de 15px:
     viram uma linha cada, com área de toque. No desktop continuam separados
     por vírgula, que é como se lê um par de endereços. */
  .inad-painel .inad-ficha a[href^="mailto:"]{display:block;min-height:44px;
    display:flex;align-items:center}
  /* A CALCULADORA DESGRUDA NO CELULAR. Grudada ela comia ~200 dos 844px da
     tela — um quarto permanente. No desktop ela continua colada ao topo: lá
     sobra altura e o operador precisa dos totais à vista enquanto rola a lista
     de títulos. */
  .inad-calculadora{position:static;box-shadow:none;
    border-bottom:1px solid var(--line)}
  /* O LUGAR LIBERADO VAI PARA A AÇÃO. "Registrar contato" era o que rolava
     para fora da tela enquanto a calculadora ficava presa — prioridade
     invertida para o polegar.
     `fixed`, não `sticky`: sticky só gruda dentro do PAI, e o pai aqui é uma
     `.col-12` de 44px — o botão saía de cena junto com ela (medido: topo em
     -182px depois de rolar). Fixo no rodapé da janela é o padrão de ação
     primária em celular, e a grade ganha o respiro para o conteúdo não
     terminar debaixo dele. */
  .inad-painel #btn-salvar-contato{position:fixed;left:0;right:0;bottom:0;width:auto;
    border-radius:0;z-index:3;box-shadow:0 -.5rem .9rem -.5rem rgba(20,26,32,.35)}
  .inad-painel-grade{padding-bottom:3.5rem}
  /* A coluna grudada é ganho no desktop (a tabela rola pouco e "Últ. pgto."
     seria o que sumia); a 390px ela come 80 dos 358 disponíveis e passa a
     cobrir "Vencimento" — a tabela inteira rola de lado ali de qualquer jeito. */
  .inad-painel .cobranca-tabela th:last-child,
  .inad-painel .cobranca-tabela td:last-child{position:static;box-shadow:none}
}

/* ── PAINEL DE COBRANÇA (tela 2, spec §2) ────────────────────────────────── */
/* `height` E `max-height` em 100%: o `.modal-dialog-scrollable` do Bootstrap
   calcula `calc(100% - 1rem)` contando com a margem que aqui foi zerada. */
.inad-painel .modal-dialog{margin:0 0 0 auto;max-width:min(85rem,100%);
  height:100%;max-height:100%}
.inad-painel .modal-content{height:100%;max-height:100%;border:0;border-radius:0;
  background:var(--surf);border-left:1px solid var(--line)}
/* FOLHA LATERAL OU TELA CHEIA — NUNCA UMA FRESTA. O teto de 85rem combinado
   com `100%` produzia uma faixa de board acidental: 176px de contexto a 1536,
   mas SEIS PIXELS a 1366 e zero a 1280 (medido). Seis pixels não são contexto,
   são um artefato — a folha parece mal encaixada em vez de sobreposta. Abaixo
   de 1536 ela assume a tela inteira (e devolve a largura à tabela de parcelas,
   que a 1366 já estava com folga zero); de 1536 para cima continua folha, com
   board suficiente atrás para dizer de onde ela saiu. */
@media (max-width:1535.98px){.inad-painel .modal-dialog{max-width:100%}}
.inad-painel .modal-body{display:flex;flex-direction:column;overflow:hidden;padding-bottom:0}
.inad-painel .modal-body > .alert{flex:0 0 auto}

/* O STEPPER: as seis fases da cobrança em linha, o ponto atual destacado, as
   anteriores preenchidas — e o placar de promessas encostado à direita. Vazio
   até a Task 3/4 montar (`cobranca.fase`/`cobranca.placar`). */
/* ── O RITMO DO PAINEL (10/08/2026) ───────────────────────────────────────
   Os vãos verticais do painel eram .2 / .25 / .3 / .7 / .75 / .85 / .9 / 1rem
   — oito valores, sete deles entre 11 e 16px. Todo intervalo media quase o
   mesmo, então NADA agrupava: ficha, tarja, notas e títulos chegavam ao olho
   como um bloco cinza só. Agora há três degraus e cada um significa uma coisa:
     4px  — dentro de um par (rótulo/valor, nota e sua lista)
     16px — entre blocos do mesmo assunto
     24px — entre SEÇÕES (quem é o cliente | o que se cobra | quanto dá hoje)
   Os números não mudam de tamanho; muda o que o espaço diz. */
.inad-stepper{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap;margin:0 0 1rem;
  font-size:var(--fonte-pequena);color:var(--ink-3)}
.inad-stepper__etapa{display:flex;align-items:center;gap:.3rem}
.inad-stepper__ponto{width:.5rem;height:.5rem;border-radius:50%;background:var(--line-3)}
.inad-stepper__etapa--feita .inad-stepper__ponto{background:var(--ink-3)}
.inad-stepper__etapa--atual{color:var(--ink);font-weight:500}
.inad-stepper__etapa--atual .inad-stepper__ponto{background:var(--acc)}
.inad-stepper__seta{color:var(--line-3)}
.inad-stepper__placar{margin-left:auto;font-weight:500;color:var(--ink-2)}
/* "· fase N de 6": só existe para o colapso móvel (spec §4) — no desktop as
   seis etapas já dizem a posição pela ordem visual, então o texto fica
   redundante e escondido até a media query de 760px virar o único lugar
   onde ele é a ÚNICA pista de posição (a etapa atual é a única visível). */
.inad-stepper__pos{display:none;color:var(--ink-3);font-size:var(--fonte-pequena);margin-left:.3rem;font-weight:400}
@media (max-width:760px){
  .inad-stepper__etapa:not(.inad-stepper__etapa--atual){display:none}
  .inad-stepper__seta{display:none}
  .inad-stepper__pos{display:inline}
}

/* A FICHA: código/telefone/contato/e-mail/vencido total, na coluna de dados
   do painel — lista rótulo/valor compacta, sem tabela (só 5 linhas). */
/* 24px abaixo dela: a ficha FECHA a seção "quem é o cliente". Era .85rem, a
   mesma distância que separava a tarja do escopo da lista de títulos — dois
   assuntos diferentes com o mesmo vão. */
/* GRADE, não pilha (10/08/2026): medido a 1760px, as cinco linhas usavam 482
   dos 923px da coluna — 441px de vazio à direita, e 150px de altura para dizer
   cinco coisas curtas. Em duas colunas o mesmo conteúdo cabe em menos da
   metade da altura e o vazio some. `auto-fit` com piso de 22rem devolve UMA
   coluna sozinho quando o painel empilha no celular — sem media query. */
/* `max-content` + `space-between`, não `1fr`: com colunas iguais a segunda
   ficava com meia largura vazia à direita (255px medidos). Medindo pelo
   conteúdo, cada par rótulo/valor ocupa só o que precisa, e o espaço que
   sobra vira o vão ENTRE as duas colunas — que é o que faz a faixa parecer
   ocupada em vez de abandonada. */
.inad-ficha{margin:0 0 1.5rem;display:grid;
  grid-template-columns:repeat(auto-fit, minmax(18rem, max-content));
  justify-content:space-between;
  gap:.25rem 2rem;font-size:var(--fonte-corpo)}
/* Contato e e-mail são os únicos textos longos da ficha: em meia coluna o
   endereço quebraria no meio. Ocupam a faixa inteira. */
.inad-ficha__linha--largo,.inad-ficha__promessa{grid-column:1/-1}
.inad-ficha__linha{display:flex;gap:.5rem;align-items:baseline;min-width:0}
.inad-ficha__valor{min-width:0}
.inad-ficha__rotulo{color:var(--ink-3);flex:0 0 6.5rem}
.inad-ficha__valor{color:var(--ink-2);font-variant-numeric:tabular-nums lining-nums}
.inad-ficha__promessa{margin-top:.2rem;font-size:var(--fonte-pequena);color:var(--ink-3)}

/* AS DUAS COLUNAS: dados à esquerda com scroll próprio (a calculadora sticky
   continua funcionando DENTRO dela), ação à direita sempre visível — o
   operador registra sem rolar por cima das NFs. `order` (não posição no DOM)
   é o que faz a AÇÃO vir antes dos DADOS em tela estreita (spec §4). */
.inad-painel-grade{display:flex;gap:1.25rem;flex:1 1 auto;min-height:0}
.inad-painel-coluna{min-height:0;overflow-y:auto}
/* `.row` do Bootstrap tem margem NEGATIVA lateral (metade da calha) e conta
   com o pai ter o padding correspondente. A coluna do painel não tem, então o
   formulário da ligação vazava 8px para fora dela em toda resolução (medido:
   form 363px, conteúdo 371px) — 8px que empurravam a barra de rolagem
   horizontal dentro do modal. Zerar a calha na origem é o que faz o form caber
   sem mexer no espaçamento entre os campos, que vem do `g-*` de cada linha. */
.inad-painel-coluna .row{--bs-gutter-x:0}
.inad-painel-coluna--dados{flex:1 1 0;order:1}
/* `col-md-6` DECIDE PELA VIEWPORT, não pelo pai — e o pai aqui tem 24rem
   fixos. Numa janela de 1760px o Bootstrap achava que "md" cabia e punha
   Canal e Previsão lado a lado com 182px cada, colados, enquanto "Próximo
   contato" ficava com 182px de vazio ao lado (medido). Um container query
   devolve a decisão a quem tem a informação: os campos ocupam a faixa inteira
   e só voltam a dividir quando a COLUNA de fato tiver largura — que é o caso
   quando o painel empilha e ela vira a tela toda. */
.inad-painel-coluna--acao{flex:0 0 24rem;order:2;border-left:1px solid var(--line);
  padding-left:1.25rem;container-type:inline-size}
.inad-painel-coluna--acao .row > [class*="col-"]{flex:0 0 100%;max-width:100%}
@container (min-width:34rem){
  .inad-painel-coluna--acao .row > .col-md-6{flex:0 0 50%;max-width:50%}
}
@media (max-width:1100px){
  .inad-painel-grade{flex-direction:column;overflow-y:auto}
  /* `flex:0 0 auto` NÃO é enfeite: empilhadas, as bases do desktop viram
     ALTURA — `flex:0 0 24rem` da coluna de ação virava 384px de altura para um
     formulário de 548, e os 164px que sobravam eram desenhados POR CIMA da
     ficha do cliente (medido a 390px: ação 184→568, ficha começando em 604,
     sobreposição de 604 a 794). Cada coluna passa a ter a altura do seu
     conteúdo; quem rola é a grade. */
  .inad-painel-coluna{overflow:visible;flex:0 0 auto}
  .inad-painel-coluna--dados{order:2}
  .inad-painel-coluna--acao{order:1;border-left:0;padding-left:0;margin-bottom:1rem}
}
.inad-painel-grade form{max-width:100%}

/* A CALCULADORA MUDOU DE PONTA (10/08/2026, decisão do dono): saiu do rodapé
   da coluna e foi para logo abaixo da ficha do cliente, acima da lista de
   cobranças. Ela é a ENTRADA da conversa — a data de "Calcular para" é a data
   que o operador promete —, então pertence ao começo. Continua colada, agora
   ao topo: o ganho da versão de baixo era ter os totais à vista enquanto se
   rola a lista de notas, e isso se preserva. A sombra inverte de direção junto
   com o lado que ela guarda. */
.inad-calculadora{position:sticky;top:0;z-index:2;background:var(--surf);
  border-bottom:1px solid var(--line);box-shadow:0 .5rem .7rem -.4rem rgba(20,26,32,.14)}

/* MOVIMENTO DE FASE na linha do tempo (10/08/2026). O que o SISTEMA fez
   sozinho (promessa vencida, saldo zerado) ganha fundo próprio: numa lista em
   que todo o resto foi alguém que ligou, "automático" escrito em cinza passa
   batido. Fundo, não faixa colorida na borda — barra lateral é enfeite banido
   no design system do app. */
.inad-movimento--auto{background:var(--surf-2);
  margin-left:-.35rem;margin-right:-.35rem;padding-left:.35rem;padding-right:.35rem;
  border-radius:4px}

/* O SELO DE CAMPO OBRIGATÓRIO. Âmbar, não vermelho: nada deu errado ainda —
   é o que falta, não um erro cometido. 11px em `--warning-text` sobre o branco
   do painel; o campo ganha o mesmo tom na borda para o olho ligar as duas
   coisas sem precisar de seta. */
.inad-exigido{font-size:var(--fonte-pequena);font-weight:500;color:var(--warning-text);
  margin-left:.35rem;letter-spacing:.01em}
/* Escopado no painel porque é só lá que a classe existe — não por disputa de
   especificidade: `.form-control` do Bootstrap tem (0,1,0) e custom.css vem
   depois, então a classe pura já venceria. (Fica o registro do susto: medindo
   `borderColor` no mesmo instante do clique, o valor lido era o cinza padrão —
   `.form-control` tem `transition: border-color .15s`, e getComputedStyle
   devolve o quadro CORRENTE da transição. O defeito era a régua, não a regra.) */
.inad-painel .inad-campo-exigido{border-color:var(--warning)}
.inad-painel .inad-campo-exigido:focus{border-color:var(--warning);
  box-shadow:0 0 0 .2rem color-mix(in srgb, var(--warning) 28%, transparent)}
/* A previsão apontando o que falta lê como instrução, não como valor. */
.inad-previsao--falta{color:var(--warning-text);font-size:var(--fonte-corpo)}

/* A ÚLTIMA COLUNA NÃO SOME. A tabela de parcelas rola dentro do
   `.table-responsive`, e a coluna da ponta é "Situação" — a que diz se aquela
   linha está vencida, paga ou descontada. Grudada, ela fica visível com a
   tabela rolada. */
/* Padding de célula devolve 44px sem tirar do operador nenhum número — a
   alternativa era apagar uma coluna que ele lê no telefone. Seletor no formato
   do Bootstrap 5 (`> :not(caption) > * > *`) porque o dele é (0,1,3) e uma
   regra de classe pura perderia. */
.cobranca-tabela > :not(caption) > * > *{padding-left:.15rem;padding-right:.15rem}

/* `--surf-1` NÃO EXISTE (os tokens são --surf/--surf-2/--surf-3): a coluna
   grudada ficava com fundo transparente e era desenhada POR CIMA da vizinha.
   Fundo opaco + z-index é o que faz sticky funcionar sobre conteúdo. */
.cobranca-tabela th:last-child,
.cobranca-tabela td:last-child{position:sticky;right:0;z-index:1;background:var(--surf);
  box-shadow:-.4rem 0 .4rem -.4rem rgba(20,26,32,.18)}
/* O separador de grupo fica FORA do grude: ele é um colspan da largura toda, e
   grudado desenharia um retângulo branco com sombra por cima do próprio grupo. */
.cobranca-tabela .cobranca-grupo > :last-child{position:static;box-shadow:none}

/* A LINHA É O TÍTULO (12/08/2026): a NF virou coluna e o grupo virou separador,
   que NOMEIA e só — o cabeçalho de nota anterior repetia o valor da linha de
   baixo (medido na LMD: R$ 11.869,24 duas vezes, cinco vezes seguidas). Foram
   embora com ele o subtotal por nota e o aviso por nota: o aviso vive na célula
   de encargos de cada linha, e o subtotal de uma linha só era a própria linha. */
.cobranca-tabela .cobranca-grupo > *{background:var(--surf-2);
  border-top:1px solid var(--line-3);padding-top:.35rem;padding-bottom:.35rem}
.cobranca-tabela .cobranca-grupo th{font-size:var(--fonte-corpo)}

/* A tarja do escopo: DECLARADA, não escolhida — ou o título estava vencido, ou
   não estava. Por isso não há checkbox nela. */
/* 8px abaixo dela, não 11: a tarja descreve a LISTA logo abaixo — ela pertence
   àquele bloco, e o vão tem que dizer isso. */
.inad-escopo{margin:0 0 .5rem;padding:.5rem .7rem;background:var(--surf-2);
  border:1px solid var(--line);border-radius:8px;font-size:var(--fonte-pequena);color:var(--ink-2);
  display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}
.inad-escopo:empty{display:none}
.inad-escopo strong{font-variant-numeric:tabular-nums lining-nums}
.inad-escopo__nota{margin-left:auto;color:var(--ink-3);font-size:var(--fonte-pequena)}
/* A diferença entre o congelado e o que o board mede. Quebra linha inteira
   (flex-basis:100%) porque é uma frase, não um par rótulo/valor. */
.inad-escopo__fora{flex:0 0 100%;color:var(--warning-text)}

/* O prazo da assessoria ainda correndo: informa, não alarma — o botão do
   jurídico ao lado está habilitado de qualquer jeito. */
.inad-prazo--correndo{color:var(--warning-text)}

/* O remendo daqui (`padding:0 1rem !important`) saiu em 18/08/2026: o eixo
   horizontal voltou a ser reposto na própria regra de altura cheia, para todas
   as telas, não só para o board. */

/* ===========================================================================
   CRM — auditoria visual de 05/08/2026 (desktop + celular real)
   =========================================================================== */

/* 1. O SELECT QUE ARRASTAVA A TELA NO SAFARI
   Item flex nasce com `min-width: auto`: não encolhe abaixo da largura
   INTRÍNSECA do conteúdo. E um `<select>` reserva a largura da MAIOR opção,
   não da escolhida — "0000 · Tabela utilizada para preços negociados fora da
   tabela de preços" exige 800px num painel de 400px.

   O Chromium encolhe assim mesmo e por isso a medição automatizada dava
   "zero overflow" nas quatro larguras testadas. O Safari do iOS respeita a
   largura intrínseca do controle nativo: o corpo do offcanvas ganhava
   rolagem horizontal e o vendedor ARRASTAVA a tela para o lado (registrado
   em foto de aparelho, 05/08).

   Já existia um `min-width: 0` no CRM — um só, preso à capa
   (`.crm-capa .crm-linha > .form-select`). Alguém bateu neste bug, remendou
   onde doeu e deixou o painel de detalhes, o cadastro do cliente, o contato
   e o fechamento com o mesmo defeito latente. Aqui a regra vira geral. */
[data-pagina^="crm"] .crm-cresce,
[data-pagina^="crm"] [class*="crm-campo-"],
[data-pagina^="crm"] .offcanvas-body .crm-linha > * { min-width: 0; }
[data-pagina^="crm"] .offcanvas-body .form-select,
[data-pagina^="crm"] .offcanvas-body .form-control { max-width: 100%; }
/* A opção longa vira reticências em vez de empurrar a caixa. */
/* Cinto de segurança: se algum campo novo escapar da régua acima, ele fica
   preso no painel em vez de transformar a tela num carrossel horizontal. */
[data-pagina^="crm"] .offcanvas-body { overflow-x: hidden; }

/* 2. ALVO DE TOQUE
   Os botões do CRM têm 31px de altura e `.crm-cartao__acao` tem 24px — menos
   da metade da polpa de um dedo. O mínimo do WCAG 2.5.5 é 44px. Só em
   ponteiro grosso: no mouse, 31px é preciso e engordar o desktop inteiro
   seria pagar o preço no lugar errado. */
@media (pointer: coarse) {
  [data-pagina^="crm"] .btn,
  [data-pagina^="crm"] .crm-cartao__acao,
  [data-pagina^="crm"] .btn-close {
    min-height: 44px; display: inline-flex; align-items: center;
    justify-content: center; }
}

/* 3. CONTRASTE
   `--crm-tinta-3` dava 4,20:1 em 12px — abaixo dos 4,5:1 que o WCAG pede
   para texto pequeno. Medido em "07/08/2026 — Ligar", "Prospecção" e nos
   rótulos dos KPIs do funil. Um passo mais escuro resolve sem mudar a
   hierarquia: ele continua sendo o cinza de apoio, só que legível. */
[data-pagina^="crm"] { --crm-tinta-3: #5b6660; }

/* CRM — CONTORNOS VISÍVEIS COM BRILHO BAIXO
   Relato de uso: com o brilho da tela baixo, os contornos sumiam. Medido:
   83 elementos abaixo de 3:1 (WCAG 1.4.11), a maioria em 1,16:1 — quase três
   vezes abaixo do mínimo. `#e2e6e3` sobre branco é praticamente nada.

   A correção separa por FUNÇÃO, porque a norma separa:

   - No CAMPO, a borda é a de fábrica do Bootstrap (#454).
   - No CARTÃO, a borda é separador: o fundo e a sombra já delimitam a caixa,
     e a norma não pede 3:1 para o que é decorativo. Fica firme o bastante
     para aparecer com brilho baixo (1,88:1 contra os 1,26:1 de antes) sem
     transformar a tela num quadriculado de linhas escuras. */
/* `acompanhamento_inadimplencia` entra aqui porque usa o MESMO bloco de tokens
   (ver o seletor lá em cima) e tinha ficado de fora desta correção: seguia com
   as bordas antigas a 1,26:1 enquanto as duas telas de CRM já estavam em 1,88:1.
   O comentário do bloco original promete "se mudar aqui, muda nas duas telas" —
   esta linha é o que torna a promessa verdadeira. */
[data-pagina="crm"], [data-pagina="crm-deal"], [data-pagina="crm-agenda"],
[data-pagina="crm-tabelas-preco"], [data-pagina="crm-clientes"],
[data-pagina="crm-representantes"], [data-pagina="crm-usuarios"],
[data-pagina="crm-classificacao"],
[data-pagina="acompanhamento_inadimplencia"] {
  --crm-borda: #b6bfb9;          /* separador de cartão/faixa */
  --crm-borda-forte: #98a29c;    /* divisor que precisa pesar mais */
}

/* ── CRM · documentos do cliente ───────────────────────────────────────────
   Lista dentro do trilho: nome primeiro (é o que se procura), metadados numa
   linha fraca embaixo, e o estado da cópia no SharePoint como etiqueta à
   direita. Sem card por item — cartão dentro de cartão é ruído, e o trilho
   já é um. */
.crm-docs { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: .1rem; }
.crm-doc { display: grid; align-items: center; gap: .15rem .5rem;
  grid-template-columns: 1fr auto auto;
  grid-template-areas: "nome copia excluir" "meta copia excluir";
  padding: .45rem 0; border-top: 1px solid var(--crm-borda); }
.crm-doc:first-child { border-top: 0; }
.crm-doc-nome { grid-area: nome; display: flex; align-items: center; gap: .4rem;
  font-weight: 500;
  /* Nome de arquivo é longo e não quebra bem: corta com reticências em vez de
     empurrar a etiqueta de estado para fora do trilho. */
  min-width: 0; }
.crm-doc-meta { grid-area: meta; color: var(--crm-tinta-3); font-size: var(--fonte-pequena); }
.crm-doc-copia { grid-area: copia; align-self: center; white-space: nowrap;
  font-size: var(--fonte-pequena); font-weight: 500; padding: .1rem .4rem;
  border-radius: var(--raio-chip); border: 1px solid currentColor; text-decoration: none; }
.crm-doc-copia--ok { color: var(--crm-ok); background: var(--crm-ok-fundo); }
.crm-doc-copia--avi { color: var(--crm-avi); background: var(--crm-avi-fundo); }
.crm-doc-copia--erro { color: var(--crm-mal); background: var(--crm-mal-fundo); }
.crm-doc-excluir { grid-area: excluir; align-self: center; }
/* A porta para o acervo inteiro, no fim da lista curta da ficha. Não é item
   de arquivo: linha própria, sem borda de topo, para não parecer um documento
   a mais. */
.crm-doc-porta { padding: .5rem 0 .1rem; }
.crm-doc-porta a { font-weight: 500; font-size: var(--fonte-corpo); }

/* ── CRM · acervo de documentos (o terceiro canvas) ────────────────────────
   A lista do canvas reusa a casca do histórico (`hst-*`); o que muda é o
   ITEM, que aqui é um link para baixar e não um texto que expande. */
.dac-lista { display: flex; flex-direction: column; gap: .1rem; }
.dac-item { display: flex; align-items: flex-start; gap: .55rem;
  padding: .5rem .25rem; border-top: 1px solid var(--crm-borda);
  color: var(--crm-tinta); }
.dac-item:first-child { border-top: 0; }
.dac-item:hover, .dac-item:focus-within { background: var(--crm-fundo-2); }
/* O link é o corpo do item; o Excluir é irmão dele (04/09/2026 — botão dentro
   de <a> é HTML inválido, e o Excluir precisava voltar a existir aqui). */
.dac-item__link { display: flex; align-items: flex-start; gap: .55rem;
  min-width: 0; color: var(--crm-tinta); text-decoration: none; }
.dac-item__link:hover .dac-item__nome { text-decoration: underline; }
/* Só aparece quando o ponteiro está na linha ou o foco entra nela: a lista
   tem centenas de arquivos, e uma coluna de botões vermelhos em todas as
   linhas transformaria "excluir" no gesto mais visível de uma tela que serve
   para ACHAR arquivo. Em toque, onde não há hover, ele fica sempre visível —
   senão não haveria como alcançá-lo.
   O lápis de Renomear (#119) segue a mesma regra, pelo mesmo motivo. */
.dac-item__excluir, .dac-item__renomear { align-self: center; opacity: 0; transition: opacity .12s; }
.dac-item:hover .dac-item__excluir, .dac-item:hover .dac-item__renomear,
.dac-item__excluir:focus-visible, .dac-item__renomear:focus-visible { opacity: 1; }
@media (hover: none) { .dac-item__excluir, .dac-item__renomear { opacity: 1; } }
.dac-item__icone { margin-top: .15rem; color: var(--crm-tinta-3); }
.dac-item__corpo { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
/* Nome de arquivo do acervo chega a 184 caracteres: quebra em vez de cortar,
   porque aqui ele é o conteúdo, não um rótulo ao lado de outra coisa. */
.dac-item__nome { font-weight: 500; overflow-wrap: anywhere; }
.dac-item__descricao { font-style: italic; }
/* Renomear (#119): campo e extensão na mesma linha — o form-control é 100%
   e a .crm-linha quebra, o que jogava o ".pdf" para baixo do campo. */
.dac-item .crm-linha:has([data-renomeando]) { flex-wrap: nowrap; gap: .3rem; }
.dac-item [data-renomeando] { flex: 1 1 auto; width: auto; min-width: 0; }
/* Linha do arquivo em trânsito: nome, percentual e uma barra fina embaixo.
   A barra ocupa a faixa inteira (grid-column) para não competir com a
   etiqueta de estado, que nesta linha ainda não existe. */
.crm-doc--enviando { grid-template-areas: "nome nome nome" "meta meta meta"
  "barra barra barra"; color: var(--crm-tinta-2); }
.crm-doc--enviando .crm-doc-nome { color: var(--crm-tinta-2); }
.crm-doc-barra { grid-area: barra; height: 3px; margin-top: .35rem;
  background: var(--crm-borda); border-radius: var(--raio-chip); overflow: hidden; }
.crm-doc-barra__cheia { display: block; height: 100%;
  background: var(--crm-acento); border-radius: var(--raio-chip);
  transition: width .15s linear; }
@media (prefers-reduced-motion: reduce) {
  .crm-doc-barra__cheia { transition: none; }
}
/* Rede terminada, servidor ainda trabalhando: a barra deixa de medir e passa
   a só dizer "ainda estou aqui". Sem animação para quem pediu menos
   movimento — aí ela fica cheia e quieta. */
.crm-doc-barra--indefinida .crm-doc-barra__cheia {
  animation: crm-doc-pulsa 1.1s ease-in-out infinite; }
@keyframes crm-doc-pulsa { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
  .crm-doc-barra--indefinida .crm-doc-barra__cheia { animation: none; }
}
/* Motivo do "Preço base" vazio, embaixo do traço. Estreito de propósito: é
   explicação, não dado — não pode competir com os números da linha. */
.crm-sem-base { font-size: var(--fonte-pequena); line-height: 1.2; max-width: 22ch;
  margin-top: .1rem; }
/* Tabela de preço na própria linha do item, embaixo do número que ela explica.
   Sem rótulo: o cabeçalho da coluna já diz "Preço base", e um rótulo por cima
   empurrava o campo para baixo e o desalinhava dos vizinhos. */
/* Altura e fonte são as do `.form-control` ao lado (decisão do dono, 10/08):
   o campo era `form-select-sm` com padding próprio e ficava 7px mais baixo e
   3px mais embaixo que os vizinhos da mesma linha. O que sobrou de próprio é
   só o espaço da seta: a seta padrão do Bootstrap come 36px de um campo de
   120px e não sobraria largura para "0002 · R$ 5,30". */
.crm-tabela-item { padding-right: 1.5rem; background-position: right .4rem center;
  margin-left: auto; }
.crm-tabela-legenda { margin-top: .15rem; font-size: var(--fonte-pequena); }

/* --- ficha do cliente: o CANVAS sobre o funil ---
   Era página própria (`crm-ficha`) com duas colunas; virou painel (decisão do
   dono, 10/08/2026). A largura é o ponto: `crm-oc--larga` (30rem) é medida de
   formulário, e aqui dentro há duas tabelas de cinco colunas. 64rem cabe o
   extrato sem rolagem horizontal em tela de trabalho, e `96vw` garante que em
   telas menores o painel não fique maior que a janela. */
/* 25/08/2026 — O MOSAICO (direção A, escolhida pelo dono sobre três mockups).
   A ficha é leitura rápida: caixa para o que tem ação dentro (agendar,
   contatar), grade de caixas para os números, e o detalhe fechado embaixo.
   Medido em 15" a 125% (1536x864 CSS, ~750px úteis): o mosaico inteiro cabe
   acima da dobra e ainda sobram ~170px de folga.

   Largura de 52rem, não os 88rem de antes: com quatro colunas, 88rem dava
   230px de caixa para dizer "2", e o painel comia dois terços da tela sem
   usar. Estreito também devolve o funil ao fundo, que é o ponto de a ficha
   ser canvas e não página. */
/* 01/09/2026 — DUAS COLUNAS, e a largura volta a 88rem. Pedido do dono, com um
   print do Ploomes na mão: "quando busco um cliente para ligar, aparece o
   cadastro dele e ao lado o histórico dos contatos".

   Isto REVERTE a largura decidida em 25/08 (o parágrafo acima) — de propósito,
   e com autorização explícita dele. O que muda em relação àquela medição: os
   88rem de então eram UMA coluna com quatro caixinhas de 230px, espaço sem
   uso; aqui os 88rem são duas colunas com trabalho dentro das duas. E 88rem
   não é tamanho novo no sistema — é o mesmo do canvas de histórico, que este
   painel já abria ao lado. A segunda razão de 25/08 (o funil ao fundo) é a que
   se perde: quem quiser voltar a estreitar, saiba que perde o arranjo do
   print, e pergunte ao dono antes.

   Esquerda, 30rem (01/09/2026, entrevista com o dono): AGENDADOS em cima e a
   CONVERSA embaixo — o que está marcado e o que foi falado, cada caixa com a
   própria ação no cabeçalho. Direita: os cards de trabalho (pessoas, o que
   compra, propostas) e a referência fechada no fundo, cadastro incluído.
   `align-items: start` para a coluna curta não esticar os cards dela até a
   altura da outra. */
#crm-modal-ficha { --bs-offcanvas-width: min(88rem, 96vw); }
/* CHÃO (03/09/2026). O corpo do canvas não declarava fundo e herdava o branco
   do Bootstrap; os cards são `--crm-superficie`, que também é branco. Fundo,
   card e card-vazio no mesmo valor deixavam a tela sem figura e sem fundo — só
   um emaranhado de molduras de peso igual, e um vão vazio lia como BURACO em
   vez de chão. Com fundo por baixo, a borda de cada card vira redundante: quem
   sustenta a caixa passa a ser a sombra. */
#crm-modal-ficha .crm-painel, #crm-modal-ficha .crm-cartao {
  border-color: transparent; }
/* HIERARQUIA DO NOME (03/09/2026). `#fc-nome` usava `.crm-titulo` (13px) e os
   títulos de seção descem para 11px: TODO cabeçalho da ficha vivia num degrau
   só, e o assunto do painel inteiro ficava tipograficamente MENOR que
   "R$ 0,00" (15-17px). Sobe para 20px e o tracking DESCE: os .08em existem
   para abrir versal de 11px e, a 20px, espalham. Continua em caixa alta
   (decisão do dono, 03/09/2026) — o contraste vem de corpo, peso e tracking,
   não da caixa. */
#crm-modal-ficha #fc-nome { font-size: var(--fonte-titulo); letter-spacing: .02em; }
/* O MARCADOR ao lado do nome (reporte #70): as cores das etiquetas do Ploomes
   (P #2a58dc, M #d32626, M1 #2ad322), que é como o comercial as reconhece. Em
   fundo claro com a cor na letra, como toda `.crm-pilula`; o verde do M1 é
   claro demais para letra e escurece na mesma matiz. Inline depois do nome:
   nome longo quebra e o selo (nowrap) desce inteiro com a última palavra. */
.crm-pilula--marcador-preferencial { background: #e7edfc; color: #2a58dc; }
.crm-pilula--marcador-mercado      { background: #fbe9e9; color: #d32626; }
.crm-pilula--marcador-m1           { background: #e3f8e2; color: #1a7a15; }
#crm-modal-ficha #fc-nome + .crm-pilula { margin-left: .5rem; vertical-align: .15em;
  font-size: var(--fonte-corpo); font-weight: 500; }
/* O título de seção cede a tinta cheia ao nome: dois degraus de cor onde antes
   havia um. */
#crm-modal-ficha #fc-leitura .crm-titulo { color: var(--crm-tinta-2); }
/* O TELEFONE é a ação do card de pessoas (03/09/2026): ocupa o lugar que era
   do botão "Ocultar" e disca de verdade (`tel:` abre o discador). Peso de
   leitura, não de metadado — era o terceiro campo de uma sublinha de 11px numa
   tela usada para ligar vinte vezes por dia. Empilha quando a pessoa tem
   celular E fixo; `nowrap` porque número quebrado no meio não se lê. */
#crm-modal-ficha .fc-discar { display: flex; align-items: center; gap: .35rem;
  font-size: var(--fonte-corpo); font-weight: 500; white-space: nowrap; }
#crm-modal-ficha .fc-discar + .fc-discar { margin-top: .15rem; }
/* TRILHO da coluna de telefones (03/09/2026). Sem largura mínima, o ícone de
   cada linha nascia num x diferente conforme o tamanho do número — 88px de
   avanço entre a linha de dois telefones e as demais. E o `margin-top` era
   resíduo de um empilhamento que não acontece: os dois <a> são irmãos num flex
   `align-items:center`, e o deslocamento só desalinhava o par em 1px. */
#crm-modal-ficha .crm-linha-lista .fc-discar {
  justify-content: flex-end; min-width: 7.5rem; }
/* Na coluna de identidade o telefone abre a linha, não a fecha: o
   trilho de 7,5rem empurrava o número para a direita e derrubava o
   ícone de WhatsApp para a linha de baixo (medido no print de
   09/09/2026). */
#crm-modal-ficha #fc-contato-principal .fc-discar {
  justify-content: flex-start; min-width: 0; gap: .35rem; }
/* O par número + WhatsApp anda junto (`fc-fone`). No card de Pessoas o
   embrulho é transparente ao flex da linha, para o trilho de 7,5rem continuar
   valendo lá; na coluna de identidade ele é a linha. */
#crm-modal-ficha .crm-linha-lista .fc-fone { display: contents; }
#crm-modal-ficha .fc-principal__fones { display: flex; flex-direction: column;
  align-items: flex-start; gap: .15rem; }
#crm-modal-ficha .fc-principal__fones .fc-fone {
  display: inline-flex; align-items: center; gap: .25rem; }
#crm-modal-ficha .fc-discar + .fc-discar { margin-top: 0; }
/* Ancorado em `#fc-contatos-todos`: `.crm-linha-lista` também serve o bloco
   Características, onde `.crm-rotulo` é o rótulo À ESQUERDA de um par
   rótulo/valor — encostá-lo à direita ali quebraria a leitura. */
#crm-modal-ficha #fc-contatos-todos .crm-linha-lista > .crm-rotulo {
  min-width: 7.5rem; text-align: right; }
/* O glifo media 1,44x a altura de versal do número ao lado. */
#crm-modal-ficha .fc-discar .fa-phone { font-size: .8em; }
/* Ícone de WhatsApp ao lado do `fc-discar`, só quando o número normalizado é
   celular (`crm_cliente.whatsapp_de`) — mesma régua da grade, escopo
   diferente: a ficha é `#crm-modal-ficha`, `.cl-fone--zap` é
   `[data-pagina="crm-clientes"]` e não alcançaria aqui. Mesmo acento das
   outras ações, não o verde da marca — o ícone já diferencia. */
#crm-modal-ficha .fc-zap { color: var(--crm-acento); margin-left: .15rem; }
#crm-modal-ficha .fc-zap:hover, #crm-modal-ficha .fc-zap:focus-visible { opacity: .7; }
/* O fio entre pessoas usava a MESMA borda do cartão e do cabeçalho de mês —
   onze fios estruturais a 56px de passo dentro de um card que agora tem chão e
   sombra. O fio de item é o mesmo da conversa, ao lado. Separação não se perde:
   o vão dentro da pessoa é 11px e entre pessoas 24px. */
#crm-modal-ficha #fc-contatos-todos .crm-linha-lista { border-top-color: var(--bi-border-color-subtle); }
/* UM vão entre cards: estava declarado .6rem nas colunas e .75rem na grade. */
#crm-modal-ficha .fc-col-identidade,
#crm-modal-ficha .fc-col-trabalho { gap: .75rem; }
/* 12px é o piso do DESIGN.md; os títulos de seção estavam a 11px. */
#crm-modal-ficha #fc-leitura h2.crm-titulo,
#crm-modal-ficha .fc-faixa { font-size: var(--fonte-pequena); }
/* A MOLDURA NÃO ROLA (09/09/2026). O corpo do offcanvas rolava inteiro:
   1.671 px de conteúdo para 641 px de dobra a 1366×768, e o topo saía da vista
   junto com o resto. Agora o corpo é o palco de altura fixa e quem rola são as
   regiões marcadas com `.fc-rola`.
   `min-height: 0` nas duas: sem ele o item de grid usa a altura do CONTEÚDO
   como piso e a rolagem interna nunca acontece — o erro clássico de flex/grid,
   e ele falha em silêncio (a barra simplesmente não aparece). */
#crm-modal-ficha .offcanvas-body { background: var(--crm-fundo);
  display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
#crm-modal-ficha #fc-leitura.fc-moldura { flex: 1; min-height: 0;
  display: grid; align-items: stretch;
  grid-template-columns: minmax(0, 19.5rem) minmax(0, 1fr); gap: 0 1.25rem; }
#crm-modal-ficha .fc-rola { min-height: 0; overflow-y: auto;
  overscroll-behavior: contain; padding-bottom: 1.5rem; }
/* A BARRA DE ABAS fica parada no topo da coluna de trabalho; quem rola é o
   painel. `overflow-x: auto` é rede de segurança, não plano: nove abas é o
   teto combinado com o dono, e a décima faz a barra rolar de lado — levando
   junto a memória de posição, que é o que ela existe para preservar. */
#crm-modal-ficha .fc-col-trabalho { min-height: 0; }
/* #480: o cartão da proposta do negócio usa as mesmas abas da ficha. */
:is(#crm-modal-ficha, #dl-itens-card) .fc-abas { flex: none; display: flex; gap: .1rem;
  overflow-x: auto; padding: 0 .25rem;
  border-bottom: 1px solid var(--crm-borda); background: var(--crm-superficie); }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba { display: flex; align-items: center; gap: .3rem;
  white-space: nowrap; padding: .7rem .45rem; border: 0;
  border-bottom: 2px solid transparent; background: transparent;
  color: var(--crm-tinta-2); font: 500 .8125rem/1 inherit; cursor: pointer; }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba:hover { color: var(--crm-tinta); }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba[aria-selected="true"] { color: var(--crm-acento);
  border-bottom-color: var(--crm-acento); font-weight: 700; }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba:focus-visible { outline: 2px solid var(--crm-acento);
  outline-offset: -2px; }
#crm-modal-ficha .fc-painel { flex: 1; display: flex; flex-direction: column;
  gap: .6rem; }
#crm-modal-ficha .fc-painel[hidden] { display: none; }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba__n { font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: .75rem; color: var(--crm-tinta); background: var(--crm-fundo);
  border-radius: 9px; padding: .05rem .35rem; min-width: 1.25rem; text-align: center; }
:is(#crm-modal-ficha, #dl-itens-card) .fc-aba__n:empty { display: none; }
#crm-modal-ficha .fc-aba[aria-selected="true"] .fc-aba__n {
  background: var(--crm-acento-fundo); color: var(--crm-acento); }
/* Zero fica no lugar, apagado: aba que some conforme o cliente destrói a
   memória de posição, que é como esta gente navega. */
#crm-modal-ficha .fc-aba__n--zero { color: var(--crm-tinta-3); font-weight: 400; }
/* A COLUNA DE IDENTIDADE (09/09/2026): par rótulo/valor, sem caixa em volta.
   Caixa dentro de caixa foi o que deixou a ficha pesada antes. */
#crm-modal-ficha .fc-dinheiro { display: grid; grid-template-columns: 1fr auto;
  gap: .25rem .5rem; margin: 0; }
#crm-modal-ficha .fc-dinheiro dt { color: var(--crm-tinta-3); font-weight: 400; }
#crm-modal-ficha .fc-dinheiro dd { margin: 0; text-align: right; font-weight: 500;
  font-variant-numeric: tabular-nums; }
/* Cor significa dinheiro: só o vencido acende, e só quando o servidor diz que
   ele está inadimplente. Vermelho permanente vira ruído. */
#crm-modal-ficha .fc-dinheiro dd.fc-dinheiro__mal { color: var(--crm-mal); }
/* A porta do cadastro: contorno tracejado para dizer "isto abre" sem competir
   com o único botão cheio da tela ("Nova proposta"). */
#crm-modal-ficha .fc-porta-cadastro { display: block; width: 100%; text-align: left;
  background: transparent; border: 1px dashed var(--crm-borda-forte);
  border-radius: 6px; padding: .5rem .65rem; cursor: pointer; font: inherit; }
#crm-modal-ficha .fc-porta-cadastro:hover,
#crm-modal-ficha .fc-porta-cadastro:focus-visible {
  border-color: var(--crm-acento); background: var(--crm-acento-fundo); }
#crm-modal-ficha .fc-porta-cadastro__verbo { display: block; font-weight: 500;
  color: var(--crm-acento); }
#crm-modal-ficha .fc-col-identidade,
#crm-modal-ficha .fc-col-trabalho { display: flex; flex-direction: column; gap: .6rem;
  min-width: 0; }
/* Empilha cedo: duas colunas só valem quando as duas cabem inteiras. Abaixo
   disto a ficha volta a ser UMA coluna na ordem do documento — agendados e
   conversa primeiro, que é o que se quer ao abrir; o `order:-1` de antes
   subia o trabalho porque agendamento e contato moravam lá, o que deixou de
   ser verdade em 01/09/2026. */
@media (max-width: 1200px) {
  #crm-modal-ficha .offcanvas-body { display: block; overflow-y: auto; }
  #crm-modal-ficha #fc-leitura.fc-moldura {
    grid-template-columns: 1fr; align-items: start; }
  #crm-modal-ficha .fc-rola { overflow-y: visible; padding-bottom: 0; }
}
/* A conversa: a lista usa o item do canvas de histórico (ver `.hst-item`), e
   aqui só se ajusta o que é de bloco — o último item não precisa do fio de
   baixo, que o card já dá, e a porta para o arquivo inteiro fica à direita,
   onde termina a leitura. */
#crm-modal-ficha .fc-conversa-lista .hst-item:last-of-type { border-bottom: 0; }
#crm-modal-ficha .fc-conversa-rodape { display: flex; justify-content: flex-end;
  padding-top: .5rem; }
/* Densidade da ficha (01/09/2026, segunda rodada — "reduzir a rolagem"):
   painel um degrau mais justo que o 1rem/1.15rem global, SÓ aqui — a régua
   global serve páginas de leitura; a ficha é bancada de trabalho e paga
   rolagem por cada .2rem de almofada. */
#crm-modal-ficha .crm-painel { padding: .8rem 1rem; }
#crm-modal-ficha .crm-tabela a { font-weight: 500; }
/* DESCENDENTE, não filho direto: com as duas colunas as seções passaram a
   morar a dois e a três níveis (`#fc-leitura > .fc-col-trabalho > .fc-acoes >
   section`). Os seletores `>` de antes deixavam de casar exatamente as
   caixas de ação — e o `:empty` abaixo é o que impede um bloco vazio de abrir
   um vão do tamanho de um card que não existe (filiais, triangulações, os
   blocos do ERP num lead, esvaziados em `ficha.js`). Não há `<section>` na
   ficha que NÃO queira estas duas regras, então descendente é a forma
   honesta. */
#crm-modal-ficha #fc-leitura section { margin-bottom: 0; }
#crm-modal-ficha #fc-leitura section:empty { display: none; }

/* Par de cards na mesma linha (Pessoas cadastradas · Cadastro). Empilha cedo:
   card espremido esconde e-mail e telefone, que são o motivo do card.
   `align-items: start` para o cadastro fechado não esticar até a altura do
   vizinho. */
#crm-modal-ficha .fc-caixa { display: flex; flex-direction: column; height: 100%; }
#crm-modal-ficha .fc-caixa-topo { margin-bottom: .35rem; }
/* O valor da caixa: caixa mista, 15px. É o único texto de conteúdo em corpo
   maior da ficha — o nome de quem se liga e o que se combinou. */
#crm-modal-ficha .fc-caixa-valor { font-size: var(--fonte-corpo); font-weight: 500;
  color: var(--crm-tinta); line-height: 1.2; }

/* A faixa rotulada do mosaico: rótulo curto e um fio até a borda. Separa os
   grupos sem dar a cada um uma caixa em volta — caixa dentro de caixa foi o
   que deixou a ficha pesada. */
#crm-modal-ficha .fc-faixa { display: flex; align-items: center; gap: .5rem;
  font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; color: var(--crm-tinta-3); margin-bottom: .35rem; }
#crm-modal-ficha .fc-faixa::after { content: ""; flex: 1; height: 1px;
  background: var(--crm-borda); }
/* A grade: quatro colunas iguais em tela de trabalho. `.measures` é o
   componente do design system (o mesmo do funil e da separação) — aqui só
   troca o flex por grade, para as caixas terem a MESMA largura: número que
   não alinha não se compara. */
/* `auto-fit` de novo desde 01/09/2026: as faixas passaram a ter contagens
   diferentes (Abrir = 3, medidas = 4, posição = 3) e um número fixo obriga a
   4ª medida a quebrar sozinha numa linha — era o whitespace que o dono
   circulou. Cada faixa preenche a própria linha; o mínimo de 12rem segura o
   rótulo comprido ("Adiantamentos a consumir") sem espremer. */
#crm-modal-ficha .fc-mosaico { display: grid; gap: .5rem; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
@media (max-width: 1200px) {
  #crm-modal-ficha .fc-mosaico { grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); }
}
/* Porta: a caixa que ABRE outra tela. Mesma forma da medida, mais o alvo de
   clique e o verde do valor, que é o que diz "isto leva a algum lugar". */
#crm-modal-ficha .fc-porta { text-align: left; cursor: pointer; font: inherit; }
#crm-modal-ficha .fc-porta .measure__v { color: var(--crm-acento); }
/* #327: Vencido é porta (abre as faturas) e alerta ao mesmo tempo — o tom do alerta vence. */
#crm-modal-ficha .fc-porta.measure--alerta .measure__v { color: var(--warning-text); }
#crm-modal-ficha .fc-porta:hover, #crm-modal-ficha .fc-porta:focus-visible {
  border-color: var(--crm-acento); background: var(--crm-superficie); }
#crm-modal-ficha .fc-porta-sub { font-size: var(--fonte-pequena); color: var(--crm-tinta-3);
  margin-top: .1rem; }

/* Os títulos dos blocos de detalhe recuam meio tom: eles são a etiqueta de
   uma gaveta fechada, não uma manchete. */
#crm-modal-ficha #fc-leitura h2.crm-titulo { font-size: var(--fonte-pequena);
  font-weight: 500; letter-spacing: .1em; color: var(--crm-tinta-2); }
/* Bloco dobrável: o cabeçalho do bloco É o <summary> — título, resumo do
   fechado ("4 produtos", "6") e a ação na mesma linha. O marcador é o
   `.drill-plus`; o resumo é rótulo, não número grande. */
#crm-modal-ficha .fc-bloco > summary { align-items: center; gap: .5rem; }
#crm-modal-ficha .fc-bloco-resumo::before { content: '· '; }
/* O cabeçalho é uma coluna (nome em cima, identidade embaixo), não a linha
   padrão do Bootstrap — o nome do cliente é o título do painel e não pode
   competir com as pílulas. */
#crm-modal-ficha .fc-cabecalho { align-items: flex-start; }
/* "Nova proposta" (28/08/2026): entre a identidade (que cresce) e o X de
   fechar — sem `gap` no `.offcanvas-header` do Bootstrap, o botão colava
   no X. */
#crm-modal-ficha #fc-capa-acao { flex: none; margin-inline-end: .5rem; }
#crm-modal-ficha .fc-identidade { display: flex; flex-wrap: wrap;
  align-items: center; gap: .5rem; margin-top: .35rem; width: 100%; }
/* Título de bloco é <h2> de verdade (leitor de tela navega por cabeçalho);
   o tamanho continua sendo o do `.crm-titulo`, só o margin do h2 sai. */
#crm-modal-ficha h2.crm-titulo, #crm-modal-ficha h3 { margin: 0; }
#crm-modal-ficha #fc-nome:focus-visible { outline: 2px solid var(--acc-line); outline-offset: 2px; }
/* Cadastro em grade: são nove pares rótulo/valor curtos, e um por linha
   esticava o bloco a uma tela inteira de leitura vertical para nada. */
#crm-modal-ficha .fc-cadastro-grade { display: grid; gap: .5rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
/* `overflow-wrap`: com o painel a 64rem a grade do cadastro chega a quatro
   colunas, e um e-mail longo passava por baixo da borda do card. */
#crm-modal-ficha .fc-campo { min-width: 0; overflow-wrap: anywhere; }
/* O componente de anexar mudou de endereço para dentro do canvas do acervo, e
   a lista curta dele não tem o que fazer ali: o acervo inteiro, com filtro e
   facetas, está logo abaixo. */
#crm-modal-documentos .dac-anexar .crm-docs { display: none; }
#crm-modal-documentos .dac-anexar .crm-painel { margin-top: 0; }
/* A lacuna do cadastro de um LEAD. Itálico no cinza-3: tem de se distinguir à
   primeira passada de olho de um campo que alguém já preencheu, sem virar um
   segundo tom de cinza no design system. */
#crm-modal-ficha .fc-campo-convite { color: var(--crm-tinta-3);
  font-style: italic; }
/* A frase do bloco vazio. Cinza-3 (não o cinza-4 de placeholder): é conteúdo
   — "este CNPJ nunca comprou" é resposta, não ausência de resposta. */
#crm-modal-ficha .fc-vazio { color: var(--crm-tinta-3);
  font-size: var(--fonte-corpo); }
/* Documentos (Task 6): o componente compartilhado nasce com `mt-3` (o
   espaço que separa dele de um bloco anterior no negócio/funil) — aqui já
   está dentro de `section.mb-3`, então o espaço de cima duplicava. */
#crm-modal-ficha #fc-doc-painel { margin-top: 0; }
/* Texto livre do vendedor (observações do cadastro), no MESMO tratamento
   âmbar da capa do negócio: preserva as quebras que a limpeza do HTML, no
   servidor, já reduziu a `\n`. */
#crm-modal-ficha .crm-obs-cliente { white-space: pre-line; }
/* Observações do cadastro: teto de 4 linhas no CONJUNTO (P0 da dobra,
   19/08/2026) — a caixa âmbar de LEONARDI tinha 1.201px de procedimento
   fiscal e a dobra inteira era isso. O resto ROLA dentro da caixa, nunca
   some atrás de reticência (#476, decisão 11). */
#crm-modal-ficha .fc-obs { max-height: 6em; overflow-y: auto; }
#crm-modal-ficha .fc-obs--inteira { max-height: none; }
/* Observações do cadastro em EDIÇÃO (19/08/2026, "tudo editável"): cada
   item = rótulo/seletor de tipo + Remover + textarea. Removida fica
   rebaixada até o Salvar — é decisão, não gesto; o Cancelar desfaz. */
#crm-modal-ficha .fc-obs-lista { display: grid; gap: .75rem; }
#crm-modal-ficha .fc-obs-item--removida textarea { opacity: .45; text-decoration: line-through; }
#crm-modal-ficha .fc-obs-campo { width: auto; }

/* `.fc-tl-*` (o item da linha do tempo que a ficha desenhava até 25/08/2026)
   foi DELETADO em 01/09/2026: o bloco saiu do corpo naquela data e virou o
   chip "Conversas", e desde então nenhum JS emitia essas classes nem o
   `data-expandir-texto` que as abria — CSS e handler órfãos. A conversa
   voltou à ficha em 01/09, mas com o item do canvas de histórico
   (`.hst-item`, logo abaixo), que é o mesmo desenho nas duas telas. Ressuscitar
   o `.fc-tl-*` teria dado à ficha um segundo desenho de conversa. */

/* Próximo passo — a faixa de decisão no topo da capa (19/08/2026). Único
   elemento em caixa mista de 16px (`.crm-pergunta`). Âmbar só quando atrasado:
   cor com significado, e só aí — mesmos tokens de `.crm-aviso--avi`. */
#crm-modal-ficha .fc-passo-linha { gap: .5rem; flex-wrap: wrap; margin-top: .35rem; }
/* #f0d9a7: a MESMA borda âmbar de `.crm-aviso--avi` (custom.css:9805), copiada
   e não tokenizada porque o par fundo/borda do aviso ainda não tem token de
   borda — mudou lá, muda aqui. */
#crm-modal-ficha .fc-passo--atrasado { background: var(--crm-avi-fundo); border-color: #f0d9a7; }

/* Compromisso vencido na lista da agenda do cliente. Mesmo fundo de aviso da
   faixa acima, para o mesmo fato ler igual nos dois lugares; quem classifica é
   o servidor (campo `atrasado`), aqui só se pinta. */
#crm-modal-ficha .fc-compromisso--atrasado > td { background: var(--crm-avi-fundo); }

/* <details> nativo para o que é referência (cadastro, extrato de pedidos):
   fechado por padrão, sem JS. Summary no tom de rótulo, cursor de alvo. O
   marcador é o `.drill-plus` canônico (+ ↔ −) que `bloco()` põe no summary;
   o do navegador some. */
#crm-modal-ficha .fc-details > summary { cursor: pointer; list-style: none; }
/* Pedidos usa <h2> dentro do <summary> (título do bloco = rótulo do
   fechado, "menos DOM"). `h2` é bloco por padrão — sem isto o marcador
   quebrava linha antes do texto. */
#crm-modal-ficha .fc-details > summary h2.crm-titulo { display: inline; }
#crm-modal-ficha .fc-details > summary::-webkit-details-marker { display: none; }
#crm-modal-ficha .fc-details > summary:focus-visible { outline: 2px solid var(--acc-line); outline-offset: 2px; }

/* No telefone as cinco medidas em fita (`.measures` é flex com `min-width: 7rem`)
   se quebravam em três linhas irregulares — 112, 112 e 157px na mesma linha,
   cada uma começando num lugar diferente. Número que não alinha não se compara,
   que é o motivo de o componente existir. Em duas colunas iguais as três linhas
   viram uma grade: mesma largura, mesma margem, e a quinta ficha ocupa a sua
   coluna sem esticar. Medido a 390x844. */
@media (max-width: 575.98px) {
  #crm-modal-ficha .measures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Os 96vw da largura padrão davam 374px no telefone contra os 390px do canvas
     de histórico, que já é 100vw: trocar de painel ("Ver a conversa inteira" e
     "Voltar à ficha") mexia a janela 16px para os lados a cada ida e volta, e
     sobrava uma faixa do funil que não é para tocar. No telefone os dois
     canvas ocupam a tela inteira. */
  #crm-modal-ficha { --bs-offcanvas-width: 100vw; }
}

/* --- CRM · histórico do cliente: o SEGUNDO canvas sobre o funil (19/08/2026) ---
   `.hst-*` escopado em :is(#crm-modal-historico, #crm-modal-documentos). Canvas de leitura longa com
   filtros: largura máxima do sistema; o corpo rola, cabeçalho/filtros/régua
   ficam. Selecionado = fundo + peso do rótulo (sem faixa lateral); canal é
   texto, não cor. */
:is(#crm-modal-historico, #crm-modal-documentos) { --bs-offcanvas-width: min(88rem, 96vw); }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-cabecalho { align-items: center; gap: .75rem; }
/* No telefone o rótulo quebrava em três linhas e esmagava o cabeçalho: o botão
   é controle de tamanho fixo, quem quebra é o nome do cliente. */
:is(#crm-modal-historico, #crm-modal-documentos) #hst-voltar { white-space: nowrap; }
:is(#crm-modal-historico, #crm-modal-documentos) h2.crm-titulo, :is(#crm-modal-historico, #crm-modal-documentos) h3 { margin: 0; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros-faixa { padding: .5rem 1.25rem; border-bottom: 1px solid var(--crm-borda); }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-busca-linha { gap: .75rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros { margin-top: .5rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros__summary { cursor: pointer; list-style: none; min-height: 2rem; display: flex; align-items: center; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros__summary::-webkit-details-marker { display: none; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros__summary .drill-plus { margin-right: .35rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros__corpo { display: grid; gap: 1rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); padding: .5rem 0 .25rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-grupo { display: flex; flex-direction: column; gap: .3rem; margin: 0; padding: 0; border: 0; min-width: 0; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-grupo--periodo { grid-column: span 2; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-presets { display: flex; flex-wrap: wrap; gap: .25rem; }
/* Campo secundário do grupo: os presets são o caminho comum, o intervalo exato
   é a exceção — largura de data, não de coluna. */
:is(#crm-modal-historico, #crm-modal-documentos) #hst-periodo { max-width: 14rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-faceta { display: flex; align-items: center; gap: .5rem; min-height: 2rem; cursor: pointer; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-faceta:has(input:checked) { font-weight: 500; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-corpo { padding-top: 0; }
/* Mês: sub-bloco em caixa mista, 12px/600, sticky DENTRO do corpo rolante.
   `#crm-modal-negocios` reaproveita a MESMA classe para o cabeçalho
   aberto/anterior (28/08/2026) — é o mesmo mecanismo "cabeçalho quando o
   grupo muda", só que o grupo aqui não é mês. */
/* O cabeçalho de mês respirava 10px acima e 12px abaixo contra 19px entre duas
   conversas, e saía mais claro que as datas que ele agrupa — separava menos do
   que o que estava separando. */
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-negocios) .hst-mes {
  padding: 1.25rem 0 .5rem; color: var(--crm-tinta); }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-negocios) .hst-mes { position: sticky; top: 0; z-index: 1; margin: 0;
  padding: .5rem 0; font-size: var(--fonte-pequena); font-weight: 500; color: var(--crm-tinta-2);
  background: var(--bs-offcanvas-bg, #fff); border-bottom: 1px solid var(--crm-borda); }
/* Um alvo por item: a linha inteira é botão. Hover/focus autorais; aberto =
   fundo + peso (sem faixa lateral).

   `#crm-modal-ficha` entra no escopo em 01/09/2026: a ficha passou a mostrar
   as últimas conversas na coluna da direita, e o item é o MESMO — mesma
   anatomia, mesmo abrir. Só as regras DO ITEM (daqui até `.hst-campo`) valem
   na ficha; cabeçalho, faixa de filtros e régua continuam sendo do canvas,
   que é quem os tem. */
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item { display: flex; flex-direction: column; gap: .15rem; width: 100%;
  text-align: left; padding: .6rem .5rem; min-height: 44px; border: 0; border-bottom: 1px solid var(--bi-border-color-subtle);
  background: transparent; color: inherit; font: inherit; cursor: pointer; transition: background-color .16s ease-out; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item:hover { background: var(--bi-bg-hover); }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item:focus-visible { outline: 2px solid var(--acc-line); outline-offset: -2px; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item[aria-expanded="true"] { background: var(--surf-2); border-bottom-color: transparent; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item[aria-expanded="true"] .hst-item__topo { font-weight: 500; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item[aria-expanded="true"] .hst-item__texto { display: none; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item--auto { opacity: .85; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item__topo { display: flex; gap: .5rem; flex-wrap: wrap; font-size: var(--fonte-pequena); }
/* A linha é o único elemento interativo da lista e em repouso nada dizia isso
   (hover não existe no toque). O `.drill-plus` no fim do topo conta as duas
   metades — "esta linha abre" e "está aberta" — pelo `aria-expanded` que
   `historico.js` já mantém (regra global do componente), sem JS. */
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item .hst-item__topo .drill-plus { margin-left: auto; }
/* No CANVAS o item tem 1368px, e o `margin-left:auto` jogava o `+` a 1089px do
   rótulo que ele abre — longe demais do que nomeia. Na ficha (coluna de 466px)
   o encosto à direita continua certo. */
:is(#crm-modal-historico, #crm-modal-documentos) .hst-item .hst-item__topo .drill-plus { margin-left: 0; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-item__texto { display: block; white-space: pre-line; max-height: 4.5em; overflow-y: auto; }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-detalhe { padding: 0 .5rem .85rem; background: var(--surf-2);
  border-bottom: 1px solid var(--bi-border-color-subtle); }
:is(#crm-modal-historico, #crm-modal-documentos, #crm-modal-ficha) .hst-texto { white-space: pre-line; margin-bottom: .6rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-campo { margin-top: .3rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-vazio { color: var(--crm-tinta-3); font-size: var(--fonte-corpo); padding: 1rem 0; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-mais { padding: .75rem 0; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-regua { align-items: center; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-frase { margin: 0; flex: 1 1 12rem; }
:is(#crm-modal-historico, #crm-modal-documentos) .hst-regua > #hst-registrar { flex: 0 0 auto; }
@media (prefers-reduced-motion: reduce) { :is(#crm-modal-historico, #crm-modal-documentos) * { transition-duration: 0ms !important; } }
@media (max-width: 575.98px) {
  :is(#crm-modal-historico, #crm-modal-documentos) { --bs-offcanvas-width: 100vw; }
  :is(#crm-modal-historico, #crm-modal-documentos) .hst-grupo--periodo { grid-column: auto; }
  :is(#crm-modal-historico, #crm-modal-documentos) :is(.btn, .form-select) { min-height: 44px; }
}
/* A 390x844 os filtros abertos empilham numa coluna só e a faixa passava de
   830px: o corpo da conversa sobrava com 16px de altura e a régua "Registrar
   contato" caía 144px ABAIXO da janela (medido). A faixa é um item de flex que
   não encolhe (bloco, sem overflow próprio), então o teto tem de estar aqui: o
   corpo dos filtros rola dentro de si e a conversa continua sendo o que ocupa a
   tela. Vale até 991,98px porque no tablet os filtros nascem ABERTOS (768px é o
   ponto em que historico.js os abre) e sem o teto sobravam 220px de conversa. */
@media (max-width: 991.98px) {
  :is(#crm-modal-historico, #crm-modal-documentos) .hst-filtros__corpo { max-height: 38vh; overflow-y: auto; }
}
/* Alvo de toque no canvas de histórico: o mínimo do WCAG 2.5.5 é 44px e aqui
   ficavam abaixo dele os presets de período (29,6px), as facetas de canal e
   origem (32px) e a busca (32,6px). A regra por LARGURA acima não alcançava o
   tablet a 768px, que é dedo igual ao telefone — quem responde por dedo é
   `pointer: coarse`, não a largura da tela. */
@media (pointer: coarse) {
  :is(#crm-modal-historico, #crm-modal-documentos) .hst-presets .btn,
  :is(#crm-modal-historico, #crm-modal-documentos) .hst-faceta,
  :is(#crm-modal-historico, #crm-modal-documentos) .form-control,
  :is(#crm-modal-historico, #crm-modal-documentos) .form-select { min-height: 44px; }
}

/* ==========================================================================
   IMPRESSÃO — o entregável declarado das telas de diretoria É o print/PDF de
   reunião (PRODUCT.md), e até 2026-08-07 a app inteira tinha ZERO regra
   própria de @media print (critique /despesas/, P2): o PDF saía com sidebar
   de ícones, topbar de filtros e controles mortos. Regra global do shell —
   o conteúdo imprime; o chrome do app, não.
   ========================================================================== */
@media print {
  .side, #topbar, .filtbtn, .fcds-filters-host, .fcds-stale { display: none !important; }
  .main { margin: 0 !important; }
  .content { padding: 0 !important; }
  body { background: #fff !important; }
  /* Cartão não quebra no meio da página; sombras/anéis fora. */
  .card, section.card { break-inside: avoid; box-shadow: none !important; }
  /* Controles de tela não fazem sentido no papel. */
  .state-error__botao-retry, [data-mostrar-mais], #bi-vazio-restaurar { display: none !important; }
  /* O skip link (`.skip`, base_fcds.html) é chrome do SHELL, igual a `.side`/
     `#topbar` acima — em nenhuma tela ele deveria ir para o papel. Achado
     16/09/2026 no pedido impresso: `position: fixed` do skip link, pensado
     para ficar fora da viewport (`top: -4rem`) até o foco de teclado, não
     respeita o recorte de página do Chromium ao gerar PDF — ele reaparece
     dentro da folha (canto inferior esquerdo da página 1). Regra global
     porque a causa é do SHELL, não desta tela: qualquer página que imprima
     está sujeita ao mesmo comportamento do Chromium. */
  .skip { display: none !important; }
}

/* ==========================================================================
   CRM · PEDIDO IMPRESSO (`[data-pagina="crm-pedido-imprimir"]`, 16/09/2026)
   — a folha do pedido no layout do modelo do Sênior
   `RVPE148.GER` ("[FOUR] Pedido de Vendas Steel"), decisão do dono
   (15-16/09/2026): o app REPLICA esse modelo, não inventa um novo.
   `crm/templates/crm/pedido_interno.html` é o único consumidor.

   Página NOMEADA (mesmo padrão de `simulacao`, acima): o `@page` anônimo já
   pertence à proposta do CRM (margens 30/40mm e cabeçalho corrido), que
   este documento não usa.
   ========================================================================== */
@page pedido-impresso { size: A4; margin: 12mm; }

/* Visual com o RVPE148 como BASE (dono, 16/09/2026): "o objetivo é não
   replicar pixel perfect, mas sim usar o Sênior como base para uma entrega
   superior". Daí: tinta preta, Arial compacta, rótulo em NEGRITO e valor
   regular, caixa fina em volta de faixa + cliente, itens em Courier — a
   cara que o leitor do pedido já conhece. A melhoria que o Sênior não tem:
   NENHUM valor é cortado ("NÃO CORTAR E-MAIL, é dado e pode comprovar uma
   entrega para endereço errado") — quebra de linha, nunca reticências. */
[data-pagina="crm-pedido-imprimir"] { background: var(--bg); min-height: 100vh; padding: 24px 0 48px; }

[data-pagina="crm-pedido-imprimir"] .folha {
  page: pedido-impresso;
  max-width: 210mm; margin: 0 auto; background: #fff; color: #000;
  padding: 12mm; font-family: Arial, Helvetica, sans-serif;
  font-size: 11.5px; line-height: 1.3; letter-spacing: 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
}
[data-pagina="crm-pedido-imprimir"] .folha b,
[data-pagina="crm-pedido-imprimir"] .folha strong { font-weight: 700; }

[data-pagina="crm-pedido-imprimir"] .folha__cabecalho {
  display: flex; align-items: flex-end; gap: 14px;
  border-top: 1px solid #000; padding-top: 8px; margin-bottom: 6px;
}
/* Marca empilhada (463×276) a ~130px: ~340 ppi no A4, nítida no papel. */
[data-pagina="crm-pedido-imprimir"] .folha__logo { width: 130px; height: auto; flex: none; }
/* Cabeçalho da empresa todo em negrito, com CEP e IE na mesma linha do
   endereço/CNPJ, como o RVPE148. */
[data-pagina="crm-pedido-imprimir"] .folha__empresa { flex: 1; min-width: 0; font-size: 11.5px; font-weight: 700; }
[data-pagina="crm-pedido-imprimir"] .folha__empresa strong { display: block; font-size: 13.5px; margin-bottom: 1px; }
[data-pagina="crm-pedido-imprimir"] .folha__empresa div span + span { margin-left: 3em; }

/* Faixa e bloco do cliente numa caixa fina só (a faixa fecha em cima, o
   bloco continua embaixo sem borda dupla). */
[data-pagina="crm-pedido-imprimir"] .folha__faixa {
  display: flex; justify-content: space-around; align-items: center; gap: 12px;
  font-size: 14px; font-weight: 700; border: 1px solid #000; padding: 4px 8px;
}
/* Pedido cancelado inteiro sai com os itens e esta marca no meio da faixa
   (dono, 16/09/2026) — sem ela a folha parece um pedido vivo. */
[data-pagina="crm-pedido-imprimir"] .folha__cancelado {
  color: var(--negative-text); border: 1px solid currentColor; padding: 0 8px; letter-spacing: .04em;
}

/* `minmax(0, 1fr)` nas duas colunas (achado de revisão, 16/09/2026): sem o
   `0`, o Grid usa o CONTEÚDO da coluna como largura MÍNIMA — os e-mails
   longos puxavam a coluna do cliente, a folha passava ~10px da área
   imprimível do A4 e o Chromium CORTAVA o texto na borda física da página
   ("Terceiros(6923)" perdia o fecha-parênteses). Não voltar a `auto`.
   `.folha__bloco--largo` (Cliente/CNPJ/Endereço) ocupa as duas colunas, e
   as condições começam na altura de "Bairro", como no RVPE148. */
[data-pagina="crm-pedido-imprimir"] .folha__duas-colunas {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 0 16px; border: 1px solid #000; border-top: 0; padding: 4px 6px; margin-bottom: 0;
}
[data-pagina="crm-pedido-imprimir"] .folha__bloco--largo { grid-column: 1 / -1; }
/* `.folha__bloco` também é o par de colunas dos TOTAIS, mais abaixo — os
   dois lêem o mesmo rótulo:valor de `.folha__linha` (Reuse before create). */
[data-pagina="crm-pedido-imprimir"] .folha__bloco { margin: 0; min-width: 0; }
[data-pagina="crm-pedido-imprimir"] .folha__linha { display: flex; gap: 4px; margin: 0; }
[data-pagina="crm-pedido-imprimir"] .folha__linha dt { font-weight: 700; white-space: nowrap; flex: none; }
/* `min-width: 0` (mesmo motivo do Grid, um nível abaixo) + `anywhere`: a
   lista de e-mails vem colada por `;`, sem espaço — `break-word` sozinho
   não reduz a largura mínima do item flex, `anywhere` reduz, e o e-mail
   quebra DENTRO da coluna em vez de ser cortado ou empurrar a folha. */
[data-pagina="crm-pedido-imprimir"] .folha__linha dd { margin: 0; font-weight: 400; min-width: 0; overflow-wrap: anywhere; }

/* Itens: cabeçalho em negrito entre dois fios, linhas em Courier como o
   RVPE148 (números alinham pela coluna); valores à direita. */
[data-pagina="crm-pedido-imprimir"] .folha__itens {
  width: 100%; border-collapse: collapse; margin: 0 0 6px; font-size: 11px;
  border-bottom: 1px solid #000;
}
[data-pagina="crm-pedido-imprimir"] .folha__itens th {
  border-bottom: 1px solid #000; padding: 2px 4px; text-align: right;
  font-weight: 700; white-space: nowrap;
}
[data-pagina="crm-pedido-imprimir"] .folha__itens td {
  padding: 1px 4px; text-align: right; vertical-align: top; border-bottom: 1px solid var(--line);
  font-family: "Courier New", Courier, monospace; font-size: 10.5px; overflow-wrap: anywhere;
}
[data-pagina="crm-pedido-imprimir"] .folha__itens td:nth-child(n+3) { white-space: nowrap; }
[data-pagina="crm-pedido-imprimir"] .folha__itens th:nth-child(-n+2),
[data-pagina="crm-pedido-imprimir"] .folha__itens td:nth-child(-n+2) { text-align: left; }

/* Mesmo `minmax(0, 1fr)` do `.folha__duas-colunas` acima, por prevenção. */
[data-pagina="crm-pedido-imprimir"] .folha__totais {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 16px;
  padding: 0 6px 6px; margin-bottom: 4px; border-bottom: 1px solid #000;
}
[data-pagina="crm-pedido-imprimir"] .folha__totais .folha__linha dd { font-weight: 700; }

[data-pagina="crm-pedido-imprimir"] .folha__clausulas { font-size: 10px; line-height: 1.3; }
[data-pagina="crm-pedido-imprimir"] .folha__clausulas p { margin: 0; }
[data-pagina="crm-pedido-imprimir"] .folha__clausula { margin: 0 0 5px; }
/* Títulos das seções e as cláusulas 1-2 em negrito, corpo miúdo (RVPE148). */
[data-pagina="crm-pedido-imprimir"] .folha__clausula strong { display: block; font-size: 11.5px; margin-bottom: 1px; }
[data-pagina="crm-pedido-imprimir"] .folha__clausula--destaque { font-size: 11.5px; font-weight: 700; }
[data-pagina="crm-pedido-imprimir"] .folha__remessa,
[data-pagina="crm-pedido-imprimir"] .folha__armazem { margin-top: 8px; }
[data-pagina="crm-pedido-imprimir"] .folha__remessa { border-top: 1px solid #000; padding-top: 2px; }
[data-pagina="crm-pedido-imprimir"] .folha__remessa p,
[data-pagina="crm-pedido-imprimir"] .folha__armazem p { margin: 0 0 2px; overflow-wrap: anywhere; }

/* A folha do pedido é o único documento do app pensado para se espalhar por
   VÁRIAS páginas — a regra global acima (linha ~13027) trava `.card` numa
   página só, o que não se aplica aqui (o novo layout nem usa `.card`).
   Nunca uma linha de item partida entre duas páginas impressas. */
@media print {
  [data-pagina="crm-pedido-imprimir"] { background: #fff; padding: 0; }
  /* `width: 100%` explícito (16/09/2026): no impresso a folha deixa de ser
     centralizada (era `margin: 0 auto` sobre `max-width: 210mm`, o layout de
     TELA) e passa a OCUPAR toda a área imprimível que o `@page
     pedido-impresso` (acima) já reservou — sem isso o `max-width: none`
     sozinho ainda deixava a largura ao sabor do conteúdo, a mesma armadilha
     do Grid resolvida logo abaixo. */
  [data-pagina="crm-pedido-imprimir"] .folha {
    box-shadow: none; width: 100%; max-width: none; padding: 0;
  }
  [data-pagina="crm-pedido-imprimir"] tr { break-inside: avoid; }
}

/* A folha como ARQUIVO (#779, `pedido_folha_pdf.html`). O WeasyPrint não mede o Grid com `minmax(0, …)` nem o
   flex com `overflow-wrap: anywhere` (saía uma letra por linha): aqui, só no PDF, as colunas viram float e o par
   rótulo/valor vira tabela. O desenho é o mesmo e o miolo é o mesmo; a impressão do navegador não passa por aqui. */
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] { min-height: 0; padding: 0; background: #fff; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha { max-width: none; width: auto; padding: 0; box-shadow: none; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__duas-colunas,
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__totais { display: flow-root; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__duas-colunas .folha__bloco { float: left; width: 51%; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__duas-colunas .folha__bloco + .folha__bloco + .folha__bloco { width: 47%; margin-left: 2%; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__duas-colunas .folha__bloco--largo { float: none; width: auto; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__totais .folha__bloco { float: left; width: 49%; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__totais .folha__bloco + .folha__bloco { margin-left: 2%; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__linha { display: table; width: 100%; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__linha dt { display: table-cell; width: 1%; padding-right: 4px; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__linha dd { display: table-cell; overflow-wrap: break-word; }
[data-pagina="crm-pedido-imprimir"][data-saida="pdf"] .folha__itens td:first-child { white-space: nowrap; }

/* ==========================================================================
   SALAS — Agendamento de Salas (data-pagina="agendamento-salas") e a página
   pública de reserva (data-pagina="salas-booking"). Saiu do <style> de cada
   template no #541. Botões e campos são os do Bootstrap de fábrica (#454);
   aqui fica só o layout, o calendário e os modais próprios.
   ========================================================================== */
[data-pagina="agendamento-salas"] { max-width: 1180px; margin: 0 auto; }
[data-pagina="agendamento-salas"] .ag-top { display: flex; align-items: center; gap: var(--bi-space-md); flex-wrap: wrap; margin-bottom: var(--bi-space-md); }
[data-pagina="agendamento-salas"] .ag-legend { display: flex; align-items: center; gap: var(--bi-space-md); flex-wrap: wrap; }
[data-pagina="agendamento-salas"] .ag-legend__it { display: inline-flex; align-items: center; gap: var(--bi-space-sm); font-size: var(--fonte-pequena); color: var(--bi-text-secondary); }
[data-pagina="agendamento-salas"] .ag-legend__sw { width: 12px; height: 12px; border-radius: var(--bi-radius-sm); display: inline-block; }
[data-pagina="agendamento-salas"] .ag-top__hint { font-size: var(--fonte-pequena); color: var(--bi-text-muted); margin-left: auto; }

/* Calendário: o FullCalendar temado pelas próprias vars, apontadas a tokens; os
   botões dele por classe (o v6 fixa a cor por classe), com a medida e a cor do
   btn-outline-primary btn-sm de fábrica — o mesmo da Agenda do CRM. */
[data-pagina="agendamento-salas"] .ag-cal-wrap { position: relative; }
:is(#ag-cal, #sb-cal) { background: var(--bi-bg-surface); border: 1px solid var(--bi-border-color); border-radius: var(--bi-radius-lg); padding: var(--bi-space-sm) var(--bi-space-md);
  --fc-border-color: var(--bi-border-color-subtle);
  --fc-today-bg-color: color-mix(in srgb, var(--brand) 6%, #fff);
  --fc-now-indicator-color: var(--negative-text);
  --fc-list-event-hover-bg-color: var(--bi-bg-hover);
  --fc-neutral-bg-color: var(--bi-bg-hover); }
:is(#ag-cal, #sb-cal) .fc-toolbar-title { font-size: var(--fonte-destaque); font-weight: 500; color: var(--bi-text-primary); }
:is(#ag-cal, #sb-cal) .fc-button-primary { padding: .25rem .5rem; font-size: var(--fonte-corpo); border-radius: var(--bs-border-radius-sm); color: var(--bs-primary); background: #fff; border-color: var(--bs-primary); box-shadow: none; text-transform: capitalize; }
:is(#ag-cal, #sb-cal) .fc-button-primary:not(:disabled):is(:hover, :active, .fc-button-active) { color: #fff; background: var(--bs-primary); border-color: var(--bs-primary); }
:is(#ag-cal, #sb-cal) .fc-col-header-cell-cushion, :is(#ag-cal, #sb-cal) .fc-timegrid-axis-cushion, :is(#ag-cal, #sb-cal) .fc-timegrid-slot-label-cushion { color: var(--bi-text-muted); text-decoration: none; }
#ag-cal .fc-event { cursor: pointer; border: none; font-size: var(--fonte-corpo); border-radius: var(--bi-radius-sm); }
#ag-cal .fc-event .fc-event-main { padding: 1px 4px; }
/* Barra fina de progresso nos refetches (navegar semana/mês, trocar de visão). */
[data-pagina="agendamento-salas"] .ag-cal-bar { position: absolute; top: 0; left: 0; right: 0; height: 3px; border-radius: var(--bi-radius-lg) var(--bi-radius-lg) 0 0; overflow: hidden; opacity: 0; transition: opacity .2s ease; pointer-events: none; z-index: 4; }
[data-pagina="agendamento-salas"] .ag-cal-bar.is-on { opacity: 1; }
[data-pagina="agendamento-salas"] .ag-cal-bar::before { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, var(--brand), transparent); transform: translateX(-100%); animation: ag-slide 1.1s ease-in-out infinite; }
@keyframes ag-slide { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  [data-pagina="agendamento-salas"] .ag-cal-bar::before { animation: none; background: var(--brand); }
}

/* Modais (nova reserva, detalhe, confirmação). */
[data-pagina="agendamento-salas"] .ag-form-back { position: fixed; inset: 0; background: color-mix(in srgb, var(--bi-text-primary) 34%, transparent); display: none; align-items: center; justify-content: center; z-index: 3000; padding: var(--bi-space-md); }
[data-pagina="agendamento-salas"] .ag-form-back.is-open { display: flex; }
[data-pagina="agendamento-salas"] .ag-form { width: 100%; max-width: 480px; background: var(--bi-bg-elevated); border: 1px solid var(--bi-border-color); border-radius: var(--bi-radius-lg); padding: var(--bi-space-lg); box-shadow: 0 8px 30px color-mix(in srgb, var(--bi-text-primary) 14%, transparent); max-height: 92vh; overflow: auto; }
[data-pagina="agendamento-salas"] .ag-form h2 { font-size: var(--fonte-destaque); font-weight: 500; margin: 0 0 var(--bi-space-md); color: var(--bi-text-primary); }
[data-pagina="agendamento-salas"] .ag-field { display: flex; flex-direction: column; gap: var(--bi-space-2xs); margin-bottom: var(--bi-space-sm); position: relative; }
:is([data-pagina="agendamento-salas"] .ag-field, [data-pagina="salas-booking"] .sb-field) label { font-size: var(--fonte-rotulo); font-weight: 500; text-transform: uppercase; letter-spacing: .04em; color: var(--bi-text-muted); }
[data-pagina="agendamento-salas"] .ag-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--bi-space-sm); }
/* Convidados: chips + autocomplete. */
[data-pagina="agendamento-salas"] .ag-chips { display: flex; flex-wrap: wrap; gap: var(--bi-space-2xs); margin-bottom: var(--bi-space-2xs); }
[data-pagina="agendamento-salas"] .ag-chip { display: inline-flex; align-items: center; gap: var(--bi-space-sm); background: var(--bi-bg-hover); border-radius: var(--bi-radius-full); padding: 3px 6px 3px 10px; font-size: var(--fonte-pequena); color: var(--bi-text-primary); }
[data-pagina="agendamento-salas"] .ag-chip button { border: none; background: transparent; cursor: pointer; color: var(--bi-text-muted); font-size: var(--fonte-corpo); line-height: 1; padding: 0 2px; border-radius: var(--bi-radius-sm); }
[data-pagina="agendamento-salas"] .ag-chip button:hover { color: var(--negative-text); }
[data-pagina="agendamento-salas"] .ag-suggest { position: absolute; top: 100%; left: 0; right: 0; z-index: 5; background: var(--bi-bg-elevated); border: 1px solid var(--bi-border-color); border-radius: var(--bi-radius-sm); margin-top: 3px; max-height: 200px; overflow: auto; box-shadow: 0 6px 20px color-mix(in srgb, var(--bi-text-primary) 12%, transparent); display: none; }
[data-pagina="agendamento-salas"] .ag-suggest.is-open { display: block; }
[data-pagina="agendamento-salas"] .ag-suggest__it { padding: 7px 10px; cursor: pointer; font-size: var(--fonte-corpo); color: var(--bi-text-primary); }
[data-pagina="agendamento-salas"] .ag-suggest__it:hover, [data-pagina="agendamento-salas"] .ag-suggest__it.is-active { background: var(--bi-bg-hover); }
[data-pagina="agendamento-salas"] .ag-suggest__it small { color: var(--bi-text-muted); display: block; }
[data-pagina="agendamento-salas"] .ag-form__msg { min-height: 18px; font-size: var(--fonte-pequena); color: var(--negative-text); margin: 2px 0 6px; }
/* Disponibilidade ao vivo (atualiza ao mudar sala/horário). */
[data-pagina="agendamento-salas"] .ag-status { font-size: var(--fonte-corpo); font-weight: 500; padding: 7px 11px; border-radius: var(--bi-radius-sm); margin-bottom: var(--bi-space-sm); }
[data-pagina="agendamento-salas"] .ag-status--checando { color: var(--bi-text-muted); background: var(--bi-bg-hover); }
[data-pagina="agendamento-salas"] .ag-status--livre { color: var(--positive-text); background: var(--positive-subtle); }
[data-pagina="agendamento-salas"] .ag-status--ocupada { color: var(--negative-text); background: var(--negative-subtle); }
[data-pagina="agendamento-salas"] .ag-form__actions { display: flex; justify-content: flex-end; gap: var(--bi-space-sm); margin-top: var(--bi-space-sm); }
/* Detalhe da reserva. */
[data-pagina="agendamento-salas"] .ag-det__head { display: flex; align-items: flex-start; gap: var(--bi-space-sm); margin-bottom: var(--bi-space-md); }
[data-pagina="agendamento-salas"] .ag-det__dot { width: 12px; height: 12px; border-radius: var(--bi-radius-sm); margin-top: 5px; flex: none; }
[data-pagina="agendamento-salas"] .ag-det__title { font-size: var(--fonte-destaque); font-weight: 500; color: var(--bi-text-primary); margin: 0; }
[data-pagina="agendamento-salas"] .ag-det__sub { font-size: var(--fonte-pequena); color: var(--bi-text-muted); }
[data-pagina="agendamento-salas"] .ag-det__row { display: grid; grid-template-columns: 108px 1fr; gap: var(--bi-space-sm); padding: 8px 0; border-top: 1px solid var(--bi-border-color-subtle); font-size: var(--fonte-corpo); }
[data-pagina="agendamento-salas"] .ag-det__k { color: var(--bi-text-muted); text-transform: uppercase; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; padding-top: 2px; }
[data-pagina="agendamento-salas"] .ag-det__v { color: var(--bi-text-primary); word-break: break-word; }
[data-pagina="agendamento-salas"] .ag-det__v ul { margin: 0; padding-left: 16px; }
[data-pagina="agendamento-salas"] .ag-det__actions { display: flex; justify-content: space-between; gap: var(--bi-space-sm); margin-top: var(--bi-space-lg); }
[data-pagina="agendamento-salas"] .ag-confirm { max-width: 380px; text-align: left; }
[data-pagina="agendamento-salas"] .ag-confirm p { color: var(--bi-text-secondary); margin: 0 0 var(--bi-space-md); line-height: 1.5; }
[data-pagina="agendamento-salas"] .ag-confirm b { font-weight: 500; color: var(--bi-text-primary); }
@media (max-width: 767px) {
  [data-pagina="agendamento-salas"] .ag-top__hint { display: none; }  /* no toque não há "arrastar" */
  #ag-cal { padding: var(--bi-space-2xs); }
  #ag-cal .fc-toolbar.fc-header-toolbar { flex-wrap: wrap; gap: var(--bi-space-sm); margin-bottom: var(--bi-space-sm); }
  #ag-cal .fc-toolbar-chunk { display: flex; }
  /* O modal vira folha de baixo. */
  [data-pagina="agendamento-salas"] .ag-form { padding: var(--bi-space-md); border-radius: var(--bi-radius-lg) var(--bi-radius-lg) 0 0; max-height: 94vh; }
  [data-pagina="agendamento-salas"] .ag-form-back { align-items: flex-end; padding: 0; }
}
/* Paisagem curta (celular deitado): o calendário rola dentro de si e o modal
   mais alto que a tela rola o véu inteiro, com o título sempre alcançável. */
@media (max-height: 520px) and (orientation: landscape) {
  #ag-cal { max-height: calc(100vh - 120px); overflow: auto; }
  [data-pagina="agendamento-salas"] .ag-form-back { align-items: flex-start; overflow-y: auto; padding: 12px 14px; }
  [data-pagina="agendamento-salas"] .ag-form { max-height: none; margin: 0 auto; }
}

/* Reserva pública (tablet na porta da sala): página sem a casca do app. */
[data-pagina="salas-booking"] { background: var(--bg); color: var(--bi-text-primary); }
[data-pagina="salas-booking"] .sb-head { padding: 16px 18px; background: var(--bi-bg-surface); border-bottom: 1px solid var(--bi-border-color); }
[data-pagina="salas-booking"] .sb-title { font-size: var(--fonte-titulo); font-weight: 500; }
[data-pagina="salas-booking"] .sb-sub { color: var(--bi-text-muted); }
[data-pagina="salas-booking"] .sb-wrap { padding: 14px 16px 96px; max-width: 640px; margin: 0 auto; }
[data-pagina="salas-booking"] .sb-cta { position: fixed; left: 0; right: 0; bottom: 0; padding: 12px 16px; background: var(--bi-bg-surface); border-top: 1px solid var(--bi-border-color); }
[data-pagina="salas-booking"] .sb-back { position: fixed; inset: 0; z-index: 40; display: none; align-items: flex-end; justify-content: center; background: color-mix(in srgb, var(--bi-text-primary) 34%, transparent); }
[data-pagina="salas-booking"] .sb-back.is-open { display: flex; }
[data-pagina="salas-booking"] .sb-form { width: 100%; max-width: 480px; background: var(--bi-bg-elevated); border-radius: var(--bi-radius-lg) var(--bi-radius-lg) 0 0; padding: 18px 18px 22px; max-height: 94vh; overflow: auto; }
[data-pagina="salas-booking"] .sb-form h2 { font-size: var(--fonte-destaque); font-weight: 500; margin: 0 0 12px; }
[data-pagina="salas-booking"] .sb-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
[data-pagina="salas-booking"] .sb-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
[data-pagina="salas-booking"] .sb-msg { min-height: 18px; color: var(--negative-text); margin: 4px 0; }
[data-pagina="salas-booking"] .sb-msg--ok { color: var(--positive-text); }

/* Alvo de toque de 44px nas duas telas de salas. */
@media (pointer: coarse) {
  :is([data-pagina="agendamento-salas"], [data-pagina="salas-booking"]) :is(.btn, .form-control, .form-select) { min-height: 44px; }
}

/* ==========================================================================
   CRM PRODUTIVIDADE — escopo de página (data-pagina="produtividade-comercial")

   A tela é um MOSTRADOR, não um documento: lê-se de relance, para decidir quem
   cobrar hoje. Daí três decisões que valem para o bloco inteiro:
   1. medida é monoespaçada e tabular — número que não alinha não se compara;
   2. magnitude tem UMA linguagem só (preenchimento atrás do número, `.massa`),
      nunca três jeitos de dizer "quanto" na mesma tela;
   3. cor semântica (verde/vermelho) responde SÓ "bateu a meta?"; volume usa a
      tinta neutra de gráfico, para nenhuma cor responder duas perguntas.
   Tudo escopado à página: nada aqui vaza para as outras ~28 telas.
   ========================================================================== */
/* ---------------------------------------------------------------------------
   CRM · Agenda. O calendário é o FullCalendar vendorizado pela tela de salas;
   o tema dele sai dos tokens FCDS pelas próprias vars da lib, e os botões por
   classe (o v6 fixa as cores por classe, não por var — mesma abordagem de
   agendamento-salas.html, só trocando #ag-cal por #crm-cal).
   `.ag-*` é o escopo desta página. Cuidado: `.fc-` é o prefixo do FullCalendar
   E o prefixo do canvas da ficha do cliente (`#crm-modal-ficha .fc-caixa`,
   `.fc-porta`, `.fc-col-*`…) — os dois estão escopados por id justamente para
   não se encontrarem.
   --------------------------------------------------------------------------- */
/* A grade ocupa a altura que sobra do shell (a página declara
   `content--altura-cheia`), e cada coluna rola dentro de si. Sem o
   `min-height: 0`, um filho que cresce empurra o grid para além da tela e a
   rolagem volta para a página inteira — que é justamente o que a altura cheia
   veio evitar. */
/* UM cartão só, não dois. Calendário e atrasados são a mesma leitura — o que
   está marcado e o que ficou para trás —, e duas molduras lado a lado faziam a
   tela parecer duas telas. A divisa entre eles é uma linha, não uma borda de
   caixa; quem tem moldura é o conjunto. */
.ag-tela { display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  flex: 1 1 auto; min-height: 0;
  background: var(--bi-bg-surface); border: 1px solid var(--bi-border-color);
  border-radius: var(--bi-radius-lg); overflow: hidden; }
.ag-tela > * { min-height: 0; }
@media (max-width: 992px) {
  /* No telefone a altura cheia atrapalha: duas caixas rolando dentro de uma
     tela de 844px dão 300px úteis cada. Ali a página rola inteira, como antes. */
  .ag-tela { grid-template-columns: minmax(0, 1fr); flex: 0 0 auto; }
  /* A caixa não tem altura própria aqui, então não pode recortar o que o
     calendário desenhar (o JS o põe em `height: auto` nesta faixa). */
  #crm-cal { overflow: visible; }
  #ag-atrasados { overflow-y: visible; }
  .ag-atrasados { border-left: 0; border-top: 1px solid var(--bi-border-color); }
}
#crm-cal { padding: var(--bi-space-sm) var(--bi-space-md);
  display: flex; flex-direction: column; overflow: hidden; }
/* O calendário preenche a caixa (o JS pede `height: 100%` ao FullCalendar) e
   a grade dos dias absorve a sobra. */
#crm-cal > .fc { flex: 1 1 auto; min-height: 0; }
#crm-cal {
  --fc-border-color: var(--bi-border-color-subtle);
  --fc-today-bg-color: color-mix(in srgb, var(--brand) 6%, #fff);
  --fc-now-indicator-color: var(--negative-text);
  --fc-list-event-hover-bg-color: var(--bi-bg-hover);
  --fc-neutral-bg-color: var(--bi-bg-hover);
}
#crm-cal .fc-toolbar-title { font-size: var(--fonte-destaque); font-weight: 500; color: var(--bi-text-primary); }
/* Botões do FullCalendar com a medida e a cor do btn-outline-primary btn-sm de fábrica (#454). */
#crm-cal .fc-button-primary { padding: .25rem .5rem; font-size: var(--fonte-corpo); border-radius: var(--bs-border-radius-sm); color: var(--bs-primary); background: #fff; border-color: var(--bs-primary); box-shadow: none; text-transform: capitalize; }
#crm-cal .fc-button-primary:not(:disabled):is(:hover, :active, .fc-button-active) { color: #fff; background: var(--bs-primary); border-color: var(--bs-primary); }
#crm-cal .fc-col-header-cell-cushion, #crm-cal .fc-timegrid-axis-cushion, #crm-cal .fc-timegrid-slot-label-cushion { color: var(--bi-text-muted); text-decoration: none; }
#crm-cal .fc-event { cursor: pointer; border: none; font-size: var(--fonte-corpo); border-radius: var(--bi-radius-sm); }
#crm-cal .fc-event .fc-event-main { padding: 1px 4px; }

.ag-atrasados { padding: var(--bi-space-md);
  border-left: 1px solid var(--bi-border-color);
  display: flex; flex-direction: column; }
/* A lista rola dentro da coluna: atraso antigo não empurra a página. */
#ag-atrasados { overflow-y: auto; min-height: 0; }
/* `<a>` desde o reporte #67 (o cadastro tem endereço, e link é o que o botão
   direito entende); segue desenhada como a linha de lista que sempre foi —
   sem tinta de link, sem sublinhado. */
.ag-linha { display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--bi-border-color-subtle); padding: .5rem 0; cursor: pointer; color: inherit; text-decoration: none; }
.ag-linha:last-child { border-bottom: 0; }
.ag-linha:hover { background: var(--bi-bg-hover); color: inherit; }
.ag-contexto-texto { white-space: pre-line; color: var(--bi-text-secondary); }
/* CAIXA ALTA no cromo da agenda (dono, 03/09/2026: "quero tudo em maiúsculo",
   e sobre o alcance: "exceto texto corrido, apenas aqui"). É escopo de PÁGINA
   de propósito — `custom.css` é lido por ~28 telas, e um token global levaria
   isto para todas elas.

   Entra o cromo: cabeçalho do calendário, botão, título de painel, rótulo,
   e a linha forte que traz o cliente (na grade, na coluna de atrasados e
   no painel). NÃO entra texto corrido — `.ag-contexto-texto` (a observação do
   compromisso), o que a pessoa digita, ajuda e mensagem de erro ficam como
   foram escritos. */
#crm-cal .fc-toolbar-title,
#crm-cal .fc-col-header-cell-cushion,
#crm-cal .fc-button,
#crm-cal .fc-event-title,
.ag-atrasados .crm-titulo,
.ag-linha .crm-forte,
.ag-linha .crm-rotulo,
#ag-modal .offcanvas-title,
#ag-modal .crm-forte,
#ag-modal .form-select,
#ag-modal .crm-rotulo,
#ag-modal .form-label,
#ag-modal .btn,
#ag-lote .form-label, #ag-lote label, #ag-lote .btn, #ag-lote #ag-lote-conta {
  text-transform: uppercase; }
/* `text-transform` não herda para dentro de <button> pela folha do agente: o
   cabeçalho ordenável e os botões do FullCalendar precisam da regra neles
   mesmos — foi essa a armadilha que deixou um `text-transform` viver morto na
   lista de pedidos. Por isso `.fc-button` e `.btn` estão na lista acima, e não
   só o contêiner. */

/* Estado do compromisso. Cor por ESTADO, e atraso é a coisa mais vermelha da
   tela — o canal (Ligar/Visita/…) vai no texto, não na cor. */
/* A cor do TEXTO tem de ir na var do FullCalendar: ele pinta o título por
   `--fc-event-text-color` (branco por padrão) num elemento mais fundo, então
   `color` no evento de fora perde — era isso que deixava letra branca sobre
   fundo claro, com o compromisso ilegível. */
#crm-cal .ag-atrasado, .ag-linha.ag-atrasado { background: var(--negative-subtle); color: var(--negative-text); }
#crm-cal .ag-atrasado { --fc-event-text-color: var(--negative-text); }
/* Compromisso em pé é VERDE: hoje em verde cheio (o mais forte da tela depois
   do atraso), o que vem pela frente no mesmo verde diluído. O cinza de antes
   sumia contra o fundo do calendário — um compromisso quase invisível é um
   compromisso esquecido. */
#crm-cal .ag-hoje { background: var(--crm-acento); color: #fff;
  --fc-event-text-color: #fff; }
#crm-cal .ag-futuro { background: color-mix(in srgb, var(--crm-acento) 14%, #fff);
  color: var(--crm-acento); --fc-event-text-color: var(--crm-acento); }
/* Canal: ícone, não cor — a cor já está dizendo o estado. Font Awesome já é
   carregado pelo shell; o glifo entra por `content` na família certa.
   O título traz só o cliente (sem "Ligar ·"): o texto depois da `/` é o nome
   do canal para leitor de tela, que num glifo sozinho não ouve nada. Vale na
   grade do mês, na lista da semana e na coluna de atrasados. */
#crm-cal .fc-event-title::before, #crm-cal .fc-list-event-title a::before, .ag-linha .crm-forte::before { font-family: 'Font Awesome 6 Free'; font-weight: 500; margin-right: .3rem; }
#crm-cal .ag-canal-ligar :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-ligar .crm-forte::before { content: '\f095' / 'Ligar'; }
#crm-cal .ag-canal-email :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-email .crm-forte::before { content: '\f0e0' / 'E-mail'; }
#crm-cal .ag-canal-visita :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-visita .crm-forte::before { content: '\f3c5' / 'Visita'; }
#crm-cal .ag-canal-whatsapp :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-whatsapp .crm-forte::before { content: '\f232' / 'WhatsApp'; font-family: 'Font Awesome 6 Brands'; font-weight: 400; }
#crm-cal .ag-canal-reuniao :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-reuniao .crm-forte::before { content: '\f0c0' / 'Reunião'; }
#crm-cal .ag-canal-outro :is(.fc-event-title, .fc-list-event-title a)::before, .ag-linha.ag-canal-outro .crm-forte::before { content: ''; margin-right: 0; }

[data-pagina="produtividade-comercial"] .n {
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
[data-pagina="produtividade-comercial"] .magro { color: var(--ink-2); }

/* Número auditável: um clique abre de onde ele vem. Marca discreta, não ícone —
   e alvo de teclado de verdade, com foco visível (o `?` só serve se chegar nele
   sem mouse). */
[data-pagina="produtividade-comercial"] .aud { cursor: help; }
[data-pagina="produtividade-comercial"] .aud:focus-visible {
  outline: 2px solid var(--chart-azul); outline-offset: 2px; border-radius: 2px;
}

/* ── CHIP DE ESCOPO ───────────────────────────────────────────────────────
   O recorte por vendedor muda TODOS os números da tela. Sem um aviso persistente
   isso vira estado invisível: o usuário lê 289.224 kg achando que é a equipe. */
[data-pagina="produtividade-comercial"] .crm-escopo {
  display: flex; align-items: center; gap: .5rem; width: max-content;
  margin-bottom: 1rem; padding: .25rem .375rem .25rem .875rem;
  border: var(--bs-border-width) solid var(--chart-azul); border-radius: var(--raio-chip);
  background: color-mix(in srgb, var(--chart-azul) 10%, transparent);
  font-size: var(--fonte-corpo);
}
[data-pagina="produtividade-comercial"] .crm-escopo__sair {
  font: inherit; border: 0; border-radius: var(--raio-chip); padding: .125rem .5rem;
  background: var(--bi-bg-surface); color: var(--ink-2); cursor: pointer;
}
[data-pagina="produtividade-comercial"] .crm-escopo__sair:hover { color: var(--ink); }

/* ── ESPERA / VAZIO / ERRO ────────────────────────────────────────────────
   Três estados com PESOS diferentes. Antes eram um só: `mostrarErro()` chamava
   `mostrarVazio()` com uma string na frente, então "o Ploomes caiu" e "não há
   negócio neste mês" saíam idênticos — uma linha cinza, sem saída. */
[data-pagina="produtividade-comercial"] .crm-espera,
[data-pagina="produtividade-comercial"] .crm-estado {
  max-width: 46rem; margin: 3rem auto; text-align: center;
}
[data-pagina="produtividade-comercial"] .crm-espera__oque {
  font-size: var(--fonte-destaque); font-weight: 500; color: var(--ink); margin: 1rem 0 .25rem;
}
[data-pagina="produtividade-comercial"] .crm-espera__recorte {
  font-size: var(--fonte-corpo); color: var(--ink-2); margin: 0 0 .25rem;
}
[data-pagina="produtividade-comercial"] .crm-espera__recorte { color: var(--ink-2); }
[data-pagina="produtividade-comercial"] .crm-espera__tempo {
  font-variant-numeric: tabular-nums; font-size: var(--fonte-corpo);
  color: var(--ink-2); margin: .75rem 0 0;
}
/* Pulso, NÃO barra de progresso: são quatro chamadas sequenciais no servidor e o
   cliente não recebe progresso. Uma barra que enche seria informação inventada;
   o que enche de verdade é o cronômetro ao lado, que conta o tempo real. */
[data-pagina="produtividade-comercial"] .crm-espera__barra {
  height: .375rem; max-width: 18rem; margin: 0 auto; overflow: hidden;
  background: var(--surf-2); border-radius: var(--raio-chip);
}
[data-pagina="produtividade-comercial"] .crm-espera__pulso {
  width: 40%; height: 100%; border-radius: inherit; background: var(--chart-azul);
  animation: crm-pulso 1.4s ease-in-out infinite;
}
@keyframes crm-pulso {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
@media (prefers-reduced-motion: reduce) {
  [data-pagina="produtividade-comercial"] .crm-espera__pulso {
    animation: none; width: 100%; opacity: .45;
  }
}
[data-pagina="produtividade-comercial"] .crm-estado__titulo {
  font-size: var(--fonte-destaque); font-weight: 500; color: var(--ink); margin: 0 0 .5rem;
}
[data-pagina="produtividade-comercial"] .crm-estado__corpo {
  font-size: var(--fonte-corpo); color: var(--ink-2); margin: 0 0 .75rem;
}
[data-pagina="produtividade-comercial"] .crm-estado__diag {
  font-family: var(--bi-font-mono); font-size: var(--fonte-pequena); color: var(--ink-2);
  margin: 0 0 1rem; overflow-wrap: anywhere;
}
[data-pagina="produtividade-comercial"] .crm-estado--erro .crm-estado__titulo {
  color: var(--negative-text);
}

/* ── MOSTRADOR ────────────────────────────────────────────────────────────
   A manchete é uma PERGUNTA respondida. À esquerda a resposta com o instrumento
   que a situa contra a meta; à direita as medidas de apoio. */
[data-pagina="produtividade-comercial"] .crm-mostrador {
  display: grid; grid-template-columns: minmax(18rem, 1.1fr) minmax(16rem, 1fr);
  gap: clamp(1.25rem, 4vw, 3rem);
}
@media (max-width: 767.98px) {
  [data-pagina="produtividade-comercial"] .crm-mostrador { grid-template-columns: 1fr; }
}
[data-pagina="produtividade-comercial"] .crm-pergunta {
  font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink-2); margin: 0 0 .375rem;
}
[data-pagina="produtividade-comercial"] .crm-resposta {
  display: flex; align-items: baseline; gap: .625rem; flex-wrap: wrap;
}
[data-pagina="produtividade-comercial"] .crm-resposta__taxa {
  font-size: var(--fonte-heroi); font-weight: 500; line-height: 40px;
  letter-spacing: -0.02em;
}
[data-pagina="produtividade-comercial"] .crm-selo {
  font-size: var(--fonte-pequena); font-weight: 500; white-space: nowrap;
  padding: .1875rem .5rem; border-radius: var(--raio-chip);
}
[data-pagina="produtividade-comercial"] .crm-selo--ruim {
  color: var(--negative-text); background: color-mix(in srgb, var(--negative) 8%, transparent);
}
[data-pagina="produtividade-comercial"] .crm-selo--bom {
  color: var(--positive-text); background: color-mix(in srgb, var(--positive) 9%, transparent);
}

/* Bullet (Few, 2006): medida contra alvo. Trilha de 0 a 2× a meta, então o tique
   do alvo cai sempre no meio e a escala não dança entre recortes. Cor só na
   medida; trilha e tique são estrutura, em tinta neutra. */
[data-pagina="produtividade-comercial"] .crm-bullet {
  position: relative; height: .6875rem; margin-top: 1rem;
  background: var(--surf-2); border: var(--bs-border-width) solid var(--line);
  border-radius: 2px;
}
[data-pagina="produtividade-comercial"] .crm-bullet__medida {
  position: absolute; inset-block: 0; left: 0; background: var(--negative); border-radius: 1px;
}
[data-pagina="produtividade-comercial"] .crm-bullet__medida--bom { background: var(--positive); }
[data-pagina="produtividade-comercial"] .crm-bullet__alvo {
  position: absolute; inset-block: -4px; width: 2px; background: var(--ink);
}
[data-pagina="produtividade-comercial"] .crm-bullet__eixo {
  display: flex; justify-content: space-between; margin-top: .4375rem;
  font-variant-numeric: tabular-nums; font-size: var(--fonte-pequena); color: var(--ink-2);
}

[data-pagina="produtividade-comercial"] .crm-apoio {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 1.25rem; align-self: center; margin: 0;
}
[data-pagina="produtividade-comercial"] .crm-apoio dt {
  font-size: var(--fonte-rotulo); color: var(--ink-2); text-transform: uppercase;
  letter-spacing: .055em; margin-bottom: .25rem; font-weight: 500;
}
[data-pagina="produtividade-comercial"] .crm-apoio dd {
  margin: 0; font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -0.02em;
}
[data-pagina="produtividade-comercial"] .crm-apoio small {
  display: block; margin-top: .1875rem; font-weight: 400;
  letter-spacing: 0; line-height: 16px; color: var(--ink-2);
}

/* ── ESTADO DE HOJE ───────────────────────────────────────────────────────
   As duas medidas gerenciais que não seguem o período do topo. Reusa a grade
   do `.crm-apoio` do mostrador de propósito: são medidas da mesma família
   visual, e um segundo desenho para a mesma coisa só cria dialeto. O que muda
   é o corpo, que aqui é a seção inteira e precisa do próprio respiro. */
[data-pagina="produtividade-comercial"] .crm-hoje__corpo {
  padding: 1rem 1.25rem 1.25rem;
}
[data-pagina="produtividade-comercial"] .crm-hoje__corpo .crm-apoio {
  align-self: start;
}
[data-pagina="produtividade-comercial"] .crm-hoje__nota,
[data-pagina="produtividade-comercial"] .crm-fora-coorte {
  margin: .75rem 0 0; font-size: var(--fonte-corpo); color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-fora-coorte { margin-top: .5rem; }
/* Composição das duas fontes, colada na taxa que ela explica. Tabular para os
   números alinharem entre um recorte e outro; a mesma tinta secundária da
   exclusão de coorte, porque as duas são nota de rodapé da manchete. */
[data-pagina="produtividade-comercial"] .crm-composicao {
  margin: .25rem 0 0; font-size: var(--fonte-corpo); color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* Cartões no grid do DS (.grid + .fcds-span-*). `start`, não o `stretch` padrão:
   as duas listas de cada par têm comprimentos diferentes e esticar a mais curta
   abria um vazio DENTRO do cartão. `min-width: 0` deixa a grade rolar dentro do
   cartão em vez de empurrar a coluna do grid além da janela. */
[data-pagina="produtividade-comercial"] #crm-board > .grid { align-items: start; }
[data-pagina="produtividade-comercial"] #crm-board > .grid > section { min-width: 0; }

/* ── TABELAS DA PÁGINA ────────────────────────────────────────────────── */
[data-pagina="produtividade-comercial"] .crm-tbl { width: 100%; border-collapse: collapse; }
[data-pagina="produtividade-comercial"] .crm-tbl th {
  font-size: var(--fonte-rotulo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .055em; color: var(--ink-2); text-align: left;
  padding: .25rem .625rem; white-space: nowrap; vertical-align: bottom;
}
[data-pagina="produtividade-comercial"] .crm-tbl td {
  padding: .25rem .625rem; line-height: 1.2; white-space: nowrap;
  border-top: var(--bs-border-width) solid var(--line);
}
[data-pagina="produtividade-comercial"] .crm-tbl th.dir,
[data-pagina="produtividade-comercial"] .crm-tbl td.dir { text-align: right; }
[data-pagina="produtividade-comercial"] .crm-tbl tbody tr:hover td { background: var(--surf-2); }
[data-pagina="produtividade-comercial"] td.posto {
  width: 1.5rem; font-variant-numeric: tabular-nums;
  font-size: var(--fonte-pequena); color: var(--ink-2);
}
/* Propostas, linha a linha (#314): sem rolagem lateral, as três colunas de
   texto longo QUEBRAM com teto em vez de esticar a tabela. O motivo sai inteiro
   (reporte #90): no CRM Four é texto livre, e cortado não diz por que se perdeu. */
[data-pagina="produtividade-comercial"] .grade .grade-tabela .crm-drill-quebra .grade-celula { white-space: normal; }
/* Sem rolagem lateral (#314): padding de célula como o da Separação e texto longo quebra. */
[data-pagina="produtividade-comercial"] #crm-drill-grade .grade-tabela :is(th, td) { padding-left: .3rem; padding-right: .3rem; }
[data-pagina="produtividade-comercial"] #crm-drill-grade .colfilter-multi__trigger { padding-left: .25rem; padding-right: .25rem; gap: .125rem; letter-spacing: 0; }
[data-pagina="produtividade-comercial"] #crm-drill-grade .colfilter-multi__trigger > span { letter-spacing: 0; }
[data-pagina="produtividade-comercial"] #crm-drill-grade .grade-tabela thead tr:first-child th { white-space: normal; }
[data-pagina="produtividade-comercial"] .grade .crm-clientes-cliente { max-width: 14rem; }
[data-pagina="produtividade-comercial"] .grade .crm-drill-vendedor { max-width: 5.5rem; }
[data-pagina="produtividade-comercial"] .grade .crm-drill-subsegmento { max-width: 6rem; }
[data-pagina="produtividade-comercial"] .grade .crm-drill-cliente { max-width: 7rem; }
[data-pagina="produtividade-comercial"] .grade .crm-drill-representante { max-width: 6rem; }
[data-pagina="produtividade-comercial"] .grade .crm-drill-motivo { max-width: 7rem; }

/* Régua de conversão na célula. Ocupa a coluna INTEIRA em vez de uma largura
   fixa: a folga da tabela caía toda nesta célula (225px de branco, medido) e
   régua comprida ainda lê melhor — a distância até o tique da meta é a
   informação, e ela ganha resolução com o comprimento. */
[data-pagina="produtividade-comercial"] .cel-regua {
  display: flex; align-items: center; gap: .5rem;
}
[data-pagina="produtividade-comercial"] .crm-micro {
  position: relative; flex: 1; min-width: 5.75rem; height: .5rem;
  background: var(--surf-2); border: var(--bs-border-width) solid var(--line);
  border-radius: 1px;
}
[data-pagina="produtividade-comercial"] .crm-micro__v {
  position: absolute; inset-block: 0; left: 0; border-radius: 1px;
}
[data-pagina="produtividade-comercial"] .crm-micro__v--bom  { background: var(--positive); }
[data-pagina="produtividade-comercial"] .crm-micro__v--ruim { background: var(--negative); }
/* Tique da meta no meio, pela mesma escala 0–2× do bullet do topo. */
[data-pagina="produtividade-comercial"] .crm-micro__regua {
  position: absolute; inset-block: -2px; left: 50%; width: 1px; background: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-micro__num {
  font-size: .8125rem; min-width: 3rem; text-align: right;
}

/* ── COMPOSIÇÃO — barra empilhada 100% ────────────────────────────────────
   Partes disjuntas comparadas por COMPRIMENTO. Ângulo não compara; e custa 28px
   de altura no lugar de um círculo de 280px.
   "Em aberto" é NEUTRO e claro de propósito: é a fatia que ainda não virou
   dinheiro, e costuma ser três quartos da barra — pintá-la punha a maior massa
   de cor da tela justamente no que não decidiu nada. Clara, ela recua e deixa
   ganho (verde) e perda (vermelho) saltarem, que é a regra "cor significa
   dinheiro". O % de cada parte vai na legenda, não na barra (#476). */
[data-pagina="produtividade-comercial"] .crm-empilhada {
  display: flex; height: 1.75rem; overflow: hidden;
  border-radius: var(--bi-radius-sm); background: var(--surf-2);
}
[data-pagina="produtividade-comercial"] .crm-empilhada__parte--aberto  { background: var(--surf-2); }
[data-pagina="produtividade-comercial"] .crm-empilhada__parte--ganha   { background: var(--positive-text); }
[data-pagina="produtividade-comercial"] .crm-empilhada__parte--perdida { background: var(--negative-text); }
[data-pagina="produtividade-comercial"] .crm-legenda {
  display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .5rem;
  font-size: var(--fonte-pequena); color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-chave::before {
  content: ""; display: inline-block; width: .5rem; height: .5rem;
  border-radius: 50%; margin-right: .375rem;
}
[data-pagina="produtividade-comercial"] .crm-chave--aberto::before  { background: var(--line-3); }
[data-pagina="produtividade-comercial"] .crm-chave--ganha::before   { background: var(--positive-text); }
[data-pagina="produtividade-comercial"] .crm-chave--perdida::before { background: var(--negative-text); }

/* A ressalva que a manchete esconde, no espaço que a fileira deixava vazio. */
[data-pagina="produtividade-comercial"] .crm-fecho {
  display: flex; align-items: baseline; gap: .75rem;
  margin-top: 1.125rem; padding-top: .75rem;
  border-top: var(--bs-border-width) solid var(--line);
}
[data-pagina="produtividade-comercial"] .crm-fecho__num {
  flex: none; font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -0.02em;
  color: var(--positive-text);
}
[data-pagina="produtividade-comercial"] .crm-fecho__txt {
  margin: 0; color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-fecho__txt b { color: var(--ink); font-weight: 500; }

/* ── MOTIVOS DE PERDA ─────────────────────────────────────────────────── */
[data-pagina="produtividade-comercial"] .crm-causa {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: 1fr auto; gap: 0 .75rem;
  align-items: baseline; padding: .3125rem .5rem;
  border-top: var(--bs-border-width) solid var(--line);
}
[data-pagina="produtividade-comercial"] .crm-causa::before {
  content: ""; position: absolute; inset-block: 1px; left: 0; z-index: -1;
  width: var(--p, 0%); border-radius: 2px;
  background: color-mix(in srgb, var(--ink-4) 30%, transparent);
}
[data-pagina="produtividade-comercial"] .crm-causa__kg {
  font-size: var(--fonte-corpo); color: var(--ink-2);
}
/* "ruído" = cotação-teste, que infla o denominador de perdas. Marca com TEXTO,
   não só cor — a informação não pode depender de enxergar a cor. */
[data-pagina="produtividade-comercial"] .crm-marca {
  font-size: var(--fonte-pequena); padding: 0 .375rem; border-radius: var(--raio-chip);
  background: var(--surf-2); color: var(--ink-2);
}

/* ── NOME DE VENDEDOR = PORTA PARA O RECORTE DELE ─────────────────────────
   Botão de verdade: cor de link, sublinhado no hover, cursor de ponteiro, foco
   visível. O que é clicável tem de parecer clicável. */
[data-pagina="produtividade-comercial"] .crm-quem {
  font: inherit; font-weight: 500; color: var(--chart-azul); background: none;
  border: 0; padding: 0; text-align: left; white-space: nowrap; cursor: pointer;
}
[data-pagina="produtividade-comercial"] .crm-quem:hover { text-decoration: underline; }
[data-pagina="produtividade-comercial"] .crm-quem:focus-visible {
  outline: 2px solid var(--chart-azul); outline-offset: 2px; border-radius: 2px;
}

/* ── ATIVIDADE NA GRADE (#314) ───────────────────────────────────────────
   A massa atrás do número continua a linguagem de magnitude da página, agora
   dentro da célula da grade. A linha do vendedor escolhido fica marcada (fundo +
   barra à esquerda, nunca só cor). O detalhe da linha-filha (leads, ligações)
   é uma grade embutida; a nota de cima diz o total do servidor. */
[data-pagina="produtividade-comercial"] .crm-massa {
  display: block; position: relative; isolation: isolate;
}
[data-pagina="produtividade-comercial"] .crm-massa::before {
  content: ""; position: absolute; inset-block: 1px; right: 0; z-index: -1;
  width: var(--p, 0%); border-radius: 2px;
  background: color-mix(in srgb, var(--ink-4) 30%, transparent);
}
[data-pagina="produtividade-comercial"] tr.crm-linha--escolhida > td {
  background: color-mix(in srgb, var(--chart-azul) 9%, transparent);
}
[data-pagina="produtividade-comercial"] tr.crm-linha--escolhida > td:first-child {
  box-shadow: inset 2px 0 0 var(--chart-azul);
}
[data-pagina="produtividade-comercial"] tr.crm-linha--escolhida .crm-quem {
  font-weight: 500;
}
[data-pagina="produtividade-comercial"] .crm-leads__nota {
  margin: 0 0 .25rem; font-size: var(--fonte-corpo); color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-leads__nota:only-child { margin: 0; }

/* ── RAMAIS DO TELEFONE (#251) ────────────────────────────────────────────
   A linha "Ramal X · sem dono" da grade de atividade não é pessoa: tinta magra,
   sem o botão que recorta a tela. O formulário de Atribuir/Trocar é uma linha
   só (vendedor, data, botão); o histórico é lista simples, a mais nova primeiro. */
[data-pagina="produtividade-comercial"] .crm-ramal-sem-dono { color: var(--ink-2); white-space: nowrap; }
[data-pagina="produtividade-comercial"] .crm-ramal__form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .5rem; margin-bottom: .5rem;
}
[data-pagina="produtividade-comercial"] .crm-ramal__campo {
  display: flex; flex-direction: column; gap: .125rem;
  font-size: var(--fonte-corpo); color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-ramal__campo .form-select { min-width: 14rem; }
[data-pagina="produtividade-comercial"] .crm-ramal__dica,
[data-pagina="produtividade-comercial"] .crm-ramais__aviso {
  font-size: var(--fonte-corpo); color: var(--ink-2);
}
[data-pagina="produtividade-comercial"] .crm-ramais__aviso { margin: 0 0 .5rem; }
[data-pagina="produtividade-comercial"] .crm-ramal__historico {
  list-style: none; margin: 0; padding: 0; font-size: var(--fonte-corpo);
}
/* Mínimo da efetiva (#251b): campo curto com a unidade colada, acima da grade. */
[data-pagina="produtividade-comercial"] .crm-minimo { margin-bottom: .75rem; }
[data-pagina="produtividade-comercial"] .crm-minimo__campo {
  display: inline-flex; align-items: center; gap: .375rem; color: var(--ink);
}
[data-pagina="produtividade-comercial"] .crm-minimo__campo .form-control { width: 5.5rem; }
[data-pagina="produtividade-comercial"] .crm-minimo__historico summary {
  font-size: var(--fonte-corpo); color: var(--ink-2); cursor: pointer;
}

/* Uma régua de densidade para TODAS as grades da tela. Medido antes: quatro
   tabelas com quatro alturas de linha (27 / 39 / 53 / 60px). A de 27px prova que
   o piso é legível; as outras eram 44% a 122% mais altas sem motivo, e era daí
   que vinha a altura da página. O piso tipográfico não muda — só o respiro. */
[data-pagina="produtividade-comercial"] .tbl > tbody > tr > td,
[data-pagina="produtividade-comercial"] .tbl > tfoot > tr > td,
[data-pagina="produtividade-comercial"] table.dataTable > tbody > tr > td {
  padding-block: .25rem; line-height: 1.25;
}
[data-pagina="produtividade-comercial"] .tbl > thead > tr > th,
[data-pagina="produtividade-comercial"] table.dataTable > thead > tr > th {
  padding-block: .25rem;
}

/* ==========================================================================
   PREVISÃO DE CAIXA — título ignorado
   A linha marcada "ignorar" sai dos números (isso é backend) mas continua na
   tabela como referência: esmaecida, com o valor ainda legível. Só cor/opacidade
   — nada de esconder, que é o ponto de deixá-la à vista.
   ========================================================================== */
/* Na barra da grade, ao lado da busca: texto de controle, não de rodapé. */
[data-pagina="previsao_caixa"] .grade .pc-pagos { flex: 0 0 auto; white-space: nowrap; }
[data-pagina="previsao_caixa"] .grade .pc-pagos .form-check-label { font-size: .8125rem; }
[data-pagina="previsao_caixa"] tr.pc-linha-ignorada > td {
  color: var(--bi-text-muted);
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--bi-text-muted) 45%, transparent);
}
[data-pagina="previsao_caixa"] tr.pc-linha-ignorada > td:has(.pc-ignorar) {
  text-decoration: none;
}

/* ==========================================================================
   COCKPIT — pipeline strip (Faturamento/Margem/Despesas/Resultado)
   Remade as a flat 2×2 metric panel. The old layout was a rigid 7-track grid
   (1.2fr 28px 1fr 28px 1fr 28px 1fr) — an "equation" row with fixed operator
   columns. Its content needed ~1040px but each strip is only span-6 (~440–670px),
   so it overflowed and clipped at every real width. The 2×2 fits the strip and
   stacks to 1 col on phones; operators dropped (labels $/⬆/⬇/= carry the relation).

   Inadimplência (snapshot of a different date, never part of the period's
   equation) was cut from here — it duplicated the TODOS row already in the
   Desempenho por Segmento table below and needed a full-width exception cell
   to avoid breaking these 4-cell positional borders. Its position note now
   lives beside that table's card-hd (`.n`); its drill-down moved into the
   table's Inadimplência `<th>`.
   ========================================================================== */
.cockpit-pipeline {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  background: var(--bi-bg-surface);
  border: var(--bi-border);
  border-radius: var(--bi-radius-md);
  overflow: hidden;
}
.cockpit-pipeline__cell {
  padding: var(--bi-space-sm) var(--bi-space-md);
  border-right: var(--bi-border);
  border-bottom: var(--bi-border);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--bi-space-2xs);
  min-width: 0;
}
.cockpit-pipeline__cell:nth-child(2n) { border-right: none; }
.cockpit-pipeline__cell:nth-last-child(-n+2) { border-bottom: none; }
.cockpit-pipeline__operator { display: none; }
.cockpit-pipeline__label {
  font-size: var(--fonte-rotulo);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bi-text-muted);
  margin-bottom: var(--bi-space-xs);
  white-space: nowrap;
}
.cockpit-pipeline__hero {
  font-family: var(--bi-font-display);
  font-size: var(--fonte-heroi);
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--bi-text-primary);
  line-height: 40px;
}
.cockpit-pipeline__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bi-space-2xs) var(--bi-space-xs);
  margin-bottom: var(--bi-space-xs);
  min-width: 0;
}
.cockpit-pipeline__row:last-child { margin-bottom: 0; }
.cockpit-pipeline__badge {
  display: inline-block;
  font-size: var(--fonte-pequena);
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: var(--bi-space-3xs) var(--bi-space-xs);
  border-radius: var(--bi-radius-sm);
  flex-shrink: 0;
  line-height: 16px;
}
/* BRUTA vs CONTRIB. are categorical label TYPES — flat tinted chips (FCDS chip
   vocabulary), not heavy dark fills. */
.cockpit-pipeline__badge--bruta   { background: var(--surf-3); color: var(--ink-2); }
.cockpit-pipeline__badge--contrib { background: var(--acc-soft); color: var(--acc-ink); }
.cockpit-pipeline__val {
  font-family: var(--bi-font-display);
  font-size: var(--fonte-destaque);
  font-weight: 500;
  color: var(--bi-text-primary);
  line-height: 24px;
  white-space: nowrap;
}
.cockpit-pipeline__pct {
  font-size: var(--fonte-pequena);
  color: var(--bi-text-secondary);
  margin-left: auto;
}
/* Faixa da inadimplência (02/09/2026) — irmã da tira acima, não uma quinta
   célula dela: a tira é a equação do PERÍODO e tem bordas posicionais de 4
   células (ver o bloco acima; a inadimplência já saiu dali uma vez).
   Faixa, não cartão: como cartão de KPI ela ocupava a largura inteira com um
   número pequeno encostado à esquerda e dois terços de vazio — "feio demais"
   (dono, 02/09/2026). Aqui o número fica numa ponta e a frase que o explica na
   outra, então a largura toda é largura USADA. Reusa `__label`/`__hero` da tira
   de propósito: mesmo tipo, mesma altura de leitura. */
.cockpit-inadimplencia {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bi-space-md);
  flex-wrap: wrap;
  padding: var(--bi-space-sm) var(--bi-space-md);
  background: var(--bi-bg-surface);
  border: var(--bi-border);
  border-radius: var(--bi-radius-md);
}
.cockpit-inadimplencia__stat { min-width: 0; }
.cockpit-inadimplencia__nota {
  margin: 0;
  font-size: var(--fonte-pequena);
  color: var(--bi-text-muted);
  text-align: right;
  min-width: 0;
}
/* Empilhado, a nota alinha com o número — texto à direita numa coluna só é
   ruído de leitura. */
@media (max-width: 767.98px) {
  .cockpit-inadimplencia__nota { text-align: left; }
}

@media (max-width: 479.98px) {
  .cockpit-pipeline { grid-template-columns: 1fr; }
  .cockpit-pipeline__cell { border-right: none; }
  .cockpit-pipeline__cell:nth-last-child(-n+2) { border-bottom: var(--bi-border); }
  .cockpit-pipeline__cell:last-child { border-bottom: none; }
}

/* "ver registros" — quiet drill-down trigger, not a floating link-blue button.
   Reuses Bootstrap's .btn/.btn-sm for sizing (no .btn-link, so no blue/
   underline-by-default); muted ink here, underline on hover/focus only. The
   keyboard focus ring lives in §23 ACCESSIBILITY (dropping .btn-link also
   drops the --bs-btn-focus-shadow-rgb it supplied). The Inadimplência trigger
   lives beside its nota in the "Desempenho por Segmento" card-hd, not in the
   table's <th> — a two-line header cell there sat 25px off the other six
   single-line column labels (all thead th are vertical-align:bottom). */
.cockpit-drill-btn {
  text-transform: none;
  letter-spacing: normal;
}
/* Left-aligned like the cell's own text (not Bootstrap's centered .btn),
   pinned to the cell's bottom edge regardless of how tall the row is —
   margin-top:auto claims the free space above it, so the label/value stay
   flush at the top and the button lands in the same place cell to cell. */
.cockpit-pipeline__cell .cockpit-drill-btn {
  align-self: flex-start;
  margin-top: auto;
}

/* Espaçamento real entre os grupos (BRUTA/CONTRIB./"N registros") do totalizador
   do modal Registros — antes era um `<span class="mx-3"></span>` vazio só para
   empurrar via margin. Cada grupo (badge+valor, ou o "N registros") chega da JS
   como um único <span>, item direto do flex; o gap fica no container, não em
   elemento decorativo. */
#bi-registros-modal-totais {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2rem;
}

#bi-tabela-segmentos-cockpit,
#bi-tabela-subsegmentos-modal {
  font-size: var(--fonte-corpo);
}
#bi-tabela-segmentos-cockpit thead th,
#bi-tabela-subsegmentos-modal thead th {
  font-size: var(--fonte-pequena);
}

/* ==========================================================================
   Tabelas de Preço (CRM) — auditoria do cadastro do ERP
   ========================================================================== */

/* Gatilho de descer um degrau (abrir a tabela, abrir o produto). É um <button>
   porque a ação acontece na própria página, e parece um link porque é isso que
   ele faz — e um botão cheio numa
   célula de código transformaria a coluna inteira numa fileira de botões. */
[data-pagina="crm-tabelas-preco"] .crm-link,
#tp-painel .crm-link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--crm-acento);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
[data-pagina="crm-tabelas-preco"] .crm-link:hover,
#tp-painel .crm-link:hover { opacity: .84; }
[data-pagina="crm-tabelas-preco"] .crm-link:focus-visible,
#tp-painel .crm-link:focus-visible {
  outline: 2px solid var(--crm-acento);
  outline-offset: 2px;
}

/* O painel divide dois níveis (itens da tabela, produto entre tabelas) e ambos
   trazem grade: mais largo que o padrão do offcanvas, senão a coluna de
   descrição do produto quebra em três linhas. */
#tp-painel { width: min(64rem, 96vw); }

/* A lista é a grade da casa (`tabelas-preco.js`, 15/09/2026), na altura da
   janela: a folha é branca como nas outras telas da grade, e o recuo de cima
   volta porque a altura cheia zera o do shell. */
.content:has(> .page[data-pagina="crm-tabelas-preco"] > .grade),
.page[data-pagina="crm-tabelas-preco"]:has(> .grade) { background: #fff; }
.content--altura-cheia > .page[data-pagina="crm-tabelas-preco"] {
  padding-top: var(--content-pad-y); }
/* A descrição é o texto longo da linha ("Comissão: 2%; Condição de pagamento:
   A Prazo; Frete: FOB; ICMS: Importado (4%)"): ela fica com a SOBRA da linha e
   corta na reticência, com o texto inteiro no `title`. `max-width:0` é o teto
   que faz a coluna ceder; o invólucro herdaria esse zero e sumiria com o
   texto, então quem corta é o `td` (mesmo caso da Cobertura). */
[data-pagina="crm-tabelas-preco"] .grade .tp-col-descricao {
  width: 100%; max-width: 0; min-width: 14rem; }
[data-pagina="crm-tabelas-preco"] .grade .tp-col-descricao .grade-celula {
  max-width: none; }
/* Três achados numa célula só é o caso comum desta lista — a coluna nasce
   larga o bastante para os três, em vez de cortar o terceiro sempre. */
[data-pagina="crm-tabelas-preco"] .grade .tp-col-achados { min-width: 21rem; }
[data-pagina="crm-tabelas-preco"] .grade .tp-col-validade { min-width: 11rem; }

/* ==========================================================================
   Clientes (CRM) — a base inteira, trabalhável  (/crm/clientes/)
   --------------------------------------------------------------------------
   Escopo de página: tudo aqui é prefixado `cl-` e vive sob
   [data-pagina="crm-clientes"], que já herda os tokens `--crm-*` do bloco da
   rampa do funil (esta página entrou naquele seletor por IGUALDADE, nunca por
   prefixo). Nenhum token global é redefinido.
   ========================================================================== */

/* A tela É a lista (reporte #134): `content--altura-cheia` dá a altura da
   janela e só o corpo da grade rola — abrir e fechar a ficha não mexe na
   posição. A folha é branca como nas outras telas da grade; o recuo de cima
   volta porque a altura cheia zera o do shell. */
.content:has(> .page[data-pagina="crm-clientes"] > .grade),
.page[data-pagina="crm-clientes"]:has(> .grade) { background: #fff; }
.content--altura-cheia > .page[data-pagina="crm-clientes"] { padding-top: var(--content-pad-y); }

/* Abas e busca dividem a mesma faixa: sao a mesma pergunta ("qual recorte?").
   A busca cruza as abas, então pô-la longe delas sugeriria que ela procura
   dentro do recorte — o oposto do que o servidor faz. */
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-topo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: .75rem;
}
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-abas { display: flex; flex-wrap: wrap; gap: .35rem; }
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-busca { flex: 1 1 18rem; max-width: 26rem; }

:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-aba {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  padding: .3rem .7rem;
  border: 1px solid var(--crm-borda);
  border-radius: var(--raio-chip);
  background: var(--crm-superficie);
  color: var(--crm-tinta-2);
  font-size: var(--bi-fs-compact);
  font-weight: 500;
  line-height: 1.3;
  cursor: pointer;
}
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-aba:hover { border-color: var(--crm-borda-forte); }
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-aba:focus-visible {
  outline: 2px solid var(--crm-acento);
  outline-offset: 2px;
}
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-aba--ativa {
  background: var(--crm-acento);
  border-color: var(--crm-acento);
  color: #fff;
}
/* A contagem é o que faz a aba se explicar sem clique — fica legível, mas não
   disputa peso com o rótulo. */
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-aba__conta {
  font-variant-numeric: tabular-nums;
  font-size: var(--bi-fs-micro);
  opacity: .78;
}


/* O resumo pessoal da lista de leads (reporte #52): "Leads que você criou —
   Hoje 2 · Esta semana 7 · Este mês 14". Uma linha silenciosa sob a faixa de
   abas: é informação DE APOIO, não o recorte da tela, e disputar peso com as
   abas faria a pessoa procurar nela o que ela não faz (não filtra a grade). */
[data-pagina="crm-clientes"] .cl-meus {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .1rem 1rem;
  margin: 0 0 .25rem;
  font-size: var(--fonte-corpo);
  color: var(--crm-tinta-2);
}
[data-pagina="crm-clientes"] .cl-meus__titulo {
  color: var(--crm-tinta-3);
  margin-right: -.4rem;
}
[data-pagina="crm-clientes"] .cl-meus__titulo::after { content: " —"; }
[data-pagina="crm-clientes"] .cl-meus__conta {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--crm-tinta);
}

/* O ✕ da busca (A3): dentro da caixa, só visível com termo. */
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-busca { position: relative; }
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-busca__limpar {
  position: absolute; right: .4rem; top: 50%; transform: translateY(-50%);
  border: 0; background: none; padding: .15rem .3rem;
  color: var(--crm-tinta-3); cursor: pointer; line-height: 1;
}
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-busca__limpar:hover { color: var(--crm-tinta); }
:is([data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-busca__limpar[hidden] { display: none; }

/* O selo do feedback: lead buscado que já virou cliente diz isso, na visão de
   leads. Verde de conclusão, não o âmbar do selo "lead" — promover é chegada. */
[data-pagina="crm-clientes"] .crm-selo--promovido {
  background: #d1e7dd; color: #0a3622; border: 1px solid #a3cfbb;
  border-radius: .35rem; padding: 0 .3rem;
  font-size: var(--fonte-pequena); font-weight: 500;
}

:is([data-pagina="crm-clientes"], [data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-cliente__nome {
  font-weight: 600;
  color: var(--crm-tinta);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
}
/* O CNPJ é linha secundária: é o desempate entre dois cadastros de nome
   parecido, não a identidade que se lê primeiro. */
:is([data-pagina="crm-clientes"], [data-pagina="crm-negocios"], [data-pagina="crm-representantes"], [data-pagina="crm-usuarios"]) .cl-cliente__doc {
  font-size: var(--bi-fs-micro);
  color: var(--crm-tinta-3);
  font-variant-numeric: tabular-nums;
}

/* Duas colunas de identificação com número: tabular para o olho comparar
   dígito com dígito, e largura própria para o CNPJ não quebrar. */
[data-pagina="crm-clientes"] .cl-col-doc {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Um lead pode ter até seis telefones (medido no Ploomes, 04/09/2026), e o
   dono mandou mostrar todos: cada número em sua linha dentro da mesma célula.
   Um por linha, e não separados por ponto, porque telefone se lê inteiro — o
   olho que procura um DDD não quer caçá-lo no meio de uma tira de dígitos. */
[data-pagina="crm-clientes"] .cl-fone {
  display: block;
  line-height: 1.35;
}
[data-pagina="crm-clientes"] .cl-fone + .cl-fone { margin-top: .1rem; }
/* Só o celular vira link — quem decide isso é o servidor. O ícone à esquerda
   dá a diferença sem depender da cor, que sozinha não serve a quem não a
   enxerga. */
[data-pagina="crm-clientes"] .cl-fone--zap i {
  margin-right: .3rem;
  opacity: .75;
}
[data-pagina="crm-clientes"] .cl-col-uf { width: 3.5rem; }
/* Próximo contato vencido (item 19): quem decide é o SERVIDOR (`tom`), aqui
   só a cor — mesmo token de `--crm-mal` que a pílula de erro já usa. */
[data-pagina="crm-clientes"] .cl-col-vencido {
  color: var(--crm-mal);
  font-weight: 500;
}
/* Situação do lead (reporte #91): "Descartado — motivo" pode ser longo (o
   detalhe do descarte é texto livre): uma linha só com reticências, e o texto
   inteiro no `title`. Escopo de página. */
[data-pagina="crm-clientes"] .cl-col-situacao {
  max-width: 14rem;



}
/* O nome quebra em linhas (text-wrap), como antes da grade: a pílula e o selo
   vão ao lado e o documento embaixo (Clientes). Cortar o nome em reticência
   escondia justamente o que diferencia dois cadastros parecidos. Nome de gente,
   de cidade, o e-mail (partido onde precisar, `text-break`) e as datas também
   quebram (text-wrap na coluna): em 1366 a grade cabe sem rolagem de lado e
   sem nada escondido (#454). */
[data-pagina="crm-clientes"] .grade .grade-tabela .cl-col-nome { min-width: 12rem; max-width: 22rem; }
[data-pagina="crm-clientes"] .grade .grade-tabela .cl-col-curta { max-width: 11rem; }
/* O seletor de base de Leads abre a barra: largura do texto, não da caixa. */
[data-pagina="crm-clientes"] .grade .cl-base { flex: 0 0 auto; margin: 0; }
[data-pagina="crm-clientes"] .grade .cl-base select { width: auto; }

/* Ficha: a faixa de "quem atende" (responsável + representante). Uma linha por
   papel, com o nome em destaque e os dois gestos à direita — assumir é um
   clique, delegar abre a lista. */
.fc-quem-atende { display: flex; flex-wrap: wrap; gap: .35rem 1.5rem; margin-top: .35rem; }
.fc-atende { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
/* Tinta de apoio: com `#fc-nome` a 20px, o nome do representante em tinta
   cheia e caixa alta virava uma SEGUNDA manchete na mesma faixa — medido em
   03/09/2026: mesma cor, mesmo peso, só 1,36x de diferença de corpo. */
.fc-atende__nome { color: var(--crm-tinta-2); }
.fc-atende__lista { width: auto; min-width: 12rem; }

/* ============================================================================
   DRE GERENCIAL  (/dre-gerencial/)
   ----------------------------------------------------------------------------
   Escopo de página: tudo aqui é prefixado `dre-` e vive sob `.page.dre`. Os
   tokens `--dre-*` são LOCAIS — nascem no `.page.dre` e não vazam para as outras
   telas. Nenhum token global é redefinido.

   O desenho reproduz o protótipo aprovado: acento steel, polo negativo óxido,
   serifa de balanço nos totais e números tabulares. As duas cores de série
   passaram o validador de paleta (banda de luminosidade, croma, separação para
   daltonismo e contraste sobre o papel).
   ============================================================================ */
.page.dre {
    --dre-papel: #ffffff;
    --dre-papel-alt: #fafbfc;
    --dre-papel-fundo: #f1f4f6;
    --dre-tinta: #141b22;
    --dre-tinta-media: #47535f;
    --dre-tinta-fraca: #6b7885;
    --dre-regua: #dfe5ea;
    --dre-regua-forte: #c3ccd4;
    --dre-acento: #136a95;
    --dre-oxido: #a3342a;
    --dre-verde: #1c6b52;
    --dre-realce: #e8f1f7;   /* fundo de realce: distorção no insight e pisca da linha focada */
}

/* --- barra de visões ----------------------------------------------------- */
.dre-instrumentos {
    background: var(--dre-papel);
    border: 1px solid var(--dre-regua);
    border-radius: 3px;
    padding: 14px 16px;
    display: flex;
    flex-wrap: wrap;
    gap: 18px 28px;
    align-items: flex-end;
    margin-bottom: 1rem;
}
/* `.page > section` zera padding lateral com !important (regra global do shell);
   aqui a barra é um cartão com moldura própria, então devolvemos os 16px. */
.page > section.dre-instrumentos { padding-inline: 16px !important; }
.dre-controle { display: flex; flex-direction: column; gap: 6px; }
.dre-fichas { display: flex; flex-wrap: wrap; gap: 6px; }
.dre-instrumentos-acoes { margin-left: auto; display: flex; gap: 8px; align-items: flex-end; }
.page.dre .dre-rotulo {
    font-size: var(--fonte-rotulo);
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--dre-tinta-fraca);
    font-weight: 500;
}
.dre-ficha {
    font: inherit;
    font-size: var(--fonte-corpo);
    padding: 5px 11px;
    border-radius: 2px;
    border: 1px solid var(--dre-regua-forte);
    background: var(--dre-papel-alt);
    color: var(--dre-tinta-media);
    cursor: pointer;
}
/* Ficha marcada é azul (recorte: quais unidades entram); a visão em vigor é
   preta, porque é escolha exclusiva e não filtro — cores diferentes, papéis diferentes. */
.dre-ficha[aria-pressed="true"] { background: var(--dre-acento); border-color: var(--dre-acento); color: #fff; }
.dre-visoes .dre-ficha[aria-pressed="true"] { background: var(--dre-tinta); border-color: var(--dre-tinta); }
.dre-ficha:hover:not(:disabled) { border-color: var(--dre-acento); }
/* Unidade sem lançamento no período (#180): apagada como `.checkrow--empty`, sem hover. */
.dre-ficha:disabled { opacity: .45; cursor: default; }
.dre-botao-texto {
    font: inherit;
    font-size: var(--fonte-corpo);
    background: none;
    border: none;
    border-bottom: 1px solid var(--dre-regua-forte);
    color: var(--dre-tinta-media);
    padding: 4px 2px;
    cursor: pointer;
}
.dre-botao-texto:hover { color: var(--dre-acento); border-color: var(--dre-acento); }

/* --- faixa de indicadores ------------------------------------------------ */
.dre-indicadores {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: 1px;
    background: var(--dre-regua);
    border: 1px solid var(--dre-regua);
    border-radius: 3px;
    overflow: hidden;
    margin-bottom: 1rem;
}
.dre-indicador { background: var(--dre-papel); padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 4px; }
.dre-indicador .dre-rotulo { font-size: var(--fonte-pequena); }
.dre-indicador .dre-valor {
    font-size: var(--fonte-heroi);
    font-weight: 500;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
    color: var(--dre-tinta);
}
.dre-indicador .dre-nota { font-size: var(--fonte-pequena); color: var(--dre-tinta-fraca); font-variant-numeric: tabular-nums; }
.page.dre .dre-positivo { color: var(--dre-verde); }
.page.dre .dre-negativo { color: var(--dre-oxido); }
.page.dre .atencao { color: var(--warning-text); font-weight: 500; }
.page.dre .positivo { color: var(--dre-verde); }
.page.dre .negativo { color: var(--dre-oxido); }

/* --- avisos do envelope -------------------------------------------------- */
.dre-avisos { margin-bottom: .75rem; }
.dre-aviso {
    border-left: 2px solid var(--warning-text);
    padding-left: 12px;
    margin: 0 0 .25rem;
    font-size: var(--fonte-corpo);
    color: var(--dre-tinta-media);
}

/* --- cabeçalho da visão -------------------------------------------------- */
.dre-cabecalho-visao { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: baseline; margin-bottom: .5rem; }
.dre-titulo-visao { font-size: var(--fonte-destaque); font-weight: 500; margin: 0; color: var(--dre-tinta); }
.dre-dica { font-size: var(--fonte-corpo); color: var(--dre-tinta-fraca); }
.dre-rolagem { overflow-x: auto; }
.dre-vazio { padding: 12px 0; font-size: var(--fonte-corpo); color: var(--dre-tinta-fraca); }

/* --- tabela da DRE: uma árvore só (reporte #85) -------------------------
   Seção, conta e item são linhas da MESMA tabela: mesma fonte, mesma régua,
   mesmas colunas. A hierarquia é só recuo, peso e tinta — nada de caixa
   dentro da tabela. A rolagem é da área da tabela, para o cabeçalho e a
   coluna de nomes ficarem presos enquanto os números rolam. */
.page.dre #dre-area-tabela { max-height: calc(100vh - 96px); overflow: auto; }
table.dre-quadro-linhas { width: 100%; border-collapse: separate; border-spacing: 0; font-variant-numeric: tabular-nums; }
table.dre-quadro-linhas th, table.dre-quadro-linhas td {
    padding: 7px 16px;
    text-align: right;
    white-space: nowrap;
    border-bottom: 1px solid var(--dre-regua);
}
table.dre-quadro-linhas thead th {
    font-size: var(--fonte-rotulo);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--dre-tinta-fraca);
    font-weight: 500;
    border-bottom: 1px solid var(--dre-regua-forte);
    background: var(--dre-papel-alt);
}
#dre-area-tabela table.dre-quadro-linhas thead th { position: sticky; top: 0; z-index: 2; }
table.dre-quadro-linhas th.dre-nome, table.dre-quadro-linhas td.dre-nome { text-align: left; white-space: normal; }
table.dre-quadro-linhas tbody tr:last-child td { border-bottom: none; }
table.dre-quadro-linhas tr.dre-grupo td { color: var(--dre-tinta); }
table.dre-quadro-linhas tr.dre-grupo td.dre-nome { font-weight: 500; }
table.dre-quadro-linhas tr.dre-total td {
    font-weight: 500;
    color: var(--dre-tinta);
    background: var(--dre-papel-alt);
    border-top: 1px solid var(--dre-regua-forte);
}
table.dre-quadro-linhas tr.dre-total.dre-destaque td { font-size: var(--fonte-destaque); }
table.dre-quadro-linhas tr.dre-conta td { color: var(--dre-tinta-media); }
table.dre-quadro-linhas tr.dre-conta td.dre-nome { padding-left: 34px; }
/* Nome de seção e de conta: uma linha; o que passa vira reticências, e o texto
   inteiro fica no title. */
.page.dre .dre-texto-linha {
    display: block;



    min-width: 0;
}
.page.dre .dre-codigo { font-variant-numeric: tabular-nums; font-size: var(--fonte-pequena); color: var(--dre-tinta-fraca); margin-right: 6px; }
.page.dre .dre-fraco { color: var(--dre-tinta-fraca); font-size: var(--fonte-pequena); font-weight: 400; }
.dre-abridor {
    font: inherit;
    background: none;
    border: none;
    padding: 0;
    color: inherit;
    cursor: pointer;
    text-align: left;
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    max-width: 100%;
    min-width: 0;
}
.dre-abridor:hover { color: var(--dre-acento); }
.dre-seta { color: var(--dre-tinta-fraca); font-size: var(--fonte-pequena); width: 11px; text-align: center; flex: none; }
.dre-abridor[aria-expanded="true"] .dre-seta { color: var(--dre-acento); }
.dre-delta { font-size: var(--fonte-corpo); }
/* Demonstrativo: a coluna de nomes leva a sobra da largura, e é dentro dela
   que a reticência do item acontece. */
table.dre-demonstrativo td.dre-nome { width: 100%; max-width: 0; }

/* --- matrizes: coluna de nomes presa, só os números rolam ---------------- */
table.dre-matriz th, table.dre-matriz td { padding: 6px 6px; font-size: var(--fonte-corpo); }
/* Na matriz o destaque fica no nome: o número a 16px encosta no vizinho com 13 colunas. */
table.dre-matriz tr.dre-total.dre-destaque td { font-size: var(--fonte-corpo); }
table.dre-matriz tr.dre-total.dre-destaque td.dre-nome { font-size: var(--fonte-corpo); }
table.dre-matriz th.dre-nome, table.dre-matriz td.dre-nome {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--dre-papel);
    border-right: 1px solid var(--dre-regua);
    width: 340px;
    min-width: 340px;
    max-width: 340px;
    padding-left: 12px;
}
table.dre-matriz tr.dre-conta td.dre-nome { padding-left: 24px; }
#dre-area-tabela table.dre-matriz thead th.dre-nome { background: var(--dre-papel-alt); z-index: 3; }
table.dre-matriz tr.dre-total td.dre-nome { background: var(--dre-papel-alt); }
table.dre-matriz th.dre-coluna-total, table.dre-matriz td.dre-coluna-total { background: var(--dre-papel-alt); }
table.dre-matriz tr.dre-secao-titulo td {
    font-size: var(--fonte-rotulo);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--dre-tinta-fraca);
    font-weight: 500;
    background: var(--dre-papel-fundo);
    padding-top: 10px;
}

/* --- detalhe da conta aberta: Agrupado | Lançamentos (reporte #85) -------
   Uma linha de ponta a ponta sob a conta, com uma subtabela dentro: data, NF
   e lote não cabem nas colunas de meses ou de BU. Sem caixa e sem fundo — o
   papel, a fonte e a régua são os da grade; o que diz "isto é da conta" é só o
   recuo. Nas matrizes o quadro fica preso à esquerda na largura VISÍVEL da
   área (100cqw), para a barra e as colunas nunca rolarem para fora da tela
   junto com os meses. */
.page.dre #dre-area-tabela { container-type: inline-size; }
table.dre-quadro-linhas tr.dre-detalhe > td { padding: 0; text-align: left; white-space: normal; }
.page.dre .dre-detalhe-quadro { padding: 4px 16px 10px 52px; }
table.dre-matriz .dre-detalhe-quadro { position: sticky; left: 0; width: 100cqw; padding-left: 42px; padding-right: 12px; }
.page.dre .dre-detalhe-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 6px 0 4px; }
.page.dre .dre-detalhe-resumo { margin-left: auto; font-size: var(--fonte-corpo); color: var(--dre-tinta-media); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dre-busca {
    width: 240px;
    font-size: var(--fonte-corpo);
    padding: 4px 8px;
    color: var(--dre-tinta);
    background: var(--dre-papel);
    border: 1px solid var(--dre-regua-forte);
    border-radius: 2px;
}
/* Larguras fixas: o texto longo (contraparte, histórico) leva a sobra e corta
   em reticências; o title da célula guarda o texto inteiro. */
table.dre-subtabela { table-layout: fixed; }
table.dre-subtabela th, table.dre-subtabela td {
    padding: 5px 8px;
    font-size: var(--fonte-corpo);
    color: var(--dre-tinta-media);


    text-align: left;
}
table.dre-subtabela thead th { background: none; padding-top: 6px; padding-bottom: 6px; font-size: var(--fonte-pequena); }
table.dre-subtabela th:first-child, table.dre-subtabela td:first-child { padding-left: 0; }
table.dre-subtabela .dre-sub-numero { text-align: right; }
table.dre-subtabela .dre-sub-data { width: 72px; }
table.dre-subtabela .dre-sub-documento { width: 104px; color: var(--dre-tinta); }
table.dre-subtabela .dre-sub-centro { width: 170px; }
table.dre-subtabela .dre-sub-curta { width: 64px; }
table.dre-subtabela .dre-sub-percentual { width: 92px; }
table.dre-subtabela .dre-sub-valor { width: 116px; color: var(--dre-tinta); }
table.dre-subtabela td.dre-sub-texto:first-child { color: var(--dre-tinta); }
table.dre-subtabela td.dre-sub-aviso, table.dre-subtabela tr.dre-restante td { color: var(--dre-tinta-fraca); }
table.dre-subtabela tbody tr:last-child td { border-bottom: none; }
/* Título que ordena: o botão é o próprio texto do cabeçalho. */
.dre-ordenar {
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
}
.dre-ordenar:hover, th[aria-sort="ascending"] .dre-ordenar, th[aria-sort="descending"] .dre-ordenar { color: var(--dre-acento); }
.dre-ordenar i { font-size: 9px; opacity: .55; }
th[aria-sort="ascending"] .dre-ordenar i, th[aria-sort="descending"] .dre-ordenar i { opacity: 1; }
table.dre-subtabela th.dre-sub-numero .dre-ordenar { flex-direction: row-reverse; }

/* --- gráficos ------------------------------------------------------------ */
.dre-legenda { display: flex; flex-wrap: wrap; gap: 14px; font-size: var(--fonte-corpo); color: var(--dre-tinta-media); margin-bottom: .25rem; }
.dre-legenda span { display: inline-flex; align-items: center; gap: 6px; }
.dre-marca { width: 11px; height: 11px; border-radius: 2px; display: inline-block; }
.dre-marca-acento { background: var(--dre-acento); }
.dre-marca-oxido { background: var(--dre-oxido); }
.dre-marca-linha { background: var(--dre-oxido); height: 2px; border-radius: 1px; }
.dre-quadro { position: relative; }
svg.dre-grafico { width: 100%; height: auto; display: block; overflow: visible; }
svg.dre-grafico text { font-size: var(--fonte-pequena); fill: var(--dre-tinta-fraca); }
.dre-balao {
    position: absolute;
    pointer-events: none;
    background: var(--dre-papel);
    border: 1px solid var(--dre-regua-forte);
    border-radius: 3px;
    padding: 8px 10px;
    font-size: var(--fonte-corpo);
    line-height: 1.5;
    box-shadow: 0 6px 18px rgba(15, 25, 35, .14);
    opacity: 0;
    transition: opacity .1s ease;
    z-index: 5;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--dre-tinta);
}

@media (max-width: 620px) {
    .dre-indicador .dre-valor { font-size: 21px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MAPEAMENTO DO GALPÃO (/mapa-galpao/) — duas vistas do mesmo envelope
   ═══════════════════════════════════════════════════════════════════════════
   Escopo de PÁGINA: tudo abaixo mora sob `.mg`, então nada aqui vaza para as
   outras ~28 telas. Os tokens vêm do FCDS (`--surf`, `--line`, `--ink-*`); as
   seis cores de família são locais e dessaturadas de propósito — a cor
   identifica a FAMÍLIA do produto e não pode competir com o azul do acento,
   que é quem marca seleção e foco.
   A vista "Espaço" usa transformações 3D do próprio CSS: são caixas
   ortogonais num plano, que é exatamente o que `preserve-3d` faz bem — não há
   biblioteca envolvida. */
.mg, .wms, .wms-tela {
  /* A cartela do galpão: oito cores nomeadas, escolhidas UMA VEZ por família
     na Configurar WMS. Não são tokens de tema e não vazam para outras telas —
     são o vocabulário de cor do chão de fábrica ("a amarela é cordoalha nua").
     Saturação média de propósito: precisa ser lida a três metros e de esguelha,
     sem competir com o acento, que marca seleção e foco. */
  --mg-cor-laranja:#d9752b; --mg-cor-amarelo:#cfa016; --mg-cor-azul:#2f6fb5;
  --mg-cor-verde:#3f8f5a;   --mg-cor-vermelho:#c04a3f; --mg-cor-roxo:#7a5aa8;
  --mg-cor-marrom:#8a6a41;  --mg-cor-cinza:#8e8e99;
  --mg-chao:var(--surf-3); --mg-pista:var(--surf-2);
}
.mg-secao {
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:0.05em; text-transform:uppercase;
  color:var(--ink-2); margin:0 0 0.75rem; padding-bottom:0.375rem;
  border-bottom:var(--bs-border-width) solid var(--line);
}
.mg-secao span { color:var(--ink-3); font-weight:400; }
.mg-vazio { color:var(--ink-3); font-size:var(--fonte-corpo); padding:0.75rem 0; margin:0; }
.mg-dica { color:var(--ink-3); font-size:var(--fonte-pequena); }

.mg-corpo { display:grid; grid-template-columns:minmax(0,1fr); gap:1rem; align-items:start; }
.mg-instrucao { margin:0.625rem 0; font-size:var(--fonte-pequena); color:var(--ink-2);
  border-left:3px solid var(--acc-line); padding-left:0.5rem; }
.mg-instrucao--erro { color:var(--bs-danger-text-emphasis); font-weight:500;
  border-left-color:var(--bs-danger); background:var(--bs-danger-bg-subtle);
  padding:0.375rem 0.5rem; }
.mg-provisoria { font-size:var(--fonte-rotulo); letter-spacing:0.05em; text-transform:uppercase;
  color:#8a5a00; background:var(--bs-warning-bg-subtle); border-radius:var(--fc-radius-sm);
  padding:0.0625rem 0.3125rem; }

/* os três selects que endereçam, dentro da grade */
.mg-campo-td { padding-top:0.25rem; padding-bottom:0.25rem; }
.mg-campo-td .mg-campo { min-width:4.5rem; max-width:14rem; }
.mg-campo-td .mg-campo[data-campo="posicao"],
.mg-campo-td .mg-campo[data-campo="nivel"] { min-width:4rem; width:4.5rem;
  font-family:var(--bs-font-monospace); }
/* A grade escreve a família por extenso numa coluna: repetir isso como faixa
   colorida na borda da linha seria a mesma informação duas vezes. A cor de
   família fica onde é a única leitura possível — os volumes da vista Espaço. */
.mg--gravando #mg-grade { opacity:0.55; pointer-events:none; }
/* Disputa na Grade: ícone e o lugar em disputa, porque o lote disputante está
   SEM posição — sem dizer qual lugar, a linha não aponta onde é a briga. */
/* Linha de filtros de coluna: sem seta de ordenação (o DataTables desenha o
   indicador em toda célula de cabeçalho, e aqui ele não ordena nada) e sem o
   negrito de título — ela é controle, não cabeçalho. */
.mg-linha-filtros td { padding:0.25rem 0.5rem; font-weight:400; }
/* O DataTables desenha o indicador de ordenação em TODA célula do cabeçalho, e
   marca as da segunda linha com `!important` — daí o `!important` aqui, único
   jeito de calar uma seta que não ordena nada. */
table.dataTable thead tr.mg-linha-filtros td::before,
table.dataTable thead tr.mg-linha-filtros td::after { display:none !important; }
.mg-conflito { color:var(--bs-danger); }
.mg-conflito-lugar { font-family:var(--bs-font-monospace); font-size:var(--fonte-pequena);
  color:var(--bs-danger-text-emphasis); }

.mg-legenda { display:flex; flex-wrap:wrap; gap:0.25rem 1rem; list-style:none;
  margin:0.5rem 0 0; padding:0; font-size:var(--fonte-pequena); color:var(--ink-2); }
.mg-legenda__item { display:flex; align-items:center; gap:0.375rem; }
.mg-legenda__cor { width:0.75rem; height:0.75rem; border-radius:2px; }

/* ── Mapa 3D ────────────────────────────────────────────────────────────────
   O desenho é SVG, e a projeção é aritmética do JS (isometria de 30° ou planta
   ortogonal). A versão anterior usava transformações 3D do CSS: funciona para
   caixa e falha para rolo — no CSS a circunferência é um retângulo de canto
   arredondado, o topo do cilindro nunca casa com o casco, e não existe
   ordenação por profundidade. Aqui a elipse é elipse e a ordem é a nossa. */
.mg-cena { position:relative; height:30rem; overflow:hidden; cursor:grab;
  background:var(--surf-2); border:var(--bs-border-width) solid var(--line);
  border-radius:var(--fc-radius); touch-action:none; }
.mg--3d .mg-cena { height:min(70vh, 44rem); }
.mg-mundo { display:block; width:100%; height:100%; }

/* O galpão: parede, chão e as pistas dos corredores. Sem contorno o chão é um
   retângulo flutuando e não há como se localizar. */
.mg-svg-parede { fill:color-mix(in srgb, var(--ink-4) 5%, transparent);
  stroke:var(--line-3); stroke-width:2; }
.mg-svg-chao { fill:var(--mg-chao); stroke:var(--line-3); stroke-width:1; }
.mg-svg-pista { fill:var(--mg-pista); stroke:var(--line-3); stroke-width:1; }
.mg-svg-portao { fill:var(--ink-4); font-size:var(--fonte-pequena); letter-spacing:0.08em; }

/* A vaga livre é o que o teto declarado permitiu desenhar: sem ela o mapa
   mostrava "o que está lá"; com ela mostra o galpão inteiro, e "cabe mais?" se
   responde olhando. */
.mg-vaga { fill:color-mix(in srgb, var(--ink-4) 8%, transparent);
  stroke:var(--line-3); stroke-width:1; stroke-dasharray:3 3; }

.mg-svg-rua { fill:var(--ink-2); font-family:var(--bs-font-monospace);
  font-size:var(--fonte-titulo); font-weight:500; paint-order:stroke; stroke:var(--surf);
  stroke-width:3px; }
.mg-svg-rua__ocupacao { fill:var(--ink-4); font-size:var(--fonte-pequena); font-weight:400;
  stroke-width:2px; }
.mg-svg-regua { fill:var(--ink-3); font-family:var(--bs-font-monospace); font-size:var(--fonte-pequena); }

/* O volume: a cor vem do cadastro da família e o relevo, do brilho de cada
   face. Caixa é plana por natureza; o rolo tem o degradê cilíndrico por cima
   da própria cor, num gradiente só, reaproveitado por todos. */
.mg-vol { cursor:pointer; }
.mg-svg-topo { fill:var(--mg-cor, var(--mg-cor-cinza)); filter:brightness(1.16); }
.mg-svg-frente { fill:var(--mg-cor, var(--mg-cor-cinza)); filter:brightness(0.92); }
.mg-svg-lado { fill:var(--mg-cor, var(--mg-cor-cinza)); filter:brightness(0.76); }
.mg-svg-corpo { fill:var(--mg-cor, var(--mg-cor-cinza)); }
.mg-svg-cilindrico { fill:url(#mg-cilindro); }
.mg-svg-furo { fill:var(--surf); stroke:color-mix(in srgb, #000 18%, transparent);
  stroke-width:0.75; }
.mg-vol--sobra { opacity:0.5; }
.mg-vol--fora .mg-svg-topo { stroke:var(--bs-danger); stroke-width:1.5;
  stroke-dasharray:2 2; }
/* Conflito: o volume MANTÉM a cor da família (o mapa não mente sobre o que
   está lá) e ganha um alerta por cima. */
.mg-svg-alerta { fill:var(--bs-danger); font-family:'Font Awesome 6 Free';
  font-weight:500; font-size:var(--fonte-pequena); paint-order:stroke; stroke:#fff; stroke-width:2px; }
/* Seleção é CONTORNO, nunca troca de matiz: com "engraxada = azul" escolhido no
   cadastro, pintar o volume selecionado de acento faria a seleção mentir sobre
   a família. */
.mg-vol:hover :is(.mg-svg-topo, .mg-svg-frente, .mg-svg-lado, .mg-svg-corpo),
.mg-vol:focus-visible :is(.mg-svg-topo, .mg-svg-frente, .mg-svg-lado, .mg-svg-corpo) {
  stroke:#fff; stroke-width:1.5; filter:brightness(1.12); }
.mg-vol:focus-visible { outline:none; }
/* Na legenda a bobina se anuncia pelo mesmo furo do mapa — a legenda tem de
   ensinar a forma, não só a cor. */
.mg-legenda__cor--bobina { border-radius:50%;
  background-image:radial-gradient(circle at 50% 50%,
    var(--surf) 0 26%, transparent 27%); }

/* Gaveta do detalhe: SPLIT, não cortina. Clicar num volume abre o card ao lado
   e a página cede a largura — escurecer o galpão justamente quando a pessoa
   quer conferir o card CONTRA o lugar no mapa seria esconder a resposta.
   `margin-right` e não `padding`: o shell trava `.page { padding: … !important }`,
   e vencer isso exigiria outro `!important` numa regra de página. */
.page.mg--3d #mg-gaveta { --bs-offcanvas-width:min(420px, 92vw);
  background:var(--surf); border-left:1px solid var(--line); }
@media (min-width: 1200px) {
  .page.mg--3d { transition:margin-right 0.3s ease-in-out; }
  .page.mg--3d.mg-com-gaveta { margin-right:min(420px, 92vw); }
}
@media (prefers-reduced-motion: reduce) {
  .page.mg--3d { transition:none; }
}
.mg-cena-controles { display:flex; gap:0.375rem; align-items:center; flex-wrap:wrap;
  margin-top:0.5rem; }
.mg-detalhe { margin-top:0.5rem; min-height:2.5rem; }
.mg-detalhe__lista { display:grid; grid-template-columns:auto 1fr; gap:0.25rem 0.75rem;
  margin:0; font-size:var(--fonte-corpo); }
.mg-detalhe__lista dt { font-size:var(--fonte-rotulo); letter-spacing:0.08em; text-transform:uppercase;
  color:var(--ink-3); align-self:center; }
.mg-detalhe__lista dd { margin:0; font-family:var(--bs-font-monospace); }

/* A cor vem do CADASTRO (bi_familiagalpao.cor), não de um índice sorteado: o
   serviço manda o nome e aqui ele vira tinta. Uma família nova entrando no
   galpão não repinta mais as outras. */
.mg-cor-laranja  { --mg-cor:var(--mg-cor-laranja); }
.mg-cor-amarelo  { --mg-cor:var(--mg-cor-amarelo); }
.mg-cor-azul     { --mg-cor:var(--mg-cor-azul); }
.mg-cor-verde    { --mg-cor:var(--mg-cor-verde); }
.mg-cor-vermelho { --mg-cor:var(--mg-cor-vermelho); }
.mg-cor-roxo     { --mg-cor:var(--mg-cor-roxo); }
.mg-cor-marrom   { --mg-cor:var(--mg-cor-marrom); }
.mg-cor-cinza    { --mg-cor:var(--mg-cor-cinza); }
/* `background-COLOR`, não o atalho: o atalho zeraria o `background-image` que
   desenha o furo e o enrolamento da bobina — e estas regras vêm depois. */
.mg-legenda__cor { background-color:var(--mg-cor, var(--mg-cor-cinza)); }

.mg-nova-rua { display:flex; align-items:center; gap:0.5rem; flex-wrap:wrap;
  margin-top:0.75rem; }
.mg-nova-rua input { width:12rem; }

/* ── Configurar WMS ─────────────────────────────────────────────────────────
   Escopo de página (`.wms`). A mini-planta é o único desenho da tela e existe
   por um motivo prático: o número de posições é abstrato até virar tiras, e é
   olhando as tiras que alguém percebe ter declarado 20 numa rua de 12. */
.wms .wms-num { width:5.5rem; font-family:var(--bs-font-monospace); }
.wms-planta { display:flex; flex-wrap:wrap; gap:2px; align-items:center;
  min-width:8rem; max-width:22rem; }
.wms-tira { display:block; width:0.5rem; height:1.125rem; border-radius:2px;
  border:1px dashed var(--line-3); }
.wms-tira--cheia { border-style:solid; border-color:transparent;
  background:var(--ink-4); }
.wms-planta-td { vertical-align:middle; }
.wms-amostra { display:inline-block; width:1.75rem; height:1.125rem;
  border-radius:3px; background:var(--mg-cor, var(--mg-cor-cinza)); }
.wms-amostra--bobina { border-radius:0.5625rem / 50%; }
.wms-detalhes { margin:0.375rem 0 0; padding-left:1.125rem; font-size:var(--fonte-pequena); }

/* ── Coletor ────────────────────────────────────────────────────────────────
   Tela de uma mão só: o endereço engatado é o único texto que precisa ser lido
   de longe, com o leitor na mão e a mercadoria na outra. Daí a mono enorme —
   endereço é código, não prosa, e é o alinhamento que deixa conferir de
   relance. O resto da tela fica quieto de propósito. */
.cl-rotulo { display:block; font-size:var(--fonte-rotulo); letter-spacing:0.09em;
  text-transform:uppercase; color:var(--ink-3); }
.cl-engate__topo { display:flex; align-items:center; justify-content:space-between;
  gap:0.5rem; }
/* A tela NÃO ROLA (decisão do dono, 27/08/2026): altura cheia via
   content--altura-cheia, cartão de trabalho flexível e a câmera ocupando
   exatamente a sobra. Tudo visível o tempo todo; o histórico virou modal. */
.content--altura-cheia > .page.cl { display:flex; flex-direction:column;
  padding-top:0.5rem; padding-bottom:0.5rem; overflow:hidden; }
.page.cl .cl-trabalho { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
/* Sem endereço selecionado o card de trabalho não existe — e o `display:flex`
   acima venceria o [hidden] se não fosse esta linha. */
.page.cl .cl-trabalho[hidden] { display:none; }
.page.cl .cl-trabalho > .card-body { flex:1 1 auto; min-height:0;
  display:flex; flex-direction:column; }
/* Compacto de propósito (27/08/2026): cada rem vertical economizado é vídeo
   maior — a tela não rola, então o espaço é orçamento. */
.page.cl .card-body { padding:0.625rem 0.75rem; }
.page.cl .cl-acoes .btn { padding:0.375rem 0.5rem; font-size:var(--fonte-corpo); }
.page.cl #cl-desfazer { padding:0.5rem 1rem; font-size:var(--fonte-destaque); }
.cl-engate__botoes { display:flex; gap:0.375rem; }
.cl-camera { flex:1 1 auto; min-height:0; display:flex; }
.cl-camera[hidden] { display:none; }
.cl-endereco { margin:0.25rem 0 0; font-family:var(--bs-font-monospace);
  font-weight:500; font-size:var(--fonte-heroi); line-height:40px;
  letter-spacing:0.02em; color:var(--ink-1); }
/* Vazio é INSTRUÇÃO ("Selecione um endereço…"), não valor: sai do monospace
   gigante e vira frase legível. */
.cl-endereco--vazio { font-size:var(--fonte-destaque); font-weight:400; color:var(--ink-4);
  font-family:inherit; }
.cl-endereco-nota { margin:0 0 0.5rem; }
/* Posição ocupada: a nota deixa de ser medida da rua e passa a declarar o que
   está lá — âmbar porque a próxima leitura mexe nisso. A descrição do produto
   é longa; duas linhas bastam para reconhecer a mercadoria. */
.cl-historico:empty::after { content:'Nada lido ainda nesta sessão.';
  font-size:var(--fonte-corpo); color:var(--ink-3); }
.cl-escolha { display:flex; flex-direction:column; gap:0.5rem; }
.cl-escolha__linha { display:flex; flex-wrap:wrap; gap:0.5rem; align-items:flex-end; }
.cl-escolha select { width:auto; min-width:9rem; }
/* Todo campo da linha diz o próprio nome: três controles lado a lado, um sem
   rótulo, faz o operador adivinhar. */
.cl-campo { display:flex; flex-direction:column; }
.cl-campo .cl-rotulo { margin-bottom:0.125rem; }
.cl-campo[hidden] { display:none; }   /* o flex acima venceria o [hidden] */
.cl-rua { min-width:5rem; font-family:var(--bs-font-monospace); font-weight:500; }
/* Alvo de toque: o galpão opera de luva. 2,75rem é o piso, igual ao da grade. */
.cl-escolha select, .cl-escolha .cl-num { min-height:2.75rem; }
/* A ocupação da rua encabeça a grade que ela conta, alinhada à direita. */
.cl-posicoes__topo { display:flex; align-items:baseline;
  justify-content:space-between; gap:0.5rem; }
.cl-rua-conta { font-size:var(--fonte-corpo); color:var(--ink-2); font-variant-numeric:tabular-nums; }
/* A mercadoria do lugar: cada valor com o próprio nome, em coluna, para
   conferir lendo de cima a baixo em vez de decorar a ordem de uma frase. */
.cl-item { display:grid; grid-template-columns:auto 1fr; gap:0.125rem 0.625rem;
  align-items:baseline; margin:0 0 0.5rem; }
.cl-item[hidden] { display:none; }
.cl-item dt { padding-top:0.125rem; }
.cl-item dd { margin:0; font-size:var(--fonte-corpo); color:var(--ink-1); }
.cl-item__dado { font-family:var(--bs-font-monospace); font-weight:500; }
/* A GRADE DE POSIÇÕES: o corredor inteiro à vista, uma célula por posição.
   Mínimo de 2.75rem porque o dedo do galpão usa luva; o resto é a grade se
   acomodando à largura do celular. */
.cl-posicoes { display:grid; gap:0.25rem;
  grid-template-columns:repeat(auto-fill, minmax(2.75rem, 1fr)); }
.cl-posicao { min-height:2.75rem; border-radius:8px; font-weight:500;
  font-size:var(--fonte-corpo); font-family:var(--bs-font-monospace); cursor:pointer;
  border:1px solid #cfd6e0; background:#fff; color:var(--ink-1); }
.cl-posicao:hover { border-color:#1d4fd8; }
.cl-posicao:active { transform:translateY(1px); }
/* Livre, ocupada e em disputa: as três cores saem do envelope, não de conta
   feita aqui. Ocupada em âmbar porque tocar nela é substituir alguém. */
.cl-posicao--livre { background:#f2f7f3; border-color:#bcd8c4; color:#137333; }
.cl-posicao--ocupada { background:#fdf1e4; border-color:#e6c393; color:#8a5a00; }
.cl-posicao--conflito { background:#fde8e8; border-color:#e3a9a6; color:#b3261e; }
/* Onde eu estou: reabrir a grade sem marcar a posição em uso faz o operador
   procurar de novo. O anel não substitui a cor de ocupação — soma a ela. */
.cl-posicao--atual { outline:2px solid #1d4fd8; outline-offset:1px;
  border-color:#1d4fd8; }
.cl .cl-num { width:5.5rem; font-family:var(--bs-font-monospace); }
.cl-codigo { font-family:var(--bs-font-monospace); font-size:var(--fonte-destaque);
  padding:0.5rem 0.75rem; }
/* O FAROL: a voz da tela — o que está acontecendo agora (grande) e a próxima
   ação (embaixo), com cor por estado. Substituiu o eco em 27/08/2026. */
/* A voz mora entre o lote lido e a câmera: a margem é de cima, e o respiro de
   baixo é o `margin-top` da própria câmera. Faixa e botão herdam a MESMA
   margem — dividem o lugar, então o vídeo não muda de tamanho na troca. */
.cl-farol { border-left:4px solid #c5cad3; background:#f6f7f9; border-radius:8px;
  padding:0.5rem 0.75rem; margin:0.5rem 0 0; }
.cl-farol__agora { display:block; margin:0; font-weight:500; font-size:var(--fonte-destaque);
  overflow-wrap:anywhere; }
.cl-farol__proximo { display:block; margin:0.125rem 0 0; font-size:var(--fonte-corpo);
  color:#495057; min-height:1.125rem; }
/* A voz é UMA SÓ, no mesmo lugar (decisão do dono, 27/08/2026): a faixa FALA
   (estado, resultado) e o botão AGE (a operação por extenso) — nunca os dois
   juntos, porque diziam a mesma coisa. Por isso o botão HERDA o desenho da
   faixa: mesma caixa, mesma tipografia, mesmo lugar. É a mesma entidade
   mudando de modo, não um segundo componente. Sem ícone: o texto é a frase. */
.cl-capturar { display:block; width:100%; text-align:left; font:inherit;
  color:inherit; border-width:0 0 0 4px; border-style:solid;
  white-space:normal; cursor:pointer; }
.cl-capturar[hidden] { display:none; }   /* `display:block` acima venceria o [hidden] */
.cl-capturar:disabled { cursor:default; }
.cl-capturar:hover:not(:disabled) { filter:brightness(0.97); }
.cl-capturar:active:not(:disabled) { transform:translateY(1px); }
/* Tom de AÇÃO: é o único estado tocável da voz, e o azul mais firme o separa
   do azul de "estou lendo". */
.cl-farol--acao { border-color:#1d4fd8; background:#dfe8fc; }
.cl-farol--acao .cl-farol__agora { color:#1a3fa8; }
.cl-farol--lendo { border-color:#2563eb; background:#e7eefc; }
/* Gravação em voo: o farol PULSA enquanto a escrita viaja até o servidor —
   sem isso o operador não sabe se o toque pegou e toca de novo. */
.cl-farol--gravando { border-color:#2563eb; background:#e7eefc;
  animation:cl-farol-pulso 0.9s ease-in-out infinite; }
.cl-farol--gravando .cl-farol__agora { color:#1d4fd8; }
@keyframes cl-farol-pulso { 50% { background:#c9d9f8; } }
.cl-farol--achou { border-color:#2563eb; background:#e7eefc; }
.cl-farol--achou .cl-farol__agora { color:#1d4fd8; }
.cl-farol--ok { border-color:#137333; background:#e6f4ea; }
.cl-farol--ok .cl-farol__agora { color:#137333; }
.cl-farol--aviso { border-color:#e08b3c; background:#fdf1e4; }
.cl-farol--aviso .cl-farol__agora { color:#8a5a00; }
.cl-farol--erro { border-color:#b3261e; background:#fde8e8; }
.cl-farol--erro .cl-farol__agora { color:#b3261e; }
/* Ações em grade, não em pilha (pedido do dono, 27/08/2026): duas por linha,
   e o Capturar atravessado — é o botão de polegar, com a mercadoria na mão. */
.cl-acoes { display:grid; grid-template-columns:1fr 1fr; gap:0.375rem; margin:0 0 0.5rem; }
.cl-acoes .btn { white-space:nowrap; }
#cl-desfazer { grid-column:1 / -1; padding:0.625rem 1rem; }
/* Linha 1: obturador | próxima. Linha 2: Capturar atravessado. O DOM mantém o
   Capturar junto do obturador (é o par lógico); a ordem VISUAL é da grade. */
#cl-camera-abrir { order:1; }
#cl-proxima { order:2; }
#cl-desfazer { order:3; }
/* A câmera do Coletor mora NA tela (não em modal), e tudo que se toca fica
   ACIMA do vídeo: no celular, vídeo + teclado ocupam metade da tela e botão
   abaixo some. Ordem: ações → campo (mostrador da etiqueta) → vídeo. */
.cl-camera { margin-top:0.5rem; }
.cl-video { width:100%; height:100%; min-height:0; object-fit:cover;
  border-radius:8px; background:#000; display:block; }
.cl-historico { list-style:none; margin:0; padding:0; display:grid; gap:0.25rem;
  max-height:18rem; overflow:auto; }
.cl-linha { display:flex; align-items:center; gap:0.5rem; font-size:var(--fonte-corpo);
  font-family:var(--bs-font-monospace); }
.cl-linha__marca { width:0.5rem; height:0.5rem; border-radius:50%;
  background:var(--ink-4); flex:0 0 auto; }
.cl-linha--ok .cl-linha__marca { background:var(--bs-success); }
.cl-linha--aviso .cl-linha__marca { background:var(--bs-warning); }
.cl-linha--erro .cl-linha__marca { background:var(--bs-danger); }
.cl-candidato { display:block; width:100%; text-align:left; padding:0.625rem 0.75rem;
  margin-bottom:0.375rem; border:var(--bs-border-width) solid var(--line);
  border-radius:var(--fc-radius); background:var(--surf); }
.cl-candidato:hover, .cl-candidato:focus-visible { border-color:var(--acc);
  background:var(--surf-2); }
.cl-candidato .mg-dica { display:block; }
.mg-origem { font-family:var(--bs-font-monospace); font-size:var(--fonte-pequena); color:var(--ink-3); }


/* --- WMS: Grade e Mesa (conceito 26/08/2026) ------------------------------
   As duas telas novas de endereçar. Escopo `.wms-tela`: nada aqui vaza para as
   outras ~28 páginas, e por isso elas podem ter tipografia e densidade
   próprias — são telas de trabalho de oito horas, não painéis de leitura.

   Três decisões, todas do desenho aprovado em 26/08:
   1. CHAPADO. Nenhuma sombra em repouso; a única sombra do conjunto é o halo
      de foco, porque foco é a informação mais importante de uma tela onde se
      digita coluna abaixo.
   2. ACENTO AZUL (#2563eb, o mesmo --chart-azul do app inteiro) para foco,
      seleção e a ação primária; âmbar (#a24a00) só para inconsistência. O
      roxo da primeira versão morreu em 26/08 ("odiei as cores") — o acento
      voltou para a família de azul que o usuário já conhece do resto do app.
      A cor da FAMÍLIA (pastilhas `.mg-cor-*`) é identidade de mercadoria,
      não estado.
   3. Neue Haas Display, a fonte da marca, escopada a estas telas: o resto do
      app continua na tipografia do FCDS. */
@font-face {
  font-family:'Neue Haas Display';
  src:url("../fonts/NeueHaasDisplayRoman.13568ea57eda.ttf") format('truetype');
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face {
  font-family:'Neue Haas Display';
  src:url("../fonts/NeueHaasDisplayMediu.c00931e8b3cc.ttf") format('truetype');
  font-weight:500; font-style:normal; font-display:swap;
}
@font-face {
  font-family:'Neue Haas Display';
  src:url("../fonts/NeueHaasDisplayBold.822ebe551ca0.ttf") format('truetype');
  font-weight:700; font-style:normal; font-display:swap;
}

.wms-tela {
  --wms-superficie:#fff; --wms-superficie-2:#f6f7f9; --wms-superficie-3:#eef0f4;
  --wms-tinta:#0b0d11; --wms-tinta-2:#464d59; --wms-tinta-fraca:#6b7280;
  --wms-linha:#e1e4e9; --wms-linha-forte:#c5cad3;
  --wms-vivo:#2563eb; --wms-vivo-tinta:#fff;
  --wms-marca:#2563eb; --wms-marca-fraca:#e7eefc;
  --wms-alerta:#a24a00; --wms-alerta-borda:#e08b3c; --wms-alerta-fraca:#fdf1e4;
  font-family:'Neue Haas Display', 'Helvetica Neue', Arial, sans-serif;
  font-size:var(--fonte-corpo); line-height:1.5; letter-spacing:-0.01em;
  font-variant-numeric:tabular-nums;
  color:var(--wms-tinta);
  display:flex; flex-direction:column; gap:0.875rem;
}
.wms-tela [hidden] { display:none !important; }
.wms-tela button { cursor:pointer; }
.wms-tela button[disabled]:not(.btn) { cursor:not-allowed; opacity:0.35; }
.wms-tela :focus-visible:not(.btn, .form-control, .form-select) { outline:2px solid var(--wms-marca); outline-offset:1px; }
.wms-tela kbd { font:inherit; font-size:var(--fonte-pequena); font-weight:500;
  color:inherit; background:none; border:1px solid currentColor; border-radius:3px;
  padding:0 0.375rem; opacity:0.7; }

.wms-tela .wms-rotulo { font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:0.11em;
  text-transform:uppercase; color:var(--wms-tinta-fraca); }
.wms-tela .wms-espaco { flex:1; }
.wms-tela .wms-direita { text-align:right; }

.wms-tela .wms-cabeca { display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap; }
.wms-tela .wms-atalho { font-size:var(--fonte-corpo); font-weight:500; }
.wms-tela .wms-fila-conta { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); }

.wms-tela .wms-campo--busca { min-width:13rem; }
.wms-tela .wms-campo--curto { width:5rem; }

/* Contagens: o estado do galpão em números, tudo vindo do `resumo` do
   envelope. Cada uma carrega `data-auditoria`, então o `?` da tela abre o
   verbete no ponto de uso. */
.wms-tela .wms-contagens { display:flex; flex-wrap:wrap; gap:1.625rem; margin:0; }
.wms-tela .wms-conta dt { margin-bottom:1px; font-size:var(--fonte-rotulo); font-weight:500;
  letter-spacing:0.11em; text-transform:uppercase; color:var(--wms-tinta-fraca); }
.wms-tela .wms-conta dd { margin:0; font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-0.03em; }
.wms-tela .wms-conta--alerta dd { color:var(--wms-alerta); }

.wms-tela .wms-alerta { display:flex; align-items:center; gap:0.875rem; flex-wrap:wrap;
  background:var(--wms-alerta-fraca); border:1px solid var(--wms-alerta-borda);
  border-radius:8px; padding:0.75rem 1rem; }
.wms-tela .wms-alerta__titulo { font-weight:500; color:var(--wms-alerta); }
.wms-tela .wms-alerta__corpo { font-size:var(--fonte-corpo); color:var(--wms-tinta-2); flex:1; min-width:15rem; }

.wms-tela .wms-painel { background:var(--wms-superficie); border:1px solid var(--wms-linha);
  border-radius:10px; }

/* --- Grade: a planilha ---------------------------------------------------- */
.wms-tela .wms-ferramentas { display:flex; align-items:center; gap:0.625rem; flex-wrap:wrap;
  padding:0.8125rem 1rem; border-bottom:1px solid var(--wms-linha); }
.wms-tela .wms-pilulas { display:flex; gap:0.3125rem; flex-wrap:wrap; }
.wms-tela .wms-ajuda { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); }

/* A Grade cabe na viewport via `content--altura-cheia` (declarado no template):
   o painel vira coluna flex e a rolagem é quem cresce — nada de calc de altura,
   que deixava sobra no pé da página. */
.wms-grade .wms-painel { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.wms-tela .wms-rolagem { overflow:auto; flex:1 1 auto; min-height:0; }
/* `content--altura-cheia` zera o padding vertical do shell; o respiro do topo
   volta aqui, do tamanho do gap interno da tela. */
.content--altura-cheia > .page.wms-grade,
.content--altura-cheia > .page.wms-mesa { padding-top:0.875rem; }
/* Mesa na viewport: a bancada é quem cresce; rodapé e teclado ficam do tamanho
   que são. `overflow:auto` é a guarda de janela baixa — a Mesa não tem scroller
   interno como a rolagem da Grade, e sem ele o botão Colocar sumiria num
   notebook pequeno. */
.content--altura-cheia > .page.wms-mesa { padding-bottom:0.875rem; overflow:auto; }
.wms-mesa .wms-bancada { flex:1 1 auto; min-height:0; }
.wms-tela .wms-tabela { border-collapse:collapse; width:100%; min-width:54rem; }
/* A folga da tabela mora DEPOIS da última coluna: sem isto o navegador
   distribui a sobra entre as colunas largas e abre um vão entre Produto e
   Quantidade. */
.wms-grade .wms-tabela th:last-child { width:100%; }
.wms-tela .wms-tabela thead th { position:sticky; top:0; z-index:2;
  background:var(--wms-superficie); text-align:left; font-size:var(--fonte-rotulo);
  font-weight:500; letter-spacing:0.09em; text-transform:uppercase;
  color:var(--wms-tinta-fraca); padding:0.5625rem 0.75rem;
  border-bottom:1px solid var(--wms-linha-forte); white-space:nowrap; }
.wms-tela .wms-tabela thead th.wms-direita { text-align:right; }
.wms-tela .wms-tabela tbody td { padding:0 0.75rem; border-bottom:1px solid var(--wms-linha);
  height:2.375rem; white-space:nowrap; }
.wms-tela .wms-tabela tbody tr:hover td { background:var(--wms-superficie-2); }
.wms-tela .wms-tabela tbody tr.wms-linha--alerta td { background:var(--wms-alerta-fraca); }
.wms-tela .wms-tabela tbody tr.wms-linha--nova td { animation:wms-acende 1.1s ease-out; }
@keyframes wms-acende { from { background:var(--wms-marca-fraca); } to { background:transparent; } }
.wms-tela .wms-tabela td.wms-lote { font-weight:500; letter-spacing:-0.02em; }
.wms-tela .wms-tabela td.wms-leve { color:var(--wms-tinta-fraca); font-size:var(--fonte-corpo); }
.wms-tela .wms-tabela td.wms-situacao { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); }
.wms-tela .wms-tabela tr.wms-linha--alerta td.wms-situacao { color:var(--wms-alerta); font-weight:500; }
/* Última conferência do lugar. "Nunca" não é um valor entre outros: é o estado
   que a recontagem existe para eliminar, e por isso é o único destacado. */
.wms-tela .wms-tabela td.wms-conferencia { font-size:var(--fonte-corpo);
  color:var(--wms-tinta-fraca); white-space:nowrap; font-variant-numeric:tabular-nums; }
.wms-tela .wms-tabela td.wms-conferencia--nunca { color:var(--wms-alerta); font-weight:500; }
/* O estado de conferência do CORREDOR — só aparece com um corredor em foco. */
.wms-conferencia-rua { margin:0 0 0.5rem; font-size:var(--fonte-corpo);
  color:var(--wms-tinta-fraca); }
.wms-conferencia-rua--alerta, .wms-conta-conferencia--alerta { color:var(--wms-alerta); font-weight:500; }
.wms-tela .wms-pastilha { display:inline-block; width:9px; height:9px; border-radius:2px;
  margin-right:9px; vertical-align:-1px;
  background:var(--mg-cor, var(--mg-cor-cinza)); }

/* A célula editável é invisível até o mouse ou o foco chegarem: uma tabela com
   300 caixas desenhadas é uma tabela que ninguém lê. */
.wms-tela .wms-tabela td.wms-edita { padding:1px 6px; }
.wms-tela .wms-tabela td.wms-edita--rua { width:5.375rem; }
.wms-tela .wms-tabela td.wms-edita--posicao { width:6rem; }
.wms-tela .wms-tabela td.wms-edita--nivel { width:4.75rem; }
/* Produto é código + descrição numa célula só (pedido do dono, 26/08): o
   código identifica, a descrição confirma — separados eram duas colunas
   dizendo meia coisa cada. */
.wms-tela .wms-produto {
  max-width:26rem; }
.wms-tela .wms-produto__descricao { color:var(--wms-tinta-fraca); margin-left:0.5rem; }
/* A linha de filtros mora no thead para rolar junto com os títulos. */
.wms-tela .wms-filtros-colunas td { padding:8px 6px; border-bottom:1px solid var(--wms-linha-forte); }
.wms-tela .wms-celula--erro { border-color:var(--wms-alerta); background:var(--wms-alerta-fraca); }

.wms-tela .wms-nada { padding:2.125rem 1rem; text-align:center; color:var(--wms-tinta-fraca); margin:0; }
.wms-tela .wms-recado { padding:0.625rem 1rem; border-top:1px solid var(--wms-linha);
  font-size:var(--fonte-corpo); color:var(--wms-tinta-2); min-height:2.5rem; margin:0; }
.wms-tela .wms-recado--erro { color:var(--wms-alerta); font-weight:500; }

/* --- Mesa: um lote de cada vez -------------------------------------------- */
.wms-tela .wms-bancada { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
.wms-tela .wms-lado { padding:1.375rem 1.5rem 1.5rem; display:grid; gap:0.875rem; align-content:start; }
.wms-tela .wms-lado + .wms-lado { border-left:1px solid var(--wms-linha); }
.wms-tela .wms-grupo { display:grid; gap:0.375rem; }
.wms-tela .wms-dica { font-size:var(--fonte-corpo); color:var(--wms-tinta-2); min-height:1.0625rem; margin:0; }
.wms-tela .wms-dica--erro { color:var(--wms-alerta); }

.wms-tela .wms-familia { display:flex; align-items:center; gap:0.5rem; font-size:var(--fonte-corpo);
  color:var(--wms-tinta-2); }
.wms-tela .wms-lote-grande { font-size:var(--fonte-heroi); font-weight:500;
  letter-spacing:-0.045em; line-height:40px; word-break:break-word; }
.wms-tela .wms-desc { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); margin:0; }
.wms-tela .wms-quantidade { font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-0.03em; }
.wms-tela .wms-tag { justify-self:start; font-size:var(--fonte-corpo); color:var(--wms-alerta);
  background:var(--wms-alerta-fraca); border:1px solid var(--wms-alerta-borda);
  border-radius:4px; padding:0.1875rem 0.5625rem; }
.wms-tela .wms-vazio-mao { font-size:var(--fonte-destaque); color:var(--wms-tinta-fraca); padding:1.75rem 0; margin:0; }

/* O endereço é o que se lê de longe, com a mercadoria na mão — é ele, e não o
   botão, o centro da metade direita. */
.wms-tela .wms-endereco { font-size:var(--fonte-heroi); font-weight:500;
  letter-spacing:-0.06em; line-height:40px; }
.wms-tela .wms-porque { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); margin:0.25rem 0 0; }
.wms-tela .wms-porque--ocupado { color:var(--wms-alerta); }

/* A régua é o corredor visto de cima: barra cheia é lugar ocupado, barra alta e
   roxa é onde este lote vai. Clicar numa barra escolhe o lugar. */
.wms-tela .wms-regua { display:grid; gap:0.5625rem; }
.wms-tela .wms-regua__cabeca { display:flex; justify-content:space-between; align-items:baseline;
  gap:0.625rem; }
.wms-tela .wms-lugares { display:flex; gap:3px; align-items:flex-end; }
.wms-tela .wms-lugar { flex:1; height:1.625rem; border-radius:2px; background:var(--wms-superficie-2);
  border:1px solid var(--wms-linha); position:relative; padding:0; }
/* Ocupado é fato, não alarme: cinza médio, não a tarja quase-preta da 1ª versão. */
.wms-tela .wms-lugar--cheio { background:var(--wms-linha-forte); border-color:var(--wms-linha-forte); }
.wms-tela .wms-lugar--aqui { background:var(--wms-marca); border-color:var(--wms-marca); height:2.125rem; }
.wms-tela .wms-lugar b { position:absolute; top:-1rem; left:50%; transform:translateX(-50%);
  font-size:var(--fonte-pequena); color:var(--wms-marca); }

.wms-tela .wms-gesto { display:flex; gap:0.5rem; align-items:center; flex-wrap:wrap; }
.wms-tela .wms-gesto .wms-grupo { flex:1; min-width:8rem; }
.wms-tela .wms-gesto .wms-grupo--nivel { flex:0 0 auto; min-width:0; }

.wms-tela .wms-rodape { display:grid; grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:0.875rem; }
.wms-tela .wms-bloco { padding:1rem 1.125rem; display:grid; gap:0.625rem; align-content:start; }
.wms-tela .wms-entrou { display:flex; align-items:baseline; justify-content:space-between;
  gap:0.75rem; font-size:var(--fonte-corpo); width:100%; text-align:left; }
.wms-tela .wms-entrou .wms-onde { font-weight:500; }
.wms-tela .wms-desfazer { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca);
  text-decoration:underline; background:none; border:0; padding:0; }
.wms-tela .wms-vaga { background:none; border:0; padding:0.125rem 0; color:inherit; }
.wms-tela .wms-vaga:hover { color:var(--wms-marca); }
.wms-tela .wms-nada-bloco { font-size:var(--fonte-corpo); color:var(--wms-tinta-fraca); margin:0; }
.wms-tela .wms-teclado { display:flex; gap:1rem; flex-wrap:wrap; font-size:var(--fonte-pequena);
  color:var(--wms-tinta-fraca); margin:0; padding:0 2px; }
.wms-tela .wms-teclado kbd { border:1px solid var(--wms-linha-forte); border-bottom-width:2px;
  background:var(--wms-superficie); opacity:1; }

@media (max-width:820px) {
  .wms-tela .wms-bancada { grid-template-columns:1fr; }
  .wms-tela .wms-lado + .wms-lado { border-left:0; border-top:1px solid var(--wms-linha); }
  .wms-tela .wms-rodape { grid-template-columns:1fr; }
}
@media (prefers-reduced-motion:reduce) {
  .wms-tela *, .wms-tela *::before, .wms-tela *::after {
    animation:none !important; transition:none !important; }
}

/* --- Insights: gaveta lateral ---------------------------------------------
   Cartão em vez de tabela porque cada achado é um argumento — a frase, a forma
   da série e a evidência viajam juntas. A cor da borda vem de `direcao`, que o
   backend decide; o CSS não sabe o que é melhora.

   Gaveta (offcanvas do Bootstrap) e não visão: o insight se lê AO LADO do
   demonstrativo, conferindo a linha enquanto o card a explica. Como o `<aside>`
   mora dentro do `.page.dre`, os tokens `--dre-*` chegam nele por herança, ainda
   que o offcanvas seja `position:fixed`. */
.page.dre #dre-insights {
  --bs-offcanvas-width: min(600px, 96vw);
  background: var(--dre-papel-fundo); color: var(--dre-tinta);
  border-left: 1px solid var(--dre-regua-forte);
}
/* Split de verdade: a página cede a largura da gaveta em vez de ficar por baixo
   dela. Sem isto o card manda olhar a linha da tabela que o painel está cobrindo.

   Era `margin-right` porque o shell travava `.page { padding: ... !important }`
   e vencer isso exigiria outro `!important` numa regra de página. A trava morreu
   em 18/08/2026 (`2484ae68`), então voltou a ser `padding-right`: o recuo é do
   conteúdo, não uma margem que muda a caixa da página. */
@media (min-width: 1200px) {
  .page.dre { transition: padding-right 0.3s ease-in-out; }
  .page.dre.dre-com-gaveta { padding-right: min(600px, 96vw); }
}
/* O pisca é o único jeito de o clique na gaveta se explicar: a tabela do outro
   lado muda, e sem a marca o olho não acha onde. */
.page.dre tr.dre-focada > td { animation: dre-piscar 1.6s ease-out; }
@keyframes dre-piscar { 0%, 30% { background: var(--dre-realce); } 100% { background: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .page.dre { transition: none; }
  .page.dre tr.dre-focada > td { animation: none; background: var(--dre-realce); }
}
/* O texto de apoio da gaveta usa tinta MÉDIA, não fraca: `--dre-tinta-fraca` foi
   calibrada contra o papel branco (4,52:1) e cai para 4,09:1 sobre o fundo
   tingido do painel — reprova o AA. Escopo local; o token não muda para o app.
   O `:not(.dre-direcao)` existe porque este seletor tem id e venceria a cor da
   direção, que é semântica (vermelho = dinheiro saindo) e não pode virar cinza. */
.page.dre #dre-insights .dre-dica,
.page.dre #dre-insights .dre-rotulo,
.page.dre #dre-insights .dre-etiqueta:not(.dre-direcao) { color: var(--dre-tinta-media); }
/* Título + recorte empilhados: o header do Bootstrap centraliza por padrão. */
.page.dre #dre-insights .offcanvas-header { align-items: flex-start; }
.page.dre #dre-insights .offcanvas-title { font-size: var(--fonte-destaque); font-weight: 500; margin: 0; }
.page.dre .dre-grupo-insight + .dre-grupo-insight { margin-top: 22px; }
.page.dre .dre-grupo-insight .dre-rotulo { display: block; margin-bottom: 3px; }

.page.dre .dre-cartoes { display: grid; gap: 12px; margin-top: 10px; }
.page.dre .dre-cartao {
  background: var(--dre-papel); border: 1px solid var(--dre-regua);
  border-radius: 6px; padding: 12px 16px;
}
/* A direção mora na ETIQUETA, com palavra e seta — não numa faixa colorida na
   borda. Faixa lateral era o único canal de "piorou" para quem não distingue
   vermelho de verde, e o eixo do MAD nem escreve a palavra na frase. */
.page.dre .dre-direcao { font-weight: 500; }
.page.dre .dre-direcao.melhora { color: var(--dre-verde); border-color: var(--dre-verde); }
.page.dre .dre-direcao.piora { color: var(--dre-oxido); border-color: var(--dre-oxido); }
.page.dre .dre-etiquetas { display: flex; gap: 5px; flex: none; }
.page.dre .dre-cartao > header {
  display: flex; align-items: baseline; gap: 10px; justify-content: space-between;
}
.page.dre .dre-cartao-titulo { font-size: var(--fonte-corpo); font-weight: 500; color: var(--dre-tinta); }
/* min-height 24px: WCAG 2.2 AA (2.5.8) é o piso do alvo, e o título sozinho
   media 23. Um pixel a menos ainda reprova. */
.page.dre button.dre-cartao-titulo {
  font-family: inherit; background: none; border: 0 solid transparent; border-bottom-width: 1px;
  padding: 0; text-align: left; cursor: pointer; min-height: 24px;
}
.page.dre button.dre-cartao-titulo:hover { color: var(--dre-acento); border-color: var(--dre-acento); }
.page.dre .dre-cartao-conta {
  font-size: var(--fonte-pequena); color: var(--dre-tinta-fraca); font-variant-numeric: tabular-nums;
}
/* Reusa .dre-botao-texto da barra de instrumentos — mesmo gesto, mesmo vestido. */
.page.dre .dre-ver-fornecedores { margin-top: 10px; min-height: 24px; }
.page.dre .dre-cartao-texto {
  margin: 6px 0 0; font-size: var(--fonte-corpo); color: var(--dre-tinta-media);
  font-variant-numeric: tabular-nums;
}
.page.dre .dre-cartao > footer { display: flex; gap: 14px; margin-top: 6px; flex-wrap: wrap; }
.page.dre .dre-cartao .dre-nota { font-size: var(--fonte-pequena); color: var(--dre-tinta-fraca); }
.page.dre .dre-etiqueta {
  font-size: 11px; color: var(--dre-tinta-fraca); background: var(--dre-papel-fundo);
  border: 1px solid var(--dre-regua); border-radius: var(--raio-chip); padding: 1px 8px;
  white-space: nowrap; flex: none;
}
/* Faixa da série: escala visual do que o backend já ordenou e já marcou. */
.page.dre .dre-faixa {
  display: flex; align-items: flex-end; gap: 3px; height: 34px; margin-top: 10px;
}
.page.dre .dre-faixa i { flex: 1; background: var(--dre-regua-forte); border-radius: 2px 2px 0 0; }
.page.dre .dre-faixa i.dre-pico { background: var(--dre-oxido); }
.page.dre .dre-cartao-contexto {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--dre-regua);
}
.page.dre .dre-cartao-contexto .dre-quadro-linhas th,
.page.dre .dre-cartao-contexto .dre-quadro-linhas td { padding: 5px 10px; font-size: var(--fonte-corpo); }
/* Distorção: quem o backend marcou com `motivo` ganha fundo de realce e a frase logo
   abaixo, na mesma faixa — a acusação viaja colada na evidência. */
.page.dre .dre-contexto tr.dre-destacada > td { background: var(--dre-realce); border-bottom: none; }
.page.dre .dre-contexto tr.dre-motivo > td {
  background: var(--dre-realce); color: var(--warning-text); font-weight: 500; font-size: var(--fonte-pequena);
  padding-top: 0; border-top: none; line-height: 1.5;
}
.page.dre .dre-nota-tabela {
  margin: 8px 0 0; font-size: var(--fonte-pequena); color: var(--dre-tinta-fraca);
}

/* certificados-lote */
/* Widget compartilhado (chip, lista, anexador) — bi/static/bi/js/certificados-lote.js.
   Hairline, sem sombra, sem cor decorativa; tokens do design system global. */
.cl-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surf); border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 8px; font-size: var(--fonte-corpo); color: var(--ink); cursor: pointer;
}
.cl-chip:hover { border-color: var(--line-3); }
@media (pointer: coarse) {
  .cl-chip { min-height: 44px; padding: 0 12px; }
}

.cl-drop {
  border: 1px dashed var(--line-3); border-radius: 8px;
  padding: 16px; text-align: center; color: var(--ink-2); font-size: var(--fonte-corpo);
}
.cl-drop.is-over { background: var(--surf-2); }

.cl-lista {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr auto auto; gap: 4px 10px;
}
.cl-doc {
  display: contents;
}
.cl-doc__nome { color: var(--ink); font-size: var(--fonte-corpo); grid-column: 1; }
.cl-doc__meta { color: var(--ink-2); font-size: var(--fonte-corpo); }
.cl-doc__confirma { color: var(--ink-2); font-size: var(--fonte-corpo); }

.cl-relatorio__resumo { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); }
.cl-progresso { font-size: var(--fonte-corpo); color: var(--ink-2); }
.cl-vazio { font-size: var(--fonte-corpo); color: var(--ink-2); }

/* Linha de detalhe do lote — Estoques (row().child() do DataTables) e
   Separação (<tr> inserido à mão): mesma classe, mesmo tratamento. */
.cl-linha-detalhe > td { background: var(--surf-2); }

/* Rodapé fixo do modal "Saldo por lote" (Estoques) — aviso sobre o alcance
   dos certificados e o atalho para o pedido já faturado. */
.cl-rodape {
  margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--line);
  font-size: var(--fonte-corpo); color: var(--ink-2);
}

/* bancada — casca das telas-ferramenta (Gerar NF Sênior · Criar lotes) */
/* Uma tela-ferramenta é usada 8 h por dia ao lado do ERP: a ação que escreve
   nunca pode sumir. Aqui a página não rola — a grade ocupa a altura disponível,
   cada região rola sozinha e a régua fecha a página por baixo. Medido em
   18/08/2026: com a ação no fluxo do conteúdo ela caía para y=936 em 1600×900 e
   exigia 430 px de rolagem em 1280×720. Template: bi/templates/bi/components/
   _bancada.html. Variáveis próprias (`--bnc-*`), nenhum token global tocado. */
.page.bnc {
  /* Colunas laterais cedem em tela pequena e param de crescer em tela grande: em
     1280 a lista fixa de 320 px mais a prancheta comiam 736 px e sobravam 544
     para o trabalho, que é onde o operador digita. O trabalho fica com o resto
     (`minmax(0,1fr)`), sempre. */
  --bnc-lista: clamp(15rem, 20vw, 20rem);        /* 240 … 320 px */
  --bnc-prancheta: clamp(20rem, 28vw, 26rem);    /* 320 … 416 px */
}

/* Três tamanhos, não seis — os da escala da casa (#476): Pequeno, Corpo e Destaque. */
.page.bnc :is(small, .small, .lab, .n, .iof-sub, .iof-f__k, .iof-note, .bnc__frase) {
  font-size: var(--fonte-pequena);
}
.page.bnc :is(h1, h2, h3) { font-size: var(--fonte-destaque); }
/* `code` traz 0.875em do Bootstrap e reintroduzia um quarto tamanho dentro da
   prancheta; aqui ele é só a fonte monoespaçada, no tamanho do texto ao redor. */
.page.bnc code { font-size: 1em; }
/* Bootstrap traz 14 px em selo, cabeçalho de tabela e rótulo de campo — é o quarto
   tamanho que ninguém pediu; botão e campo ficam no -sm de fábrica (#454). */
.page.bnc :is(.table, .iof-f__v, .iof-doc__t, .iof-lote, .iof-result) {
  font-size: var(--fonte-corpo);
}
.page.bnc :is(th, .iof-deprow, .iof-doc__sub, .iof-items th) {
  font-size: var(--fonte-pequena);
}
/* O valor informado da nota: era `.fs-5` (20 px com `!important` do Bootstrap). */
.iof-valor { font-size: var(--fonte-destaque); font-weight: 500;
  font-variant-numeric: tabular-nums; }

/* O que é clicável tem de parecer, e o teclado tem de ver onde está (TR-2). */
.bnc__lista .list-group-item { transition: background-color .16s ease-out; }
.bnc__lista .list-group-item:hover:not(:disabled) { background: var(--surf-3); }
.page.bnc .list-group-item:focus-visible {
  outline: 2px solid var(--acc-line); outline-offset: 2px; box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .page.bnc *, .page.bnc *::before, .page.bnc *::after { transition-duration: 0ms !important; }
}
.content--altura-cheia > .page.bnc {
  display: grid;
  grid-template-columns: var(--bnc-lista) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0; min-height: 0; overflow: hidden;
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r);
}
/* Prancheta aberta = terceira coluna. `:has` porque quem manda é o `hidden` do
   próprio elemento — sem classe de estado no pai para o JS esquecer de tirar. */
.content--altura-cheia > .page.bnc:has(> .bnc__prancheta:not([hidden])) {
  grid-template-columns: var(--bnc-lista) minmax(0, 1fr) var(--bnc-prancheta);
}

.bnc__lista {
  display: flex; flex-direction: column; min-height: 0;
  border-right: 1px solid var(--line); background: var(--surf-2);
}
.bnc__busca {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem; border-bottom: 1px solid var(--line);
}
.bnc__busca .n { color: var(--ink-2); font-size: var(--fonte-pequena); white-space: nowrap; }
.bnc__rolagem { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

.bnc__trabalho { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
.bnc__vazio { padding: 3rem 1rem; text-align: center; color: var(--ink-2); }

.bnc__prancheta {
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  border-left: 1px solid var(--line); background: var(--surf-2);
}
.bnc__prancheta[hidden] { display: none; }
.bnc__prancheta-cab {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 0.75rem 1rem; border-bottom: 1px solid var(--line);
}
.bnc__prancheta-cab h2 { margin: 0; font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); }
.bnc__prancheta-cab .n { color: var(--ink-2); font-size: var(--fonte-pequena); }
.bnc__prancheta-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 1rem; }

/* Régua: a linha que fecha a página. Uma frase (do backend) e a ação primária. */
.bnc__regua {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding: 0.625rem 1rem;
  border-top: 1px solid var(--line); background: var(--surf);
}
.bnc__frase { flex: 1 1 12rem; margin: 0; font-size: var(--fonte-corpo); color: var(--ink-2); }
.bnc__frase b { color: var(--ink); font-variant-numeric: tabular-nums; }

@media (max-width: 991.98px) {
  .content--altura-cheia > .page.bnc,
  .content--altura-cheia > .page.bnc:has(> .bnc__prancheta:not([hidden])) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }
  .bnc__lista { max-height: 14rem; border-right: 0; border-bottom: 1px solid var(--line); }
  .bnc__prancheta { border-left: 0; border-top: 1px solid var(--line); }
}

/* bancada · importar certificado */
/* A tela entrou na bancada em 18/08/2026: histórico à esquerda, envio e bloco
   extraído no trabalho, avisos do parse na prancheta. Estas regras viviam num
   `<style>` dentro do template (regra dura: CSS autoral só aqui). */
.cert-envio { display: flex; flex-direction: column; gap: 0.5rem; padding: 1rem;
  border-bottom: 1px solid var(--line); }
.cert-envio .lab, .cert-resultado .lab { margin: 0; color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .04em; }

.cert-drop { display: flex; align-items: center; gap: 1rem; width: 100%;
  border: 1.5px dashed var(--line-3); border-radius: var(--r-sm); background: var(--surf-2);
  padding: 1.1rem 1.25rem; cursor: pointer; text-align: left;
  transition: border-color .16s ease-out, background-color .16s ease-out; }
.cert-drop:hover { border-color: var(--acc-line); background: var(--surf-3); }
.cert-drop--drag { border-color: var(--brand); background: var(--brand-soft); }
/* O input de arquivo é 1 px e invisível — mas continua sendo o que recebe o
   Tab. Sem isto o foco de teclado pousava num ponto que ninguém vê (IC-5). */
.cert-drop:focus-within { outline: 2px solid var(--acc-line); outline-offset: 2px; }
.cert-drop__input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.cert-drop__icon { font-size: var(--fonte-heroi); color: var(--ink-3); flex: none; }
.cert-drop__txt { display: flex; flex-direction: column; gap: .1rem; }
.cert-drop__hint { color: var(--ink); }
.cert-drop__sub { color: var(--ink-3); font-size: var(--fonte-pequena); }

.cert-foot { display: flex; align-items: center; gap: .75rem; }
.cert-chip { display: inline-flex; align-items: center; gap: .5rem;
  padding: .35rem .6rem; background: var(--surf-2); border: 1px solid var(--line);
  border-radius: var(--r-xs); color: var(--ink-2); max-width: 60%; }
.cert-chip__x { border: 0; background: transparent; color: var(--ink-3);
  font-size: var(--fonte-destaque); line-height: 1; cursor: pointer; padding: 0 .1rem; }
.cert-erro { color: var(--negative-text); margin: 0; }
.cert-loading { display: flex; align-items: center; gap: .6rem; color: var(--ink-2); padding: 1.4rem; }

.cert-resultado { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; min-height: 0; }
.cert-resultado #cert-tabela { font-size: var(--fonte-pequena); }
/* Os cartões de resumo vinham com `.fs-4`/`.fs-5` do Bootstrap (24 e 20 px) —
   o quarto e o quinto tamanho da tela. O maior número da bancada é o título. */
.cert-resultado #cert-kpis :is(.fs-4, .fs-5) { font-size: var(--fonte-destaque) !important; }
.cert-resultado #cert-kpis .card-body { padding: 0.625rem 0.75rem; }
.cert-resultado #cert-tabela tbody td { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Linha do histórico: abre o import. Era uma `<tr>` de DataTables com
   `cursor: auto` — clicável e sem parecer (IC-4). */
.cert-hist__arquivo { font-weight: 500; }
.cert-hist__sub { color: var(--ink-2); font-size: var(--fonte-pequena); }
.cert-aviso { padding: .5rem .75rem; border-radius: var(--r-sm);
  background: var(--warning-subtle); color: var(--warning-text); margin: 0 0 .5rem; }

@media (max-width: 640px) {
  .cert-drop { flex-direction: column; text-align: center; align-items: center; }
  .cert-chip { max-width: 100%; }
}

/* criar lotes (URL /romaneio/) */
/* A tela entrou na bancada em 18/08/2026: colunas, rolagem, régua e prancheta
   são `.bnc*` — daqui para baixo é só o conteúdo do lançamento. As regras de
   grade, lista e painel lateral que moravam aqui morreram junto com o
   offcanvas. Tokens do design system global. */

.rom__ok { color: var(--positive-text); font-weight: 500; }

.rom__corpo { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; padding: 1rem; gap: 0.75rem; }
.rom__cabecalho { display: flex; align-items: center; gap: 0.75rem; }
.rom__cab { font-weight: 500; color: var(--ink); }
.rom__item { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.rom__item .lab { color: var(--ink-2); font-size: var(--fonte-pequena); margin: 0; }
.rom__item select { width: auto; min-width: 18rem; max-width: 100%; }

/* Alvo do item: os três números que a conferência tem de fechar. Era um `dl`
   com `margin-left:auto` dentro da linha do item; sem espaço sobrando, ele
   colapsava para `width: 0` na borda direita e os três números sumiam da tela
   (CL-1, medido em 18/08/2026). Agora é linha própria, com largura garantida. */
.rom__alvo { display: flex; flex-wrap: wrap; gap: 1.5rem; margin: 0;
  padding: 0.625rem 0.75rem; border-radius: var(--r-sm); background: var(--surf-2); }
.rom__alvo:empty { display: none; }
.rom__alvo > div { min-width: 7rem; }
.rom__alvo dt { color: var(--ink-2); font-size: var(--fonte-pequena); font-weight: 400; }
.rom__alvo dd { margin: 0; font-variant-numeric: tabular-nums; color: var(--ink);
  font-size: var(--fonte-destaque); }

/* "Preencher com os certificados" (Tarefa 11b, fix round 1, #143): botão ao
   lado do campo do romaneio, ou a confirmação inline no lugar dele — mesmo
   layout em linha do `.rom__painel-rodape`, sem herdar o `position: sticky`
   (este contêiner não vive dentro da prancheta). */
.rom__preencher-certificados { display: flex; align-items: center; gap: 0.5rem; }
.rom__preencher-certificados[hidden] { display: none; }   /* o flex acima venceria o [hidden] */

/* Upload do certificado quando o Conexos não tem nenhum (Tarefa 12, #143):
   mesmo padrão em linha de `.rom__preencher-certificados`, ao lado do campo
   do romaneio — nunca dentro da prancheta. */
.rom__certificado-upload { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  padding: 0.625rem 0.75rem; border-radius: var(--r-sm); background: var(--surf-2); }
.rom__certificado-upload[hidden] { display: none; }   /* o flex acima venceria o [hidden] */
.rom__certificado-upload .rom-cert-upload__texto { flex: 1 1 100%; margin: 0; color: var(--ink-2); font-size: var(--fonte-corpo); }
.rom__certificado-upload input[type="file"] { flex: 1 1 auto; min-width: 12rem; }
.rom-cert-upload__estado { color: var(--ink-2); font-size: 13px; }

/* Packing list (#343): mesmo bloco em linha do envio de certificado, ao lado do
   campo do romaneio; o resumo ocupa a linha inteira acima do envio. O aviso de
   layout desconhecido e as divergências usam o texto de atenção da casa. */
.rom__packing-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  padding: 0.625rem 0.75rem; border-radius: var(--r-sm); background: var(--surf-2); }
.rom__packing-list[hidden] { display: none; }   /* o flex acima venceria o [hidden] */
.rom__packing-list .rom-pl__resumo { flex: 1 1 100%; }
.rom__packing-list input[type="file"] { flex: 1 1 auto; min-width: 12rem; }
.rom-pl__texto { margin: 0; color: var(--ink); font-size: 13px; }
.rom-pl__aviso, .rom-pl__divergencias { margin: 0.25rem 0 0; color: var(--warning-text); font-weight: 600; font-size: 13px; }
.rom-pl__divergencias { padding-left: 1.1rem; }
.rom-pl--conferencia { margin-bottom: 0.5rem; }
.rom-regua__motivo { margin: 0; color: var(--warning-text); font-weight: 600; font-size: 13px; }

.rom__textarea { flex: 1 1 auto; min-height: 12rem; font-family: var(--mono); }
.rom__linhas { color: var(--ink-2); font-size: var(--fonte-pequena); }
.rom__lancado {
  padding: 0.5rem 0.75rem; border-radius: var(--r-sm);
  background: var(--positive-subtle); color: var(--positive-text); font-size: var(--fonte-corpo);
}

/* Topo fixo da prancheta: a soma vs. alvo não rola com as 74 linhas. */
.rom__painel-topo { padding: 0 1rem; border-bottom: 1px solid var(--line); }
.rom__painel-topo:empty { display: none; }
.rom__painel-topo .rom-result { margin-bottom: 0.75rem; }
#rom-painel-titulo:focus-visible { outline: 2px solid var(--acc-line); outline-offset: 2px; }
.rom__painel-rodape {
  position: sticky; bottom: 0; display: flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem 1rem; border-top: 1px solid var(--line); background: var(--surf);
}
.rom__painel-rodape:empty { display: none; }
.rom-confirma__texto { flex: 1 1 auto; color: var(--ink); font-size: 13px; }

/* Situação da conferência: texto colorido com glifo, nunca cor sozinha. */
.rom-result { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem; border-radius: var(--r-sm); font-size: 13px; }
.rom-result__ic { flex: none; font-weight: 700; }
.rom-result--ok { background: var(--positive-subtle); }
.rom-result--ok, .rom-result--ok b { color: var(--positive-text); }
.rom-result--warn { background: var(--warning-subtle); }
.rom-result--warn, .rom-result--warn b { color: var(--warning-text); }
.rom-result--err { background: var(--negative-subtle); }
.rom-result--err, .rom-result--err b { color: var(--negative-text); }
.rom-muted { color: var(--ink-2); }
.rom-items { font-size: 13px; font-variant-numeric: tabular-nums; }
.rom-items th { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-2); }
/* Selo "sem certificado" por bobina (Tarefa 8b) e andamento da leitura, na
   conferência: pendência de rotina, NUNCA marrom/âmbar (dono, 28/09) — usa
   os tokens neutros, como o resto da tela em estado de espera. */
.rom-sem-certificado { background: var(--surf-2); color: var(--ink-2); }
.rom-cert-progresso { font-size: 13px; margin: 0.5rem 0; }
.rom-erros {
  margin: 0.75rem 0; padding: 0.75rem; border-radius: var(--r-sm);
  background: var(--negative-subtle); color: var(--negative-text); font-size: 13px;
}
.rom-dup-list { margin: 0.25rem 0 0; padding-left: 1rem; }

/* Chips-contadores: FILTRO DE APRESENTAÇÃO (escondem <tr>). O N do botão Gravar
   vem de `contadores` e não muda com o filtro. */
.rom-chips { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.75rem 0; }
.rom-chip__n { font-variant-numeric: tabular-nums; }
.rom-chips__estado { color: var(--ink-2); font-size: 12px; }
.rom-gravando { padding: 2rem 1rem; text-align: center; color: var(--ink-2); }

/* Etapa Certificados — opcional: o lote já está gravado, o papel pode vir depois. */
.rom-cert__linha { color: var(--ink); font-size: 14px; }
.rom-cert__aviso {
  padding: 0.75rem; border-radius: var(--r-sm);
  background: var(--warning-subtle); color: var(--warning-text); font-size: 13px;
}
.rom-cert__lista { list-style: none; margin: 1rem 0 0; padding: 0; }
.rom-cert__lote {
  display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  padding: 0.25rem 0; border-bottom: 1px solid var(--line); font-size: 13px;
}
.rom-cert__chip { margin-left: auto; }
/* Papéis do lote (abertos pelo chip) e anexador daquele lote — ocupam a linha
   inteira, logo abaixo dela: um anexador no fim da lista não diria de qual lote é. */
.rom-cert__docs, .rom-cert__anexar { flex: 0 0 100%; padding: 0.5rem 0 0.5rem 1rem; }

/* Estado do laudo por lote, depois de gravar (Tarefa 8b): cor com
   significado — gerado é positivo, falhou usa o vermelho do design system,
   na fila é a MESMA pendência neutra do selo acima (nunca marrom/âmbar). */
.rom-cert__laudo--na_fila { background: var(--surf-2); color: var(--ink-2); }
.rom-cert__laudo--gerado { background: var(--positive-subtle); color: var(--positive-text); }
.rom-cert__laudo--falhou { background: var(--negative-subtle); color: var(--negative-text); }

/* wms-expedicao */
/* Expedição (`/wms/expedicao/`, 03/09/2026) — bi/templates/bi/expedicao.html +
   bi/static/bi/js/expedicao.js. Duas abas sobre a MESMA tabela (a fila troca
   de fonte, a forma da linha não). Botão único por linha, sempre azul sólido
   (`.btn-primary`) — cinza lê como desabilitado, regra da casa. Tokens do
   design system global; segue o FCDS sem desvio (o override é só da tela de
   Pedidos). */

/* `gap` escopado à página, não em `.card-hd` (componente de ~29 templates —
   mudar o global exige aval do dono, ver task-9-report.md "Fix round 1/2").
   Sem ele, o `margin-left:auto` de `.exp__busca` consome o espaço livre antes
   do `space-between` de `.card-hd` ter o que distribuir, e "Notas" cola no
   botão da aba (achado ao vivo em /wms/expedicao/, 03/09/2026). */
[data-pagina="wms-expedicao"] .card-hd { gap: 0.75rem; }

.exp__abas { display: flex; gap: 0.375rem; }
.exp__aba.active { background: var(--acc); border-color: var(--acc); color: #fff; }

.exp__busca { display: flex; align-items: flex-end; gap: 0.5rem; flex-wrap: wrap; margin-left: auto; }
.exp__campo { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.exp__campo .lab { margin: 0; font-size: var(--fonte-rotulo); color: var(--ink-2); }
.exp__campo input { width: 9rem; }

.exp__aviso {
  margin: 0 0 0.75rem; padding: 0.5rem 0.75rem; border-radius: var(--r-sm);
  background: var(--surf-2); color: var(--ink-2); font-size: var(--fonte-corpo);
}
.exp__aviso--erro { background: var(--negative-subtle); color: var(--negative-text); }

.exp-num { font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 500; }
.exp-vazio { color: var(--ink-2); font-size: var(--fonte-corpo); text-align: center; padding: 1.5rem 0.75rem; }
.exp-autor { color: var(--ink); }
.exp-quando { display: block; color: var(--ink-2); font-size: var(--fonte-pequena); font-variant-numeric: tabular-nums; }

@media (pointer: coarse) {
  .exp__aba, .exp__busca .btn, #exp-tabela .btn { min-height: 44px; }
  .exp__campo input { min-height: 44px; }
}

/* ============================================================
   SIMULAÇÕES — DOCUMENTO DA SIMULAÇÃO (impressão / PDF WeasyPrint)
   Renderizado por bi/templates/bi/simulacao_pdf.html via
   bi/services/simulacoes_registro.py. Prefixo .simpdf-.
   Página NOMEADA de propósito: o @page anônimo lá em cima pertence à
   proposta do CRM (margens de 30/40 mm e cabeçalho corrido); este
   documento não tem cabeçalho corrido e precisa da sua própria caixa.
   ============================================================ */
@page simulacao { size: A4; margin: 18mm 14mm; }
.simpdf-doc{ page:simulacao; font-family:'DejaVu Sans', Arial, sans-serif;
  font-size:10.5pt; color:#1f2937; }
.simpdf-titulo{ font-size:15pt; margin:0 0 2mm; }
.simpdf-sub{ color:#6b7280; font-size:9pt; margin-bottom:6mm; }
.simpdf-tabela{ width:100%; border-collapse:collapse; margin-bottom:6mm; }
.simpdf-tabela th, .simpdf-tabela td{ padding:2mm 2.5mm;
  border-bottom:0.3mm solid #e5e7eb; text-align:right; }
.simpdf-tabela th:first-child, .simpdf-tabela td:first-child{ text-align:left; }
.simpdf-tabela th{ font-size:8.5pt; color:#6b7280; font-weight:500; }
.simpdf-soma td{ font-weight:600; border-top:0.5mm solid #1f2937; border-bottom:0; }
.simpdf-neg{ color:#b91c1c; }

/* ===========================================================================
   Simulações (/simulacoes/criar/ e /simulacoes/lista/).
   Porte do mockup aprovado docs/superpowers/mockups/simulacoes-a.html: MESMOS
   nomes de classe, prefixados `sim-`, mesmas medidas. Tudo local à tela — o
   prefixo mantém o alcance e nenhum token global é redefinido aqui.
   Da bancada (18/08/2026) ficou só o comportamento: a página não rola (mesa em
   `content--altura-cheia`, catálogo e coluna rolam sozinhos) e a régua de baixo
   fecha a página com piso + frase + a única ação. A versão de três colunas com
   controles de 44 px foi rejeitada pelo dono (19/08/2026): "o mockup é superior".
   =========================================================================== */
.sim-page{--sim-gap:0.75rem}
.sim-num{font-variant-numeric:tabular-nums}
/* `.sim-nota` é o `.sk` do mockup: a linha pequena, cinza, embaixo de um campo
   ou de um número. `.sim-atencao`/`--positivo`/`--negativo` são o pill-*. */
.sim-nota{font-size:var(--fonte-pequena);color:var(--ink-3);display:block}
.sim-atencao{color:var(--warning-text)}
.sim-positivo{color:var(--positive-text)}
.sim-negativo{color:var(--negative-text)}
.sim-hint{margin-left:auto;font-weight:400;color:var(--ink-3);font-size:var(--fonte-pequena)}
/* Cor nesta tela (19/08/2026): UM contrato — o azul do sistema é a cor de
   ação e de seleção (Registrar, Sim/Não ativo, Próximo do assistente, linha
   selecionada do catálogo). Sem botão preto em lugar nenhum. Vermelho/âmbar/
   verde só onde significa margem (régua, KPI de MB, linhas divergentes).
   Teclas (`kbd`) são chips claros — o preto do Bootstrap em cima do azul
   destoava; dentro de botão azul o chip é translúcido. */
.sim-page kbd{font-family:inherit;font-size:var(--fonte-pequena);font-weight:500;line-height:1;
  padding:0.15rem 0.35rem;border-radius:4px;background:var(--surf-3);color:var(--ink-2);
  border:1px solid var(--line-3);box-shadow:none;vertical-align:baseline}
.sim-page .btn-primary kbd{background:rgba(255,255,255,.18);color:#fff;border-color:transparent}
/* Link de texto dentro de rótulo (o "usar o piso"): é botão por acessibilidade, com a cara do link de fábrica (#714). */
.sim-link{border:0;background:none;padding:0;color:var(--bs-link-color);font:inherit;
  cursor:pointer;text-decoration:underline}
.sim-link:hover{color:var(--bs-link-hover-color)}

/* Cartões: o mockup tem cabeçalho branco, 10/14, peso 600 — não o cabeçalho
   cinza do FCDS. Reescrito SÓ dentro de `.sim-page`. */
.sim-page .card{border-radius:10px}
.sim-page .card-header.sim-card-h{display:flex;align-items:baseline;gap:0.5rem;
  padding:0.625rem 0.875rem;background:var(--surf);font-weight:500;
  font-size:var(--fonte-rotulo);text-transform:uppercase;letter-spacing:0.04em;color:var(--ink-2);
  border-bottom:1px solid var(--line)}
.sim-page .card-header.sim-card-h .sim-hint,.sim-page .card-header.sim-card-h .sim-link{
  text-transform:none;letter-spacing:0;font-weight:400}
.sim-page .card-body.sim-card-b{padding:0.75rem 0.875rem}
.sim-card-b--tabela{padding:0.25rem 0.5rem 0.5rem}

/* Mesa: catálogo à esquerda, tudo o mais à direita (mockup: 320px 1fr) */
.sim-mesa{display:grid;grid-template-columns:320px minmax(0,1fr);
  gap:var(--sim-gap);align-items:start;
  /* altura cheia: a mesa ocupa o que sobra e cada coluna rola sozinha */
  flex:1 1 auto;min-height:0;grid-template-rows:minmax(0,1fr)}
.sim-mesa>.sim-coluna{max-height:100%;overflow-y:auto;padding-right:2px}
.sim-page.page{padding-top:var(--sim-gap)}
.sim-coluna{display:flex;flex-direction:column;gap:var(--sim-gap);min-width:0}
.sim-split{display:grid;grid-template-columns:5fr 6fr;gap:var(--sim-gap);
  align-items:start}

/* Catálogo */
.sim-catalogo{display:flex;flex-direction:column;max-height:100%;min-height:0}
.sim-catalogo__busca{padding:0.5rem 0.625rem;border-bottom:1px solid var(--line)}
.sim-catalogo__lista{overflow:auto;flex:1}
.sim-catalogo__vazio{font-size:var(--fonte-corpo);color:var(--ink-3);padding:0.75rem 0.875rem;
  margin:0}
.sim-catalogo__grupo{display:flex;align-items:baseline;gap:0.5rem;
  padding:0.5rem 0.875rem 0.15rem;font-size:var(--fonte-pequena);font-weight:500;
  color:var(--ink-2);background:var(--surf);position:sticky;top:0;z-index:1}
.sim-catalogo__meta{margin-left:auto;font-weight:400;color:var(--ink-3)}
.sim-catalogo__item{display:flex;justify-content:space-between;align-items:center;
  gap:0.5rem;width:100%;text-align:left;padding:0.4375rem 0.875rem;border:0;
  border-bottom:1px solid var(--line);background:none;color:inherit;
  font-size:var(--fonte-corpo);cursor:pointer}
.sim-catalogo__item:hover,.sim-catalogo__item:focus-visible{background:var(--surf-2)}
.sim-catalogo__item.is-ativo{background:var(--acc-soft);box-shadow:inset 3px 0 var(--acc)}
.sim-catalogo__texto{min-width:0;display:flex;flex-direction:column;gap:0.1rem}
.sim-catalogo__nome{}
.sim-catalogo__codigo{color:var(--ink-3)}
.sim-catalogo__custo{font-size:var(--fonte-pequena);color:var(--ink-3);white-space:nowrap}
.sim-catalogo__custo b{color:var(--ink)}
.sim-catalogo__ocultos{padding:0.25rem 0.875rem 0.5rem;font-size:var(--fonte-pequena);
  color:var(--ink-3);border-bottom:1px solid var(--line)}

/* Ficha do item + KPIs */
.sim-item{display:flex;align-items:baseline;gap:0.625rem;flex-wrap:wrap}
.sim-item__nome{font-size:var(--fonte-destaque);font-weight:500;margin:0;min-width:0;
max-width:60%}
.sim-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:0.625rem;margin-top:0.625rem}
.sim-kpi{border:1px solid var(--line);border-radius:10px;
  padding:0.625rem 0.875rem;background:var(--surf)}
.sim-kpi__rotulo{font-size:var(--fonte-rotulo);color:var(--ink-3);font-weight:500;
  text-transform:uppercase;letter-spacing:0.04em}
.sim-kpi__valor{font-size:var(--fonte-heroi);font-weight:500;line-height:40px;margin-top:2px;
  letter-spacing:-0.01em;font-variant-numeric:tabular-nums;transition:color 220ms ease-out}
.sim-kpi__nota{font-size:var(--fonte-corpo);color:var(--ink-3);margin-top:3px}
.sim-kpi.sim-ok{background:var(--positive-subtle);
  border-color:color-mix(in srgb,var(--positive) 28%,var(--surf))}
.sim-kpi.sim-atencao{background:var(--warning-subtle);
  border-color:color-mix(in srgb,var(--warning) 28%,var(--surf))}
.sim-kpi.sim-ruim{background:var(--negative-subtle);
  border-color:color-mix(in srgb,var(--negative) 28%,var(--surf))}
.sim-kpi.sim-ok .sim-kpi__valor{color:var(--positive-text)}
.sim-kpi.sim-atencao .sim-kpi__valor{color:var(--warning-text)}
.sim-kpi.sim-ruim .sim-kpi__valor{color:var(--negative-text)}
.sim-kpi--alerta .sim-kpi__valor,.sim-kpi--alerta .sim-kpi__nota{color:var(--negative-text)}
.sim-aviso{color:var(--warning-text)}

/* Régua de preço — o instrumento da tela. Prejuízo (< custo) · abaixo da meta
   (custo → piso) · na meta (≥ piso). Os LIMITES são custo e piso, do serviço; o
   cursor é o preço líquido e se ARRASTA: a posição vira número no campo de
   preço e o backend recalcula. Barra alta (14 px), marcas com o número em
   destaque, cursor com alça de 44 px de alvo (o único controle grande da tela,
   e é o que se pega com o dedo). */
.sim-regua{margin-top:0.75rem;padding:0 0.375rem}
.sim-regua__vazia{font-size:var(--fonte-corpo);color:var(--ink-3);margin:1rem 0 0.25rem}
.sim-regua__barra{position:relative;height:14px;border-radius:7px;background:var(--surf-3);
  margin:2rem 3rem 2.25rem;cursor:pointer;touch-action:none}
.sim-regua__barra--fantasma{cursor:default;opacity:0.5}
.sim-regua__faixa{position:absolute;top:0;height:100%}
.sim-regua__faixa--ruim{background:color-mix(in srgb,var(--negative) 32%,var(--surf));
  border-radius:7px 0 0 7px}
.sim-regua__faixa--atencao{background:color-mix(in srgb,var(--warning) 38%,var(--surf))}
.sim-regua__faixa--ok{background:color-mix(in srgb,var(--positive) 32%,var(--surf));
  border-radius:0 7px 7px 0}
.sim-regua__marca{position:absolute;top:-5px;width:2px;height:24px;background:var(--ink);
  border-radius:1px}
.sim-regua__marca span{position:absolute;top:-1.375rem;left:50%;transform:translateX(-50%);
  white-space:nowrap;font-size:var(--fonte-pequena);color:var(--ink-3);font-weight:400}
.sim-regua__marca em{font-style:normal;color:var(--ink);font-weight:500;
  font-variant-numeric:tabular-nums}
/* Cursor do preço: alça redonda de 22 px sobre a barra, alvo invisível de 44 px
   em volta, rótulo pendurado embaixo. A cor da alça é a situação da margem
   (classificada no backend: data-situacao na barra). */
.sim-regua__cursor{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);
  width:44px;height:44px;border:0;background:transparent;padding:0;cursor:grab;
  transition:left 220ms cubic-bezier(.22,1,.36,1)}
.sim-regua__cursor::before{content:"";position:absolute;left:50%;top:50%;
  width:22px;height:22px;transform:translate(-50%,-50%);border-radius:50%;
  background:var(--surf);border:3px solid var(--acc);box-shadow:0 1px 3px rgba(25,28,34,.25)}
.sim-regua__barra[data-situacao="na_meta"] .sim-regua__cursor::before{border-color:var(--positive-text)}
.sim-regua__barra[data-situacao="abaixo_meta"] .sim-regua__cursor::before{border-color:var(--ds-atencao)}
.sim-regua__barra[data-situacao="prejuizo"] .sim-regua__cursor::before{border-color:var(--negative-text)}
.sim-regua__cursor:hover::before{transform:translate(-50%,-50%) scale(1.08)}
.sim-regua__cursor:focus-visible{outline:none}
.sim-regua__cursor:focus-visible::before{box-shadow:0 0 0 4px var(--acc-soft)}
.sim-regua.is-arrastando .sim-regua__cursor{cursor:grabbing;transition:none}
.sim-regua.is-arrastando .sim-regua__cursor::before{transform:translate(-50%,-50%) scale(1.12)}
.sim-regua__preco{position:absolute;top:calc(100% - 4px);left:50%;transform:translateX(-50%);
  white-space:nowrap;font-size:var(--fonte-pequena);color:var(--ink-3)}
.sim-regua__preco em{font-style:normal;font-weight:500;font-size:var(--fonte-corpo);
  font-variant-numeric:tabular-nums;color:var(--ink)}
.sim-regua__barra[data-situacao="na_meta"] .sim-regua__preco em{color:var(--positive-text)}
.sim-regua__barra[data-situacao="abaixo_meta"] .sim-regua__preco em{color:var(--warning-text)}
.sim-regua__barra[data-situacao="prejuizo"] .sim-regua__preco em{color:var(--negative-text)}
@media (prefers-reduced-motion:reduce){.sim-regua__cursor{transition:none}}
/* Sem item: a ficha é um convite */
.sim-vazio{padding:0.5rem 0.25rem 0}
.sim-vazio__titulo{font-size:var(--fonte-destaque);font-weight:500;margin:0 0 0.25rem}
.sim-vazio__texto{font-size:var(--fonte-corpo);color:var(--ink-3);margin:0;max-width:60ch}

/* Parâmetros da venda */
.sim-parametros{display:grid;grid-template-columns:1fr 1fr;gap:0.5rem 0.75rem}
.sim-campo{display:flex;flex-direction:column;gap:0.15rem;margin:0}
.sim-campo--largo{grid-column:1/3}
.sim-campo__rotulo{font-size:var(--fonte-pequena);color:var(--ink-3);font-weight:500}

/* Tabelas (tributos e entradas): a `.t` do mockup */
.sim-tributos,.sim-entradas{margin:0}
.sim-tributos th,.sim-entradas th{font-size:var(--fonte-pequena);color:var(--ink-3);font-weight:500;
  padding:0.375rem 0.4rem;border-bottom:1px solid var(--line);white-space:nowrap}
.sim-tributos td,.sim-entradas td{padding:0.375rem 0.4rem;border-bottom:1px solid var(--line);
  white-space:nowrap;vertical-align:top}
.sim-tributos .sim-op{display:inline-block;width:0.875rem;color:var(--ink-4);text-align:center}
.sim-tributos td:nth-child(2),.sim-tributos td:nth-child(3),.sim-tributos td:nth-child(4){
  font-variant-numeric:tabular-nums}
.sim-tributos tbody tr:hover{background:var(--surf-2)}
.sim-tributos .sim-base{white-space:normal;color:var(--ink-3);font-size:var(--fonte-corpo);min-width:8.5rem}
.sim-tributos__linha--soma td{font-weight:500;border-top:2px solid var(--ink);
  border-bottom:0}
.sim-tributos__linha--mute td{color:var(--ink-3)}
.sim-tributos__nota td{color:var(--ink-3);font-size:var(--fonte-corpo)}
/* Fornecedor é campo livre e vem longo ("DINGHZOU YIKANG METAL PRODUCTS
   CO., LTD."): sem o corte ele empurra kg e R$/kg para fora do cartão. */
.sim-entradas__fornecedor{max-width:13rem;
}
/* 12 meses de compra podem ser dezenas de notas — a lista rola dentro do
   cartão em vez de esticar a coluna inteira. */
#sim-entradas{max-height:11rem;overflow:auto}
/* Gráfico das entradas (um só: linhas de preço + barras de volume): altura fixa
   em 190 px — a mesma que o JS passa ao Plotly. Sem ela o card pula de tamanho. */
.sim-grafico{min-height:11.875rem;margin-bottom:0.375rem}
.sim-grafico:empty{display:none}
/* Assistente de montar a venda: um passo por vez, em cima dos campos. Compacto —
   é ajuda, não dado: uma linha de pergunta, uma de dica, os botões pequenos. */
.sim-assistente{background:var(--surf-2);border:1px solid var(--line);border-radius:8px;
  padding:0.5rem 0.625rem;margin:0 0 0.625rem;display:flex;flex-direction:column;gap:0.125rem;
  font-size:var(--fonte-corpo)}
.sim-assistente[hidden]{display:none}
.sim-assistente__topo{display:flex;align-items:center;gap:0.5rem;font-size:var(--fonte-pequena);color:var(--ink-3)}
.sim-assistente__topo .btn-close{margin-left:auto}
.sim-assistente__pergunta{margin:0}
.sim-assistente__dica{margin:0;color:var(--ink-2);font-size:var(--fonte-pequena)}
.sim-assistente__acoes{display:flex;gap:0.375rem;flex-wrap:wrap;margin-top:0.25rem}
.sim-assistente__acoes kbd{margin-left:0.25rem;font-size:var(--fonte-pequena)}
.sim-campo.is-assistido :is(.form-control,.form-select,.btn-group){outline:2px solid var(--acc-line);
  outline-offset:1px;border-radius:6px}
.sim-tabela-scroll{overflow-x:auto}

/* Régua: fecha a página por baixo — piso, frase do backend e a única ação */
.sim-rodape{flex:0 0 auto;display:flex;align-items:center;
  gap:0.625rem;flex-wrap:wrap;padding:0.625rem 1.25rem;margin-top:var(--sim-gap);
  background:var(--surf);border-top:1px solid var(--line)}
.sim-rodape__frase{color:var(--ink-2);font-size:var(--fonte-corpo);margin-left:0.5rem}
.sim-rodape__frase b{color:var(--ink)}
.sim-rodape__piso{font-size:var(--fonte-destaque)}
.sim-rodape__acoes{margin-left:auto;display:flex;gap:0.5rem;align-items:center}

/* Estado REGISTRADA: a ficha congela e o único caminho de edição é duplicar */
.sim-registrada .sim-parametros .form-control,
.sim-registrada .sim-parametros .form-select,
.sim-registrada .sim-catalogo{opacity:0.6;pointer-events:none}
.sim-registrada__aviso{margin:0 0 var(--sim-gap);border-radius:10px}

/* Responsividade do mockup: 1400 → catálogo 280; 1100 → colunas empilham e
   KPIs 2×2; 900 → catálogo no topo e itens de 44px; 600 → KPIs em coluna. */
@media (max-width:1400px){.sim-mesa{grid-template-columns:280px minmax(0,1fr)}}
@media (max-width:1100px){
  .sim-split{grid-template-columns:1fr}
  .sim-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:900px){
  .sim-mesa{grid-template-columns:1fr}
  .sim-catalogo{max-height:16.25rem}
  .sim-page .sim-catalogo__item{min-height:44px}}
@media (max-width:600px){
  .sim-kpis{grid-template-columns:1fr}
  .sim-parametros{grid-template-columns:1fr}
  .sim-campo--largo{grid-column:1}
  .sim-regua__barra{margin:2.125rem 0.5rem 1.875rem}}

/* ==========================================================================
   COMPRAS — Solicitações de Compra padronizadas (#630): lista na grade da casa,
   detalhe e Nova SC no painel lateral. Escopo de página: tudo mora sob
   [data-pagina="compras"] e nada vaza para as outras telas.
   ========================================================================== */

/* O campo buscável é o do CRM (`crm/js/combo.js`), e as regras dele são
   escopadas a [data-pagina="crm"]/[data-pagina="crm-deal"]. Reusar o
   COMPORTAMENTO exige repetir aqui a pintura — inclusive `.crm-oculto`, que é
   o que fecha a lista de sugestões: sem ela o typeahead ficaria aberto para
   sempre nesta página. */
[data-pagina="compras"] .crm-oculto { display: none !important; }
[data-pagina="compras"] .crm-combo { position: relative; display: block; }
[data-pagina="compras"] .crm-lista {
  background: var(--surf); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: 0 8px 24px rgba(25, 28, 34, .12);
  overflow: hidden; overflow-y: auto; }
/* `fixed`, e não `absolute`: a ficha da SC rola dentro do painel lateral, e um
   `absolute` seria recortado por ele. As coordenadas vêm de `crm/js/combo.js`. */
[data-pagina="compras"] .crm-lista--flutua {
  position: fixed; z-index: 1060; max-height: 16rem; }
[data-pagina="compras"] .crm-lista__item {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  border-bottom: 1px solid var(--line-2); padding: .5rem .75rem;
  font-size: var(--fonte-corpo); color: var(--ink); cursor: pointer; }
[data-pagina="compras"] .crm-lista__item:last-child { border-bottom: 0; }
[data-pagina="compras"] .crm-lista__item:hover,
[data-pagina="compras"] .crm-lista__item:focus,
[data-pagina="compras"] .crm-lista__item[data-destacado] { background: var(--surf-2); }
[data-pagina="compras"] .crm-vazio {
  color: var(--ink-3); font-size: var(--fonte-corpo); padding: .6rem .75rem; }

.content:has(> .page[data-pagina="compras"] > .grade),
.page[data-pagina="compras"]:has(> .grade) { background: #fff; }
.content--altura-cheia > .page[data-pagina="compras"] { padding-top: var(--content-pad-y); }
.compras-motivo { font-size: var(--fonte-pequena); color: var(--ink-2); margin-right: .5rem; }

[data-pagina="compras"] .compras-barra { display: inline-flex; align-items: center; gap: .5rem; margin-right: .5rem; }
[data-pagina="compras"] .compras-barra[hidden] { display: none; }
/* Larguras das colunas das listas: as medidas de Pedidos e NF (`.pd-col-*`); o que sobra fica com o texto livre
   (fornecedor, CCU). */
[data-pagina="compras"] .compras-col-numero { width: 5rem; font-variant-numeric: tabular-nums; }
[data-pagina="compras"] .compras-col-data { width: 5.5rem; font-variant-numeric: tabular-nums; }
[data-pagina="compras"] .compras-col-pessoa { width: 10rem; }
[data-pagina="compras"] .compras-col-itens { width: 4rem; }
[data-pagina="compras"] .compras-col-valor { width: 7rem; font-variant-numeric: tabular-nums; }
[data-pagina="compras"] .compras-col-situacao { width: 9rem; }
[data-pagina="compras"] .compras-col-nota { width: 7rem; }
[data-pagina="compras"] .compras-col-parada { width: 5rem; }
[data-pagina="compras"] .compras-link { font-weight: 500; }

/* Situação: a pílula compartilhada `.situacao-pilula` (seção "Pílula de situação", junto do Processar DDA). */
[data-pagina="compras"] .compras-col-documento { width: 8rem; }

[data-pagina="compras"] .compras-aviso {
  margin: .5rem 0; padding: .5rem .75rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: var(--fonte-corpo); background: #fff; }
[data-pagina="compras"] .compras-aviso--erro { border-color: var(--ds-perigo); color: var(--ds-perigo); }
[data-pagina="compras"] .compras-aviso--atencao { border-color: #FF7B00; color: #FA4B00; }

/* Painel lateral: largo o bastante para a tabela de itens da ficha. */
[data-pagina="compras"] .compras-painel { --bs-offcanvas-width: min(1100px, 96vw); }
[data-pagina="compras"] .compras-painel .offcanvas-header { gap: .75rem; border-bottom: 1px solid var(--line); }
[data-pagina="compras"] .compras-painel__titulo { font-size: var(--fonte-titulo); font-weight: 500; letter-spacing: .01em; line-height: 1.2; margin: 0; }
/* Tabelas da ficha e do formulário com as medidas da ficha do pedido (`.pd-docs-grade`): cabeçalho rótulo em
   versal, célula no corpo, só o fio de baixo (pesos da escala #476: 500). */
[data-pagina="compras"] :is(.compras-itens, .compras-ficha) { font-size: var(--fonte-corpo); }
[data-pagina="compras"] :is(.compras-itens, .compras-ficha) thead th {
  font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: #4A4D52;
  padding: .4rem .75rem .4rem 0; border-bottom: 1px solid #D9DBDE; vertical-align: bottom; }
[data-pagina="compras"] :is(.compras-itens, .compras-ficha) tbody td { padding: .5rem .75rem .5rem 0; }
[data-pagina="compras"] .compras-painel .btn-close { margin-left: auto; }
[data-pagina="compras"] .compras-acoes { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .75rem; }
[data-pagina="compras"] .compras-acoes:empty { display: none; }
[data-pagina="compras"] .compras-itens td, [data-pagina="compras"] .compras-ficha td { vertical-align: middle; }
[data-pagina="compras"] .compras-descricao { color: var(--ink-2); }
[data-pagina="compras"] .compras-observacao { color: var(--ink-3); font-size: var(--fonte-pequena); margin-top: .25rem; }
[data-pagina="compras"] .compras-rateio td { color: var(--ink-2); font-size: var(--fonte-pequena); border-top: 0; padding-top: 0; }
[data-pagina="compras"] .compras-subtitulo { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: #4A4D52; margin: 1rem 0 .5rem; }
[data-pagina="compras"] .compras-historico { list-style: none; padding: 0; margin: 0; font-size: var(--fonte-corpo); }
[data-pagina="compras"] .compras-historico li { padding: .2rem 0; }
[data-pagina="compras"] .compras-quando { color: var(--ink-3); font-variant-numeric: tabular-nums; margin-right: .5rem; }
[data-pagina="compras"] .compras-carregando { color: var(--ink-3); }

/* Ficha (Nova SC e + Item). */
[data-pagina="compras"] .compras-formulario { margin-bottom: 1rem; }
[data-pagina="compras"] .compras-campo { display: flex; flex-direction: column; gap: .25rem; margin-bottom: .75rem; max-width: 32rem; }
[data-pagina="compras"] .compras-ficha .compras-col-codigo { min-width: 12rem; }
[data-pagina="compras"] .compras-ficha select[data-campo="tipo"] { min-width: 6rem; }
[data-pagina="compras"] .compras-ficha select[data-campo="deposito"] { min-width: 10rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="observacao"] { min-width: 7rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="unidade"] { width: 3.5rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="quantidade"],
[data-pagina="compras"] .compras-ficha input[data-campo="preco"] { width: 5.5rem; }
[data-pagina="compras"] .compras-rateio-campos { display: flex; flex-wrap: wrap; gap: .25rem .75rem; margin: 1rem 0 .75rem; }
[data-pagina="compras"] .compras-rateio-campos .compras-campo { flex: 1 1 16rem; margin-bottom: 0; }
[data-pagina="compras"] .compras-rotulo { flex: 1 0 100%; margin: 0; }
/* Nova SC (#715): o painel ocupa a janela menos a barra lateral (o detalhe da SC segue na largura acima); Filial,
   Observação e Clonar numa linha no topo; o produto com espaço para código e descrição; números com a máscara pt-BR
   (até 5 casas na quantidade) e o preço com o prefixo R$ do input-group de fábrica. */
[data-pagina="compras"] .compras-painel--larga { --bs-offcanvas-width: calc(100vw - var(--sidebar-width) - var(--sidebar-margin) * 2); }
[data-pagina="compras"] .compras-capa { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 1rem; }
[data-pagina="compras"] .compras-capa .compras-campo { flex: 0 1 24rem; }
[data-pagina="compras"] .compras-capa .compras-campo--largo { flex: 1 1 24rem; }
[data-pagina="compras"] .compras-capa__clonar { margin-bottom: .75rem; }
[data-pagina="compras"] .compras-ficha .compras-col-produto { min-width: 22rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="quantidade"] { width: 7.5rem; }
[data-pagina="compras"] .compras-ficha .compras-preco { width: 10rem; flex-wrap: nowrap; }
[data-pagina="compras"] .compras-ficha .compras-preco input[data-campo="preco"] { width: auto; }
[data-pagina="compras"] .compras-ficha input[data-campo="necessidade"] { width: 9.5rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="unidade"] { width: 4.5rem; }
[data-pagina="compras"] .compras-valor { white-space: nowrap; font-variant-numeric: tabular-nums; }
[data-pagina="compras"] .compras-anexos { list-style: none; padding: 0; margin: 0 0 .5rem; font-size: var(--fonte-corpo); }
[data-pagina="compras"] .compras-anexos li { display: flex; align-items: center; gap: .75rem; padding: .2rem 0; }
/* Modal Clonar (#715): a lista das SC à esquerda, os dados da escolhida à direita. */
[data-pagina="compras"] .compras-clonar { display: grid; grid-template-columns: minmax(16rem, 22rem) minmax(0, 1fr); gap: 1rem; align-items: start; }
[data-pagina="compras"] .compras-clonar__lista { max-height: 65vh; overflow-y: auto; }
[data-pagina="compras"] .compras-clonar__opcao { display: flex; flex-direction: column; align-items: flex-start; gap: .125rem; }
@media (max-width: 767.98px) { [data-pagina="compras"] .compras-clonar { grid-template-columns: minmax(0, 1fr); } }

/* Painel da solicitação de compra (#728): linha de capa e ações nos dois lados (vermelho à esquerda, verde à
   direita). As etapas da compra e o histórico usam os componentes globais `.fcds-etapas` e `.fcds-linha-do-tempo`. */
/* Capa só leitura da ficha (#736): rótulo pequeno em cinza, valor em preto logo abaixo. */
[data-pagina="compras"] .compras-capa--leitura { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 2fr); gap: 0 2rem; margin-bottom: .75rem; }
@media (max-width: 767.98px) { [data-pagina="compras"] .compras-capa--leitura { grid-template-columns: minmax(0, 1fr); } }
[data-pagina="compras"] .compras-capa--leitura .compras-campo { gap: 0; margin-bottom: 0; }
[data-pagina="compras"] .compras-capa--leitura .form-label { color: var(--ink-2); font-size: var(--fonte-pequena); margin: 0; }
[data-pagina="compras"] .compras-capa--leitura .form-control-plaintext { color: var(--ink); font-weight: 500; padding: 0; }
[data-pagina="compras"] .compras-acoes--lados { justify-content: space-between; }
[data-pagina="compras"] .compras-acoes--lados > div { display: flex; gap: .5rem; flex-wrap: wrap; }
[data-pagina="compras"] .compras-rateio-etiquetas { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .375rem; }
[data-pagina="compras"] .compras-rateio-etiquetas span { font-size: var(--fonte-pequena); color: var(--ink-2); background: var(--bs-gray-100); border-radius: .25rem; padding: 0 .4rem; }
[data-pagina="compras"] .compras-nowrap { white-space: nowrap; font-variant-numeric: tabular-nums; }
[data-pagina="compras"] .compras-lado-a-lado { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; margin-top: 1rem; }
@media (max-width: 767.98px) { [data-pagina="compras"] .compras-lado-a-lado { grid-template-columns: minmax(0, 1fr); } }
[data-pagina="compras"] .compras-historico-completo > summary { cursor: pointer; width: max-content; }
[data-pagina="compras"] .compras-historico-completo[open] > summary { margin-bottom: .5rem; }

/* Ordens de Compra (#630, fatia 4): dados da capa no painel e a página própria de Nova OC / Editar. */
[data-pagina="compras"] .compras-barra__tipo { width: auto; }
[data-pagina="compras"] .compras-dados { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: .5rem 1rem; margin-bottom: 1rem; }
[data-pagina="compras"] .compras-dado { display: flex; flex-direction: column; gap: .125rem; }
[data-pagina="compras"] .compras-dado__rotulo { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: #4A4D52; }
.page.compras-ordem { background: #fff; }
[data-pagina="compras"] .compras-ordem__titulo { font-size: var(--fonte-destaque); font-weight: 500; margin: 0 0 .75rem; }
[data-pagina="compras"] .compras-ordem__origem { color: var(--ink-2); margin-bottom: .75rem; }
[data-pagina="compras"] .compras-ordem__capa { display: flex; flex-wrap: wrap; gap: 0 1rem; }
[data-pagina="compras"] .compras-ordem__capa .compras-campo { flex: 0 1 12rem; }
[data-pagina="compras"] .compras-ordem__capa .compras-campo--largo { flex: 1 1 22rem; }
[data-pagina="compras"] .compras-ordem__capa .compras-campo:has(#oc-filial) { flex-basis: 24rem; }  /* "3 - FOUR DISTRIBUICAO - ITAJAI - CNPJ" inteiro (#658) */
[data-pagina="compras"] .compras-campo--largo { max-width: 48rem; }
[data-pagina="compras"] .compras-ordem__texto { margin-top: 1rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="entrega"] { width: 9.5rem; }
[data-pagina="compras"] .compras-ficha input[data-campo="percentual"] { width: 5.5rem; }
[data-pagina="compras"] :is(#sc-rateio, #oc-rateio) :is(th, td):nth-child(n+3) { width: 1%; }
/* Resumo no rodapé da lista de SC (#673), ao lado da contagem, como o de Pedidos. */
[data-pagina="compras"] .grade .datatable-bottom .compras-resumo { margin-left: 1.25rem; font-size: .8125rem; font-variant-numeric: tabular-nums; }

/* Aprovações (#630, fatia 5; painel lateral #660): o documento abre no painel, com o Aprovar/Reprovar dele; o motivo
   da reprovação e o lote no rodapé, sem caixa. */
[data-pagina="compras"] #ap-painel-motivo .form-control { width: 24rem; }
[data-pagina="compras"] #ap-painel-motivo[hidden] { display: none; }
[data-pagina="compras"] .compras-lote { display: inline-flex; align-items: center; gap: .75rem; margin: 0 auto 0 1.5rem; }
[data-pagina="compras"] .compras-lote__texto { font-weight: 500; white-space: nowrap; }
[data-pagina="compras"] :is(.compras-lote__acoes, .compras-lote__motivo) { display: inline-flex; align-items: center; gap: .5rem; }
[data-pagina="compras"] :is(.compras-lote__acoes, .compras-lote__motivo)[hidden] { display: none; }
[data-pagina="compras"] .compras-lote__motivo .form-control { width: 24rem; }
[data-pagina="compras"] .compras-lote__recusa { color: #FA4B00; font-weight: 500; }
[data-pagina="compras"] .compras-lote[hidden] { display: none; }
[data-pagina="compras"] #ap-aviso .compras-aviso { margin-bottom: .5rem; }

/* Painel de Compras (#630, fatia 6): os cartões do Painel Comex (`.pcx-cartoes`, a pele `--dnv-*` entra pela lista de
   telas acima), POR TIPO na largura toda, e os panes da casa (fc-paineis) para o drill. Número que abre a conta é o
   `.conta-calc` da casa: o link de fábrica do Bootstrap (#681). */
.compras-pc__filtros { display: flex; align-items: center; gap: .5rem; }
.compras-pc { display: flex; flex-direction: column; gap: 1rem; }
.compras-pc__estado { margin: 0; color: var(--ds-perigo); }
.compras-pc__titulo { margin: 0 0 .25rem; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .11em; color: var(--dnv-ink-3); }
.compras-pc__paineis { min-height: 24rem; height: 70vh; padding: 18px 20px 16px; }
/* Sem molduras (#675, dono: "minimalista, com cara de dashboard"): a pele do Painel Comex desenha caixas com
   `gap:1px` sobre o fundo de fio; aqui os blocos se separam só pelo espaço. O Painel Comex não muda. */
.compras-pc :is(.pcx-pagina, .pcx-cartoes) { background: none; border: 0; gap: 0; }
.compras-pc .pcx-cartao { padding-left: 20px; padding-right: 20px; }  /* alinha com os blocos de baixo */
/* #677: os 4 KPIs e os 3 de atenção na mesma faixa. A partir de 1600 px cabem numa linha, cada cartão do tamanho do
   seu conteúdo; abaixo disso a grade do Painel Comex quebra em fileiras (4 + 3), sem cortar nem encolher o número. */
@media (min-width: 1600px) {
  .compras-pc .pcx-cartoes { grid-template-columns: repeat(7, minmax(min-content, auto)); justify-content: space-between; }
  .compras-pc .pcx-cartoes > .pcx-cartao:last-child { grid-column: auto; }
}
.compras-pc .pcx-cartao__valor { white-space: nowrap; }  /* o número é o piso da coluna: nunca quebra nem corta */
/* Cartão de KPI (#714): o número é texto; o "Ver a conta" do pé (link de fábrica) abre a conta, e o `.stretched-link`
   estende o clique ao cartão. A vaga do dropdown fica estática para o `::after` cobrir o cartão, não só o link; o % do
   apoio segue clicável por cima. */
.compras-pc .pcx-cartao { position: relative; }
.compras-pc .pcx-cartao__pe { display: block; margin-top: 6px; font-size: var(--fonte-pequena); }
.compras-pc .pcx-cartao .conta-calc-vaga { position: static; }
.compras-pc .pcx-cartao__apoio .conta-calc { position: relative; z-index: 2; }
/* Entre 1600 e 1800 px os sete rótulos inteiros não cabem (medido: 1558 px para 1512): o rótulo quebra em duas linhas e
   todos reservam as duas, para os números seguirem alinhados. */
@media (min-width: 1600px) and (max-width: 1799.98px) {
  .compras-pc .pcx-cartao__rotulo { white-space: normal; min-height: 2lh; }
}
@media (min-width: 1200px) {
  .compras-pc__paineis[data-profundidade="2"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .compras-pc__paineis[data-profundidade="3"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); }
}
.compras-pc__cabeca { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .25rem 0; }
.compras-pc__grade { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* Nos panes lado a lado o nome (fornecedor, produto) quebra a linha: inteiro à vista e VALOR, NOTAS e COM OC também.
   No modal da conta (#679), as colunas de texto depois do documento quebram: sem isso FORNECEDOR nascia com 850 px e o
   SALDO saía da vista. */
.compras-pc__grade .grade-tabela tbody td:first-child, .compras-pc__grade .grade-tabela tbody td:first-child *,
#pc-conta-grade .grade-tabela tbody td:not(.text-end, :first-child),
#pc-conta-grade .grade-tabela tbody td:not(.text-end, :first-child) * { white-space: normal; }
.compras-pc__aberto { font-weight: 500; color: var(--ds-acao); }
.compras-pc__resultado { font-weight: 500; }
/* A grade da casa sempre tem a 2ª linha do cabeçalho (filtros); nas tabelas curtas do painel ela fica vazia e sai. */
.compras-pc tr.grade-filtros-col:not(:has(input, .colfilter-multi)) { display: none; }

/* ==========================================================================
   CRM · Lista de NEGÓCIOS (`[data-pagina="crm-negocios"]`)
   Reaproveita a faixa de abas e busca da lista de clientes (os seletores
   `.cl-*` acima valem nas duas telas por `:is()`). O que é próprio daqui é a
   linha de seletores e o rodapé de paginação — a lista tem ~16 mil negócios
   com o acervo do Ploomes dentro, e paginar é a única forma de trabalhá-la.
   ========================================================================== */

[data-pagina="crm-negocios"] .ng-filtros {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-bottom: .75rem;
}
[data-pagina="crm-negocios"] .ng-filtro {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  min-width: 9rem;
}
[data-pagina="crm-negocios"] .ng-filtro__rotulo {
  font-size: var(--fonte-pequena);
  color: var(--crm-tinta-2);
}
/* O cadeado ao lado do título é o mesmo fato da pílula de origem, dito onde o
   olho já está: quem varre a coluna do negócio vê que aquela linha não abre
   para trabalhar. Discreto de propósito — repetir a informação em destaque
   duas vezes na mesma linha vira ruído. */
[data-pagina="crm-negocios"] .ng-cadeado {
  margin-left: .35rem;
  font-size: var(--fonte-pequena);
  color: var(--ink-3);
}
/* Densidade: 100 linhas por página pedem linha magra. O `<a>` do título e as
   pílulas puxavam a linha para ~52px; com o padding curto e a pílula sem
   respiro vertical a mesma página mostra ~40% mais negócios por tela. */
[data-pagina="crm-negocios"] #ng-tabela td { padding: .3rem .5rem; }
[data-pagina="crm-negocios"] #ng-tabela .crm-pilula { padding: .05rem .5rem; }
[data-pagina="crm-negocios"] #ng-tabela .crm-rotulo { font-size: var(--fonte-pequena); }
/* Passo 2 do passe de compacidade: negócio e cliente truncam com reticência
   e o nome inteiro vai para o `title` (hover) — nome comprido não pode
   forçar a linha a quebrar em duas. */
[data-pagina="crm-negocios"] #ng-tabela .ng-truncar {
  max-width: 16rem; }
/* Passo 1 do passe de compacidade do CRM (aprovado pelo dono, 28/08/2026):
   `#ng-tabela` já tinha o padding raso acima; `#cl-tabela` (clientes) ganha o
   MESMO tratamento agora, e as duas ganham corpo/entrelinha e cabeçalho mais
   secos — token existente (`--bi-fs-*`), sem cor/token novo — para ~30%
   menos altura de linha nas duas listas. */
[data-pagina="crm-negocios"] #ng-tabela {
  font-size: var(--fonte-corpo);
}
[data-pagina="crm-negocios"] #ng-tabela tbody td {
  line-height: 1.2;
}
[data-pagina="crm-negocios"] #ng-tabela thead th {
  padding: .3rem .5rem;
  font-size: var(--fonte-rotulo);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--crm-tinta-2);
}
[data-pagina="crm-clientes"] #cl-tabela .crm-pilula { padding: .05rem .5rem; }

[data-pagina="crm-negocios"] .ng-rodape {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  margin-top: .75rem;
}
[data-pagina="crm-negocios"] .ng-rodape__contagem {
  font-size: var(--fonte-corpo);
  color: var(--crm-tinta-2);
  font-variant-numeric: tabular-nums;
}
[data-pagina="crm-negocios"] .ng-rodape__paginas {
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* ==========================================================================
   CRM · Negócio em MODO ARQUIVO (importado do Ploomes)
   O servidor decide o modo (`importado_do_ploomes`); aqui só se esconde o que
   não pode ser oferecido — formulário sobre negócio congelado é convite para
   um erro — e se dá corpo à ficha simples de conversas e documentos.
   ========================================================================== */

.crm-negocio--arquivo #dl-frete-card,
.crm-negocio--arquivo #dl-abrir-condicoes-alerta,
.crm-negocio--arquivo .crm-passo { display: none; }

/* O rodapé de decisão FICA: dentro dele mora o "Ver proposta (PDF)", que é o
   item 11 da triagem — e os 8.785 perdidos da base são todos importados, ou
   seja, esconder o rodapé inteiro apagava o link exatamente em quem precisa
   dele. Some só o GESTO DE ESCRITA (`<button>`); o selo de status e o link
   do papel continuam. Quem pode reabrir ou corrigir já é decidido no
   servidor (`pode_reabrir_perdido`, `pode_corrigir`) — este seletor é cinto,
   não a regra. */
.crm-negocio--arquivo #dl-decisao button { display: none; }

/* "Sem preço base" / "Sem IPI no cadastro" são cobrança de quem ainda vai
   vender — em arquivo são ruído em toda linha. O número continua lá; o
   carimbo de pendência some. */
.crm-negocio--arquivo .crm-pilula--tracejada { display: none; }

.crm-negocio--arquivo .crm-arquivo-texto {
  font-size: var(--fonte-corpo);
  padding: .35rem 0;
  color: var(--crm-tinta);
}

.crm-negocio--arquivo .crm-arquivo-grade {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
@media (max-width: 900px) {
  .crm-negocio--arquivo .crm-arquivo-grade { grid-template-columns: 1fr; }
}
.crm-negocio--arquivo .crm-arquivo-doc {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  padding: .3rem 0;
  text-decoration: none;
}
.crm-negocio--arquivo .crm-arquivo-conversa {
  padding: .45rem 0;
  border-bottom: 1px solid var(--crm-borda);
}
.crm-negocio--arquivo .crm-arquivo-conversa:last-child { border-bottom: 0; }

/* ===== CAMPANHAS WHATSAPP (cw-*) ===== */
/* Funil-trapézio central (rampa azul, verde só na conversão — resposta é o
   dinheiro da tela), juntas tipográficas com a perda entre estágios, ritmo
   diário em micro-colunas e fila de conversas. Rótulos sempre em tinta.
   Design System da casa (#306, 09/10/2026): cores pelos --ds-* do :root (a
   rampa e as tintas saem de color-mix sobre eles, sem hex novo), cartão e caixa
   retos, botão e campo com 2px, ação primária azul, situação em pílula com
   ponto. A fonte segue a da casa: migração de fonte é global. */
.cw-page { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2rem 3rem; padding: 1.75rem 2rem 3rem; align-items: start; background: #fff; color: var(--ds-tinta); }
@media (min-width: 992px) { .cw-page:has(.cw-respostas:not([hidden])) { grid-template-columns: minmax(0, 1.35fr) minmax(340px, 1fr); } }

.cw-campanha { margin-bottom: 2.5rem; max-width: 640px; }
.cw-cabecalho { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.cw-titulo { display: flex; align-items: baseline; gap: .75rem; }
.cw-nome { font-size: var(--fonte-titulo); font-weight: 500; letter-spacing: -.02em; color: var(--ds-tinta); margin: 0; }
.cw-periodo { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.cw-notas { display: flex; gap: .9rem; }
.cw-nota { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); }
.cw-nota-optout { color: var(--ds-perigo); font-weight: 500; }

/* progresso da campanha: quanto da lista já foi trabalhado */
.cw-progresso { margin: 0 0 1.1rem; }
.cw-progresso-barra { height: 6px; background: var(--ds-filete); overflow: hidden; }
.cw-progresso-cheio { height: 100%; background: var(--ds-acao); transition: width .5s cubic-bezier(.2,0,.2,1); }
@media (prefers-reduced-motion: reduce) { .cw-progresso-cheio { transition: none; } }
.cw-progresso-legenda { margin-top: .4rem; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.cw-progresso-legenda strong { color: var(--ds-tinta); font-weight: 500; }

/* Situação = pílula de fundo claro com o ponto da cor dentro e texto escuro
   (a forma que o DS reserva à etiqueta; o botão é reto e cheio, então os dois
   não se confundem). Saúde do chip, estado da rodada e o "Saiu" do opt-out.
   Verde é "de pé"; azul é "andando"; vermelho é o único estado que pede
   alguém; pendência é neutra. */
.cw-chip, .cw-rodada-estado, .cw-saiu {
  display: inline-flex; align-items: center; gap: 6px; min-height: 22px; padding: .15rem 10px .15rem 8px;
  border-radius: 999px; font-size: var(--fonte-pequena); font-weight: 500; line-height: 1.2; color: var(--ds-tinta);
  background: color-mix(in srgb, var(--ds-tinta) 5%, #fff); box-shadow: inset 0 0 0 1px rgba(22,22,22,.06);
  font-variant-numeric: tabular-nums; }
.cw-chip::before, .cw-rodada-estado::before, .cw-saiu::before {
  content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ds-tinta-3); }
/* Filho direto de `.cw-page`, que é grid de duas colunas: sem o span, o chip
   ocupava a primeira célula e empurrava o funil para a coluna das conversas. */
.cw-chip { grid-column: 1 / -1; justify-self: start; margin-bottom: 1.5rem;
           background: color-mix(in srgb, var(--ds-sucesso) 10%, #fff); }
.cw-chip::before { background: var(--ds-sucesso); }
.cw-chip-caida { background: color-mix(in srgb, var(--ds-perigo) 10%, #fff); }
.cw-chip-caida::before { background: var(--ds-perigo); }
/* Reconectar pela tela (#325): a faixa do chip ganha o botão ao lado e, abaixo,
   a caixa do QR. "Conectando" pinta de ação (azul), não de alerta. */
.cw-chip-linha { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin-bottom: 1.5rem; }
.cw-chip-linha .cw-chip { margin-bottom: 0; }
.cw-chip-conectando { background: var(--ds-acao-tinta); }
.cw-chip-conectando::before { background: var(--ds-acao); }
.cw-qr { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 1.25rem; align-items: flex-start;
         padding: 1rem; margin: -0.5rem 0 1.5rem; border: 1px solid var(--ds-filete); background: #fff; }
.cw-qr img { flex: none; width: 240px; height: 240px; image-rendering: pixelated; border: 1px solid var(--ds-filete); }
.cw-qr-texto { display: grid; gap: .5rem; max-width: 36rem; font-size: var(--fonte-corpo); color: var(--ds-tinta); }
.cw-qr-texto p { margin: 0; }
.cw-qr-situacao { color: var(--ds-tinta-2); font-size: var(--fonte-corpo); }
.cw-rodada-rodando .cw-rodada-estado { background: var(--ds-acao-tinta); }
.cw-rodada-rodando .cw-rodada-estado::before { background: var(--ds-acao); }
/* Sem rodada aberta: a pílula diz como a última terminou. Cancelada fica neutra. */
.cw-rodada-ultima-concluida .cw-rodada-estado { background: color-mix(in srgb, var(--ds-sucesso) 10%, #fff); }
.cw-rodada-ultima-concluida .cw-rodada-estado::before { background: var(--ds-sucesso); }
.cw-rodada-ultima-erro .cw-rodada-estado { background: color-mix(in srgb, var(--ds-perigo) 10%, #fff); }
.cw-rodada-ultima-erro .cw-rodada-estado::before { background: var(--ds-perigo); }
.cw-saiu { flex: none; background: color-mix(in srgb, var(--ds-perigo) 10%, #fff); }
.cw-saiu::before { background: var(--ds-perigo); }

.cw-rodada { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem;
             margin: 0 0 1.4rem; padding: .7rem .85rem; border: 1px solid var(--ds-filete);
             background: #fff; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); }
.cw-rodada-detalhe { flex-basis: 100%; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); }
.cw-rodada-rotulo { color: var(--ds-tinta-2); }
.cw-rodada-form { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-left: auto; }
.cw-rodada-form input { width: 4.5rem; }
.cw-rodada-form .cw-rodada-limite { width: 3.5rem; }
.cw-rodada-erro { flex-basis: 100%; margin: 0; font-size: var(--fonte-corpo); color: var(--ds-perigo); font-weight: 500; }

/* Ficha da campanha (#306): textos e lista dentro do cartão, antes da rodada. */
.cw-ficha-bloco { display: grid; gap: .5rem; padding: .75rem 0; border-top: 1px solid var(--ds-filete); }
.cw-ficha-linha { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
/* Importar/Trocar lista: o rótulo é o botão; o input nativo fica dentro, invisível mas alcançável pelo teclado. */
.cw-ficha-arquivo { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cw-ficha-preview { display: grid; gap: .5rem; }
.cw-ficha-variacao { margin: 0; padding: .6rem .8rem; background: #fff; border: 1px solid var(--ds-filete); white-space: pre-wrap; font-size: var(--fonte-corpo); color: var(--ds-tinta); }
.cw-ficha-resumo { margin: 0; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.cw-ficha-recusadas { display: grid; gap: .35rem; }
.cw-ficha-recusada { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.cw-ficha-numero { font-size: var(--fonte-corpo); color: var(--ds-tinta-3); min-width: 4.5rem; font-variant-numeric: tabular-nums; }
.cw-ficha-form { display: grid; gap: .5rem; padding: 1rem; overflow: auto; color: var(--ds-tinta); }
/* Rótulo de campo = eyebrow do DS. */
.cw-ficha-form label { margin-top: .5rem; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--ds-tinta-2); }
.cw-ficha-form label:first-child { margin-top: 0; }
.cw-ficha-form .btn, .cw-ficha-bloco > .btn, .cw-qr-texto .btn { justify-self: start; }
.cw-ficha-hint { margin: 0; font-size: var(--fonte-corpo); color: var(--ds-tinta-3); }
.cw-ficha-recusada input { width: 11rem; }

/* Agenda de rodadas (#324): manhã e tarde, colada embaixo da faixa da rodada.
   A situação de cada turno usa a pílula de `.cw-rodada-estado` (neutra);
   azul = rodando, verde = rodou, vermelho = falhou (rodada em erro); cancelada fica neutra. */
.cw-agenda { display: grid; gap: .45rem; margin: 0 0 1.4rem; padding: .7rem .85rem; border: 1px solid var(--ds-filete);
             background: #fff; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); }
.cw-rodada + .cw-agenda { margin-top: -1.4rem; border-top: 0; }
.cw-agenda-titulo { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--ds-tinta-2); }
.cw-agenda-turno { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.cw-agenda-ativa { display: inline-flex; align-items: center; gap: .35rem; min-width: 5.5rem; color: var(--ds-tinta); font-weight: 500; }
.cw-agenda input[type="number"] { width: 4rem; }
.cw-agenda-faixa { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
/* A pílula fica à direita da linha; se não couber, desce inteira e continua à direita. */
.cw-agenda-situacao { margin-left: auto; max-width: 100%; }
.cw-agenda-rodando { background: var(--ds-acao-tinta); }
.cw-agenda-rodando::before { background: var(--ds-acao); }
.cw-agenda-rodou { background: color-mix(in srgb, var(--ds-sucesso) 10%, #fff); }
.cw-agenda-rodou::before { background: var(--ds-sucesso); }
.cw-agenda-falhou { background: color-mix(in srgb, var(--ds-perigo) 10%, #fff); }
.cw-agenda-falhou::before { background: var(--ds-perigo); }

/* funil — a rampa sai do azul de ação; verde só na conversão */
.cw-funil { display: flex; flex-direction: column; }
.cw-estagio { position: relative; }
.cw-forma { height: 58px; }
.cw-forma-fila        { background: var(--ds-filete); }
.cw-forma-enviados    { background: color-mix(in srgb, var(--ds-acao) 25%, #fff); }
.cw-forma-entregues   { background: color-mix(in srgb, var(--ds-acao) 60%, #fff); }
.cw-forma-lidos       { background: var(--ds-acao); }
.cw-forma-responderam { background: var(--ds-sucesso); }
.cw-rotulo { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: .45rem; pointer-events: none; }
.cw-rotulo > * { background: rgba(255,255,255,.92); }
.cw-valor { font-size: var(--fonte-destaque); font-weight: 500; color: var(--ds-tinta); font-variant-numeric: tabular-nums; padding: .05rem .55rem; }
.cw-rotulo-nome { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); padding: .15rem .55rem; }
.cw-taxa { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ds-acao-hover); padding: .18rem .5rem; font-variant-numeric: tabular-nums; }
.cw-estagio:last-child .cw-taxa { color: var(--ds-positivo); }
.cw-junta { display: flex; justify-content: center; padding: .3rem 0; }
.cw-junta-texto { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }

/* ritmo diário */
.cw-ritmo { margin-top: 1.5rem; }
.cw-ritmo-cabecalho { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .4rem; }
.cw-ritmo-titulo { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--ds-tinta-2); }
.cw-ritmo-legenda { font-size: var(--fonte-pequena); color: var(--ds-tinta-2); }
.cw-dot { display: inline-block; width: 8px; height: 8px; vertical-align: baseline; }
.cw-dot-envio { background: color-mix(in srgb, var(--ds-acao) 40%, #fff); }
.cw-dot-resposta { background: var(--ds-sucesso); }
.cw-trilha { display: flex; align-items: flex-end; gap: 5px; height: 72px; border-bottom: 1px solid var(--ds-filete); }
.cw-dia { position: relative; flex: 1 1 0; max-width: 26px; height: 100%; display: flex; align-items: flex-end; cursor: default; }
.cw-col-envio { width: 100%; background: color-mix(in srgb, var(--ds-acao) 40%, #fff); min-height: 2px; }
.cw-col-resposta { position: absolute; bottom: 0; left: 25%; width: 50%; background: var(--ds-sucesso); }
.cw-dia-rotulo { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); font-size: var(--fonte-pequena); color: var(--ds-tinta-3); padding-top: 3px; font-variant-numeric: tabular-nums; }
.cw-dia:hover .cw-col-envio { background: color-mix(in srgb, var(--ds-acao) 60%, #fff); }

/* conversas */
.cw-respostas { border-top: 1px solid var(--ds-filete); padding-top: 1.25rem; }
/* A lista de conversas cresce sem fim (50 respostas) e empurrava a página para
   baixo do funil. Na coluna, ela gruda abaixo da topbar (sticky, 52px) e rola
   por dentro: o funil fica no lugar enquanto se percorre as conversas. */
@media (min-width: 992px) {
  .cw-respostas { border-top: 0; border-left: 1px solid var(--ds-filete); padding: 0 0 0 2.25rem;
                  position: sticky; top: calc(52px + 1.75rem);
                  max-height: calc(100vh - 52px - 3.5rem); display: flex; flex-direction: column; }
  .cw-respostas ul { overflow-y: auto; overscroll-behavior: contain; padding-right: .35rem; }
}
.cw-respostas h2 { font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -.02em; color: var(--ds-tinta); display: flex; align-items: baseline; gap: .5rem; margin: 0; }
.cw-contagem { font-size: var(--fonte-corpo); font-weight: 400; letter-spacing: 0; color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.cw-respostas-hint { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); margin: .3rem 0 1.1rem; }
.cw-respostas ul { list-style: none; margin: 0; padding: 0; }
.cw-resposta { display: flex; align-items: center; gap: .8rem; padding: .7rem .25rem; }
.cw-resposta + .cw-resposta { border-top: 1px solid var(--ds-filete); }
.cw-avatar { flex: none; width: 36px; height: 36px; background: color-mix(in srgb, var(--ds-sucesso) 12%, #fff); color: var(--ds-positivo); font-size: var(--fonte-corpo); font-weight: 500; display: flex; align-items: center; justify-content: center; }
.cw-quem { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cw-quem strong { color: var(--ds-tinta); font-size: var(--fonte-corpo); font-weight: 500; }
.cw-texto-resposta { display: block; margin-top: .2rem; font-size: var(--fonte-corpo); color: var(--ds-tinta); }
.cw-resposta-optout .cw-texto-resposta { color: var(--ds-perigo); }
.cw-detalhe { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
/* Ação secundária = contorno no azul de ação. */
.cw-resposta-optout .cw-avatar { background: var(--ds-filete); color: var(--ds-tinta-3); }
.cw-resposta-optout .cw-quem strong { color: var(--ds-tinta-3); text-decoration: line-through; }

/* conversa (gaveta) — o Four Cloud é o proxy de leitura da UazAPI, porque o
   link wa.me exigia o WhatsApp Web logado com o número da Four */
.cw-fundo { position: fixed; inset: 0; background: rgba(22, 22, 22, .5); z-index: 1040; }
.cw-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(430px, 100vw); background: #fff; z-index: 1050; display: flex; flex-direction: column; box-shadow: -8px 0 28px rgba(22, 22, 22, .22); }
.cw-drawer-cabecalho { flex: none; display: flex; align-items: center; gap: .75rem; padding: 1rem 1.1rem; border-bottom: 1px solid var(--ds-filete); }
.cw-drawer-cabecalho > strong { flex: 1; min-width: 0; font-size: var(--fonte-destaque); font-weight: 500; letter-spacing: -.02em; color: var(--ds-tinta); }
.cw-drawer-quem { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cw-drawer-quem strong { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ds-tinta); }
.cw-drawer-quem span { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.cw-thread { flex: 1; overflow-y: auto; padding: 1rem 1.1rem 1.4rem; background: #fff; display: flex; flex-direction: column; gap: .35rem; }
/* Separador de dia = eyebrow, sem caixa. */
.cw-thread-dia { align-self: center; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--ds-tinta-3); margin: .8rem 0 .35rem; }
.cw-balao { max-width: 84%; padding: .5rem .7rem; font-size: var(--fonte-corpo); color: var(--ds-tinta); white-space: pre-wrap; word-break: break-word; }
.cw-balao-lead { align-self: flex-start; background: #fff; border: 1px solid var(--ds-filete); }
.cw-balao-nos { align-self: flex-end; background: var(--ds-acao-tinta); border: 1px solid transparent; }
.cw-balao-hora { display: block; margin-top: .2rem; font-size: var(--fonte-pequena); color: var(--ds-tinta-2); text-align: right; font-variant-numeric: tabular-nums; }
.cw-thread-aviso { margin: auto; text-align: center; font-size: var(--fonte-corpo); color: var(--ds-tinta-2); padding: 2rem 1rem; }
.cw-responder { flex: none; display: flex; gap: .5rem; align-items: flex-end; padding: .7rem .9rem; border-top: 1px solid var(--ds-filete); background: #fff; }
.cw-responder textarea { flex: 1; resize: none; max-height: 120px; }
.cw-erro { flex: none; margin: 0; padding: .5rem .95rem .8rem; font-size: var(--fonte-corpo); color: var(--ds-perigo); background: #fff; }
@media (max-width: 575.98px) { .cw-drawer { width: 100vw; } }

.cw-vazio { padding: 3rem 0; color: var(--ds-tinta); }
.cw-vazio-sub { font-size: var(--fonte-corpo); color: var(--ds-tinta-2); }

@media (max-width: 575.98px) {
  .cw-page { padding: 1.25rem 1rem 2.5rem; }
  .cw-forma { height: 48px; }
  .cw-detalhe { white-space: normal; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DESPESAS — DIAGNÓSTICO DE INCONSISTÊNCIAS
   Escopo: /despesas/ apenas. Faixa-resumo (reaproveita .destaque dos alertas),
   offcanvas de tratamento e a flag por linha das duas tabelas. Zero token
   global tocado — todo seletor daqui para baixo é prefixado `diag-`, lido só
   por bi/templates/bi/despesas.html + bi/static/bi/js/despesas.js.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Flag por linha — bandeira desenhada em CSS (mastro + pano) para não depender
   de ícone: cinza vazada = linha limpa e marcável, âmbar cheia = heurística
   aberta, vermelha cheia = marca manual, apagada = linha sem documento. */
.diag-celula { width: 38px; text-align: center; vertical-align: middle; }
.diag-flag {
  position: relative; display: inline-block; width: 14px; height: 15px;
  padding: 0; border: 0; background: none; cursor: pointer; vertical-align: middle;
}
.diag-flag::before {
  content: ""; position: absolute; left: 1px; top: 0; bottom: 0;
  width: 2px; border-radius: 1px; background: var(--ink-4);
}
.diag-flag::after {
  content: ""; position: absolute; left: 3px; top: 1px; width: 9px; height: 8px;
  border: 1.5px solid var(--ink-4); border-left: 0; border-radius: 0 2px 2px 0;
}
.diag-flag:hover::before, .diag-flag:focus-visible::before { background: var(--ink-2); }
.diag-flag:hover::after, .diag-flag:focus-visible::after { border-color: var(--ink-2); }
.diag-flag--heuristica::before { background: var(--warning); }
.diag-flag--heuristica::after { border-color: var(--warning); background: var(--warning); }
.diag-flag--manual::before { background: var(--negative); }
.diag-flag--manual::after { border-color: var(--negative); background: var(--negative); }
.diag-flag--inerte { cursor: default; opacity: .3; }

/* Offcanvas — largo por pedido do dono: tratar inconsistência é a tarefa da
   vez, não nota de rodapé. Vai pela VARIÁVEL do Bootstrap, como as gavetas do
   CRM (.crm-oc--larga): `width` solto empata em especificidade com
   `.offcanvas-end` e perdia — o painel ficava nos 400px do padrão por mais que
   a regra dissesse 480 ou 960. */
.diag-offcanvas { --bs-offcanvas-width: min(1920px, 94vw); }
.diag-offcanvas .offcanvas-body {
  display: flex; flex-direction: column; gap: .75rem;
  container: diag-painel / inline-size;
}

/* Os 4 indicadores ficam numa linha só, com teto de largura: esticar cada
   um para 470px deixaria número pequeno boiando em caixa gigante. */
.diag-indicadores {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 16rem));
  justify-content: start; gap: .5rem;
}
.diag-indicador {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .45rem .6rem; border-radius: var(--r-sm); background: var(--surf-2);
}
.diag-indicador__rotulo {
  font-size: var(--fonte-rotulo); text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3);
}
.diag-indicador__valor { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); }

.diag-erro { margin: 0; font-size: var(--fonte-corpo); color: var(--negative-text); }

.diag-marcar {
  display: flex; flex-direction: column; gap: .4rem;
  padding: .7rem .8rem; border: 1px solid var(--line-3); border-radius: var(--r-sm); background: var(--surf);
}
.diag-marcar__titulo { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); }

/* A grade. A lista de <details> empilhados saiu: quem ordena, filtra e soma é
   o DataTables padrão da casa (opt-in por `.tbl-wrapper.datatable` no wrapper —
   sem essa classe a toolbar, a rolagem e a paginação ficam sem estilo e se
   sobrepõem à tabela). O corpo do painel é uma coluna e só a GRADE rola: o
   cabeçalho de filtros tem de continuar ao alcance com 187 linhas embaixo. */
/* Barra de "Limpar filtros" + aviso de omitidas: os dois nascem escondidos, e
   sem altura mínima ela não abre uma faixa vazia entre indicadores e grade. */
.diag-barra { display: flex; align-items: center; gap: .75rem; }
.diag-barra:not(:has(> :not([hidden]):not(.d-none))) { display: none; }
.diag-corpo .tbl-wrapper { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.diag-corpo .dataTables_wrapper { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.diag-corpo .datatable-scroll { flex: 1 1 auto; min-height: 0; max-height: none; }
.diag-controle { width: 28px; text-align: center; }
/* Chevron de abrir/fechar o detalhe: o ícone do app, que gira ao abrir. */
.diag-abrir {
  width: 20px; height: 20px; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--ink-3); font-size: var(--fonte-pequena); line-height: 20px; transition: transform .12s ease;
}
#bi-diagnostico-tabela tbody tr { cursor: pointer; }
.diag-linha--aberta .diag-abrir { transform: rotate(90deg); color: var(--ink); }
/* A linha aberta é a âncora do dossiê logo abaixo: precisa se destacar da
   zebra, senão o cartão parece solto no meio da lista. */
.diag-linha--aberta > td {
  background: var(--acc-soft) !important; font-weight: 500;
  border-top: 1px solid var(--acc-line); border-bottom: 0;
}

/* A LINHA-FILHA é o dossiê da inconsistência, e não pode parecer "mais uma
   linha": vira um cartão embutido, com barra de acento à esquerda na cor do
   tipo, provas à esquerda e conversa à direita. Sem o cartão, motivo, provas e
   caixa de texto ficavam boiando entre duas linhas zebradas. */
/* `.child` é a classe que o próprio DataTables carimba na linha-filha. */
#bi-diagnostico-tabela tbody tr.child > td { padding: 0; background: var(--surf-2); }
.diag-item__corpo {
  display: grid; gap: .6rem 1.5rem; grid-template-columns: minmax(0, 1fr);
  margin: .35rem .5rem .6rem 2rem; padding: .7rem .9rem;
  border: 1px solid var(--line); border-left: 3px solid var(--warning);
  border-radius: var(--r-sm); background: var(--surf);
}
.diag-item__corpo .diag-motivo, .diag-item__corpo .diag-obs { grid-column: 1 / -1; }
@container diag-painel (min-width: 900px) {
  .diag-item__corpo { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
}
.diag-item__meta { font-size: var(--fonte-pequena); color: var(--ink-3); }

/* O motivo: a frase que diz POR QUE a linha caiu, com as provas dentro. Abre o
   corpo do item porque é a primeira pergunta de quem abre. */
.diag-motivo {
  margin: 0; padding: .45rem .6rem; border-radius: var(--r-sm);
  background: var(--warning-subtle); color: var(--warning-text);
  font-size: var(--fonte-corpo); line-height: 1.2;
}

/* Descrição da despesa (observação, ou histórico na falta dela): é a prova do
   obs_diverge — quem julga a inconsistência precisa ler o texto que citou a
   outra NF. Ocupa a linha inteira, acima das duas colunas. */
.diag-obs {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .35rem .5rem; border-radius: var(--r-sm); background: var(--surf-2);
}
.diag-obs__rotulo {
  flex: 0 0 auto; font-size: var(--fonte-rotulo); text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-3); font-weight: 500;
}
.diag-obs__texto { font-size: var(--fonte-corpo); color: var(--ink); overflow-wrap: anywhere; }

/* Dados da despesa: rótulo em cima, valor embaixo. Era uma linha corrida de
   texto cinza ("conta · doc X · data") que ninguém lia. */
.diag-dados {
  margin: 0; display: grid; gap: .5rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.diag-dado { display: flex; flex-direction: column; gap: .05rem; min-width: 0; }
.diag-dado > dt {
  font-size: var(--fonte-rotulo); text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-3); font-weight: 500;
}
.diag-dado > dd {
  margin: 0; font-size: var(--fonte-corpo); color: var(--ink);
  overflow-wrap: anywhere;
}
/* Teto na conversa: caixa de comentário de 1000px é pior de ler que uma de
   700px — o texto vira uma linha só e o olho perde o retorno. */
.diag-conversa { display: flex; flex-direction: column; gap: .5rem; min-width: 0; max-width: 46rem; }

/* Duas colunas a partir de 900px de OFFCANVAS (container query: a largura que
   importa é a do painel, não a da janela). */
@container diag-painel (min-width: 900px) {
  .diag-item__corpo {
    display: grid; grid-template-columns: 1fr minmax(28rem, 46rem);
    column-gap: 1.5rem; align-items: start;
  }
  .diag-motivo, .diag-obs { grid-column: 1 / -1; }
  .diag-dados { grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); }
}

.diag-pilula {
  flex-shrink: 0; padding: .1rem .45rem; border-radius: var(--r-full);
  font-size: var(--fonte-pequena); font-weight: 500; white-space: nowrap;
}
.diag-pilula--heuristica { background: var(--warning-subtle); color: var(--warning-text); }
.diag-pilula--manual { background: var(--negative-subtle); color: var(--negative-text); }

.diag-feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.diag-comentario {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .35rem .5rem; border-radius: var(--r-sm); background: var(--surf-2);
  font-size: var(--fonte-corpo); color: var(--ink); white-space: pre-wrap; word-break: break-word;
}
.diag-comentario__meta { font-size: var(--fonte-pequena); color: var(--ink-3); }
.diag-comentario--vazio { background: none; padding: 0; color: var(--ink-3); font-size: var(--fonte-pequena); }

.diag-acoes { display: flex; gap: .4rem; justify-content: flex-end; }

/* Indicador que tem lista atrás vira botão de verdade (abertas, resolvidas,
   falsos positivos). Impacto e idade média continuam texto — não há balde para
   abrir. O ativo se declara pela borda, não por fundo colorido: o painel já é
   denso. */
.diag-indicador--balde {
  border: 1px solid transparent; text-align: left; cursor: pointer;
  font: inherit; color: inherit;
}
.diag-indicador--balde:hover { border-color: var(--line-3); }
.diag-indicador--balde.is-ativo { border-color: var(--acc); background: var(--surf); }

/* Linha já apontada abre o painel inteira — a bandeira de 12px não é o único
   alvo. Linha limpa segue sem cursor: nela só a bandeira marca. */
.diag-linha { cursor: pointer; }
.diag-linha:hover { background: var(--surf-2); }

@media (max-width: 575.98px) { .diag-offcanvas { --bs-offcanvas-width: 100vw; } }

/* ==========================================================================
   BAIXA DE RETORNO BANCÁRIO — /conferencia-retorno/
   ==========================================================================
   A tela é um CANO, lido de cima para baixo. Duas bocas alimentam (portal e
   arquivo do computador), o arquivo se reparte em veredito, e o dinheiro cai
   numa conta de tesouraria. A espinha da esquerda é o processo desenhado:
   chega e vê os três nós, só o primeiro aceso.

   NADA NAVEGA. Conferir não troca de tela — os nós acendem, o conteúdo cresce
   embaixo, e o que já passou encolhe numa linha e continua visível. O operador
   nunca perde de vista qual arquivo está conferindo.

   ESCOPO DE PÁGINA. Tudo aqui é `ret-`, inclusive o que no experimento não era
   (`.no`, `.boca`, `.barra`, `.selo`…): sem prefixo, `.destino` ou `.conta`
   vazariam para as outras 27 telas. Nenhum token global é redefinido — a
   paleta de papel/carbono vive em `--ret-*` sob o seletor da página.

   A TIPOGRAFIA é a `--sans` do app (Roboto). O experimento
   (`/static/bi/demo/retorno-fluxo.html`) usa Archivo; trocar exigiria carregar
   uma segunda webfont no `<head>` global, que é mudança global — fica de fora
   até o dono pedir.

   CONTRASTE: `--ret-tinta-3` (#8A909C) é tinta de APOIO e de valor apagado,
   nunca de dado que precise ser lido ao centavo. Texto pequeno normal usa
   `--ret-tinta-2` (#5C6270), que passa AA sobre o papel.                     */

.page[data-pagina="retorno_conferencia"] {
  --ret-papel: #F1F2EE;
  --ret-painel: #FFFFFF;
  --ret-tinta: #171B24;
  --ret-tinta-2: #5C6270;
  --ret-tinta-3: #8A909C;
  --ret-regua: #DEE0D9;
  --ret-regua-forte: #C7CAC1;
  /* Espinha e nó aceso usam o MESMO azul dos botões do app: dois azuis na
     mesma tela é família misturada, que é o que a regra proíbe. */
  --ret-carbono: var(--acc-ink);
  --ret-carbono-claro: var(--acc-soft);
  --ret-confere: #3F6B4E;
  --ret-aberto: #B0761B;
  --ret-diverge: #AE3126;
  --ret-info: #8A909C;
  --ret-raio: 3px;

  background: var(--ret-papel);
  color: var(--ret-tinta);
  font-variant-numeric: tabular-nums;
}

/* Cadeia de altura: page → fluxo → estação da grade → grade. Um elo sem
   `min-height:0` faz o scroller interno sumir e a PÁGINA voltar a rolar. */
.ret-cabeca {
  flex: 0 0 auto; display: flex; align-items: baseline; gap: 1rem;
  padding-block: var(--bi-space-sm) var(--bi-space-sm);
  border-bottom: 1px solid var(--ret-regua);
}
.ret-cabeca h1 {
  margin: 0; font-size: var(--fonte-destaque); font-weight: 500;
  letter-spacing: -.01em; color: var(--ret-tinta);
}
.ret-cabeca__sub { color: var(--ret-tinta-2); font-size: var(--fonte-corpo); }
.ret-cabeca__fim { margin-left: auto; }

/* ── O cano ─────────────────────────────────────────────────────────────── */
.ret-fluxo {
  flex: 1 1 auto; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; padding-bottom: var(--bi-space-md);
  position: relative;
}
.ret-estacao {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 3rem 1fr; align-items: start;
  padding-top: var(--bi-space-lg);
}
/* A linha contínua é o que diz "isto é UM caminho", não três cartões
   empilhados. Cada estação pinta o próprio trecho — assim ela nasce no
   primeiro nó e MORRE no último, em vez de descer pendurada no vazio. */
.ret-estacao::before {
  content: ''; position: absolute; left: 8px; top: 0; bottom: 0; width: 2px;
  background: var(--ret-regua); z-index: 0;
}
.ret-estacao:first-of-type::before { top: 1.65rem; }
.ret-estacao:last-of-type::before { bottom: auto; height: 1.65rem; }
/* A estação da grade é a que cede altura — mas só depois de acordar. Dormindo
   ela reservava a janela inteira e abria um buraco morto entre os nós. */
.ret-estacao--grade { flex: 1 1 auto; min-height: 0; align-items: stretch; }
.ret-estacao--grade.ret-dorme { flex: 0 0 auto; align-items: start; }
.ret-estacao--grade > .ret-no { align-self: start; }

/* O nó: vazado (não chegou), sólido (é a vez), com visto (já passou). O visto
   é `fa-solid fa-check` — desenhá-lo com duas bordas rotacionadas nascia fora
   do centro. */
.ret-no {
  grid-column: 1; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--ret-regua-forte); background: var(--ret-papel);
  margin-top: .15rem; position: relative;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .25s, background .25s;
}
.ret-estacao.ret-viva > .ret-no { border-color: var(--ret-carbono); background: var(--ret-carbono); }
.ret-estacao.ret-viva > .ret-no::after {
  content: ''; position: absolute; inset: 4px; border-radius: 50%;
  background: var(--ret-painel);
}
.ret-estacao.ret-feita > .ret-no { border-color: var(--ret-carbono); background: var(--ret-painel); }
.ret-no__v { display: none; font-size: var(--fonte-pequena); line-height: 1; color: var(--ret-carbono); }
.ret-estacao.ret-feita .ret-no__v { display: block; }

.ret-corpo {
  grid-column: 2; min-width: 0; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column;
  /* âncora do "Recomeçar", que fica no alto da estação em qualquer das fases */
  position: relative;
}
.ret-estacao h2 {
  margin: 0 0 .15rem; font-size: var(--fonte-corpo); font-weight: 500;
  letter-spacing: -.005em; color: var(--ret-tinta);
}
.ret-estacao.ret-dorme h2 { color: var(--ret-tinta-3); }
/* Estação dormindo mostra só o próprio nome: as linhas de apoio que explicavam
   cada etapa foram removidas a pedido do dono. */
.ret-estacao h2 + * { margin-top: .8rem; }
.ret-estacao.ret-dorme .ret-corpo > :not(h2) { display: none; }

/* ── Estação 1: UMA lista de origens ───────────────────────────────────────
   Antes eram duas bocas lado a lado com um "ou" no meio, e a operação leu como
   duas coisas soltas: escolhia o Banco do Brasil e em seguida tentava clicar em
   "escolher arquivo". Agora é uma lista só — portal e envio manual são linhas
   irmãs, e a escolha de uma exclui a outra por construção. */
.ret-origens {
  background: var(--ret-painel); border: 1px solid var(--ret-regua);
  border-radius: var(--ret-raio); max-width: 56rem; padding: .35rem 1.15rem;
}
.ret-boca__s { font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
.ret-boca__n { font-size: var(--fonte-pequena); color: var(--ret-tinta-3); }
/* Recomeçar mora no alto da estação, fora do fluxo das duas fases: ele existe
   tanto antes de carregar (errei o arquivo) quanto depois (era outro dia). Não
   é botão cinza: cinza, nesta casa, quer dizer desabilitado. */
.ret-recomecar {
  position: absolute; top: 0; right: 0; padding: 0; border: 0; background: none;
  font: inherit; font-size: var(--fonte-pequena); color: var(--ret-tinta-2);
  text-decoration: underline; cursor: pointer;
}
.ret-recomecar:hover { color: var(--ret-carbono); }

/* Instituição é ETAPA, não rótulo. Hoje só a Multiplike tem conector, mas a
   escolha existe desde já: quando forem seis, a tela não muda de forma — muda
   de tamanho. */
.ret-inst { border-top: 1px solid var(--ret-regua); }
.ret-inst:first-of-type { border-top: 0; }
.ret-inst__cab {
  display: flex; align-items: baseline; gap: .6rem; width: 100%; text-align: left;
  padding: .45rem .1rem; background: none; border: 0; font: inherit;
  cursor: pointer; color: var(--ret-tinta);
}
.ret-inst__cab:hover { color: var(--ret-carbono); }
.ret-inst__n { font-size: var(--fonte-corpo); font-weight: 500; }
.ret-inst.is-aberta .ret-inst__n { color: var(--ret-carbono); }
.ret-inst__r { margin-left: auto; font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
/* A marca ocupa o lugar do nome da instituição — mesma altura da linha de texto
   que ela substitui, para o cabeçalho não crescer. `align-self` porque a linha
   alinha por baseline, e imagem não tem baseline. */
/* CAIXA ÚNICA PARA TODA MARCA. As marcas têm proporções muito diferentes — o
   Banco do Brasil é uma faixa (7:1), a Multiplike é um lockup de duas linhas
   (4:1). Igualando só a ALTURA, o BB ficava duas vezes mais largo e a lista
   parecia desalinhada; igualando só a largura, o "(Portal)" da Multiplike
   fechava. A caixa fixa com `contain` normaliza as duas pela ÁREA: cada uma
   cresce até tocar o lado que a limita, e nenhuma distorce. Alinhadas à
   esquerda porque é por ali que o olho desce a lista. */
.ret-inst__logo {
  width: 8.5rem; height: 2.1rem; display: block; align-self: center;
  object-fit: contain; object-position: left center;
}
.ret-inst__cab:has(.ret-inst__logo) { padding-top: .25rem; padding-bottom: .25rem; }
.ret-inst__carteiras { display: none; }
/* O filete à esquerda repete, em miniatura, a espinha da página: as carteiras
   PENDEM da instituição, não são irmãs dela. */
.ret-inst.is-aberta .ret-inst__carteiras {
  display: flex; flex-direction: column; gap: .1rem;
  margin: 0 0 .5rem .35rem; padding-left: .65rem; border-left: 2px solid var(--ret-regua);
}

/* Carteira e data dividem uma linha. A data ocupa a MESMA caixa com e sem
   seletor: carteira de uma data só não pode desalinhar a coluna. */
.ret-carteira-linha { display: flex; align-items: center; gap: .5rem; }
/* #513: ao lado do "Buscar boletos" a situação ("Buscando boletos: 120 de 222") é frase, não a coluna da data */
.ret-carteira-linha .ret-carteira__d { width: auto; text-align: left; }
.ret-carteira {
  flex: 1 1 auto; display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
  padding: .4rem .55rem; border: 1px solid transparent; border-radius: var(--ret-raio);
  background: none; font: inherit; color: var(--ret-tinta-2); cursor: pointer;
}
.ret-carteira:hover { background: #F6F7F4; }
.ret-carteira.is-escolhida {
  border-color: var(--ret-carbono); background: var(--ret-carbono-claro); color: var(--ret-tinta);
}
.ret-carteira__n { font-size: var(--fonte-corpo); color: var(--ret-tinta); }
.ret-carteira.is-escolhida .ret-carteira__n { font-weight: 500; }
.ret-carteira__q { margin-left: auto; font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
/* A data ocupa a MESMA caixa com e sem seletor: carteira de uma data só não
   pode desalinhar a coluna. */
/* 8,5rem porque a data é dd/mm/aaaa E o `form-select` reserva o espaço da
   seta à direita: a 7rem o ano ficava por baixo dela. */
.ret-carteira__d, .ret-carteira__datas {
  flex: 0 0 auto; width: 8.5rem; font-size: var(--fonte-pequena);
  color: var(--ret-tinta-2); text-align: right;
}
.ret-carteira__d { padding-right: .3rem; }
.ret-carteira__datas { padding-block: .1rem; }

/* O input de arquivo fica TRANSPARENTE cobrindo a área inteira: o rótulo é
   nosso e em português, e o arrastar-e-soltar continua sendo o do navegador —
   esconder o input mataria a soltura. */
.ret-solta {
  position: relative; flex: 1 1 auto; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .5rem; padding: 1rem;
  border: 1px dashed var(--ret-regua-forte); border-radius: var(--ret-raio);
  color: var(--ret-tinta-2); font-size: var(--fonte-corpo); text-align: center;
}
.ret-solta strong { font-weight: 400; color: var(--ret-tinta); }
.ret-solta .ret-file {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer; font-size: 0;
}
.ret-solta .ret-file:focus-visible ~ .btn { box-shadow: var(--ring); }
.ret-file-nome {
  max-width: 100%;
  font-size: var(--fonte-pequena); color: var(--ret-tinta-2);
}
/* O painel do envio manual respira mais que uma lista de carteiras: são três
   coisas diferentes empilhadas (arquivo, banco, limites), não itens de lista. */
.ret-inst--manual.is-aberta .ret-inst__carteiras { gap: .55rem; padding-bottom: .5rem; }
.ret-leiaute { display: flex; align-items: center; gap: .6rem; }
.ret-leiaute__t { font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
/* 12.5rem, não 9: "Detectar pelo arquivo" é a opção padrão e cortava em
   "Detectar pelo arquivc" — visto no preview em 08/09/2026. */
.ret-leiaute .form-select { flex: 0 0 auto; width: 12.5rem; }
/* A PERGUNTA DO BANCO tem peso de pergunta, não de rodapé: o rótulo sai do
   micro cinza do leiaute e o campo cresce, porque nele cabe "COOPERATIVA
   CENTRAL DE CRÉDITOS – AILOS (085)". É a única coisa que a estação 1 pede
   além do arquivo. */
.ret-banco { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.ret-banco__t {
  font-size: var(--fonte-corpo); color: var(--ret-tinta);
  font-weight: 500;
}
.ret-banco .form-select { flex: 1 1 16rem; min-width: 0; max-width: 26rem; }
/* Detalhe técnico dobrado: fechado é uma linha discreta, aberto é o seletor de
   leiaute com o mesmo desenho de antes. */
.ret-avancado > summary {
  font-size: var(--fonte-pequena); color: var(--ret-tinta-2);
  cursor: pointer; width: fit-content; padding: .1rem 0;
}
.ret-avancado > summary:hover { color: var(--ret-tinta); }
.ret-avancado[open] > summary { margin-bottom: .45rem; }
.ret-acao { margin-top: .9rem; }

/* O que já passou fica na tela, encolhido: a estação cumprida troca a lista de
   origens por uma linha com o arquivo escolhido. */
.ret-estacao.ret-feita .ret-origens,
.ret-estacao.ret-feita .ret-acao { display: none; }
.ret-origem-fina { display: none; }
.ret-estacao.ret-feita .ret-origem-fina {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  font-size: var(--fonte-corpo); color: var(--ret-tinta-2);
}
.ret-origem-fina .ret-dado { color: var(--ret-tinta); }

/* ── Estação 2: o arquivo se repartindo ─────────────────────────────────── */
.ret-medida { display: flex; align-items: baseline; gap: .7rem; margin-bottom: .65rem; }
.ret-medida__v {
  font-size: var(--fonte-heroi); font-weight: 500;
  letter-spacing: -.02em; line-height: 40px;
}
.ret-medida__q { font-size: var(--fonte-corpo); color: var(--ret-tinta-2); }
.ret-medida__f { margin-left: auto; font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }

/* A barra só é desenhada quando há MAIS DE UMA faixa (decidido no JS a partir
   de `kpis.faixas`, que o backend já somou): com uma faixa só ela vira uma
   tira de cor inteira dizendo o que a legenda já disse. */
.ret-barra { display: flex; height: 10px; border-radius: 2px; overflow: hidden; background: var(--ret-regua); }
.ret-naco { height: 100%; width: 0; transition: width .55s cubic-bezier(.22,.61,.36,1); }
.ret-naco--confere { background: var(--ret-confere); }
.ret-naco--aberto_no_erp { background: var(--ret-aberto); }
.ret-naco--baixa_divergente,
.ret-naco--encargo_nao_lancado,
.ret-naco--valor_divergente { background: var(--ret-diverge); }
.ret-naco--ambiguo, .ret-naco--nao_encontrado { background: var(--ret-info); }

.ret-chaves { display: flex; gap: 1.4rem; margin: .5rem 0 1rem; flex-wrap: wrap; }
.ret-chave {
  display: flex; align-items: baseline; gap: .4rem;
  font-size: var(--fonte-corpo); color: var(--ret-tinta-2);
}
.ret-chave::before { content: ''; width: 8px; height: 8px; border-radius: 2px; flex: 0 0 auto; }
.ret-chave b { font-weight: 500; color: var(--ret-tinta); }
.ret-chave--confere::before { background: var(--ret-confere); }
.ret-chave--aberto_no_erp::before { background: var(--ret-aberto); }
.ret-chave--baixa_divergente::before,
.ret-chave--encargo_nao_lancado::before,
.ret-chave--valor_divergente::before { background: var(--ret-diverge); }
.ret-chave--ambiguo::before, .ret-chave--nao_encontrado::before { background: var(--ret-info); }
.ret-chave--aviso::before { background: var(--ret-info); opacity: .45; }

/* ── A grade (a grade da casa, `static/js/grade.js`) ─────────────────────── */
/* Sem moldura: o dono já rejeitou caixa+fio em volta da lista no piloto
   (`grade-minimalista-sem-moldura`, reporte #27, 15/09/2026) — "piorou, quero
   EVITAR AO MÁXIMO MOLDURAS e linhas". O visual da grade (cabeçalho, fio,
   selo de estado) é o padrão da casa; esta página só liga o `.grade` à
   cadeia de altura do próprio "cano" (`.ret-corpo`/`.ret-pane`, que É
   `display:flex`): sem isto o `.dataTables_wrapper` não recebe altura e as
   linhas de baixo ficam recortadas pelo `overflow:hidden` do wrapper — o
   mesmo sintoma que a caixa antiga (`.ret-grade-cx`) existia para evitar.
   Visto ao vivo com o arquivo de 02/09. */
.page[data-pagina="retorno_conferencia"] .grade {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  /* Folha branca, sem moldura: o corpo da grade é transparente e nas outras
     telas a página já é branca. Aqui o papel da estação é `--ret-papel`
     (#F1F2EE) e vazava por trás das linhas. */
  background: var(--ret-painel);
}
/* A estação tem altura fixa (o cano mostra as outras estações embaixo), então
   quem sobra é o CORPO da lista: ele rola por dentro, com a barra, o cabeçalho
   e o pé sempre à vista. Mesma cadeia das telas de altura cheia; aqui escopada
   na página porque o cano não é `content--altura-cheia`. */
.page[data-pagina="retorno_conferencia"] .grade .tbl-wrapper {
  flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; flex-direction: column;
}
.page[data-pagina="retorno_conferencia"] .grade .dataTables_wrapper {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}
.page[data-pagina="retorno_conferencia"] .grade .datatable-scroll {
  flex: 1 1 auto; min-height: 0; max-height: none; overflow: auto;
}
.ret-cel { display: flex; flex-direction: column; line-height: 1.2; }
.ret-cel__sub { font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
/* Valor de aviso não é dinheiro que entrou: é o saldo do título, que o banco
   repete ao mudar um dado. Apagado para não competir com o herói. */
.ret-num--apagado { color: var(--ret-tinta-3); }
/* Observação/Impacto no ERP são as únicas colunas que se LEEM, mas quebrar o
   texto em três linhas triplicava a altura da linha e a estação, que é de
   altura fixa, passava a mostrar UMA linha da lista. Uma linha por título,
   com reticências e o texto inteiro no `title` da célula. */
.page[data-pagina="retorno_conferencia"] .grade .grade-tabela .ret-col-obs {
  min-width: 14rem;
}
.page[data-pagina="retorno_conferencia"] .grade .grade-tabela .ret-col-obs .grade-celula {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* A caixa de marcar é a da grade (`selecao`, reporte #200); aqui só a cor. */
.page[data-pagina="retorno_conferencia"] .grade-selecao { accent-color: var(--ret-carbono); }

/* O veredito da linha virou `.grade-status` (ponto + palavra) da grade da
   casa — ver `TOM_VEREDITO` em `conferencia-retorno.js`. O selo próprio
   (`.ret-selo`) saiu daqui em 16/09/2026; a barra/legenda da repartição
   (`.ret-naco`/`.ret-chave`, acima) continua com as cores por veredito. */

/* MARCA DO BANCO. Monograma, não logotipo: a marca oficial é arte de
   terceiro e não entra no repositório. A sigla e o `slug` vêm do backend
   (`retorno_conferencia.BANCOS`), então acrescentar um banco não mexe aqui —
   só quem quiser cor própria escreve a regra `--slug`. Sem slug, cinza neutro. */
.ret-marca {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.6rem; height: 1.6rem; padding: 0 .45rem;
  border-radius: var(--ret-raio); border: 1px solid var(--ret-regua);
  background: #fff; color: var(--ret-tinta-2);
  font-size: var(--fonte-pequena); font-weight: 500;
  letter-spacing: .02em; line-height: 1;
}
.ret-marca--bb { background: #fbe64a; border-color: #e6d02f; color: #12467f; }
.ret-marca--itau { background: #ec7000; border-color: #d16400; color: #fff; }
/* A marca vive DENTRO do `#ret-origem-dita`, então o `gap` da linha não a
   separa do texto que vem depois — a margem é dela mesma. */
.ret-origem-fina .ret-marca { margin-right: .55rem; }
/* Com logotipo a caixa some: a marca já é a forma. Altura fixa e largura livre
   porque as marcas são horizontais e cada uma tem sua proporção. */
/* Mesma caixa da lista, em miniatura: a marca na linha de origem e na conta de
   destino ocupa sempre o mesmo espaço, seja qual for a proporção do logotipo. */
.ret-marca--img {
  width: 5.4rem; height: 1.35rem; min-width: 0; padding: 0;
  border: 0; background: none; border-radius: 0;
  object-fit: contain; object-position: left center;
}

/* ── Estação 3: para onde o dinheiro vai ────────────────────────────────── */
.ret-destino {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--ret-painel); border: 1px solid var(--ret-regua);
  border-radius: var(--ret-raio); padding: .8rem 1.1rem;
}
.ret-destino + .ret-destino { margin-top: var(--bi-space-sm); }
.ret-conta { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.ret-conta__n { font-size: var(--fonte-corpo); font-weight: 500; }
.ret-conta__d { font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
.ret-destino__fim { margin-left: auto; display: flex; align-items: center; gap: .9rem; }
/* Trocar a conta é decisão de dinheiro: fica na MESMA pilha do destino e logo
   acima do botão que escreve, não escondida numa estação anterior. */
.ret-troca { display: flex; align-items: center; gap: .75rem; width: 100%; min-width: 0; }
.ret-troca__t {
  flex: 0 0 auto; font-size: var(--fonte-pequena); color: var(--ret-tinta-2);
}
.ret-troca .form-select { max-width: 34rem; }
.ret-somatorio { text-align: right; font-size: var(--fonte-pequena); color: var(--ret-tinta-2); }
.ret-somatorio b {
  display: block; font-size: var(--fonte-destaque); color: var(--ret-tinta);
  font-weight: 500;
}

/* ── Botões: NÃO existem aqui ───────────────────────────────────────────
   Regra dura do dono: uma família de botão por tela, o azul de fábrica do
   Bootstrap — sólido para agir agora, contorno para navegar — e o desabilitado
   é o do próprio framework. Esta seção já teve uma família própria (carbono
   sólido + fantasma cinza + link sublinhado + `:disabled` pintado à mão): eram
   quatro aparências, e o cinza mentia dizendo "desabilitado" numa ação viável.
   Nada de botão mora mais aqui. Se aparecer `.ret-btn` de novo, é regressão. */

/* ── Baixas realizadas: a mesma casca, fora do cano ─────────────────────── */
.ret-pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
            padding-top: var(--bi-space-md); }
.ret-pane__topo {
  flex: 0 0 auto; display: flex; align-items: center; gap: var(--bi-space-sm);
  margin-bottom: var(--bi-space-sm); font-size: var(--fonte-corpo);
  color: var(--ret-tinta-2);
}
.ret-carteira:focus-visible, .ret-inst__cab:focus-visible {
  outline: 2px solid var(--ret-carbono); outline-offset: 2px;
}

/* ── Painel de confirmação (componente compartilhado) ─────────────────────
   O offcanvas que trava uma escrita no ERP (tipo C): o impacto em pares rótulo/valor, o total em
   destaque e Cancelar/Confirmar no rodapé. Nasceu na Conferência de Retorno (`ret-oc`) e é usado
   também pelo Processar DDA (#638):
     <div class="offcanvas offcanvas-end painel-confirmacao">…<div class="offcanvas-body">
       <dl class="painel-confirmacao__impacto"><dt>Total</dt><dd class="painel-confirmacao__forte">…</dd></dl>
     </div><div class="offcanvas-footer">Cancelar · Confirmar</div></div> */
.painel-confirmacao { --bs-offcanvas-width: 30rem; }
.painel-confirmacao .offcanvas-body { display: flex; flex-direction: column; gap: var(--bi-space-md); }
.painel-confirmacao .offcanvas-footer {
  display: flex; justify-content: flex-end; gap: var(--bi-space-sm);
  padding: var(--bi-space-md); border-top: 1px solid var(--line);
}
.painel-confirmacao__impacto {
  display: grid; grid-template-columns: auto 1fr; gap: .3rem var(--bi-space-md);
  margin: 0; font-size: var(--fonte-corpo);
}
.painel-confirmacao__impacto dt { color: var(--ink-2); font-weight: 400; }
.painel-confirmacao__impacto dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; }
.painel-confirmacao__forte { font-size: var(--fonte-destaque); font-weight: 500; }

/* ── Notas ─────────────────────────────────────────────────────────────── */
.ret-nota {
  flex: 0 0 auto; padding: var(--bi-space-sm) var(--bi-space-md);
  margin-top: var(--bi-space-sm); border-radius: var(--ret-raio);
  font-size: var(--fonte-corpo);
}
.ret-nota--aviso { background: #fef1dd; color: var(--warning-text); }
.ret-nota--erro  { background: var(--negative-subtle); color: var(--negative-text); }

@media (max-width: 900px) {
  /* A lista de origens já é uma coluna só — nada a empilhar aqui desde que as
     duas bocas viraram linhas irmãs. */
  .ret-troca { flex-wrap: wrap; }
  .ret-estacao { grid-template-columns: 2rem 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CURVA ABC  —  /curva-abc/
   Matriz mês × bitola (o desenho da aba `Curva ABC` da planilha Gerencial).
   Escopo de PÁGINA: nenhuma regra aqui vaza para fora de `.cabc`.
   ═══════════════════════════════════════════════════════════════════════════ */
/* A topbar fica FORA da `div.cabc` (bloco `topbar_actions` do base), então
   escopar em `.cabc .cabc-ano` não casa — a regra nunca aplicava e o
   `width:100%` do .form-select cobria o botão Fixadores. `.cabc-ano` é
   nome exclusivo desta página, então a regra nua continua page-scoped. */
.cabc-ano { flex: 0 0 auto; width: auto; min-width: 6rem; }

/* A tela usa a janela inteira — sem faixa morta no rodapé. O desconto é a
   topbar + o header do card, medidos, não chutados. */
.cabc-wrap { overflow: auto; max-height: calc(100vh - 9.5rem); }

.cabc-mx { width: 100%; border-collapse: separate; border-spacing: 0;
           font-size: var(--fonte-corpo); }
.cabc-mx th, .cabc-mx td { padding: .28rem .3rem; white-space: nowrap;
                           border-bottom: 1px solid var(--line-2); }

.cabc-mx thead th { position: sticky; top: 0; z-index: 2;
                    background: var(--surf-2); color: var(--ink-2);
                    font-weight: 500; text-align: right;
                    border-bottom: 1px solid var(--line); }
/* O cabeçalho gruda INTEIRO (`thead` sticky): as duas linhas sobem juntas, sem
   offset em rem por linha que não bate com a altura real (deixava 7 px de vão). */
.cabc-mx thead { position: sticky; top: 0; z-index: 5; }
.cabc-mx th.cabc-grupo { text-align: center; background: var(--surf-3);
                         color: var(--ink); border-left: 1px solid var(--line-3); }
.cabc-mx th.cabc-tot { background: var(--surf-3); }

/* Coluna do mês: congelada à esquerda, senão a matriz perde a âncora ao rolar. */
.cabc-mx th.cabc-mes { position: sticky; left: 0; z-index: 3;
                       background: var(--surf); text-align: left;
                       color: var(--ink); font-weight: 500;
                       border-right: 1px solid var(--line); }
.cabc-mx thead th.cabc-mes { z-index: 4; background: var(--surf-2); }

/* Cabeçalho de coluna: o MESMO componente da Gerencial (`gc-bh__*`), que já
   empilha total · barra · bitola · código · unidade. Os tokens `--gc-*` são
   declarados lá no contêiner `.gc`, então aqui eles são apontados para os
   mesmos valores globais — apontar é o que evita duplicar a regra do
   componente (e ele deixaria de ser um só, que é o ponto). */
.cabc { --gc-ink: var(--ink); --gc-ink-2: var(--ink-2); --gc-ink-3: var(--ink-3);
        --gc-line: var(--line); --gc-panel-3: var(--surf-2);
        --gc-green: var(--bs-success); --gc-red: var(--bs-danger); }
.cabc-mx th.cabc-bitola { vertical-align: bottom; text-align: right; }
/* A barra da Gerencial cresce dos DOIS lados de uma linha de zero (saldo pode
   ser negativo). Aqui a medida é volume do ano: cresce só para cima, a partir
   da base — sem linha de zero, que não teria o que separar. */
.cabc-mx .gc-bh__bar { height: 1.6rem; margin: .1rem 0 .15rem; }
.cabc-mx .gc-bh__bar b { left: 30%; right: 30%; bottom: 0; }
.cabc-mx .gc-bh__num { color: var(--ink); font-size: var(--fonte-corpo); }
.cabc-mx .gc-bh--dn .gc-bh__num { color: var(--negative-text); }
.cabc-mx .gc-bh__lbl { font-size: var(--fonte-corpo); }
.cabc-mx .gc-bh__und { line-height: 1.2; }
/* Verde na Gerencial quer dizer "saldo positivo". Aqui a barra mede TAMANHO da
   coluna no ano — não há bom nem ruim —, então ela usa a mesma família azul da
   rampa de participação do corpo, e não uma cor com opinião. */
.cabc-mx .gc-bh__bar b { background: var(--acc-line); }
.cabc-mx .gc-bh--dn .gc-bh__bar b { background: var(--negative-text); }
/* O código tem 8 dígitos e é ele que dita a largura da coluna: sem apertar a
   fonte dele, as 12 bitolas empurram Faturamento/Compra/Margem/Meta para fora
   da janela (medido: 137 px de sobra). */
.cabc-mx .gc-bh__cod { font-size: var(--fonte-pequena); letter-spacing: -0.04em; }
.cabc-mx th, .cabc-mx td { padding: .24rem .22rem; }

.cabc-mx td.cabc-num { text-align: right; font-variant-numeric: tabular-nums; }
.cabc-mx td.cabc-zero { color: var(--ink-4); }
.cabc-mx td.cabc-sub { background: var(--surf-2); font-weight: 500; }
.cabc-share { display: block; font-size: var(--fonte-pequena); font-weight: 400; color: var(--ink-3); }

/* O hover NÃO pode pintar o fundo: apagaria justo a tinta da linha que o
   leitor está lendo. Vira anel. */
.cabc-mx tbody tr:hover td { box-shadow: inset 0 -1px 0 var(--line-3), inset 0 1px 0 var(--line-3); }
.cabc-mx tbody tr:hover th.cabc-mes { background: var(--surf-3); }
.cabc-linha-vazia td, .cabc-linha-vazia th { color: var(--ink-4); }

.cabc-mx tfoot th, .cabc-mx tfoot td { background: var(--surf-2); }
.cabc-mx tfoot tr.cabc-total th, .cabc-mx tfoot tr.cabc-total td {
  background: var(--surf-3); font-weight: 500; color: var(--ink); }
.cabc-mx tfoot th.cabc-mes { background: var(--surf-3); }

.cabc-ok { color: var(--positive-text, #1a7f4b); }
.cabc-abaixo { color: var(--negative-text); }

/* ── Mira (hover acende linha + coluna) ──────────────────────────────────── */
/* `biUtils.ligarMira` marca as células; aqui a coluna vira um par de trilhos
   verticais, pelo mesmo motivo do hover de linha logo acima: pintar o fundo
   apagaria a rampa de participação, que é o dado da célula. */
.cabc-mx td.bi-mira-coluna, .cabc-mx tfoot th.bi-mira-coluna {
  box-shadow: inset 1px 0 0 var(--acc-line), inset -1px 0 0 var(--acc-line); }
/* Cruzamento: os trilhos da coluna + o anel da linha, num box-shadow só —
   a propriedade não acumula entre regras, a mais específica vence inteira. */
.cabc-mx tbody tr:hover td.bi-mira-coluna {
  box-shadow: inset 1px 0 0 var(--acc-line), inset -1px 0 0 var(--acc-line),
              inset 0 -1px 0 var(--line-3), inset 0 1px 0 var(--line-3); }
/* Cabeçalho: o fundo é chapado, então a coluna mirada pode receber a marca
   cheia — é o que diz de qual bitola são os trilhos. */
.cabc-mx thead th.bi-mira-coluna { background: var(--acc-soft); color: var(--ink); }
.cabc-mx thead th.cabc-grupo.bi-mira-coluna,
.cabc-mx thead th.cabc-tot.bi-mira-coluna { background: var(--acc-soft); }

.cabc-legenda { font-size: var(--fonte-corpo); color: var(--ink-3); }

/* ═══════════════════════════════════════════════════════════════════════════
   METAS POR VENDEDOR  —  /metas-vendedor/
   Quadro meta × realizado × atingimento por representante, em dois blocos
   (equipe interna e externos). Escopo de PÁGINA.
   ═══════════════════════════════════════════════════════════════════════════ */
.mvd-ano { flex: 0 0 auto; width: auto; min-width: 5.5rem; }
.mvd-eixo { flex: 0 0 auto; width: auto; min-width: 10rem; }
.mvd-salvar { flex: 0 0 auto; }
.mvd-base { flex: 0 0 auto; width: auto; min-width: 12rem; }

/* A tela usa a janela inteira: o card estica e a grade ocupa o que sobra, em vez
   de deixar faixa branca embaixo quando o mês tem poucos vendedores. */
.mvd .card { display: flex; flex-direction: column; min-height: calc(100vh - 6.5rem); }
.mvd .card-body { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.mvd-wrap { overflow: auto; flex: 1 1 auto; min-height: 0; }

/* Metas por Vendedor — gráficos */
/* Dois gráficos lado a lado (Faturado | Faturado + Previsto), um sobre o outro
   abaixo de 1200px. O cartão tem a altura do conteúdo: quem estica até o fim da
   janela é o cartão da tabela, logo abaixo. */
.mvd .card.mvd-graficos-cartao { min-height: 0; margin-bottom: var(--bi-space-md); }
.mvd .card.mvd-graficos-cartao[hidden] { display: none; }
.mvd .card-body.mvd-graficos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
                gap: var(--bi-space-md); }
.mvd-grafico { min-width: 0; }
.mvd-grafico__caixa { position: relative; height: 18rem; }
.mvd-grafico__aviso { display: flex; align-items: center; justify-content: center;
                      height: 18rem; margin: 0; color: var(--ink-3);
                      font-size: var(--fonte-corpo); }
.mvd-grafico__aviso[hidden], .mvd-grafico__caixa[hidden] { display: none; }
@media (max-width: 1199.98px) {
  .mvd .card-body.mvd-graficos { grid-template-columns: minmax(0, 1fr); }
}

.mvd-mx { width: 100%; border-collapse: separate; border-spacing: 0;
          font-size: var(--fonte-corpo); }
.mvd-mx th, .mvd-mx td { padding: .3rem .4rem; white-space: nowrap;
                         border-bottom: 1px solid var(--line-2); }

.mvd-mx thead th { position: sticky; top: 0; z-index: 2; background: var(--surf-2);
                   color: var(--ink-2); font-weight: 500;
                   text-align: right; border-bottom: 1px solid var(--line); }
/* Cabeçalho inteiro grudado, sem offset por linha (o `top: 2.1rem` deixava 3,5 px de vão). */
.mvd-mx thead { position: sticky; top: 0; z-index: 5; }
.mvd-mx th.mvd-eixo { text-align: center; background: var(--surf-3); color: var(--ink);
                      border-left: 1px solid var(--line-3); }

.mvd-mx th.mvd-nome { position: sticky; left: 0; z-index: 3; background: var(--surf);
                      text-align: left; color: var(--ink);
                      font-weight: 500;
                      border-right: 1px solid var(--line); }
/* O nome quebra linha (#291): seis eixos não cabem em 1366 com a razão social
   mais longa numa linha só, e o nome é a única coluna que pode crescer para
   baixo sem perder número. */
.mvd-mx tbody th.mvd-nome { white-space: normal; min-width: 11rem; max-width: 16rem; }
.mvd-mx thead th.mvd-nome { z-index: 4; background: var(--surf-2); }

.mvd-mx td.mvd-num { text-align: right; font-variant-numeric: tabular-nums; }
.mvd-mx td.mvd-meta { padding: .15rem .25rem; }

.mvd-mx td.mvd-ano-total { background: var(--surf-2); font-weight: 500; }

/* Célula editável: o form-control-sm de fábrica (a borda diz que ali se digita).
   4,4rem nos dois modos: a folha do ano tem doze colunas de digitação, e o
   quadro do mês tem seis eixos desde o recozido (#291) — com 6rem a rolagem
   horizontal escondia as últimas colunas em 1366. */
.mvd-input { width: 4.4rem; text-align: right; font-variant-numeric: tabular-nums; }
/* Período de vários meses: a meta é a SOMA e não se edita (o backend manda
   `editavel: false`). Sem o tracejado, a célula não promete digitação. */
.mvd-input[readonly] { border-color: transparent; }
/* Meta digitada e ainda não gravada: o número na tela não é o do banco, e isso
   precisa ser visível — senão o usuário sai achando que salvou. */
.mvd-input--sujo { background: var(--warning-subtle); border-color: var(--warning-text); }
/* #443: área de atuação ao lado do nome (UFs do serviço) e o campo de UFs na
   folha do ano; Sugerida com o ↙ que copia para a meta. */
.mvd-mx td.mvd-atuacao { color: var(--ink-2); }
.mvd-input--atuacao { width: 9rem; text-align: left; }
.mvd-mx td.mvd-sugerida { color: var(--ink-3); }
.mvd-copiar { margin-left: .25rem; padding: 0 .2rem; border: 0; background: none;
  color: var(--bs-primary, #0d6efd); line-height: 1; cursor: pointer; }
.mvd-copiar:hover, .mvd-copiar:focus-visible { background: var(--acc-soft); border-radius: .25rem; }

.mvd-mx tr.mvd-bloco th { background: var(--surf-3); color: var(--ink);
                          text-align: left; text-transform: uppercase;
                          letter-spacing: .04em; font-size: var(--fonte-rotulo); }
.mvd-mx tr.mvd-subtotal th, .mvd-mx tr.mvd-subtotal td { background: var(--surf-2);
                                                         font-weight: 500; }
/* Agenda — seleção em lote na coluna de atrasados. A caixa fica FORA do botão
   da linha (botão dentro de botão não é HTML válido) e o item vira a régua que
   alinha os dois. A BARRA de ação não mora aqui: é `position-fixed` no rodapé
   da janela, mesma anatomia da savebar da Matriz de Acesso — dentro desta
   coluna ela empurrava a lista a cada clique.
   `center` e não `flex-start`: a caixa fica na altura do NOME, que é a
   primeira linha do rótulo, sem margem chutada. */
.ag-item { display: flex; align-items: center; gap: .5rem; }
.ag-item .ag-marcar { flex: 0 0 auto; margin: 0; }
.ag-item .ag-linha { flex: 1 1 auto; min-width: 0; }
/* Rodapé fixo cobriria a última linha da coluna, que rola por dentro. */
[data-pagina="crm-agenda"] .ag-atrasados { padding-bottom: 3.5rem; }

/* Pendentes de meta: quem tem acesso ao CRM e ainda não entrou no quadro. A
   seção fica DEPOIS do último subtotal e não soma em nada — o recuo e o texto
   apagado são o que impede alguém de ler estas linhas como parte do time
   medido. Zero não é resultado ruim aqui, é "ninguém digitou a meta ainda". */
.mvd-mx tr.mvd-bloco--pendente th { background: var(--surf-2); color: var(--ink-2);
                                    font-style: italic; text-transform: none;
                                    letter-spacing: 0; }
/* A linha pendente NÃO é apagada: o campo de meta dela é editável, e cinza
   lê como desabilitado — foi o que fez a gerente achar que não dava para
   digitar ali. Quem sinaliza o estado é a etiqueta "sem meta", não a tinta. */
.mvd-mx tr.mvd-pendente th, .mvd-mx tr.mvd-pendente td { color: inherit; }
.mvd-mx tr.mvd-pendente .mvd-nome { padding-left: var(--sp-4); }
.mvd-mx tfoot tr.mvd-total th, .mvd-mx tfoot tr.mvd-total td {
  position: sticky; bottom: 0; background: var(--surf-3);
  font-weight: 500; color: var(--ink);
  border-top: 1px solid var(--line-3); }

.mvd-vazio { color: var(--ink-3); text-align: center; padding: .75rem; }
.mvd-tag { margin-left: .35rem; padding: 0 .3rem; border-radius: var(--r-sm);
           background: var(--warning-subtle); color: var(--warning-text);
           font-size: var(--fonte-pequena); font-weight: 500; }

.mvd-ok { color: var(--positive-text, #1a7f4b); }
.mvd-abaixo { color: var(--negative-text); }
/* #298: fatia do bloco no total, sob a meta e o realizado do subtotal. */
.mvd-participacao { display: block; font-size: var(--fonte-pequena); font-weight: 400;
                    color: var(--ink-2); }
.mvd-participacao.mvd-abaixo { color: var(--negative-text); }
.mvd-status { font-size: var(--fonte-corpo); color: var(--ink-3); }

/* ── Mira (hover acende linha + coluna) ──────────────────────────────────── */
/* Marcação de `biUtils.ligarMira`, a mesma da Gerencial e da Curva ABC. Aqui as
   células não têm tinta de dado própria, então a mira pode ser fundo — é o que
   mantém o olho na dupla vendedor × coluna numa grade de 12 colunas. */
.mvd-mx tbody tr.bi-mira-linha td, .mvd-mx tbody tr.bi-mira-linha th.mvd-nome {
  background: var(--surf-2); }
.mvd-mx tbody td.bi-mira-coluna { background: var(--surf-2); }
.mvd-mx tbody tr.bi-mira-linha td.bi-mira-coluna { background: var(--surf-3); }
.mvd-mx thead th.bi-mira-coluna { background: var(--acc-soft); color: var(--ink); }

/* Custo herdado de um mês anterior (mês sem importação): o número é estimativa,
   não medição, e a tela não pode deixar os dois com a mesma cara. */
.cabc-mx td.cabc-estimado { color: var(--ink-3); font-style: italic; }

/* Faixas de família no cabeçalho da Curva ABC — a planilha manual colore o
   cabeçalho por bloco (Fio verde, Cordoalha azul `4F81BD`, totais verde-oliva
   `9BBB59`), e é assim que o usuário lê a matriz há anos. Mesmos matizes, na
   luminosidade do tema claro do app: o verde puro (#00FF00) da planilha não
   sobrevive ao lado de texto. */
/* A família é IDENTIDADE (categórico); a célula de dado é MAGNITUDE
   (sequencial). Os dois não podem dividir o mesmo canal: com fundo pastel no
   cabeçalho e azuis de dado logo abaixo, a banda lia como mais um degrau da
   mesma escala (o `#d6e3f3` antigo caía exatamente entre as faixas 1 e 2 da
   rampa). Então a família desce para uma RÉGUA — 3px de borda — e o fundo do
   cabeçalho volta a ser neutro. */
.cabc-mx th.cabc-banda-1 { box-shadow: inset 0 -3px 0 #7fb872; }
.cabc-mx th.cabc-banda-2 { box-shadow: inset 0 -3px 0 #6d93cc; }
.cabc-mx th.cabc-banda-3 { box-shadow: inset 0 -3px 0 #9ab863; }
.cabc-mx th.cabc-banda-4 { box-shadow: inset 0 -3px 0 #b98fb4; }

/* Limite de família descendo o corpo inteiro: sem ele o agrupamento morre na
   primeira linha de dado e a varredura vertical perde a referência. */
.cabc-mx th.cabc-fim-familia, .cabc-mx td.cabc-fim-familia {
  border-right: 1px solid var(--line-3); }

/* Rampa sequencial de PARTICIPAÇÃO da bitola no mês, normalizada por LINHA —
   o total mensal varia de 1.072 t a 2.299 t, e uma escala global confundiria
   "mês grande" com "bitola dominante". Um hue só (o azul de gráfico do app),
   monotônica em luminosidade: em escala de cinza a leitura sobrevive.
   Faixa 0 (< 3%) fica SEM tinta de propósito — é o branco que faz o Pareto
   aparecer; pintar tudo mataria a leitura. */
.cabc-mx td.cabc-f1 { background: #e0e9fc; }
.cabc-mx td.cabc-f2 { background: #c2d3f9; }
.cabc-mx td.cabc-f3 { background: #a3bdf7; }
.cabc-mx td.cabc-f4 { background: #87a9f4; }
/* Em célula pintada o texto vai para `--ink`: `--ink-3` mede 2,07:1 sobre o
   degrau mais escuro e reprova AA. */
.cabc-mx td.cabc-f1, .cabc-mx td.cabc-f2,
.cabc-mx td.cabc-f3, .cabc-mx td.cabc-f4 { color: var(--ink); }

/* Devolução maior que venda: fora da rampa. Cor chapada e o sinal no número. */
.cabc-mx td.cabc-neg { background: var(--negative-subtle); color: var(--negative-text); }

/* Mês que ainda não aconteceu: meta visível, atingimento sem cor de direção. */
.cabc-mx td.cabc-futuro { color: var(--ink-4); }

/* Rodapé fixo: Total · Média · % no grupo · % do total precisam ficar
   co-visíveis com o dado. Sem isso, responder "quais são as bitolas A" custa
   descer 600 px, ler 14 percentuais, memorizar os três maiores e voltar.
   Mesmo padrão que a /metas-vendedor/ já usa. */
/* O rodapé gruda inteiro, como o cabeçalho: as quatro linhas sem vão entre si. */
.cabc-mx tfoot { position: sticky; bottom: 0; z-index: 5; }
.cabc-mx tfoot th.cabc-mes { z-index: 4; }

/* ==========================================================================
   CRM · PEDIDOS (`[data-pagina="crm-pedidos"]`)
   Fora do FCDS por decisão do dono (02/09/2026): linguagem própria, moderna
   e minimalista. Tudo escopado no seletor da página — nenhum token global,
   nenhum vazamento nas outras ~28 telas. Uma cor semântica só (alerta);
   "despachado" não ganha cor, ganha o ponto preenchido do trilho.

   A GRADE daqui (folha, chips, tabela, seta, filtros de coluna, vazio,
   rodapé, ponto de estágio) vale também para `/reportes/`, que usa o mesmo
   `crm/js/grade.js` desde o reporte #27 (15/09/2026): o dono tomou esta lista
   como a canônica. `:is()` pesa o mesmo que o seletor sozinho, então nada
   muda na cascata do Pedidos; dossiê, busca e colunas próprias ficam só aqui.
   ========================================================================== */
/* MUDANÇA DE ESCOPO (justificativa, #307 Task 2.3c, 09/10/2026): a Programação de Faturamento tem a coluna ESTÁGIO
   de Pedidos (as regras do ponto já miravam [data-pagina="separacao_faturamento"]), mas sem os tokens --pedido-* no
   escopo o ponto vazado ficava invisível. Os nomes são próprios (--pedido-*): nada colide com o DS. */
:is([data-pagina="crm-pedidos"], [data-pagina="reportes"], [data-pagina="separacao_faturamento"], .pd-canvas[data-variante="nova"]) {
  /* Paleta PRÓPRIA desta tela (decisão do dono, 03/09/2026: liberdade total
     com cor, sem reusar token nem elemento do FCDS). Nomes próprios de
     propósito — nada aqui deve ser confundido com os tokens globais, e nada
     daqui vaza: tudo vive sob este seletor.

     A cor não é enfeite: a rampa petróleo→verde acompanha a JORNADA do
     pedido, então a cor diz "quão longe isso foi" em vez de rotular
     categorias sem ordem. Âmbar e vermelho ficam para o que sai da jornada
     (travado, cancelado) e para o prazo vencido. */
  --pedido-papel: #ffffff;
  --pedido-papel-2: #f5f7f8;
  --pedido-tinta: #0d1117;
  --pedido-tinta-2: #59626e;
  --pedido-fio: #e3e6ea;
  --pedido-fio-forte: #b9c1ca;
  --pedido-petroleo: #0b5c66;
  --pedido-petroleo-2: #cfe3e5;
  --pedido-verde: #1c7a52;
  --pedido-ambar: #8a5a00;
  --pedido-vermelho: #a4241c;
  background: var(--pedido-papel);
  color: var(--pedido-tinta);
  /* A folha ocupa a janela inteira e SANGRA para fora do recuo do `.content`,
     em cima e embaixo. Sem isto sobrava o cinza do shell (`--bg`) nas duas
     pontas — duas cores de fundo na mesma tela, com costura no meio. Só na
     VERTICAL: sangrar na horizontal também joga a folha para baixo da barra
     lateral (medido: começava em 28px, e a lateral ocupa 48).
     As margens negativas usam as MESMAS variáveis do recuo que
     estão anulando, e o respiro interno volta como padding: assim o dia em
     que o shell mudar o recuo, isto acompanha sozinho, em vez de descolar. */
  margin: calc(var(--content-pad-y) * -1) 0 calc(var(--content-pad-b) * -1);
  padding: var(--content-pad-y) 0 var(--content-pad-b);
  min-height: calc(100vh - 52px);
  box-sizing: border-box;
}
/* Ponte: as regras desta seção nasceram com os nomes `--pd-*`. A paleta nova
   é a única fonte; estes cinco apenas apontam para ela, para não haver dois
   valores de verdade enquanto os seletores antigos existirem. */
:is([data-pagina="crm-pedidos"], [data-pagina="reportes"], .pd-canvas[data-variante="nova"]) {
  --pd-tinta: var(--pedido-tinta);
  --pd-secundario: var(--pedido-tinta-2);
  --pd-fio: var(--pedido-fio);
  --pd-fundo: var(--pedido-papel);
  --pd-alerta: var(--pedido-vermelho);
}

/* Sem título aqui: a topbar já diz "Pedidos". Só o resumo, à direita. */
[data-pagina="crm-pedidos"] .pd-resumo {
  color: var(--pd-secundario); font-variant-numeric: tabular-nums;
}
/* O Bootstrap dá `width: 100%` a `.form-select`/`.form-control` — dentro de
   um flex container isso vira o próprio flex-basis, e cada select tenta
   tomar a LINHA INTEIRA (era o que empurrava "Todas as UF" de ponta a
   ponta). Largura pelo conteúdo: cada controle do lado do vendedor. */
[data-pagina="crm-pedidos"] .pd-periodo { display: flex; align-items: center; gap: .5rem; }
/* O grid, em `table-layout: auto`: cada coluna toma só o que o conteúdo
   pede — os `width` abaixo são pistas mínimas para nº/uf/datas/valor, não
   uma partilha forçada de 100% (era o que abria o vão entre cliente e uf:
   `fixed` + `width:100%` estica a coluna sem largura própria para
   preencher a sobra, mesmo com nome curto). Sem `width:100%` na tabela: ela
   lê como uma linha só, não uma grade esticada até a borda. */
/* Piso e teto por coluna. Sem piso, a lista vazia esmaga tudo contra a borda
   (medido: Nº com 23px, SAIR ATÉ com 31px); sem teto, o cliente engolia
   metade da tela (1.102px) e o representante 346px. Os números saem da
   largura real do conteúdo — data cabe em 5,5rem, UF em 2,5rem. */
[data-pagina="crm-pedidos"] .pd-col-numero { min-width: 4.5rem; }
[data-pagina="crm-pedidos"] .pd-col-cliente { min-width: 12rem; }
[data-pagina="crm-pedidos"] .pd-col-uf { min-width: 3rem; }
[data-pagina="crm-pedidos"] .pd-col-estagio { min-width: 8rem; }
[data-pagina="crm-pedidos"] .pd-col-data { min-width: 6rem; }
[data-pagina="crm-pedidos"] .pd-col-nf { min-width: 5rem; }
[data-pagina="crm-pedidos"] .pd-col-valor { min-width: 7rem; }
[data-pagina="crm-pedidos"] .pd-col-representante { min-width: 8rem; max-width: 12rem; }
/* A seta de ordenação aparece SEMPRE: apagada na coluna inativa (diz "dá para
   ordenar por aqui"), cheia e em petróleo na ativa (diz "está ordenado por
   aqui, neste sentido"). Afordância que só aparece depois de usada não é
   afordância. */
[data-pagina="crm-pedidos"] .pd-col-numero { width: 4.5rem; font-variant-numeric: tabular-nums; }
[data-pagina="crm-pedidos"] .pd-col-uf { width: 2.75rem; }
[data-pagina="crm-pedidos"] .pd-col-estagio { width: 7rem; max-width: 16rem; }
[data-pagina="crm-pedidos"] .pd-col-data { width: 5.5rem; font-variant-numeric: tabular-nums; }
[data-pagina="crm-pedidos"] .pd-col-nf { width: 4rem; }
[data-pagina="crm-pedidos"] .pd-col-representante { width: 10rem; }
[data-pagina="crm-pedidos"] .pd-col-valor {
  width: 7rem; text-align: right; font-variant-numeric: tabular-nums;
}
/* Teto, não largura fixa: nome curto fica curto (a linha "lê como uma linha
   só"), nome comprido trunca no `ellipsis` do `td` — nunca abre a coluna até
   empurrar as vizinhas para longe. */
[data-pagina="crm-pedidos"] .pd-col-cliente { font-weight: 600; max-width: 16rem; }
[data-pagina="crm-pedidos"] .pd-alerta { color: var(--pd-alerta); font-weight: 600; }

/* As seis colunas que vieram da /pedidos/ quando ela foi absorvida
   (10/09/2026). Mesma régua das outras: piso pela largura real do conteúdo,
   teto onde o texto do ERP é longo (descrição de transação e de condição de
   pagamento passam de 30 caracteres). */
[data-pagina="crm-pedidos"] .pd-col-codigo {
  width: 4.5rem; color: var(--pd-secundario); font-variant-numeric: tabular-nums;
}
[data-pagina="crm-pedidos"] .pd-col-segmento { max-width: 7rem; }
[data-pagina="crm-pedidos"] .pd-col-sub-segmento { max-width: 9rem; }
[data-pagina="crm-pedidos"] .pd-col-situacao { max-width: 8rem; }
[data-pagina="crm-pedidos"] .pd-col-transacao { max-width: 10rem; }
[data-pagina="crm-pedidos"] .pd-col-pagamento { max-width: 7rem; }
/* O rótulo "CONDIÇÃO DE PAGAMENTO" é mais largo que o teto da coluna: quebra em vez de invadir EMISSÃO. */
[data-pagina="crm-pedidos"] .grade-tabela thead th.pd-col-pagamento { white-space: normal; }
[data-pagina="crm-pedidos"] .pd-col-itens {
  width: 3.5rem; text-align: right; font-variant-numeric: tabular-nums;
}
/* Os dias de atraso ao lado da previsão — o badge que a /pedidos/ desenhava,
   agora com o número que o serviço calcula. */
[data-pagina="crm-pedidos"] .pd-atraso {
  color: var(--pd-alerta); font-weight: 600; font-variant-numeric: tabular-nums;
}
/* "+N entregas" ao lado do ENTREGAR EM da tela nova: o pedido tem outras
   datas em aberto além da primeira. Legenda, não alerta. */
[data-pagina="crm-pedidos"][data-tela="nova"] .pd-marca { color: var(--pd-secundario); }
/* O dossiê (ADENDO item 6, 03/09/2026): mesma gramática do resto da tela —
   sem cartão, sem sombra, sem raio, sem ícone colorido por trilha. O trilho
   é a única peça gráfica; o resto é texto e um traço embaixo do link. */
/* O canvas usa a janela: eram 32rem (512 px) numa tela de 1440, com o pedido
   inteiro empilhado numa coluna só e faixa de branco à direita. Duas colunas
   ASSIMÉTRICAS (pedido do dono, 03/09/2026), porque as duas metades têm pesos
   diferentes: à esquerda a identidade do pedido, de tamanho previsível; à
   direita o que cresce sem limite — uma NOTA por bloco. */
/* Mais largo desde 03/09/2026: com as regiões ganhando superfície e
   respiro, 70rem espremia a coluna da identidade a ponto de "Four Importacao
   e Distribuicao Ltda" quebrar em duas linhas e a linha do tempo ler quatro
   palavras por linha. */
[data-pagina="crm-pedidos"] .pd-canvas,
.pd-canvas[data-variante="nova"] { width: min(84rem, 96vw); }
[data-pagina="crm-pedidos"] .pd-dossie,
.pd-canvas[data-variante="nova"] .pd-dossie {
  display: grid; grid-template-columns: 1fr; gap: 1.5rem; align-items: start;
}
@media (min-width: 62rem) {
  [data-pagina="crm-pedidos"] .pd-dossie,
  .pd-canvas[data-variante="nova"] .pd-dossie { grid-template-columns: 25rem 1fr; }
}
[data-pagina="crm-pedidos"] .pd-dossie__coluna,
.pd-canvas[data-variante="nova"] .pd-dossie__coluna { min-width: 0; }
[data-pagina="crm-pedidos"] .pd-canvas__cabecalho,
.pd-canvas[data-variante="nova"] .pd-canvas__cabecalho { border-bottom: 1px solid var(--pd-fio); }
/* `PEDIDO 21135 — CLIENTE` na barra de título (pedido do dono, 03/09/2026):
   o nome do cliente subiu da capa para cá. Caixa alta por `text-transform`,
   nunca reescrevendo o texto no JS — o dado segue legível para quem copia. */
[data-pagina="crm-pedidos"] .pd-canvas__titulo,
.pd-canvas[data-variante="nova"] .pd-canvas__titulo {
  font-size: var(--fonte-titulo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .01em; line-height: 1.2; min-width: 0;
}
/* Imprimir, Enviar e Baixar nascem no cabeçalho e o pedido-edicao.js os move para o bloco de ações, onde são
   links de documento; o Baixar fica apagado enquanto o pacote monta. */
.pd-canvas[data-variante="nova"] .pd-canvas__baixar[disabled] { opacity: .5; cursor: progress; }
/* O PAINEL DE ENVIO: mesma superfície branca das outras regiões, aberto
   dentro do dossiê — o canvas já é um painel sobre a lista, e um modal por
   cima seria a terceira camada. Duas colunas: à esquerda o que vai, à
   direita para quem e o que se escreve. */
[data-pagina="crm-pedidos"] .pd-envio,
.pd-canvas[data-variante="nova"] .pd-envio {
  background: var(--surf); border: 1px solid var(--pedido-fio);
  border-radius: var(--r, .5rem); padding: 1.25rem 1.5rem; margin-bottom: 1.25rem;
}
[data-pagina="crm-pedidos"] .pd-envio__capa,
.pd-canvas[data-variante="nova"] .pd-envio__capa {
  display: flex; align-items: baseline; gap: 1rem;
  padding-bottom: .75rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--pedido-fio);
}
[data-pagina="crm-pedidos"] .pd-envio__capa .pd-canvas__titulo-secao,
.pd-canvas[data-variante="nova"] .pd-envio__capa .pd-canvas__titulo-secao { margin: 0; }
[data-pagina="crm-pedidos"] .pd-envio__fechar,
.pd-canvas[data-variante="nova"] .pd-envio__fechar { margin-left: auto; }
[data-pagina="crm-pedidos"] .pd-envio__corpo,
.pd-canvas[data-variante="nova"] .pd-envio__corpo {
  display: grid; grid-template-columns: 1fr; gap: 1.5rem;
}
@media (min-width: 52rem) {
  [data-pagina="crm-pedidos"] .pd-envio__corpo,
  .pd-canvas[data-variante="nova"] .pd-envio__corpo { grid-template-columns: 1fr 1fr; }
}
[data-pagina="crm-pedidos"] .pd-envio__grupo,
.pd-canvas[data-variante="nova"] .pd-envio__grupo {
  font-size: var(--fonte-rotulo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .04em; color: var(--pd-secundario); margin: 1rem 0 .35rem;
}
[data-pagina="crm-pedidos"] .pd-envio__grupo:first-child,
.pd-canvas[data-variante="nova"] .pd-envio__grupo:first-child { margin-top: 0; }
/* A linha inteira é o alvo do clique, não só a caixinha de 13px. */
[data-pagina="crm-pedidos"] .pd-envio__item,
.pd-canvas[data-variante="nova"] .pd-envio__item {
  display: flex; align-items: center; gap: .6rem; min-height: 2.25rem;
  padding: .15rem .35rem; border-radius: .25rem; cursor: pointer;
  font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .pd-envio__item:hover,
.pd-canvas[data-variante="nova"] .pd-envio__item:hover { background: var(--surf-2); }
[data-pagina="crm-pedidos"] .pd-envio__item input,
.pd-canvas[data-variante="nova"] .pd-envio__item input { cursor: pointer; }
[data-pagina="crm-pedidos"] .pd-envio__rotulo,
.pd-canvas[data-variante="nova"] .pd-envio__rotulo { color: var(--pedido-tinta); }
[data-pagina="crm-pedidos"] .pd-envio__tamanho,
.pd-canvas[data-variante="nova"] .pd-envio__tamanho {
  margin-left: auto; font-size: var(--fonte-corpo); color: var(--pd-secundario);
  font-variant-numeric: tabular-nums;
}
/* O estado do preparo mora na mesma coluna do tamanho: é a mesma pergunta
   ("quanto isso pesa, e já está pronto?"), e uma coluna a mais para dizer
   "pronto" seria largura gasta. */
[data-pagina="crm-pedidos"] .pd-envio__tamanho--pronto,
.pd-canvas[data-variante="nova"] .pd-envio__tamanho--pronto { color: var(--pedido-petroleo); }
[data-pagina="crm-pedidos"] .pd-envio__tamanho--recusado,
.pd-canvas[data-variante="nova"] .pd-envio__tamanho--recusado {
  color: var(--pd-alerta); white-space: normal; text-align: right;
}
/* O painel do pacote não tem a coluna de e-mail. A lista NÃO ocupa a largura
   toda por isso: o tamanho de cada documento é empurrado para a direita por
   `margin-left: auto`, e numa faixa de 1.300px ele acabava a um palmo do
   rótulo. Uma coluna da largura da do e-mail mantém os dois lados juntos. */
[data-pagina="crm-pedidos"] .pd-envio__corpo--pacote,
.pd-canvas[data-variante="nova"] .pd-envio__corpo--pacote {
  grid-template-columns: minmax(0, 1fr);
}
/* #770 fase 2: a lista de documentos ocupa a largura toda e se reparte em colunas por tipo (notas e boletos,
   laudos, originais); no painel de e-mail ela fica numa faixa acima dos campos. Coluna vazia nem é desenhada. */
[data-pagina="crm-pedidos"] .pd-envio__corpo > .pd-envio__documentos,
.pd-canvas[data-variante="nova"] .pd-envio__corpo > .pd-envio__documentos { grid-column: 1 / -1; }
[data-pagina="crm-pedidos"] .pd-envio__colunas,
.pd-canvas[data-variante="nova"] .pd-envio__colunas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.5rem; align-items: start;
}
[data-pagina="crm-pedidos"] .pd-envio__tipo,
.pd-canvas[data-variante="nova"] .pd-envio__tipo {
  font-size: var(--fonte-rotulo); font-weight: 600; letter-spacing: .04em; color: var(--pedido-tinta);
  margin: 0 0 .5rem; padding-bottom: .35rem; border-bottom: 1px solid var(--pedido-fio);
}
/* O preview dos documentos (modal de fábrica, tamanho extra grande): o quadro do PDF usa a altura da janela. */
.pd-previa__quadro { width: 100%; height: 75vh; border: 0; }
.pd-previa__texto { margin: 0; max-height: 75vh; overflow: auto; font-size: .8125rem; white-space: pre-wrap; word-break: break-all; }
[data-pagina="crm-pedidos"] .pd-envio__corpo--pacote .pd-envio__enviar,
.pd-canvas[data-variante="nova"] .pd-envio__corpo--pacote .pd-envio__enviar {
  margin-top: 1rem;
}
[data-pagina="crm-pedidos"] .pd-envio__teto,
.pd-canvas[data-variante="nova"] .pd-envio__teto {
  margin: 1rem 0 0; font-size: var(--fonte-corpo); color: var(--pd-secundario);
}
[data-pagina="crm-pedidos"] .pd-envio__campo,
.pd-canvas[data-variante="nova"] .pd-envio__campo {
  display: block; font-size: var(--fonte-rotulo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .04em; color: var(--pd-secundario); margin-bottom: .9rem;
}
.pd-canvas[data-variante="nova"] .pd-envio__campo .form-control {
  margin-top: .3rem; text-transform: none; letter-spacing: normal;
}
/* O CAMPO "PARA" É UMA CAIXA DE ETIQUETAS (04/09/2026). O cadastro do cliente
   tem quatro campos de e-mail, cada um com mais de um endereço, e as pessoas
   ligadas a ele são várias — o campo de um endereço só descartava tudo isso.
   Todas nascem postas; tirar é um clique no `×`.

   A caixa é um form-control-sm de fábrica e a entrada
   livre mora DENTRO dela, sem borda própria: quem clica em qualquer ponto da
   caixa cai no lugar de digitar. O foco é desenhado na caixa, não na entrada,
   senão o anel apareceria no meio das etiquetas. */
/* A PRÉVIA DA GRADE DE BOLETOS (09/09/2026): o mesmo bloco que o cliente
   recebe, mostrado abaixo da mensagem para quem envia conferir antes. Ele já
   vem com estilo INLINE (é HTML de e-mail, que não enxerga folha de estilo),
   então aqui só se cuida de ele não empurrar a coluna do painel: tabela larga
   rola por dentro. */
[data-pagina="crm-pedidos"] .pd-envio__previa,
.pd-canvas[data-variante="nova"] .pd-envio__previa {
  overflow-x: auto; margin-bottom: .9rem;
}
[data-pagina="crm-pedidos"] .pd-envio__legenda,
.pd-canvas[data-variante="nova"] .pd-envio__legenda { display: block; }
.pd-canvas[data-variante="nova"] .pd-envio__tags {
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; cursor: text;
}
/* O foco do form-control de fábrica, desenhado na caixa e não na entrada. */
.pd-canvas[data-variante="nova"] .pd-envio__tags:focus-within {
  border-color: #86b7fe; box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
}
[data-pagina="crm-pedidos"] .pd-envio__tag,
.pd-canvas[data-variante="nova"] .pd-envio__tag {
  display: inline-flex; align-items: center; gap: .1rem;
  max-width: 100%; padding: 0 .1rem 0 .45rem;
  border-radius: var(--raio-chip); background: var(--surf-2);
  font-size: var(--fonte-corpo); font-weight: 400; text-transform: none;
  letter-spacing: normal; color: var(--pedido-tinta);
}
[data-pagina="crm-pedidos"] .pd-envio__tag-x,
.pd-canvas[data-variante="nova"] .pd-envio__tag-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.25rem; height: 1.25rem; padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--pd-secundario); font-size: var(--fonte-destaque); line-height: 1;
  cursor: pointer;
}
[data-pagina="crm-pedidos"] .pd-envio__tag-x:hover,
.pd-canvas[data-variante="nova"] .pd-envio__tag-x:hover {
  background: var(--pedido-fio); color: var(--pedido-tinta);
}
/* A entrada livre não tem moldura: a moldura é a caixa. `min-width` para ela
   não sumir quando as etiquetas ocupam a linha, e `flex: 1` para tomar o
   resto da última linha — é ali que se digita o endereço que falta. */
.pd-canvas[data-variante="nova"] .pd-envio__entrada {
  flex: 1; min-width: 9rem; padding: 0 .2rem; border: 0; background: none; font: inherit; color: inherit;
}
.pd-canvas[data-variante="nova"] .pd-envio__entrada:focus-visible { outline: none; }
[data-pagina="crm-pedidos"] .pd-envio__remetente,
.pd-canvas[data-variante="nova"] .pd-envio__remetente {
  font-size: var(--fonte-corpo); color: var(--pd-secundario); margin: 0 0 .5rem;
}
/* A assinatura aparece ANTES do envio: é ela que fecha o e-mail, e é aqui
   que se descobre que falta o telefone. Mesma decisão da tela de proposta. */
[data-pagina="crm-pedidos"] .pd-envio__assinatura,
.pd-canvas[data-variante="nova"] .pd-envio__assinatura {
  font-size: var(--fonte-corpo); color: var(--pd-secundario);
  padding: .6rem .75rem; background: var(--surf-2);
  border-radius: var(--r, .5rem); margin-bottom: 1rem;
}
/* A BARRA DO PACOTE: um fio que enche, não um cartão. Só aparece durante o
   download — o resto do tempo a tela não tem por que falar do assunto. */
[data-pagina="crm-pedidos"] .pd-baixar,
.pd-canvas[data-variante="nova"] .pd-baixar {
  display: flex; align-items: center; gap: .75rem; margin-bottom: 1.25rem;
}
[data-pagina="crm-pedidos"] .pd-baixar__trilho,
.pd-canvas[data-variante="nova"] .pd-baixar__trilho {
  flex: 1; height: 4px; border-radius: 2px; overflow: hidden;
  background: var(--pedido-fio);
}
[data-pagina="crm-pedidos"] .pd-baixar__feito,
.pd-canvas[data-variante="nova"] .pd-baixar__feito {
  display: block; height: 100%; width: 0; background: var(--pedido-petroleo);
  transition: width .18s linear;
}
/* Enquanto o servidor monta o ZIP não há porcentagem que não seja invenção:
   a barra corre em vaivém para dizer "estou trabalhando", e só passa a
   medir quando os bytes começam a chegar. Quem pediu menos movimento na
   tela não vê o vaivém — vê o fio parado e o texto. */
[data-pagina="crm-pedidos"] .pd-baixar--indefinida .pd-baixar__feito,
.pd-canvas[data-variante="nova"] .pd-baixar--indefinida .pd-baixar__feito {
  width: 35%; animation: pd-baixar-vaivem 1.1s ease-in-out infinite;
}
@keyframes pd-baixar-vaivem {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(285%); }
}
@media (prefers-reduced-motion: reduce) {
  [data-pagina="crm-pedidos"] .pd-baixar--indefinida .pd-baixar__feito,
  .pd-canvas[data-variante="nova"] .pd-baixar--indefinida .pd-baixar__feito {
    animation: none; width: 100%; opacity: .4;
  }
  [data-pagina="crm-pedidos"] .pd-baixar__feito,
  .pd-canvas[data-variante="nova"] .pd-baixar__feito { transition: none; }
}
/* O texto vem ANTES da barra: a frase é o que importa ("Emitindo o boleto
   27916-02 no Senior…", ou a recusa do ERP por extenso), e à direita ela era
   empurrada contra a borda e cortada. */
[data-pagina="crm-pedidos"] .pd-baixar__texto,
.pd-canvas[data-variante="nova"] .pd-baixar__texto {
  font-size: var(--fonte-corpo); color: var(--pedido-tinta); font-weight: 500;
  flex: 0 1 auto; min-width: 0;
}
[data-pagina="crm-pedidos"] .pd-canvas__capa,
.pd-canvas[data-variante="nova"] .pd-canvas__capa {
  padding-bottom: 1rem; margin-bottom: 1rem; border-bottom: 1px solid var(--pd-fio);
}
[data-pagina="crm-pedidos"] .pd-canvas__cliente { font-weight: 500; margin: 0 0 .5rem; }
[data-pagina="crm-pedidos"] .pd-canvas__linha,
.pd-canvas[data-variante="nova"] .pd-canvas__linha {
  display: flex; flex-wrap: wrap; gap: .1rem .75rem;
  color: var(--pd-secundario); font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .pd-canvas__secao,
.pd-canvas[data-variante="nova"] .pd-canvas__secao { margin-bottom: 2rem; }
/* Todo título em caixa alta (pedido do dono, 03/09/2026), pelo CSS. */
[data-pagina="crm-pedidos"] .pd-canvas__titulo-secao,
.pd-canvas[data-variante="nova"] .pd-canvas__titulo-secao {
  font-size: var(--fonte-rotulo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .04em; color: var(--pd-secundario); margin: 0 0 .75rem;
}
/* Um bloco por NOTA: régua e espaço, não cartão com sombra — são muitos numa
   tela só, e caixa repetida achataria a diferença entre "identidade do
   pedido" (à esquerda) e "o que cada nota levou" (aqui). */
[data-pagina="crm-pedidos"] .pd-nota__titulo,
.pd-canvas[data-variante="nova"] .pd-nota__titulo {
  font-size: var(--fonte-corpo); font-weight: 500; text-transform: uppercase;
  letter-spacing: .03em; margin: 0; color: var(--pedido-tinta);
}
[data-pagina="crm-pedidos"] .pd-nota__meta,
.pd-canvas[data-variante="nova"] .pd-nota__meta {
  font-size: var(--fonte-corpo); color: var(--pd-secundario);
  font-variant-numeric: tabular-nums;
}
[data-pagina="crm-pedidos"] .pd-nota__capa,
.pd-canvas[data-variante="nova"] .pd-nota__capa {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: .25rem .75rem;
  padding-bottom: .6rem; margin-bottom: .85rem;
  border-bottom: 1px solid var(--pd-fio);
}
/* #373: a carta de correção da nota — uma linha sob a capa, sem caixa. */
[data-pagina="crm-pedidos"] .pd-nota__carta,
.pd-canvas[data-variante="nova"] .pd-nota__carta {
  margin: -.35rem 0 .85rem; font-size: var(--fonte-corpo); color: var(--pedido-tinta);
}
[data-pagina="crm-pedidos"] .pd-nota__carta .pd-nota__meta,
.pd-canvas[data-variante="nova"] .pd-nota__carta .pd-nota__meta { display: block; }
/* REGIÕES, não uma folha corrida (reclamação do dono, 03/09/2026: "sem
   separações lógicas, layout pobre"). O corpo do canvas passou a ser o CHÃO
   cinza do app (`--surf-app`, o mesmo das outras telas) e cada região é uma
   superfície branca sobre ele: a cabeça, a coluna da identidade, cada nota.
   O olho separa por superfície, que é instantâneo, em vez de por fio fino,
   que exige procurar. Nenhuma superfície mora dentro de outra. */
[data-pagina="crm-pedidos"] .pd-canvas__corpo,
.pd-canvas[data-variante="nova"] .pd-canvas__corpo { background: var(--surf-app); }
[data-pagina="crm-pedidos"] .pd-dossie-resumo,
.pd-canvas[data-variante="nova"] .pd-dossie-resumo {
  background: var(--surf); border: 1px solid var(--pd-fio);
  border-radius: var(--r, .5rem); padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}
[data-pagina="crm-pedidos"] .pd-dossie-resumo:empty,
.pd-canvas[data-variante="nova"] .pd-dossie-resumo:empty { display: none; padding: 0; border: 0; }
[data-pagina="crm-pedidos"] .pd-nota__capa .pd-doc,
.pd-canvas[data-variante="nova"] .pd-nota__capa .pd-doc { margin-left: auto; }
/* Com DOIS downloads no cabeçalho (DANFE e XML), o `auto` só vale para o
   primeiro: no segundo ele abriria uma segunda vala e jogaria os dois para
   os cantos opostos. O segundo anda colado, a um respiro do primeiro. */
[data-pagina="crm-pedidos"] .pd-nota__capa .pd-doc + .pd-doc,
.pd-canvas[data-variante="nova"] .pd-nota__capa .pd-doc + .pd-doc {
  margin-left: 1.1rem;
}
/* A DANFE tem o mesmo peso do link de certificado dentro da grade (`.pd-docs-grade .pd-doc`); o seletor cita `a`
   para a nota sem DANFE (`<span>`) continuar cinza. */
[data-pagina="crm-pedidos"] .pd-nota__capa a.pd-doc,
.pd-canvas[data-variante="nova"] .pd-nota__capa a.pd-doc { font-weight: 500; }
/* O espaçamento e a superfície da nota moram no bloco "Notas e boletos",
   mais abaixo neste arquivo — é o que vence por ordem, e ter as duas metades
   em lugares diferentes foi o que fez a versão anterior se anular sozinha. */
/* O boleto é consequência da nota, não irmão do item: mesma grade, um
   degrau abaixo no peso e bem separada da lista de itens. O seletor tem de
   citar `.pd-rolagem` porque a grade de itens passou a morar dentro da caixa
   de rolagem — sem isso o `+` não alcança mais a grade de boletos, que é
   irmã da CAIXA, não da tabela. */
[data-pagina="crm-pedidos"] .pd-nota .pd-rolagem + .pd-docs-grade,
.pd-canvas[data-variante="nova"] .pd-nota .pd-rolagem + .pd-docs-grade {
  margin-top: 1.75rem; font-size: var(--fonte-corpo);
}
/* O certificado é uma PILHA de links, um por arquivo — o lote costuma ter
   mais de um papel, e enfileirá-los na horizontal estouraria a coluna. Nome
   longo corta com reticências; o nome inteiro e o tamanho ficam no `title`. */
[data-pagina="crm-pedidos"] .pd-cel-certificado,
.pd-canvas[data-variante="nova"] .pd-cel-certificado {
  color: var(--pd-secundario); white-space: nowrap;
  max-width: 14rem;
}
[data-pagina="crm-pedidos"] .pd-doc--arquivo,
.pd-canvas[data-variante="nova"] .pd-doc--arquivo {
  display: block; max-width: 100%;
  font-weight: 500;
}
[data-pagina="crm-pedidos"] .pd-doc--arquivo + .pd-doc--arquivo,
.pd-canvas[data-variante="nova"] .pd-doc--arquivo + .pd-doc--arquivo { margin-top: .2rem; }
[data-pagina="crm-pedidos"] .pd-docs-grade thead th,
.pd-canvas[data-variante="nova"] .pd-docs-grade thead th { text-transform: uppercase; }
[data-pagina="crm-pedidos"] .pd-canvas__vazio,
.pd-canvas[data-variante="nova"] .pd-canvas__vazio { color: var(--pd-secundario); font-size: var(--fonte-corpo); }

/* Os quatro blocos recolhíveis (itens/notas/títulos/certificados): `<details>`
   nativo, sem JS para abrir/fechar — o navegador já faz. */
[data-pagina="crm-pedidos"] .pd-bloco > summary,
.pd-canvas[data-variante="nova"] .pd-bloco > summary { cursor: pointer; }
[data-pagina="crm-pedidos"] .pd-item-lista,
.pd-canvas[data-variante="nova"] .pd-item-lista { list-style: none; padding: 0; margin: .5rem 0 0; }
[data-pagina="crm-pedidos"] .pd-item-linha,
.pd-canvas[data-variante="nova"] .pd-item-linha {
  display: grid; grid-template-columns: 1fr auto auto; gap: .75rem;
  padding: .35rem 0; border-bottom: 1px solid var(--pd-fio); font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .pd-item-linha__quantidade,
.pd-canvas[data-variante="nova"] .pd-item-linha__quantidade,
[data-pagina="crm-pedidos"] .pd-item-linha__valor,
.pd-canvas[data-variante="nova"] .pd-item-linha__valor {
  color: var(--pd-secundario); text-align: right; white-space: nowrap;
}

/* O trilho: uma linha de pontos ligados por um filete de 1px. Vazio =
   contorno (`inset 0 0 0 1px`); cumprido = preenchido. Nada de cor por
   trilha — só a tinta principal, cumprido ou não. */
[data-pagina="crm-pedidos"] .pd-trilho,
.pd-canvas[data-variante="nova"] .pd-trilho { list-style: none; display: flex; padding: 0; margin: 0; }
[data-pagina="crm-pedidos"] .pd-parada,
.pd-canvas[data-variante="nova"] .pd-parada {
  flex: 1; position: relative; padding-top: 1.25rem; font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .pd-parada:not(:first-child)::before,
.pd-canvas[data-variante="nova"] .pd-parada:not(:first-child)::before {
  content: ''; position: absolute; top: .3rem; left: -50%; width: 100%;
  height: 1px; background: var(--pd-fio);
}
[data-pagina="crm-pedidos"] .pd-ponto,
.pd-canvas[data-variante="nova"] .pd-ponto {
  position: absolute; top: 0; left: 0; width: 8px; height: 8px; border-radius: 50%;
  background: var(--pd-fundo); box-shadow: inset 0 0 0 1px var(--pd-fio);
}
[data-pagina="crm-pedidos"] .pd-parada--feita .pd-ponto,
.pd-canvas[data-variante="nova"] .pd-parada--feita .pd-ponto {
  background: var(--pd-tinta); box-shadow: none;
}
[data-pagina="crm-pedidos"] .pd-parada__rotulo,
.pd-canvas[data-variante="nova"] .pd-parada__rotulo { display: block; font-weight: 500; }
[data-pagina="crm-pedidos"] .pd-parada__data,
.pd-canvas[data-variante="nova"] .pd-parada__data,
[data-pagina="crm-pedidos"] .pd-parada__autor,
.pd-canvas[data-variante="nova"] .pd-parada__autor { display: block; color: var(--pd-secundario); }

/* O extrato: grid de três colunas, sem caixa nem ícone. */
[data-pagina="crm-pedidos"] .pd-extrato,
.pd-canvas[data-variante="nova"] .pd-extrato { list-style: none; padding: 0; margin: 0; }
[data-pagina="crm-pedidos"] .pd-evento,
.pd-canvas[data-variante="nova"] .pd-evento {
  display: grid; grid-template-columns: auto 1fr auto; gap: .25rem .75rem;
  padding: .7rem 0; border-bottom: 1px solid var(--pd-fio); font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .pd-evento__quando,
.pd-canvas[data-variante="nova"] .pd-evento__quando {
  color: var(--pd-secundario); font-variant-numeric: tabular-nums; white-space: nowrap;
}
[data-pagina="crm-pedidos"] .pd-evento__autor,
.pd-canvas[data-variante="nova"] .pd-evento__autor { color: var(--pd-secundario); text-align: right; }
/* O log do Sênior guarda QUEBRA DE LINHA dentro do texto (`\r` entre
   "Pedido Liberado…", "Usuário de bloqueio:…", "Motivo do bloqueio:…"). O
   HTML engolia as quebras e as quatro frases viravam um parágrafo corrido.
   `pre-line` devolve a quebra e mantém a quebra automática do resto. */
[data-pagina="crm-pedidos"] .pd-evento__frase,
.pd-canvas[data-variante="nova"] .pd-evento__frase { white-space: pre-line; }

/* CAIXA DE ROLAGEM (pedido do dono, 03/09/2026): linha do tempo e lista de
   itens cresciam sem fim — um pedido de doze itens com histórico longo
   empurrava tudo para fora da janela e obrigava a rolar o dossiê inteiro
   para chegar aos boletos. Agora cada lista tem teto e rola por dentro; o
   teto é a JANELA, não um número fixo, para caber igual num notebook e num
   monitor de pé. O padding à direita reserva o lugar da barra de rolagem —
   sem ele o conteúdo dança quando a lista passa do teto. */
[data-pagina="crm-pedidos"] .pd-rolagem,
.pd-canvas[data-variante="nova"] .pd-rolagem {
  max-height: min(30rem, 48vh); overflow-y: auto; padding-right: .5rem;
  overscroll-behavior: contain;
}
/* Cabeçalho grudado no topo da caixa: rolar cem lotes sem ver "PRODUTO |
   LOTE | QUANTIDADE" é ler número sem rótulo. Fundo opaco porque o cabeçalho
   passa POR CIMA das linhas que rolam. */
[data-pagina="crm-pedidos"] .pd-rolagem .pd-docs-grade thead th,
.pd-canvas[data-variante="nova"] .pd-rolagem .pd-docs-grade thead th {
  position: sticky; top: 0; z-index: 1; background: #fff;
}

/* Documentos: uma LINHA por documento (revisão da Task 4, 03/09/2026 — a
   versão em parágrafo corrido escorria data/valor/motivo numa massa só).
   Link com traço embaixo — sem botão preenchido, sem
   raio. Ausente mostra o MOTIVO por extenso (ADENDO item 5), nunca um link
   morto. */
[data-pagina="crm-pedidos"] .pd-docs,
.pd-canvas[data-variante="nova"] .pd-docs { list-style: none; padding: 0; margin: 0; font-size: var(--fonte-corpo); }
[data-pagina="crm-pedidos"] .pd-doc-linha,
.pd-canvas[data-variante="nova"] .pd-doc-linha {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem .75rem;
  padding: .35rem 0; border-bottom: 1px solid var(--pd-fio);
}
[data-pagina="crm-pedidos"] .pd-doc--ausente,
.pd-canvas[data-variante="nova"] .pd-doc--ausente { color: var(--pd-secundario); }
[data-pagina="crm-pedidos"] .pd-doc-linha__meta,
.pd-canvas[data-variante="nova"] .pd-doc-linha__meta,
[data-pagina="crm-pedidos"] .pd-doc-linha__motivo,
.pd-canvas[data-variante="nova"] .pd-doc-linha__motivo { color: var(--pd-secundario); }

/* --------------------------------------------------------------------------
   ABAS · Pedidos | Notas fiscais (10/09/2026)
   Três telas viraram uma; a aba é o que separa os dois índices (pedido por
   numped, nota por empresa+filial+número+série). Mesma pílula dos estágios,
   um degrau acima em peso: é a troca de assunto, não de recorte.
   -------------------------------------------------------------------------- */
/* Componente compartilhado (#638): sem escopo, para o Processar DDA usar as mesmas abas. As cores
   do Pedidos (`--pd-*`, petróleo) valem onde existem; fora dele, as do DS. A Ficha do produto tem
   as dela, mais específicas (seção #462). */
.pd-abas {
  display: flex; gap: .5rem; padding: .25rem 0 .75rem;
}
.pd-aba {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: .25rem .1rem; color: var(--pd-secundario, var(--ds-tinta-2));
  font-size: var(--fonte-corpo); cursor: pointer;
}
.pd-aba:hover { color: var(--pd-tinta, var(--ds-tinta)); }
.pd-aba--ativa {
  color: var(--pd-tinta, var(--ds-tinta)); font-weight: 500;
  border-bottom-color: var(--pedido-petroleo, var(--ds-acao));
}

/* A grade de NOTAS reusa a folha, a tabela, o vazio e o rodapé da grade de
   pedidos — o que muda são quatro colunas próprias e o status do título.
   Nada de cartão novo: é a mesma tela. */
[data-pagina="crm-pedidos"] .nt-col-serie,
[data-pagina="crm-pedidos"] .nt-col-codigo { color: var(--pd-secundario); }
[data-pagina="crm-pedidos"] .nt-col-acoes { text-align: right; }
[data-pagina="crm-pedidos"] .nt-abrir {
  color: var(--pd-secundario); font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .grade-linha:hover .nt-abrir { color: var(--pedido-petroleo); }
[data-pagina="crm-pedidos"] .nt-pedido {
  color: var(--pd-tinta); text-decoration: underline; text-underline-offset: 2px;
}
/* Nota sem pedido é a maioria (41% das notas de doze meses) — o rótulo diz o
   que ela é, em vez de deixar a célula vazia parecendo dado faltando. */
[data-pagina="crm-pedidos"] .nt-avulsa {
  color: var(--pd-secundario); font-size: var(--fonte-corpo);
}
[data-pagina="crm-pedidos"] .nt-status { font-weight: 500; }
/* #373: nota com carta de correção — marcador de texto, sem etiqueta. */
[data-pagina="crm-pedidos"] .nt-carta {
  color: var(--pd-secundario); font-size: var(--fonte-corpo); font-weight: 500;
}
[data-pagina="crm-pedidos"] .nt-status--ve { color: var(--pedido-vermelho); }
[data-pagina="crm-pedidos"] .nt-status--ab { color: var(--pedido-ambar); }
[data-pagina="crm-pedidos"] .nt-status--ba { color: var(--pedido-verde); }
[data-pagina="crm-pedidos"] .nt-abertos {
  color: var(--pd-secundario); font-variant-numeric: tabular-nums;
}

/* O detalhe da nota não tem folha de estilo própria: ele é o canvas do
   pedido (`.pd-canvas` & cia, mais abaixo). As regras do modal antigo saíram
   daqui em 11/09/2026 junto com o modal — estilo de componente que não existe
   é dívida que ninguém cobra e todos leem. */

/* O LINK DENTRO DA FICHA da capa — o pedido de origem da nota, a ponte de
   volta para a outra aba. Tinta do pedido e sublinhado discreto, a mesma
   gramática dos outros links do dossiê. */
[data-pagina="crm-pedidos"] .pd-ficha__link,
.pd-canvas[data-variante="nova"] .pd-ficha__link {
  color: var(--pedido-tinta); text-decoration: underline;
  text-underline-offset: 2px;
}
[data-pagina="crm-pedidos"] .pd-ficha__link + .pd-ficha__link,
.pd-canvas[data-variante="nova"] .pd-ficha__link + .pd-ficha__link { margin-left: .5rem; }


/* ==========================================================================
   CRM · PEDIDOS — segunda passada de desenho (03/09/2026)
   Decisões do dono nesta rodada: rótulo sempre capitalizado; cabeçalho não
   pode pesar menos que o dado; documentos em GRADE, não em texto solto;
   liberdade total com cor; e NADA do FCDS — nem token, nem elemento.
   Por isso os controles de filtro abaixo deixam de ser `.form-select` do
   Bootstrap e passam a ser desenhados aqui.
   ========================================================================== */

/* O nome do cliente toma a sobra: o teto de 20rem existia para fechar um vão
   que sumiu quando a tabela deixou de esticar, e o que ele faz hoje é truncar
   nome com espaço livre à direita. */
[data-pagina="crm-pedidos"] .pd-col-cliente,
.pd-canvas[data-variante="nova"] .pd-col-cliente { max-width: none; width: 100%; }

/* --- Estágio: UM tom, preenchimento crescente (vazio -> meio -> cheio).
   A primeira versão usava seis matizes na rampa da jornada; o benchmark
   corrige: a convenção (Ant Design, replicada por Retool e Sentry) é no
   máximo cinco cores semânticas e cor SÓ quando o valor é acionável —
   estado normal fica neutro. Então o progresso vira densidade de um mesmo
   petróleo, e a cor fica reservada para exceção: travado, cancelado e
   prazo vencido. --- */
:is([data-pagina="crm-pedidos"], [data-pagina="reportes"], [data-pagina="separacao_faturamento"]) .pd-estagio-marca {
  display: inline-block; width: .5rem; height: .5rem; border-radius: 50%;
  margin-right: .45rem; vertical-align: baseline;
  box-shadow: inset 0 0 0 1.25px var(--pedido-petroleo); background: transparent;
}
[data-pagina="crm-pedidos"] .pd-e-separado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-separado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-separado .pd-estagio-marca {
  background: linear-gradient(90deg, var(--pedido-petroleo) 50%, transparent 50%);
}
[data-pagina="crm-pedidos"] .pd-e-faturado_parcial .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-faturado_parcial .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-faturado_parcial .pd-estagio-marca {
  background: linear-gradient(90deg, var(--pedido-petroleo) 75%, transparent 75%);
}
[data-pagina="crm-pedidos"] .pd-e-faturado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-faturado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-faturado .pd-estagio-marca,
[data-pagina="crm-pedidos"] .pd-e-despachado_parcial .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-despachado_parcial .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-despachado_parcial .pd-estagio-marca,
[data-pagina="crm-pedidos"] .pd-e-despachado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-despachado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-despachado .pd-estagio-marca {
  background: var(--pedido-petroleo);
}
/* O despacho é o fim da jornada: ganha o anel externo, não outra cor. */
[data-pagina="crm-pedidos"] .pd-e-despachado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-despachado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-despachado .pd-estagio-marca {
  box-shadow: 0 0 0 2px var(--pedido-petroleo-2), inset 0 0 0 1.25px var(--pedido-petroleo);
}
/* Exceção — aqui a cor vale, porque pede ação. */
[data-pagina="crm-pedidos"] .pd-e-bloqueado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-bloqueado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-bloqueado .pd-estagio-marca {
  background: var(--warning-text); box-shadow: inset 0 0 0 1.25px var(--warning-text);
}
[data-pagina="crm-pedidos"] .pd-e-cancelado .pd-estagio-marca,
[data-pagina="separacao_faturamento"] .pd-e-cancelado .pd-estagio-marca,
.pd-canvas[data-variante="nova"] .pd-e-cancelado .pd-estagio-marca {
  background: var(--pedido-vermelho); box-shadow: inset 0 0 0 1.25px var(--pedido-vermelho);
}
[data-pagina="crm-pedidos"] .pd-e-bloqueado,
[data-pagina="separacao_faturamento"] .pd-e-bloqueado,
.pd-canvas[data-variante="nova"] .pd-e-bloqueado { color: var(--warning-text); }
/* Segunda linha do Estágio bloqueado: quem travou, desde quando e por quê. */
[data-pagina="crm-pedidos"] .pd-bloqueio-frase {
  color: var(--warning-text); font-size: var(--fonte-pequena); font-weight: 400;
  min-width: 15rem; white-space: normal; overflow-wrap: anywhere;
}
[data-pagina="crm-pedidos"] .pd-e-cancelado,
[data-pagina="separacao_faturamento"] .pd-e-cancelado,
.pd-canvas[data-variante="nova"] .pd-e-cancelado { color: var(--pedido-vermelho); }

/* Os blocos do dossiê são seções abertas, não acordeão — o benchmark é
   unânime: dentro de painel de detalhe, tudo aberto e rolando. */
[data-pagina="crm-pedidos"] .pd-bloco > .pd-canvas__titulo-secao,
.pd-canvas[data-variante="nova"] .pd-bloco > .pd-canvas__titulo-secao { cursor: default; }

/* --- Documentos em grade (pedido do dono): mesma régua da grade principal —
   cabeçalho capitalizado em tinta, número à direita com `tabular-nums`, e o
   motivo da recusa numa COLUNA, não como frase pendurada embaixo. --- */
[data-pagina="crm-pedidos"] .pd-docs-grade,
.pd-canvas[data-variante="nova"] .pd-docs-grade {
  width: 100%; border-collapse: collapse; font-size: var(--fonte-corpo);
}
/* O RESPIRO das grades (pedido do dono, 03/09/2026): a linha apertada fazia
   doze itens lerem como um bloco de texto. O teto de rolagem, acima, é o que
   permite a linha mais alta sem a lista voltar a empurrar a tela. */
[data-pagina="crm-pedidos"] .pd-docs-grade thead th,
.pd-canvas[data-variante="nova"] .pd-docs-grade thead th {
  text-align: left; font-weight: 500; font-size: var(--fonte-pequena);
  color: var(--pedido-tinta); padding: 0 .75rem .55rem 0;
  border-bottom: 1px solid var(--pedido-fio-forte);
}
[data-pagina="crm-pedidos"] .pd-docs-grade tbody td,
.pd-canvas[data-variante="nova"] .pd-docs-grade tbody td {
  padding: .65rem .75rem .65rem 0; border-bottom: 1px solid var(--pedido-fio);
  vertical-align: baseline;
}
/* O nome do DOCUMENTO nunca quebra em duas linhas: "27916-01" partido no
   hífen vira dois documentos aos olhos de quem varre. Vale para o link, não
   para a célula inteira: desde que a grade passou a listar ITENS
   (03/09/2026), a primeira coluna é a descrição do produto — "FOUR - FIO DE
   ACO NAO LIGADO RECOZIDO DUPLO TRANCADO BWG 18" sem quebra empurrava a
   tabela para fora do bloco e cortava a coluna de valor. */
[data-pagina="crm-pedidos"] .pd-docs-grade .pd-doc,
.pd-canvas[data-variante="nova"] .pd-docs-grade .pd-doc { white-space: nowrap; }
[data-pagina="crm-pedidos"] .pd-docs-grade,
.pd-canvas[data-variante="nova"] .pd-docs-grade { table-layout: auto; }
[data-pagina="crm-pedidos"] .pd-docs-grade tbody td:first-child:not(.pd-cel-codigo),
.pd-canvas[data-variante="nova"] .pd-docs-grade tbody td:first-child:not(.pd-cel-codigo),
[data-pagina="crm-pedidos"] .pd-docs-grade tbody td.pd-cel-codigo + td,
.pd-canvas[data-variante="nova"] .pd-docs-grade tbody td.pd-cel-codigo + td { word-break: break-word; }
/* A FOLGA VAI PARA A PRIMEIRA COLUNA, nas duas grades — é o que faz item e
   boleto ocuparem a mesma largura (pedido do dono, 03/09/2026). Antes a folga
   era da coluna Situação (`width: 99%` nela), e a grade de boletos amontoava
   as quatro colunas na metade esquerda enquanto a de itens ia até a borda:
   dois objetos de larguras diferentes empilhados dentro da mesma nota. */
   Desde 10/09/2026 a grade de itens começa pelo CÓDIGO do produto, e a folga
   não pode ser dele: código é largura fixa. Ela passa para a coluna
   seguinte — a descrição —, endereçada pelo irmão adjacente para a grade de
   boletos (que não tem código) continuar com a folga na primeira. */
[data-pagina="crm-pedidos"] .pd-docs-grade thead th:first-child:not(.pd-cel-codigo),
.pd-canvas[data-variante="nova"] .pd-docs-grade thead th:first-child:not(.pd-cel-codigo),
[data-pagina="crm-pedidos"] .pd-docs-grade tbody td:first-child:not(.pd-cel-codigo),
.pd-canvas[data-variante="nova"] .pd-docs-grade tbody td:first-child:not(.pd-cel-codigo),
[data-pagina="crm-pedidos"] .pd-docs-grade thead th.pd-cel-codigo + th,
.pd-canvas[data-variante="nova"] .pd-docs-grade thead th.pd-cel-codigo + th,
[data-pagina="crm-pedidos"] .pd-docs-grade tbody td.pd-cel-codigo + td,
.pd-canvas[data-variante="nova"] .pd-docs-grade tbody td.pd-cel-codigo + td { width: 99%; }
[data-pagina="crm-pedidos"] .pd-doc-cel--data,
.pd-canvas[data-variante="nova"] .pd-doc-cel--data,
[data-pagina="crm-pedidos"] .pd-doc-cel--valor,
.pd-canvas[data-variante="nova"] .pd-doc-cel--valor {
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
[data-pagina="crm-pedidos"] .pd-doc-cel--valor,
.pd-canvas[data-variante="nova"] .pd-doc-cel--valor { text-align: right; }
[data-pagina="crm-pedidos"] .pd-doc-cel--situacao,
.pd-canvas[data-variante="nova"] .pd-doc-cel--situacao { color: var(--pedido-tinta-2); }
[data-pagina="crm-pedidos"] .pd-docs-grade .pd-doc,
.pd-canvas[data-variante="nova"] .pd-docs-grade .pd-doc { font-weight: 500; }
[data-pagina="crm-pedidos"] .pd-docs-grade .pd-doc--ausente,
.pd-canvas[data-variante="nova"] .pd-docs-grade .pd-doc--ausente {
  color: var(--pedido-tinta-2); font-weight: 400;
}

/* --- O trilho da jornada herda a mesma rampa: ponto cumprido em petróleo,
   pendente vazio com o fio por fora. --- */
[data-pagina="crm-pedidos"] .pd-parada--feita .pd-ponto,
.pd-canvas[data-variante="nova"] .pd-parada--feita .pd-ponto { background: var(--pedido-petroleo); }
[data-pagina="crm-pedidos"] .pd-canvas__titulo-secao,
.pd-canvas[data-variante="nova"] .pd-canvas__titulo-secao { color: var(--pedido-tinta); }

/* A GRADE CABE NA JANELA (pedido do dono, 15/09/2026, vendo a lista inteira
   de 100 pedidos esticar a página): as duas telas usam `content--altura-cheia`,
   e aqui a cadeia fecha até a `.grade`, que faz o resto (barra, cabeçalho e
   rodapé à vista; só as linhas rolam, nos dois eixos).
   A sangria de margem da folha branca sai: sob `altura-cheia` o `.content` já
   não tem recuo vertical para anular, e ela empurraria a tela 16px para baixo
   da topbar. A Programação de Faturamento (#540) usa a mesma folha e entrou
   depois: fora desta lista, os −36px de baixo passavam a paginação da janela. */
.content--altura-cheia > .page:is([data-pagina="crm-pedidos"], [data-pagina="reportes"], [data-pagina="separacao_faturamento"]) {
  margin: 0; min-height: 0; padding-top: var(--content-pad-y); padding-bottom: 0;
}
.content--altura-cheia > .page[data-pagina="crm-pedidos"] > section {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}
/* O valor é o que o olho procura numa lista de pedidos. */
[data-pagina="crm-pedidos"] .pd-col-valor,
.pd-canvas[data-variante="nova"] .pd-col-valor { font-weight: 600; }


/* --- A FICHA do dossiê (pedido do dono, 03/09/2026): rótulo em cima, valor
   embaixo, em grade. Antes era uma frase corrida e quem procurava a condição
   de pagamento tinha de ler tudo. Grade que se adapta: quatro colunas em
   painel largo, duas em painel estreito. --- */
[data-pagina="crm-pedidos"] .pd-ficha,
.pd-canvas[data-variante="nova"] .pd-ficha {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: .75rem 1.25rem; margin: .75rem 0 0; padding: 0;
}
[data-pagina="crm-pedidos"] .pd-ficha__par,
.pd-canvas[data-variante="nova"] .pd-ficha__par { margin: 0; }
[data-pagina="crm-pedidos"] .pd-ficha__rotulo,
.pd-canvas[data-variante="nova"] .pd-ficha__rotulo {
  font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em;
  text-transform: uppercase; color: var(--pedido-tinta-2); margin: 0 0 .1rem;
}
[data-pagina="crm-pedidos"] .pd-ficha__valor,
.pd-canvas[data-variante="nova"] .pd-ficha__valor {
  margin: 0; font-size: var(--fonte-corpo); color: var(--pedido-tinta);
  font-variant-numeric: tabular-nums;
}
[data-pagina="crm-pedidos"] .pd-ficha__valor .pd-alerta,
.pd-canvas[data-variante="nova"] .pd-ficha__valor .pd-alerta { color: var(--pedido-vermelho); font-weight: 600; }
/* O link de um par (Separar em → "Cadastrar dias de separação") quebra
   alinhado à esquerda, como o texto do par, não centrado como botão. */
[data-pagina="crm-pedidos"] .pd-ficha__valor .fcds-siglink,
.pd-canvas[data-variante="nova"] .pd-ficha__valor .fcds-siglink { text-align: left; }

/* --- Notas e boletos: um bloco por NOTA, com os boletos dela dentro. É a
   hierarquia real do ERP (o título nasce da nota), e era o que faltava para
   parar de casar número por número na cabeça. --- */
/* Uma nota é UMA superfície branca sobre o chão cinza. Antes eram blocos
   separados por fio e espaço, e num pedido de três notas as seis grades liam
   como uma lista só — a "falta de separação lógica" que o dono apontou em
   03/09/2026. Agora cada nota tem começo e fim visíveis. */
[data-pagina="crm-pedidos"] .pd-nota,
.pd-canvas[data-variante="nova"] .pd-nota {
  background: var(--surf); border: 1px solid var(--pedido-fio);
  border-radius: var(--r, .5rem); padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}
/* A COLUNA DA IDENTIDADE tem as mesmas duas superfícies: a ficha com a
   jornada, e a linha do tempo. São coisas diferentes — o que o pedido É e o
   que aconteceu com ele — e estavam empilhadas sem nada entre elas. */
[data-pagina="crm-pedidos"] #pd-capa,
.pd-canvas[data-variante="nova"] #pd-capa,
[data-pagina="crm-pedidos"] #pd-historico,
.pd-canvas[data-variante="nova"] #pd-historico {
  background: var(--surf); border: 1px solid var(--pedido-fio);
  border-radius: var(--r, .5rem); padding: 1.25rem 1.25rem .5rem;
}
[data-pagina="crm-pedidos"] #pd-capa:empty,
.pd-canvas[data-variante="nova"] #pd-capa:empty,
[data-pagina="crm-pedidos"] #pd-historico:empty,
.pd-canvas[data-variante="nova"] #pd-historico:empty { display: none; }
[data-pagina="crm-pedidos"] #pd-historico,
.pd-canvas[data-variante="nova"] #pd-historico { margin-top: 1.25rem; }
/* O boleto NÃO leva fundo próprio (o dono vetou a faixa cinza em
   03/09/2026): dentro de uma nota que já é superfície branca, um segundo
   fundo vira mancha. Ele se distingue por espaço e por corpo menor — a
   regra logo acima —, que é o suficiente para dizer que é consequência da
   nota, não irmão do item. */
[data-pagina="crm-pedidos"] .pd-nota__capa,
.pd-canvas[data-variante="nova"] .pd-nota__capa {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; padding-bottom: .4rem;
}
[data-pagina="crm-pedidos"] .pd-nota__numero,
.pd-canvas[data-variante="nova"] .pd-nota__numero {
  font-weight: 500; font-variant-numeric: tabular-nums;
}
[data-pagina="crm-pedidos"] .pd-nota .pd-docs-grade,
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade { margin-bottom: .35rem; }
[data-pagina="crm-pedidos"] .pd-nota .pd-docs-grade tbody tr:last-child td,
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade tbody tr:last-child td { border-bottom: 0; }
/* O código do lote não quebra: "250200701-1" partido no hífen vira dois lotes
   aos olhos de quem confere no galpão. */
[data-pagina="crm-pedidos"] .pd-cel-lote,
.pd-canvas[data-variante="nova"] .pd-cel-lote {
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* Código do produto e unidade de medida: largura do conteúdo, nunca da
   folga. O código fica em tinta secundária — quem lê a grade procura o nome
   do produto, e o código é a confirmação que ele consulta depois (é assim
   que a folha impressa do Senior o apresenta). */
[data-pagina="crm-pedidos"] .pd-cel-codigo,
.pd-canvas[data-variante="nova"] .pd-cel-codigo {
  white-space: nowrap; font-variant-numeric: tabular-nums;
  color: var(--pedido-tinta-2); width: 1%;
}
/* ==========================================================================
   MALHA — mapa da operação, dores, POPs
   Escopo de página: tudo prefixado `.malha-`. Nenhum token global tocado.
   O canvas do grafo é a única superfície escura do app, de propósito: é
   superfície de grafo (padrão Obsidian), não "modo escuro" da página, e por
   isso tem tokens próprios em vez de reusar os do tema.
   ========================================================================== */

/* A régua de maturidade colore chip, anel do grafo e badge da ficha. Os tokens
   ficam nas RAÍZES das quatro telas, e não só em `.malha-app`: definidos apenas
   no mapa, o badge da ficha caía em `var()` indefinido e saía transparente. */
.malha-app,
.malha-ficha,
.malha-dores-tela,
.malha-base,
.malha-documento {
  --malha-canvas-fundo: #14181b;
  --malha-canvas-texto: #d7dde0;
  --malha-canvas-aresta: rgba(255, 255, 255, .16);
  --malha-canvas-aresta-fluxo: rgba(216, 153, 88, .55);
  --malha-canvas-aresta-apoio: rgba(255, 255, 255, .09);

  --malha-nao_mapeado: #6b7480;
  --malha-mapeado: #d0a72a;
  --malha-sop_criado: #5698d1;
  --malha-sop_implementado: #3fae7a;
  --malha-melhoria_continua: #33d3b3;
}

.malha-app {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* A tela usa a janela inteira: sem faixa branca sobrando no rodapé. O desconto
     é a topbar do shell mais o respiro do `.content`. */
  height: calc(100dvh - 118px);
  min-height: 480px;
}

/* --- barra do mapa --- */
.malha-barra {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.malha-busca {
  position: relative;
  flex: 1 1 240px;
  max-width: 380px;
}

.malha-busca i {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: #8b8474;
  font-size: var(--fonte-corpo);
}

.malha-busca input { padding-left: 30px; }

.malha-legenda {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.malha-chip {
  border: 1px solid #dee2e6;
  background: #fff;
  border-radius: var(--raio-chip);
  padding: 3px 10px;
  font-size: var(--fonte-pequena);
  color: #495057;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.malha-chip::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--malha-nao_mapeado);
}

.malha-chip--mapeado::before { background: var(--malha-mapeado); }
.malha-chip--sop_criado::before { background: var(--malha-sop_criado); }
.malha-chip--sop_implementado::before { background: var(--malha-sop_implementado); }
.malha-chip--melhoria_continua::before { background: var(--malha-melhoria_continua); }

.malha-chip--ativo {
  border-color: #212529;
  color: #212529;
  font-weight: 500;
}

/* --- canvas --- */
.malha-canvas-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 420px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--malha-canvas-fundo);
}

#malhaGrafo {
  width: 100%;
  height: 100%;
  display: block;
}

.malha-aresta {
  stroke: var(--malha-canvas-aresta);
  stroke-width: 1;
}

.malha-aresta--fluxo {
  stroke: var(--malha-canvas-aresta-fluxo);
  stroke-width: 1.6;
}

.malha-aresta--apoio {
  stroke: var(--malha-canvas-aresta-apoio);
  stroke-dasharray: 3 4;
}

.malha-aresta--apagada { opacity: .12; }

.malha-seta { fill: var(--malha-canvas-aresta-fluxo); }

.malha-no { cursor: pointer; }

.malha-no text {
  fill: var(--malha-canvas-texto);
  font-size: var(--fonte-pequena);
  pointer-events: none;
}

.malha-no--area text { font-size: var(--fonte-corpo); }
.malha-no--raiz text { font-size: var(--fonte-pequena); font-weight: 500; }

.malha-no circle {
  stroke: var(--malha-nao_mapeado);
  stroke-width: 3;
}

.malha-no--raiz circle { fill: #efe6d5; stroke: #b8532b; }

.malha-anel--mapeado { stroke: var(--malha-mapeado); }
.malha-anel--sop_criado { stroke: var(--malha-sop_criado); }
.malha-anel--sop_implementado { stroke: var(--malha-sop_implementado); }
.malha-anel--melhoria_continua { stroke: var(--malha-melhoria_continua); }

.malha-no--apagado { opacity: .18; }

.malha-no--selecionado circle {
  stroke-width: 5;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, .35));
}

.malha-resumo {
  position: absolute;
  left: 14px;
  bottom: 12px;
  display: flex;
  gap: 16px;
  font-size: var(--fonte-pequena);
  color: #d7dde0;
  background: rgba(20, 24, 27, .78);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 8px;
  padding: 6px 12px;
}

.malha-dica {
  position: absolute;
  right: 14px;
  bottom: 12px;
  margin: 0;
  max-width: 340px;
  text-align: right;
  font-size: var(--fonte-pequena);
  color: #7d8790;
}

/* --- ficha, dores, base --- */
.malha-secao {
  font-size: var(--fonte-destaque);
  font-weight: 500;
  color: #212529;
  margin: 0 0 10px;
}

.malha-contador {
  font-size: var(--fonte-pequena);
  color: #6c757d;
  font-weight: 400;
}

.malha-ficha__titulo {
  display: flex;
  align-items: center;
  gap: 12px;
}

.malha-ficha__titulo h1 {
  font-size: var(--fonte-titulo);
  margin: 0;
}

.malha-ficha__sub,
.malha-ficha__desc {
  color: #6c757d;
  font-size: var(--fonte-corpo);
  margin: 2px 0 0;
}

.malha-pino {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--malha-cor, #6c757d);
  flex: 0 0 auto;
}

.malha-status {
  margin-left: auto;
  border-radius: var(--raio-chip);
  padding: 3px 12px;
  font-size: var(--fonte-pequena);
  color: #fff;
  background: var(--malha-nao_mapeado);
}

.malha-status--mapeado { background: var(--malha-mapeado); }
.malha-status--sop_criado { background: var(--malha-sop_criado); }
.malha-status--sop_implementado { background: var(--malha-sop_implementado); }
.malha-status--melhoria_continua { background: var(--malha-melhoria_continua); }

.malha-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 14px 0 0;
}

.malha-meta dt {
  font-size: var(--fonte-rotulo);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #8b8474;
  font-weight: 500;
}

.malha-meta dd {
  margin: 2px 0 0;
  font-size: var(--fonte-corpo);
  color: #212529;
}

.malha-tag {
  display: inline-block;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  padding: 1px 6px;
  margin-right: 4px;
  font-size: var(--fonte-pequena);
  color: #495057;
}

.malha-dores,
.malha-docs,
.malha-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.malha-dor {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid #f1f3f5;
}

.malha-dor p { margin: 0; font-size: var(--fonte-corpo); color: #212529; }
.malha-dor__corpo { flex: 1 1 auto; }

.malha-dor__meta {
  font-size: var(--fonte-pequena);
  color: #6c757d;
  margin-top: 3px !important;
}

.malha-dor--resolvida .malha-dor__corpo p { text-decoration: line-through; color: #adb5bd; }

.malha-sev {
  flex: 0 0 auto;
  border-radius: 4px;
  padding: 1px 7px;
  font-size: var(--fonte-pequena);
  color: #fff;
  background: #6c757d;
}

.malha-sev--alta { background: #c0392b; }
.malha-sev--media { background: #d0a72a; }
.malha-sev--baixa { background: #7f8c8d; }

.malha-vazio {
  color: #adb5bd;
  font-size: var(--fonte-corpo);
  padding: 10px 0;
}

.malha-form-dor__linha {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.malha-form-dor__linha > * { flex: 1 1 150px; }
.malha-form-dor__linha > button { flex: 0 0 auto; }

.malha-filtros {
  /* `.card` do Bootstrap já é flex-column; sem declarar a direção, a barra de
     filtro empilhava um campo por linha. */
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.malha-filtros input,
.malha-filtros select { flex: 1 1 160px; width: auto; }

.malha-form-processo,
.malha-form-documento {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.malha-form-processo label,
.malha-form-documento label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fonte-rotulo);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #8b8474;
  font-weight: 500;
}

.malha-form-processo__largo,
.malha-form-documento__largo { grid-column: 1 / -1; }

.malha-form-documento textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.malha-timeline li {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  padding: 6px 0;
  border-top: 1px solid #f1f3f5;
  font-size: var(--fonte-corpo);
  color: #495057;
}

.malha-timeline__data { color: #8b8474; }
.malha-timeline__tipo { font-weight: 500; }
.malha-timeline__nota { color: #6c757d; }

.malha-docs li {
  padding: 7px 0;
  border-top: 1px solid #f1f3f5;
  font-size: var(--fonte-corpo);
}

.malha-prosa { font-size: var(--fonte-corpo); color: #212529; line-height: 1.5; }
.malha-prosa h1, .malha-prosa h2, .malha-prosa h3 { font-size: var(--fonte-destaque); margin: 16px 0 6px; }
.malha-prosa ul, .malha-prosa ol { padding-left: 20px; }
.malha-prosa code { background: #f1f3f5; border-radius: 4px; padding: 1px 4px; }
.malha-prosa pre { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 10px; overflow-x: auto; }
.malha-prosa table { width: 100%; font-size: var(--fonte-corpo); border-collapse: collapse; }
.malha-prosa th, .malha-prosa td { border: 1px solid #dee2e6; padding: 5px 8px; }

/* ============================================================
   CRM · VENDEDORES E REPRESENTANTES  (/crm/representantes/)
   Uma tabela para varrer com o olho: 140 linhas de cadastro. Sem cartão por
   linha — cartão por linha viraria rolagem. A cor só aparece onde há trabalho
   a fazer: a conta desligada. A tela é CONSULTA; amarrar é em /crm/usuarios/.
   ============================================================ */
.rep-resumo { display: flex; flex-wrap: wrap; gap: 24px; align-items: baseline;
              margin-bottom: 14px; }
.rep-resumo__item { display: flex; flex-direction: column; gap: 2px; }
.rep-resumo__rotulo { font-size: .72rem; letter-spacing: .04em;
                      text-transform: uppercase; color: var(--crm-tinta-2); }
.rep-numero { font-size: 1.5rem; font-weight: 600; line-height: 1;
              font-variant-numeric: tabular-nums; color: var(--crm-tinta); }
.rep-numero--alerta { color: var(--crm-avi); }
.rep-numero--ok     { color: var(--crm-ok); }


.rep-filtros { margin-bottom: 12px; }
/* Flex num `<td>` tira a célula do layout de tabela: ela deixa de obedecer ao
   `align-middle` da linha e as pílulas sobem, desalinhadas do resto da linha.
   Por isso o flex mora num `<span>` DENTRO da célula, nunca na célula. */
.rep-segmentos { display: flex; flex-wrap: wrap; gap: 4px; }
/* O segmento é etiqueta de leitura, não estado: fica em cinza, e a cor da
   tela continua reservada para o que pede providência. */
.rep-seg { font-size: .7rem; letter-spacing: .03em; padding: 1px 6px;
           border-radius: 10px; background: #eaeeec; color: var(--crm-tinta-2); }
.rep-codigo { font-variant-numeric: tabular-nums; font-weight: 600; }
.rep-nome { display: block; font-weight: 600; }
.rep-tipo { display: block; font-size: .74rem; color: var(--crm-tinta-2); }
.rep-vinculo { margin-top: 3px; }
.rep-vinculo__nome { font-size: .82rem; }
.rep-vinculo__login { font-size: .74rem; color: var(--crm-tinta-2); }
.rep-vazio { color: var(--crm-tinta-2); }
.rep-desligada { font-size: .74rem; color: var(--crm-avi); }
/* Só o código preso a conta desligada ganha marca: sem vínculo é o estado
   NORMAL de 130 dos 140 ativos (escritório de representação não tem login
   aqui), e pintá-lo de falta apagaria a falta de verdade. */
.rep-linha--conta_inativa > td:first-child { box-shadow: inset 3px 0 var(--crm-avi); }
/* Situação do CADASTRO do Sênior (#227): ponto + palavra. Inativo é cinza —
   está na lista para consulta, não pede providência. */
.rep-situacao { display: inline-flex; align-items: center; gap: 6px; font-size: .82rem;
                white-space: nowrap; }
.rep-situacao::before { content: ''; width: 7px; height: 7px; border-radius: 50%; }
.rep-situacao--ativo::before { background: var(--crm-ok); }
.rep-situacao--inativo { color: var(--crm-tinta-2); }
.rep-situacao--inativo::before { background: var(--crm-tinta-2); }
.rep-linha--inativo .rep-nome { color: var(--crm-tinta-2); }
/* Região: texto livre do Sênior, pode passar de 200 caracteres. Corta na
   reticência; o inteiro e a origem ficam na dica (`title`). */
.rep-col-regiao { max-width: 240px; }
.rep-regiao { display: block; overflow: hidden; text-overflow: ellipsis;
              white-space: nowrap; font-size: .82rem; }
/* O número de clientes é a porta do drill: parece número, age como link. */
.rep-drill-botao { border: 0; background: none; padding: 0; color: var(--crm-tinta);
                   font-variant-numeric: tabular-nums; text-decoration: underline dotted;
                   text-underline-offset: 3px; cursor: pointer; }
.rep-drill-botao:hover, .rep-drill-botao[aria-expanded="true"] { color: var(--ds-acao); }
.rep-drill > td { background: #f8f9fa; padding: 8px 16px 12px; }
.rep-drill__titulo { font-size: .78rem; color: var(--crm-tinta-2); margin: 0 0 6px; }
.rep-drill__tabela { margin: 0; max-width: 760px; font-size: .82rem; background: transparent; }
.rep-drill__corpo { max-height: 360px; overflow-y: auto; }

/* Drill de clientes atendidos (#312): dois panes — a lista e o escolhido —,
   cada um com rolagem própria; a página não rola. Estreito: só o escolhido,
   com o "Representantes" de volta. */
.rep-panes { display: grid; grid-template-columns: minmax(13rem, 16rem) minmax(0, 1fr);
             gap: 1.5rem; height: calc(100vh - 150px); min-height: 420px; }
.rep-panes[hidden] { display: none; }
.rep-pane { min-height: 0; overflow: auto; }
.rep-pane--detalhe { border-left: 1px solid var(--ds-filete, #dee2e6); padding-left: 1.5rem;
                     display: flex; flex-direction: column; }
.rep-compacta { list-style: none; margin: 0; padding: 0; }
.rep-compacta a { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) auto; gap: .5rem;
                  align-items: baseline; padding: .4rem .5rem; color: var(--crm-tinta);
                  text-decoration: none; border-bottom: 1px solid var(--ds-filete, #dee2e6); }
.rep-compacta a:hover { background: #f8f9fa; }
.rep-compacta a[aria-current="page"] { box-shadow: inset 3px 0 0 var(--ds-acao); font-weight: 600; }
.rep-compacta__nome { font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-voltar { font-size: .82rem; }
.rep-voltar i { margin-right: .35rem; }
.rep-detalhe__titulo { font-size: 1.15rem; font-weight: 600; margin: .35rem 0 0; }
.rep-detalhe__sub { font-size: .8rem; color: var(--crm-tinta-2); margin: 0 0 .75rem; }
.rep-detalhe__sub:empty { display: none; }
.rep-detalhe__barra { display: flex; flex-wrap: wrap; gap: .75rem 1.5rem; align-items: center;
                      justify-content: space-between; margin-bottom: 12px; }
.rep-numero--detalhe { font-size: 1.15rem; }
.rep-detalhe__nota { font-size: .8rem; color: var(--crm-tinta-2); margin: 0 0 .5rem; }
.rep-grade { flex: 1 1 auto; min-height: 0; }
.rep-panes { background: #fff; padding: 12px 16px; }
#rep-grade td.rep-col-cliente, #rep-grade td.rep-col-material { white-space: normal; min-width: 12rem; max-width: 18rem; }
.rep-cliente { display: block; font-weight: 600; }
@media (max-width: 991.98px) {
  .rep-panes { grid-template-columns: minmax(0, 1fr); height: auto; }
  .rep-pane--lista { display: none; }
  .rep-pane--detalhe { border-left: 0; padding-left: 0; }
}

/* ===== REUNIÃO SEMANAL (rs-*) =====================================
   Tela da reunião de segunda (STEEL). Gabarito:
   `docs/redesign/mockups/reuniao-semanal-terminal-claro.html` — a variante C,
   aprovada pelo dono em 17/09/2026. NÃO EDITAR POR GOSTO: mude o mockup
   primeiro e depois meça a tela contra ele (mesmo trato de /despesas/nova/).

   Terminal claro: tema claro fixo, uma fonte (a do shell, tabular-nums), tinta
   + uma cor de estado. Sem cartão, moldura, raio ou sombra em repouso — o que
   separa as regiões é a faixa de título clara, o conteúdo branco e o fio de
   cabelo no vão. `--dnv-mark` é seleção, foco e link; `--dnv-risco` só o que
   pede ação, e o estado vem sempre do serviço. A tela é a janela: a página não
   rola, cada região rola por dentro e AVISA quantas linhas ficaram abaixo.

   A pele vem dos tokens `--dnv-*` da seção DESPESAS (a página entra na LISTA DE
   SELETORES deles, `custom.css` ~19700) — nenhum valor de cor é copiado para cá.
   A letra é a escala da casa (#476, decisão 9): só a pele é própria.
   ================================================================== */
.rs-tela{
  /* fio de cabelo entre linhas de lista (mais claro que `--dnv-rule`) e os dois
     cinzas dos segmentos (entrada/saída, faturado/carteira). Escopo de página. */
  --rs-fio:#ECEEF1; --rs-seg-1:#2B323C; --rs-seg-3:#AAB1BA;
  background:var(--dnv-surface);color:var(--dnv-ink);font-family:var(--dnv-sans);
  line-height:1.2;-webkit-font-smoothing:antialiased;overflow:hidden;color-scheme:light}
.rs-tela button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;text-align:left}
.rs-tela :focus-visible{outline:2px solid var(--dnv-mark);outline-offset:1px}
.rs-tela .rs-d,.rs-tela .rs-cnv,.rs-tela .rs-val,.rs-tela .rs-dia b,.rs-tela .rs-caixatot b,
.rs-tela .rs-tb td,.rs-tela .rs-dev-dias{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1,"lnum" 1}
.rs-tela .rs-mudo{color:var(--dnv-ink-3)}
.rs-tela .rs-risco{color:var(--dnv-risco)}
.rs-tela h2{margin:0}
/* a tela encosta na barra lateral e na borda direita da janela: quem dá o
   respiro é `.rs-app`, com o mesmo recuo do gabarito. */
.content--altura-cheia > .page.rs-tela{padding:0}
/* rótulos dos seletores do topo no vocabulário de /despesas/nova/ (`.dnv-k`):
   rótulo pequeno em versal, valor em 600. Só na barra desta tela. */

/* ── estrutura: três faixas empilhadas, sem cartão ─────────────────────── */
.rs-tela .rs-app{flex:1 1 auto;min-height:0;min-width:0;display:flex;flex-direction:column;gap:25px;padding:14px 20px 12px;overflow-y:auto}
.rs-tela .rs-l1{flex:0 0 auto;position:relative}
.rs-tela .rs-l2{flex:0 0 auto;position:relative;display:grid;grid-template-columns:minmax(0,max-content) minmax(280px,1fr);gap:25px}   /* áreas na largura do conteúdo (reporte #122: o ESTOQUE · VOLUME cortava em 1600); o diário fica com o resto */
/* a faixa de baixo não encolhe abaixo de 420px (#554): em 1366×768 e 1440×900 o espremido zerava a lista de
   maiores devedores; com a janela baixa, quem cede é a rolagem do `.rs-app`, não o conteúdo */
.rs-tela .rs-l3{flex:1 1 0;min-height:420px;position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:25px}
.rs-tela .rs-bloco{position:relative;min-width:0;min-height:0;display:flex;flex-direction:column}
/* o fio de cabelo mora no VÃO, na metade dele — não é borda de cartão */
.rs-tela .rs-sep-t::before{content:"";position:absolute;top:-13px;left:0;right:0;height:1px;background:var(--dnv-rule)}
.rs-tela .rs-sep-l::before{content:"";position:absolute;left:-13px;top:0;bottom:0;width:1px;background:var(--dnv-rule)}
/* faixa de título clara + conteúdo branco: a separação sem cartão */
.rs-tela .rs-cab{flex:0 0 auto;display:flex;align-items:center;gap:8px;min-height:28px;margin-bottom:6px;
  padding:0 10px;background:var(--dnv-surface-3);white-space:nowrap}
.rs-tela .rs-cab h2{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.02em}
.rs-tela .rs-cab-meta{margin-left:auto;display:flex;align-items:center;gap:14px;
  font-size:var(--fonte-rotulo);letter-spacing:.04em;text-transform:uppercase;color:var(--dnv-ink-2)}
.rs-tela .rs-cab-meta b{font-weight:500;color:var(--dnv-ink)}
.rs-tela .rs-corpo{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
.rs-tela .rs-corpo[hidden]{display:none}

/* ── gramática comum ──────────────────────────────────────────────────── */
.rs-tela .rs-rot{display:inline-flex;align-items:center;gap:6px;font-size:var(--fonte-rotulo);font-weight:500;
  letter-spacing:.04em;text-transform:uppercase;color:var(--dnv-ink-3);white-space:nowrap}
.rs-tela .rs-rot.rs-risco{color:var(--dnv-risco)}
/* o que abre gaveta tem sublinhado SEMPRE visível: a porta não se esconde até
   o ponteiro passar. Uma porta por registro — o valor é a porta. */
.rs-tela .rs-drill{cursor:pointer;text-decoration:underline;text-decoration-thickness:1px;
  text-decoration-color:var(--dnv-rule-2);text-underline-offset:3px}
.rs-tela .rs-drill:hover{text-decoration-color:var(--dnv-ink)}
.rs-tela .rs-link,.rs-tela .rs-acao,.rs-tela .rs-abrir{color:var(--bs-link-color);font-weight:500;white-space:nowrap;text-decoration:underline}
.rs-tela .rs-link:hover,.rs-tela .rs-acao:hover,.rs-tela .rs-abrir:hover{color:var(--bs-link-hover-color)}
.rs-tela .rs-acao{font-size:var(--fonte-rotulo);letter-spacing:.03em}
.rs-tela .rs-link[hidden],.rs-tela .rs-acao[hidden]{display:none}
.rs-tela .rs-frase{font-size:var(--fonte-pequena);color:var(--dnv-ink-2);white-space:nowrap}
.rs-tela .rs-dir{margin-left:auto}
.rs-tela .rs-vazio{padding:8px 0;font-size:var(--fonte-pequena);color:var(--dnv-ink-3)}
/* amostra da cor do segmento, do tamanho de uma letra */
.rs-tela .rs-am{display:inline-block;width:9px;height:9px;flex:none}
.rs-tela .rs-t1{background:var(--rs-seg-1)}
.rs-tela .rs-t2{background:repeating-linear-gradient(135deg,var(--rs-seg-1) 0 2px,var(--dnv-surface) 2px 4px)}
.rs-tela .rs-t3{background:var(--rs-seg-3)}
.rs-tela .rs-t4{background:repeating-linear-gradient(135deg,var(--rs-seg-3) 0 2px,var(--dnv-surface) 2px 4px)}
.rs-tela .rs-t5{background:repeating-linear-gradient(135deg,var(--dnv-risco) 0 1.5px,var(--dnv-surface) 1.5px 5px);
  box-shadow:inset 0 0 0 1px var(--dnv-risco)}
/* par de visões (Previsão/Fluxo, Pauta/Projetos): aba sublinhada, não pílula */
.rs-tela .rs-par{display:flex;gap:12px}
.rs-tela .rs-pr{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-3);
  padding:4px 0;border-bottom:2px solid transparent;white-space:nowrap}
.rs-tela .rs-pr:hover{color:var(--dnv-ink)}
.rs-tela .rs-pr.rs-on{color:var(--dnv-ink);border-bottom-color:var(--dnv-mark)}
.rs-tela .rs-par-titulo .rs-pr{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.02em}
.rs-tela .rs-par-titulo .rs-pr b{margin-left:4px;font-weight:400;color:var(--dnv-ink-3)}
.rs-tela .rs-par-titulo .rs-pr b:empty{display:none}

/* ── a conta do mês: parcela + parcela + … = firme, e o que falta vender ── */
.rs-tela .rs-conta{display:flex;align-items:flex-start;justify-content:space-between;gap:6px;margin:0 0 10px}
.rs-tela .rs-pcl,.rs-tela .rs-res,.rs-tela .rs-vender{display:flex;flex-direction:column;gap:2px;min-width:0}
.rs-tela .rs-vender{padding-left:18px}
.rs-tela .rs-op{font-size:var(--fonte-destaque);color:var(--dnv-ink-3);padding-top:18px}
.rs-tela .rs-cnv{font-size:var(--fonte-titulo);font-weight:500;line-height:1.2;letter-spacing:-.01em;white-space:nowrap}
.rs-tela .rs-res .rs-cnv,.rs-tela .rs-vender .rs-cnv{font-size:var(--fonte-heroi);font-weight:500}
.rs-tela .rs-cns{font-size:var(--fonte-pequena);color:var(--dnv-ink-2);white-space:nowrap}
/* a trilha é a mesma conta, em largura: cada pedaço já vem em % do serviço */
.rs-tela .rs-trilho{position:relative;height:10px;display:flex;background:var(--dnv-surface)}
.rs-tela .rs-sg{height:100%;display:block}
.rs-tela .rs-trilho-meta{position:absolute;top:-5px;bottom:-5px;width:2px;margin-left:-2px;background:var(--dnv-ink)}
.rs-tela .rs-trilho-meta b{position:absolute;right:4px;top:calc(100% + 3px);font-size:var(--fonte-rotulo);
  font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-2);white-space:nowrap;font-variant-numeric:tabular-nums}

/* ── tabelas: a régua do gabarito ─────────────────────────────────────── */
.rs-tela .rs-tb{width:100%;border-collapse:collapse;font-size:var(--fonte-corpo)}
.rs-tela .rs-tb th{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-2);
  text-align:right;padding:0 8px;height:20px;white-space:nowrap;vertical-align:bottom}
.rs-tela .rs-tb th:first-child,.rs-tela .rs-tb td:first-child{text-align:left;padding-left:0}
.rs-tela .rs-tb th:last-child,.rs-tela .rs-tb td:last-child{padding-right:0}
.rs-tela .rs-tb td{padding:0 8px;height:25px;text-align:right;white-space:nowrap;
  border-bottom:1px solid var(--rs-fio)}
.rs-tela .rs-tb .rs-d{text-align:right}
.rs-tela .rs-tb .rs-n{text-align:left}
.rs-tela .rs-tb .rs-pct{color:var(--dnv-ink-2)}
.rs-tela .rs-tb td.rs-vol{white-space:normal;line-height:1.2;padding-top:3px;padding-bottom:3px}   /* estoque: R$ em cima, volume embaixo; várias unidades quebram entre elas, nunca no meio de uma (reporte #122) */
.rs-tela .rs-tb .rs-sub-vol{display:block;font-size:var(--fonte-pequena);color:var(--dnv-ink-3)}
.rs-tela .rs-tb .rs-nw{white-space:nowrap}
.rs-tela .rs-tb tbody tr:hover td{background:var(--dnv-surface-2)}
/* áreas: os grupos (Faturamento · Volume · Margem bruta) se separam por respiro,
   com um fio sob o rótulo que começa na 1ª coluna do grupo. */
.rs-tela .rs-tb-areas thead tr.rs-grupos th{color:var(--dnv-ink);font-weight:500;text-align:left;vertical-align:bottom}
.rs-tela .rs-tb-areas thead tr.rs-grupos th span{display:block;border-bottom:1px solid var(--dnv-rule-2);
  padding-bottom:2px;margin-right:6px}
.rs-tela .rs-tb-areas thead tr.rs-colunas th{border-bottom:1px solid var(--dnv-ink)}
.rs-tela .rs-tb-areas td.rs-vao,.rs-tela .rs-tb-areas th.rs-vao{padding:0 6px;width:14px}   /* o vão guarda o fio da linha: sem ele o filete da linha nasce picado */
.rs-tela .rs-tb-areas tfoot td{border-top:1px solid var(--dnv-ink);border-bottom:0;font-weight:500;
  height:27px}
/* cabeçalho que ordena (dono, 17/09/2026): o rótulo é o próprio botão, sem
   moldura em repouso — a coluna ativa é a que mostra a seta. As duas colunas de
   VOLUME não ordenam (KG, RL e PC não formam um ranking), e por isso continuam
   `th` de texto: o que não é clicável não parece clicável. */
.rs-tela .rs-ord{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:3px;
  font:inherit;color:inherit;letter-spacing:inherit}
.rs-tela .rs-ord:hover{color:var(--dnv-mark)}
.rs-tela .rs-ord:focus-visible{outline:1px solid var(--dnv-mark);outline-offset:2px}
.rs-tela .rs-seta{font-size:var(--fonte-pequena)}
.rs-tela .rs-seta-repouso{opacity:.35}
/* O ícone não entra na largura da coluna (somava 16px e a tabela rolava de lado
   em 1366): fica no vão à esquerda do rótulo, que as colunas numéricas já têm
   por causa dos valores; a coluna de texto (`rs-n`), à direita.
   Vale para TODO cabeçalho que ordena, não só o das áreas: no Comex, com quatro
   colunas ordenáveis, os ícones somavam 21px e o cartão (301px em 1366) passava
   a pedir 322px. Escopo `.rs-ord` — nunca o `▸` do drill, que não é botão. */
.rs-tela .rs-ord{position:relative}
.rs-tela .rs-ord .rs-seta{position:absolute;right:100%;margin-right:2px}
.rs-tela .rs-n .rs-ord .rs-seta{right:auto;left:100%;margin:0 0 0 3px}
.rs-tela .rs-ord:hover .rs-seta-repouso{opacity:.8}
.rs-tela .rs-tb-areas thead tr.rs-colunas th.rs-ord-on{color:var(--dnv-ink)}
.rs-tela .rs-area{max-width:100%;display:inline-block;vertical-align:bottom}

/* ── faturamento diário: o SVG é desenhado em pixel (não estica) ───────── */
.rs-tela .rs-graf{position:relative;flex:1 1 auto;min-height:110px;min-width:0}
.rs-tela .rs-graf svg{position:absolute;inset:0;overflow:visible}
.rs-tela .rs-graf text{font-family:inherit;font-size:var(--fonte-pequena);fill:var(--dnv-ink-3)}
.rs-tela .rs-graf .rs-g-forte{fill:var(--dnv-ink);font-weight:500}
.rs-tela .rs-graf .rs-graf-avender{fill:var(--dnv-risco);font-weight:500}
.rs-tela .rs-g-grade{stroke:var(--rs-fio)}
.rs-tela .rs-g-base{stroke:var(--dnv-rule-2)}
.rs-tela .rs-g-hoje{stroke:var(--dnv-rule-3);stroke-dasharray:2 3}
.rs-tela .rs-g-anterior{fill:none;stroke:var(--chart-azul);stroke-opacity:.45;stroke-width:1.5}
.rs-tela .rs-g-meta{stroke:var(--chart-azul);stroke-dasharray:5 4;stroke-width:1.3}
.rs-tela .rs-g-faturado-area{fill:var(--chart-azul);fill-opacity:.12}
.rs-tela .rs-g-faturado{fill:none;stroke:var(--dnv-ink);stroke-width:2}
.rs-tela .rs-g-firme{fill:none;stroke:var(--dnv-ink);stroke-width:1.5;stroke-dasharray:5 3}
.rs-tela .rs-g-vao{stroke:var(--dnv-risco);stroke-width:3}
.rs-tela .rs-g-ponto{fill:var(--dnv-ink)}
/* cores do Faturamento (dono, 29/09/2026): a linha do mês na valência do ritmo contra a meta */
.rs-tela .rs-g-pos{stroke:var(--positive)}.rs-tela .rs-g-alerta{stroke:#FF7B00}.rs-tela .rs-g-neg{stroke:var(--negative)}
.rs-tela .rs-g-ponto.rs-g-pos{fill:var(--positive)}.rs-tela .rs-g-ponto.rs-g-alerta{fill:#FF7B00}.rs-tela .rs-g-ponto.rs-g-neg{fill:var(--negative)}
.rs-tela .num--alerta{color:#FF7B00 !important}   /* exceção da Reunião Semanal (tela com pele própria, terminal claro), mantida por decisão do dono até reporte próprio (#229) */
.rs-tela .rs-g-mira{stroke:var(--dnv-mark)}
.rs-tela .rs-g-zona{fill:transparent}

/* ── dica (gráfico diário e dia do caixa): a de /despesas/nova/ ─────────── */
.rs-tela .rs-balao{position:fixed;z-index:70;pointer-events:none;display:flex;flex-direction:column;gap:2px;min-width:12rem;
  padding:8px 11px;background:var(--dnv-surface);border:1px solid var(--dnv-rule-2);box-shadow:0 10px 24px -12px rgba(0,0,0,.35);
  font-size:var(--fonte-pequena);color:var(--dnv-ink-2);white-space:nowrap}
.rs-tela .rs-balao[hidden]{display:none}
.rs-tela .rs-balao-k{margin-bottom:2px;font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.06em;color:var(--dnv-ink-3)}
.rs-tela .rs-balao-l{display:flex;justify-content:space-between;gap:1rem}
.rs-tela .rs-balao-l b{font-weight:500;color:var(--dnv-ink);font-variant-numeric:tabular-nums}
.rs-tela .rs-balao-l b.rs-risco{color:var(--dnv-risco)}

/* ── inadimplência ────────────────────────────────────────────────────── */
/* cabeçalho de número grande, comum à inadimplência e ao Comex */
/* o cabeçalho quebra em vez de estourar a coluna: em 1366 a contagem de
   títulos não cabe ao lado do valor, e número cortado não é número. */
.rs-tela .rs-cab2{flex:0 0 auto;display:flex;flex-wrap:wrap;align-items:baseline;gap:0 10px;margin:4px 0 6px;min-width:0;white-space:nowrap}
.rs-tela .rs-val{font-size:var(--fonte-titulo);font-weight:500;letter-spacing:-.01em}
.rs-tela .rs-fxs{flex:0 0 auto;display:grid;grid-template-columns:auto minmax(30px,1fr) auto;column-gap:10px;
  align-items:center;font-size:var(--fonte-pequena)}
.rs-tela .rs-fxs > *{height:20px;display:flex;align-items:center}
.rs-tela .rs-fxs .rs-d{justify-content:flex-end}
.rs-tela .rs-trk{height:6px;display:block;align-self:center;background:var(--dnv-surface-3)}
.rs-tela .rs-trk i{display:block;height:100%;background:var(--rs-seg-1)}
/* minigráfico do % da carteira em 12 meses (#365): rótulo · linha · rótulo, na
   métrica das faixas logo abaixo; o SVG estica, o traço não engrossa. */
.rs-tela .rs-serie{flex:0 0 auto;display:grid;grid-template-columns:auto minmax(30px,1fr) auto;column-gap:10px;
  align-items:center;margin:0 0 6px;font-size:var(--fonte-pequena)}
.rs-tela .rs-serie svg{display:block;width:100%;height:27px;overflow:visible}
.rs-tela .rs-serie polyline{fill:none;stroke:var(--rs-seg-1);stroke-width:1.5;vector-effect:non-scaling-stroke;
  stroke-linejoin:round}
.rs-tela .rs-serie rect{fill:transparent}
.rs-tela .rs-serie rect:hover{fill:var(--dnv-surface-3);fill-opacity:.6}
.rs-tela .rs-trk.rs-risco i{background:var(--dnv-risco)}
.rs-tela .rs-dev{flex:1 1 auto;min-height:0;overflow:auto;align-content:start;margin-top:4px;display:grid;
  grid-template-columns:minmax(0,1fr) auto auto;grid-auto-rows:min-content;column-gap:10px;align-items:center;font-size:var(--fonte-pequena)}
.rs-tela .rs-dev .rs-rot{grid-column:1/-1;height:20px;display:flex;align-items:flex-end;padding-bottom:3px}
.rs-tela .rs-dev ol{display:contents;margin:0;padding:0;list-style:none}
.rs-tela .rs-dev li{display:contents}
/* nome longo quebra linha e a linha cresce junto (#554): altura mínima, não fixa; min-content na faixa porque a
   caixa rola (com o conteúdo maior que ela, faixa auto fica no mínimo); stretch põe o fio das 3 células no pé da linha */
.rs-tela .rs-dev li > *{min-height:19px;align-self:stretch;display:flex;align-items:center;border-bottom:1px solid var(--rs-fio)}
.rs-tela .rs-dev-nome{display:block!important;padding:1px 0;
  line-height:16px}
.rs-tela .rs-dev-dias{justify-content:flex-end;color:var(--dnv-ink-3);font-size:var(--fonte-rotulo);
  text-transform:uppercase;white-space:nowrap}
.rs-tela .rs-dev .rs-d{justify-content:flex-end;white-space:nowrap}
/* vencido por ano (#538, #568): ano · emissão (valor, %) · vencimento (valor, %), na métrica dos devedores */
/* respiro de 12px separa o bloco dos anos das faixas de atraso (#568): o valor da faixa "Mais de 90" lia como total dos anos */
.rs-tela .rs-anos{flex:0 0 auto;margin-top:12px;display:grid;grid-template-columns:minmax(0,1fr) auto auto auto auto;
  column-gap:10px;align-items:center;font-size:var(--fonte-pequena)}
.rs-tela .rs-anos .rs-rot{grid-column:1/-1;height:20px;display:flex;align-items:flex-end;padding-bottom:3px}
.rs-tela .rs-anos ol{display:contents;margin:0;padding:0;list-style:none}
.rs-tela .rs-anos li{display:contents}
.rs-tela .rs-anos li > *{height:19px;display:flex;align-items:center;gap:6px;border-bottom:1px solid var(--rs-fio);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.rs-tela .rs-anos .rs-d{justify-content:flex-end}
.rs-tela .rs-ano-pct,.rs-tela .rs-ano-meta{color:var(--dnv-ink-3)}
.rs-tela .rs-anos .rs-ano-total > *{font-weight:500}
/* cabeçalho dos dois recortes (#568): cada um cobre valor e % */
.rs-tela .rs-anos .rs-ano-cab{grid-column:span 2;height:16px;display:flex;align-items:flex-end;justify-content:center;
  font-size:var(--fonte-rotulo);font-weight:500;color:var(--dnv-ink-3);letter-spacing:.02em}

/* ── caixa do mês: calendário compacto, valor só na dica ───────────────── */
.rs-tela .rs-caixatot{flex:0 0 auto;display:grid;grid-template-columns:repeat(3,auto);justify-content:space-between;
  margin:4px 0 6px;gap:0 10px}
.rs-tela .rs-caixatot > span{display:flex;flex-direction:column;min-width:0}
.rs-tela .rs-caixatot .rs-dir{text-align:right;align-items:flex-end;margin-left:0}
.rs-tela .rs-caixatot b{font-size:var(--fonte-corpo);font-weight:500;white-space:nowrap}
.rs-tela .rs-cal{flex:1 1 auto;min-height:0;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  grid-template-rows:auto;grid-auto-rows:minmax(0,1fr);column-gap:3px;row-gap:3px}
.rs-tela .rs-sem{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-3);padding-bottom:2px}
.rs-tela .rs-dia{position:relative;min-height:0;padding:2px 3px;border-top:1px solid var(--rs-fio);width:100%;
  display:flex;flex-direction:column;align-items:stretch}   /* flex, não block: `<button>` centra o miolo na vertical e o dia sairia do alto da célula */
.rs-tela span.rs-dia{cursor:default}
.rs-tela .rs-dia:hover{background:var(--dnv-surface-2)}
.rs-tela .rs-dia.rs-vazio{border-top:0}
.rs-tela .rs-dia b{display:block;font-size:var(--fonte-pequena);font-weight:400;color:var(--dnv-ink-2);line-height:1}
.rs-tela .rs-dia.rs-fds b{color:var(--dnv-rule-3)}
/* dia negativo é MARCADO, sem valor escrito: o número mora na dica */
.rs-tela .rs-dia.rs-neg b{color:var(--dnv-risco);font-weight:500}
.rs-tela .rs-dia.rs-hoje{box-shadow:inset 0 2px 0 var(--dnv-mark)}
.rs-tela .rs-dia.rs-hoje b{color:var(--dnv-mark);font-weight:500}
.rs-tela .rs-fl{position:absolute;left:3px;right:3px;bottom:2px;top:14px;display:flex;align-items:flex-end;
  gap:2px;justify-content:flex-end}
.rs-tela .rs-fl i{width:5px;display:block;min-height:1px}
.rs-tela .rs-fl .rs-e{background:var(--rs-seg-1)}
.rs-tela .rs-fl .rs-s{background:var(--rs-seg-3)}
/* fonte parada: uma linha vermelha por cima e o conteúdo apagado — o número
   velho continua legível, mas não se confunde com o de agora. */
.rs-tela .rs-avisofrio{flex:0 0 auto;padding:2px 0 4px;font-size:var(--fonte-pequena);font-weight:500;color:var(--dnv-risco);
  white-space:normal}
.rs-tela .rs-frio{opacity:.4}

/* ── comex em trânsito: o detalhe abre NA LINHA ────────────────────────── */
.rs-tela .rs-tb-proc th{position:sticky;top:0;z-index:1;background:var(--dnv-surface);
  font-size:var(--fonte-pequena);height:18px;border-bottom:1px solid var(--dnv-ink);padding:0 0 0 8px}
.rs-tela .rs-tb-proc td{height:22px;padding:0 0 0 8px}
.rs-tela .rs-tb-proc tr.rs-linha{cursor:pointer}
.rs-tela .rs-tb-proc tr.rs-linha:hover td{background:var(--dnv-surface-2)}
.rs-tela .rs-seta{display:inline-block;width:12px;font-style:normal;color:var(--dnv-ink-3);transition:transform .15s ease-out}
.rs-tela .rs-tb-proc tr[aria-expanded="true"] .rs-seta{transform:rotate(90deg);color:var(--dnv-ink)}
.rs-tela .rs-tb-proc tr[aria-expanded="true"] td{border-bottom-color:transparent;font-weight:500}
.rs-tela .rs-quando{margin-left:6px;color:var(--dnv-ink-3);font-size:var(--fonte-pequena)}
/* A contagem regressiva da ENTREGA ("3 dias") custa 28px: com ela a tabela pede
   300px, e o cartão tem 279px em 1280 — por isso ela some abaixo de 1366, onde
   fica só a data de entrega, que é o dado.
   RISCO CONHECIDO, aceito pelo dono em 22/09/2026 com o número na mesa: em 1366
   o cartão tem 301px e a tabela pede 301px — folga ZERO. Medido: com um
   `codigo_processo_four` de 12 caracteres (REC41972/26B) a tabela passa a pedir
   307px e o cartão ROLA DE LADO em 1366; com 13, pede 314px. REC4197/26B, o mais
   longo que existe hoje, é o que cabe. Se um código maior aparecer, o conserto é
   subir este breakpoint para 1599 — em 1600 a folga é de 32px, em 1920 de 112px.
   Folga por largura: 1280 → 7px (sem contagem), 1366 → 0px, 1600 → 32px,
   1920 → 112px. */
@media (max-width:1365px){.rs-tela .rs-tb-proc .rs-quando{display:none}}
/* CHEGADA mistura duas naturezas de data na mesma coluna: a REAL (tom cheio, sem
   marca) e a PREVISTA (tom fraco, com o "~" que o serviço já manda). Os dois
   sinais juntos dispensam legenda — reporte #106, continuação. */
.rs-tela .rs-tb-proc td.rs-prevista{color:var(--dnv-ink-3)}
.rs-tela .rs-tb-proc .rs-eta-vencida{color:var(--dnv-risco)}
/* "No porto": segunda linha só de quem já chegou ao porto (reporte #106). Quem
   está na água não ganha linha nenhuma e a densidade fica. Era "Atracou em
   16/09/2026 — no porto" e encolheu para o ESTADO (dono, 22/09/2026): a data
   passou a viver na coluna CHEGADA, e a frase longa sozinha exigia 177px da
   coluna PROCESSO — a tabela pedia 378px num bloco de 301px em 1366.
   Segue podendo QUEBRAR (`white-space:normal`, reporte #122): curta ela não
   quebra em largura nenhuma, então o `normal` não custa um pixel hoje e é o que
   impede uma frase maior, amanhã, de fazer o cartão rolar de lado outra vez. */
.rs-tela .rs-tb-proc .rs-porto{display:block;margin-left:12px;color:var(--dnv-ink-3);
  font-size:var(--fonte-pequena);white-space:normal}
.rs-tela .rs-detalhe td{padding:0 0 8px;text-align:left;white-space:normal;border-bottom:1px solid var(--rs-fio);height:auto}
.rs-tela .rs-quadro{border:1px solid var(--dnv-rule);padding:8px 10px;font-size:var(--fonte-pequena)}
.rs-tela .rs-quadro dl{display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px 10px;margin:0 0 8px}
.rs-tela .rs-quadro dt{font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-3);align-self:center}
.rs-tela .rs-quadro dd{margin:0}
.rs-tela .rs-itens{list-style:none;margin:2px 0 0;padding:0}
.rs-tela .rs-itens li{padding:4px 0;border-top:1px solid var(--rs-fio)}
.rs-tela .rs-it-num{display:flex;justify-content:space-between;gap:8px;margin-top:1px;color:var(--dnv-ink-2);
  font-variant-numeric:tabular-nums}
.rs-tela .rs-it-num b{color:var(--dnv-ink);font-weight:500}
.rs-tela .rs-it-cod{margin-right:6px;color:var(--dnv-ink-3);font-variant-numeric:tabular-nums}
.rs-tela .rs-busca{flex:0 0 auto;width:100%;margin:0 0 6px}

/* ── pauta e projetos: um bloco, duas abas ─────────────────────────────── */
.rs-tela .rs-frm{flex:0 0 auto;display:flex;gap:6px;padding:4px 0 6px;border-bottom:1px solid var(--dnv-rule)}
.rs-tela .rs-frm[hidden]{display:none}
.rs-tela .rs-cmp{min-width:0;height:1.6rem;padding:0 6px;border:1px solid var(--dnv-rule-2);border-radius:0;
  background:var(--dnv-surface);color:var(--dnv-ink);font:inherit;font-size:var(--fonte-pequena);appearance:none}
.rs-tela .rs-frm .rs-cmp{flex:1 1 auto}
.rs-tela .rs-cmp::placeholder{color:var(--dnv-ink-3);letter-spacing:.04em}
.rs-tela .rs-cmp:focus{outline:0;border-color:var(--dnv-mark)}
.rs-tela .rs-frm .rs-sel-pessoas{flex:0 0 9rem}
.rs-tela .rs-botao{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;flex:none;
  height:1.6rem;padding:0 10px;border:0;border-radius:4px;background:var(--dnv-mark);color:var(--dnv-surface);
  font-size:var(--fonte-pequena);font-weight:500;white-space:nowrap}
.rs-tela .rs-botao:hover{filter:brightness(1.12)}
.rs-tela .rs-erro{padding:2px 0;font-size:var(--fonte-pequena);color:var(--dnv-risco)}
.rs-tela .rs-erro:empty{display:none}
.rs-tela .rs-tf,.rs-tela .rs-ft{display:grid;grid-template-columns:18px minmax(0,1fr) auto;gap:6px;
  align-items:start;padding:4px 0;border-bottom:1px solid var(--rs-fio);font-size:var(--fonte-pequena)}
.rs-tela .rs-cxb,.rs-tela .rs-q{width:13px;height:13px;margin-top:2px;flex:none;
  border:1px solid var(--dnv-rule-3);background:var(--dnv-surface)}
.rs-tela .rs-cxb:hover{border-color:var(--dnv-mark)}
.rs-tela .rs-q.rs-ok,.rs-tela .rs-feito .rs-cxb{background:var(--dnv-mark);border-color:var(--dnv-mark)}
.rs-tela .rs-tt,.rs-tela .rs-ftt{min-width:0;overflow-wrap:anywhere}
.rs-tela .rs-feito .rs-tt,.rs-tela .rs-risc{color:var(--dnv-ink-3);text-decoration:line-through}
.rs-tela .rs-tt .rs-mudo{margin-left:4px;font-size:var(--fonte-pequena)}
.rs-tela .rs-resp{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.03em;color:var(--dnv-ink-2);
  padding-top:1px;white-space:nowrap}
.rs-tela .rs-resp.rs-risco{color:var(--dnv-risco)}
/* O ponto de pauta ganhou uma quarta coluna: o × que manda para a lixeira.
   Ele só aparece quando o cursor (ou o teclado) está na linha — gesto do
   To-Do: a linha fica limpa e a ação aparece onde a mão está. */
.rs-tela .rs-tf{grid-template-columns:18px minmax(0,1fr) auto 12px}
.rs-tela .rs-xr{width:12px;line-height:1;text-align:center;color:var(--dnv-ink-3);
  opacity:0;transition:opacity .12s}
.rs-tela .rs-tf:hover .rs-xr,.rs-tela .rs-tf:focus-within .rs-xr{opacity:1}
.rs-tela .rs-xr:hover{color:var(--dnv-risco)}
/* O título abre o detalhe: é botão, e o único sinal disso é o cursor — fio
   embaixo em dezesseis linhas viraria cerca. */
.rs-tela button.rs-tt,.rs-tela button.rs-ftt{width:100%}
.rs-tela button.rs-tt:hover,.rs-tela button.rs-ftt:hover{color:var(--dnv-mark)}
/* A oferta de DESFAZER, entre a recusa e a lista. */
.rs-tela .rs-desfeito{display:flex;align-items:center;gap:8px;
  font-size:var(--fonte-pequena);color:var(--dnv-ink-2)}
.rs-tela .rs-desfeito:empty{display:none}
.rs-tela .rs-desfeito span{min-width:0;}
.rs-tela .rs-desf{margin-left:auto;flex:none;font-size:var(--fonte-pequena);font-weight:500;
  letter-spacing:.03em;color:var(--dnv-mark);text-decoration:underline}
.rs-tela .rs-pj{padding-bottom:6px}
.rs-tela .rs-pj-cab{display:flex;align-items:baseline;gap:10px;padding:4px 0 2px}
.rs-tela .rs-pj-cab .rs-t{font-weight:500;font-size:var(--fonte-corpo)}
.rs-tela .rs-pj-prog{font-size:var(--fonte-pequena);color:var(--dnv-ink-2);white-space:nowrap}
.rs-tela .rs-pj-cab .rs-abrir{margin-left:auto;font-size:var(--fonte-pequena);letter-spacing:.03em}
.rs-tela .rs-prog{height:4px;margin:2px 0 6px;background:var(--dnv-surface-3)}
.rs-tela .rs-prog i{display:block;height:100%;background:var(--rs-seg-1)}
.rs-tela .rs-pj .rs-s{font-size:var(--fonte-pequena);color:var(--dnv-ink-2)}
.rs-tela .rs-fn{display:flex;gap:8px;padding:6px 0 1px;font-size:var(--fonte-rotulo);font-weight:500;
  letter-spacing:.04em;text-transform:uppercase;color:var(--dnv-ink-2)}
.rs-tela .rs-fn span:first-child{flex:1;min-width:0}
.rs-tela #rs-pauta-minhas{flex:0 0 auto;padding-top:4px;font-size:var(--fonte-pequena);letter-spacing:.04em}

/* ── rolagem por dentro: a pista avisa quantas linhas ficaram abaixo ───── */
.rs-tela .rs-rola{position:relative;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-width:thin}
.rs-tela .rs-rola.rs-tem-mais{-webkit-mask-image:linear-gradient(#000 calc(100% - 18px),rgba(0,0,0,.25));
  mask-image:linear-gradient(#000 calc(100% - 18px),rgba(0,0,0,.25))}
.rs-tela .rs-mais{flex:0 0 auto;height:15px;line-height:16px;text-align:right;font-size:var(--fonte-pequena);
  font-weight:500;letter-spacing:.04em;color:var(--dnv-ink-2)}
.rs-tela .rs-mais:empty{display:none}

/* ── janelas: cabeçalho comum aos três diálogos ───────────────────────── */
.rs-tela .rs-hd{flex:none;display:flex;flex-wrap:wrap;align-items:center;align-content:flex-start;gap:0 .5rem;min-height:2.25rem;padding:.25rem .75rem}
.rs-tela .rs-hd h2{margin:0;font-size:var(--fonte-corpo);line-height:28px;font-weight:500;letter-spacing:.04em;color:var(--dnv-ink);white-space:nowrap}
.rs-tela .rs-hd > .rs-par{margin-left:auto}
.rs-tela .rs-botao-principal{font-weight:500}

/* ── estado de carga e falha ──────────────────────────────────────────── */
.rs-tela .rs-esqueleto{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;gap:.625rem;padding:.75rem}
.rs-tela .rs-esqueleto i{display:block;height:10px;background:linear-gradient(100deg,var(--dnv-surface-3) 0 38%,var(--dnv-surface-2) 52%,var(--dnv-surface-3) 66% 100%);
  background-size:320% 100%;animation:rs-esqueleto 1.25s linear infinite}
.rs-tela .rs-esqueleto i:nth-child(2n){width:72%} .rs-tela .rs-esqueleto i:nth-child(3n){width:88%}
@keyframes rs-esqueleto{from{background-position:130% 0}to{background-position:-190% 0}}
@media (prefers-reduced-motion:reduce){.rs-tela .rs-esqueleto i{animation:none}}
.rs-tela .rs-falha{flex:1;min-height:0;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
  gap:.5rem;padding:.75rem;font-size:var(--fonte-corpo);color:var(--dnv-ink-3)}
.rs-tela .rs-tentar{height:1.75rem;padding:0 .625rem;border:1px solid var(--dnv-rule-2);color:var(--dnv-ink);font-size:var(--fonte-corpo)}

/* ── diálogos: a única sombra da tela ─────────────────────────────────────
   `<dialog>` sobe para a top layer e continua herdando os tokens de `.rs-tela`
   por ser filho dela no DOM. */
.rs-tela .rs-dialog{width:100%;max-width:min(920px,92vw);max-height:86vh;overflow:auto;padding:0;border:1px solid var(--dnv-rule-2);
  border-radius:0;background:var(--dnv-surface);color:var(--dnv-ink);font:var(--fonte-corpo)/1.5 var(--dnv-sans);
  box-shadow:0 12px 32px rgb(11 14 18/.16)}
.rs-tela .rs-dialog::backdrop{background:rgb(11 14 18/.32)}
.rs-tela .rs-dialog-largo{max-width:min(1400px,96vw)}
.rs-tela .rs-dialog .rs-hd{position:sticky;top:0;z-index:3;background:var(--dnv-surface);border-bottom:1px solid var(--dnv-rule)}
.rs-tela .rs-dialog .rs-hd h2{text-transform:uppercase;letter-spacing:.04em}
/* registros na grade da casa: a janela cabe na tela e só a grade rola por
   dentro; texto livre corta em reticências (texto inteiro no `title`) para a
   coluna de valor nunca sair da janela */
/* a gaveta da ÁREA prova três números (R$, volume e margem) e por isso leva dez
   colunas: a janela usa a largura do `rs-dialog-largo`, senão a coluna Valor sai
   dela. Mesmo teto do quadro de metas do ano, na mesma tela. */
.rs-tela .rs-dialog-registros{max-width:min(1400px,96vw)}
.rs-tela .rs-dialog-registros .grade{padding:0 .75rem .5rem;background:var(--dnv-surface)}
.rs-tela .rs-dialog-registros .grade .rs-reg-texto{max-width:18rem}
/* a gaveta da ÁREA é a mais larga: além do R$ ela prova volume e margem
   (quantidade, líquido, CMV, MB, MC). Quem cede largura é o texto livre —
   cliente e item já cortam em reticências, com o texto inteiro no `title`. */
.rs-tela #rs-registros-faturamento-grade .rs-reg-texto{max-width:12rem}
/* o SEGUNDO nível da gaveta (pedido → itens, negócio → proposta) abre na linha,
   sob a clicada: fundo branco e um fio fino à esquerda marcando o nível — sem
   cartão, sem sombra (o padrão de drill do dono). A lista de dentro é grade
   CSS de `div` (ver `tabelaDoDetalhe`), fora do alcance do estilo da grade. */
.rs-tela .rs-dialog-registros .grade .grade-tabela tbody tr.grade-detalhe>td{background:var(--dnv-surface);padding:.125rem .75rem .625rem 1.25rem}
.rs-tela .rs-nivel-abrir{max-width:100%;vertical-align:top}
.rs-tela .rs-nivel-abrir::before{content:'▸';display:inline-block;width:.875rem;color:var(--dnv-ink-3);transition:transform .12s}
.rs-tela .rs-nivel-abrir[aria-expanded="true"]::before{transform:rotate(90deg);color:var(--dnv-ink)}
.rs-tela .rs-nivel{border-left:1px solid var(--dnv-rule-2);padding-left:.75rem}
.rs-tela .rs-nivel-ficha{display:flex;flex-wrap:wrap;gap:.25rem 1.5rem;padding:.25rem 0 .375rem;font-size:var(--fonte-rotulo);
  text-transform:uppercase;letter-spacing:.04em;color:var(--dnv-ink-3)}
.rs-tela .rs-nivel-ficha b{margin-left:.25rem;font-weight:500;letter-spacing:0;color:var(--dnv-ink)}
.rs-tela .rs-nivel-aviso{margin:0;padding:.25rem 0;color:var(--dnv-ink-3)}
.rs-tela .rs-nivel-tabela{display:inline-grid;font-variant-numeric:tabular-nums}
.rs-tela .rs-nivel-5{grid-template-columns:repeat(5,auto)}
.rs-tela .rs-nivel-6{grid-template-columns:repeat(6,auto)}
.rs-tela .rs-nivel-l{display:contents}
.rs-tela .rs-nivel-c{padding:.25rem 1.25rem .25rem 0;border-bottom:1px solid var(--rs-fio);white-space:nowrap}
.rs-tela .rs-nivel-c:nth-child(2){white-space:normal;min-width:14rem;max-width:28rem}
.rs-tela .rs-nivel-n{text-align:right}
.rs-tela .rs-nivel-c[role="columnheader"]{border-bottom-color:var(--dnv-rule);font-size:var(--fonte-rotulo);font-weight:500;
  text-transform:uppercase;letter-spacing:.04em;color:var(--dnv-ink-3)}
.rs-tela #rs-modal-registros-totais .rs-tot{justify-content:flex-start;flex-wrap:wrap;gap:.25rem 1.5rem;box-shadow:none;
  text-transform:uppercase;letter-spacing:.04em;font-size:var(--fonte-rotulo)}
.rs-tela #rs-modal-registros-totais .rs-rt{font-weight:500;color:var(--dnv-ink-3)}
.rs-tela #rs-modal-registros-totais .rs-rt b{margin-left:.25rem;font-size:var(--fonte-corpo);font-weight:500;letter-spacing:0;
  color:var(--dnv-ink);font-variant-numeric:tabular-nums}
.rs-tela #rs-modal-registros-totais .rs-esqueleto{padding:.5rem .75rem}
.rs-tela .rs-dialog .rs-tb th{top:2.5rem}
.rs-tela .rs-fechar{margin-left:auto;width:1.75rem;height:1.75rem;text-align:center!important;color:var(--dnv-ink-3)}
.rs-tela .rs-fechar:hover{color:var(--dnv-ink)}
.rs-tela .rs-dcorpo{display:flex;flex-direction:column;align-items:flex-start;gap:.5rem;padding:.75rem}
.rs-tela .rs-dialog-projeto{max-width:min(640px,92vw)}
.rs-tela .rs-dica{margin:0;font-size:var(--fonte-pequena);color:var(--dnv-ink-3)}
.rs-tela .rs-pj-campos{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,12rem) 9.5rem;gap:.5rem;width:100%}
.rs-tela .rs-rotulo{display:flex;flex-direction:column;gap:2px;margin:0;font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.04em;
  text-transform:uppercase;color:var(--dnv-ink-2)}
.rs-tela .rs-rotulo .rs-cmp{font-weight:400;letter-spacing:0;text-transform:none}
.rs-tela #rs-projeto-fases{width:100%;display:flex;flex-direction:column;gap:.5rem}
.rs-tela #rs-projeto-fases:empty{display:none}
.rs-tela .rs-fase{display:flex;flex-direction:column;align-items:flex-start;gap:.375rem;padding:.5rem 0 .5rem .75rem;
  border-left:2px solid var(--dnv-rule-3)}
.rs-tela .rs-fase-cab,.rs-tela .rs-tarefa{display:flex;align-items:center;gap:.375rem;width:100%}
.rs-tela .rs-fase-nome{font-weight:500}
.rs-tela .rs-fase-nome,.rs-tela .rs-tarefa-titulo{flex:1 1 auto}
.rs-tela .rs-fase-tarefas{display:flex;flex-direction:column;gap:.375rem;width:100%;padding-left:.75rem}
.rs-tela .rs-fase-tarefas:empty{display:none}
.rs-tela .rs-fase .rs-tarefa-add{margin-left:.75rem}
.rs-tela .rs-tarefa .rs-sel-pessoas{flex:0 0 11rem}
/* O gatilho da escolha de responsáveis: 1,75rem e a letra da Reunião. O reset
   `.rs-tela button{border:0}` vence a borda da regra base, então ele segue SEM
   borda (antes e depois do #273); da regra base só vale a cor do ativo (#1268AB). */
.rs-tela .tf-pessoas .colfilter-multi__trigger{height:1.75rem;
  background:var(--dnv-surface);font:.8125rem/1 var(--dnv-sans)}
.rs-tela .rs-acoes{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;border-top:1px solid var(--dnv-rule)}
.rs-tela .rs-acoes .rs-erro{padding:0}
.rs-tela div.rs-tot{display:flex;justify-content:space-between;gap:.75rem;padding:.5rem .75rem;
  box-shadow:inset 0 1px 0 var(--dnv-rule-3);font-weight:500}
.rs-tela div.rs-tot .rs-v{font-variant-numeric:tabular-nums}
/* metas do ano: realizado e atingimento moram DENTRO da célula do mês, abaixo
   da meta — uma linha extra por área dobraria a altura da grade */
.rs-tela .rs-ano-legenda{margin:0;padding:.375rem .75rem;font-size:var(--fonte-pequena);letter-spacing:.04em;color:var(--dnv-ink-3)}
.rs-tela .rs-ano-legenda b{font-weight:500;color:var(--dnv-ink-2)}
.rs-tela .rs-anow{overflow-x:auto;padding:0 0 .5rem}
.rs-tela .rs-tbano td{vertical-align:top}
/* doze meses + área + ano cabem em 1366 sem rolar de lado: célula mais justa */
.rs-tela .rs-tbano th,.rs-tela .rs-tbano td{padding:.25rem .375rem;font-size:var(--fonte-corpo)}
.rs-tela .rs-dialog .rs-tbano th{top:0}   /* o contêiner que rola de lado é o `.rs-anow`, não o diálogo */
.rs-tela .rs-tbano b{display:block;font-weight:500;font-variant-numeric:tabular-nums}
.rs-tela .rs-tbano i{display:block;font-style:normal;font-size:var(--fonte-pequena);color:var(--dnv-ink-3);font-variant-numeric:tabular-nums}
.rs-tela .rs-tbano .rs-n i{text-transform:uppercase;letter-spacing:.04em}
/* as duas pontas presas enquanto o meio rola: o nome da área e o total do ano */
.rs-tela .rs-tbano th:first-child,.rs-tela .rs-tbano td:first-child{position:sticky;left:0;z-index:2;background:var(--dnv-surface);
  min-width:120px;max-width:170px;white-space:normal}
.rs-tela .rs-tbano thead th:first-child,.rs-tela .rs-tbano thead th:last-child{z-index:3}
.rs-tela .rs-tbano th:last-child,.rs-tela .rs-tbano td:last-child{position:sticky;right:0;z-index:2;background:var(--dnv-surface)}

/* o cabeçalho das janelas gruda no topo: fora da tela a `.rs-tb` não é sticky */
.rs-tela .rs-dialog .rs-tb th{position:sticky;z-index:1;background:var(--dnv-surface);text-transform:uppercase}
.rs-tela .rs-dialog .rs-tb td{white-space:nowrap}

/* ── até 1440px: as onze colunas das áreas cedem folga lateral ─────────── */
@media (max-width:1440px){
  .rs-tela .rs-tb th,.rs-tela .rs-tb td{padding-left:6px;padding-right:6px}
  .rs-tela .rs-tb-areas td.rs-vao,.rs-tela .rs-tb-areas th.rs-vao{padding:0 4px;width:10px}
  .rs-tela .rs-area{max-width:11rem}
}

/* ── até 1700px: treze colunas nas áreas desde o ESTOQUE HOJE (reporte #122);
   com a folga de 8px a tabela rolava de lado em 1366 e 1600 ──────────── */
@media (max-width:1700px){
  .rs-tela .rs-tb-areas th,.rs-tela .rs-tb-areas td{padding-left:4px;padding-right:4px}
}

/* ── ESTREITO (≤1100px) ou deitado (altura ≤500px): uma coluna e a página
   rola. Nesse tamanho a tela não é um terminal, é uma consulta. ────────── */
@media (max-width:1100px),(max-height:500px){
  .rs-tela{overflow:auto}
  .rs-tela .rs-app{overflow:auto;gap:18px}
  .rs-tela .rs-l2,.rs-tela .rs-l3{grid-template-columns:minmax(0,1fr);gap:18px}
  .rs-tela .rs-l3{flex:none}
  .rs-tela .rs-sep-l::before{display:none}
  .rs-tela .rs-conta{flex-wrap:wrap}
  .rs-tela .rs-graf{height:260px;flex:none}
  .rs-tela .rs-cal{grid-auto-rows:34px;flex:none}
  .rs-tela .rs-rola{flex:none;max-height:420px}
}

/* ═══ CRM · USUÁRIOS ══════════════════════════════════════════════════════
   Grade compacta no molde de /crm/pedidos/. As regras abaixo são CÓPIA
   deliberada (decisão do dono, 08/09/2026): com duas telas não dá para saber
   quais regras são do padrão e quais são do pedido. Promover a componente
   compartilhado quando aparecer a terceira cópia.
   Os chips não são cópia: reusam o `.cl-aba` das grades de clientes e
   negócios, e a página só entrou na lista de escopo daquele bloco.
   ============================================================ */
[data-pagina="crm-usuarios"] .us-tabela { table-layout: auto; }
/* Adensa por ESPAÇAMENTO, nunca por fonte menor: linha de 28-32px com a
   fonte intacta continua legível; fonte menor não. */
[data-pagina="crm-usuarios"] .us-tabela td,
[data-pagina="crm-usuarios"] .us-tabela th { padding: .1rem .5rem .1rem 0;
                                             font-size: var(--fonte-corpo); }
[data-pagina="crm-usuarios"] .us-tabela thead th { position: sticky; top: 0;
                                                   z-index: 1; background: var(--surf); }
[data-pagina="crm-usuarios"] .us-filtros-col th { position: sticky; top: 1.6rem;
                                                  z-index: 3; background: var(--surf); }
/* O cabeçalho inteiro é o alvo de ordenar — botão que parece link dentro do
   <th>, não um ícone pequeno ao lado do rótulo. */
[data-pagina="crm-usuarios"] .us-ordenar {
  border: 0; background: none; padding: 0; color: inherit; font: inherit;
  font-weight: 500; text-align: left; cursor: pointer;
}
[data-pagina="crm-usuarios"] .us-seta { color: var(--crm-tinta-2); font-weight: 400; }
[data-pagina="crm-usuarios"] .us-nome { display: block; font-weight: 500; }
[data-pagina="crm-usuarios"] .us-login { display: block; font-size: var(--fonte-pequena);
                                         color: var(--crm-tinta-2); }
[data-pagina="crm-usuarios"] .us-codigo { font-variant-numeric: tabular-nums;
                                          font-weight: 500; margin-right: .35rem; }
[data-pagina="crm-usuarios"] .us-representante__nome { color: var(--crm-tinta-2); }
[data-pagina="crm-usuarios"] .us-num { text-align: right;
                                       font-variant-numeric: tabular-nums; }
[data-pagina="crm-usuarios"] .us-alerta { color: var(--crm-avi); font-size: var(--fonte-pequena); }
[data-pagina="crm-usuarios"] .us-select { width: auto; min-width: 6rem; }
[data-pagina="crm-usuarios"] .us-filtro-texto {
  width: 100%; min-width: 8rem; border: 1px solid var(--crm-borda);
  border-radius: 4px; padding: .1rem .35rem; font-size: var(--fonte-corpo); font-weight: 400;
}

/* Transferir carteira (reporte #8): uma linha acima da grade, De · Para ·
   Transferir. A pergunta de confirmação toma o lugar do botão. */
[data-pagina="crm-usuarios"] .us-carteira__painel {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .5rem 1rem;
}
[data-pagina="crm-usuarios"] .us-carteira__campo {
  display: flex; flex-direction: column; gap: .15rem; font-size: var(--fonte-corpo);
  font-weight: 500; flex: 1 1 18rem; max-width: 34rem;
}
[data-pagina="crm-usuarios"] .us-carteira__confirma {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
}
[data-pagina="crm-usuarios"] .us-carteira__pergunta { margin: 0; flex: 1 1 24rem; }

/* A GRADE É A TELA: ocupa a janela inteira. Medido em 08/09/2026, antes disto:
   o cartão terminava em 564px numa janela de 900 e sobravam 336px de chão
   cinza — 37% da tela vazia embaixo de uma lista que cresce toda semana.
   Mesmo padrão de `.page[data-pagina="forecast_comex"]`: a página vira coluna
   flex de altura fixa (52px é a topbar; não existe token para ela) e o cartão
   fica com a sobra, rolando por dentro com os dois cabeçalhos parados. */
.page[data-pagina="crm-usuarios"] {
  display: flex; flex-direction: column; gap: .5rem;
  height: calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b));
}
/* O respiro entre chips, aviso, painel e cartão é o `gap` da coluna, e só
   ele. Medido em 15/09/2026: o aviso de sucesso começava no pixel em que os
   chips terminavam (0px), porque nenhuma faixa tinha margem em cima. Aviso
   vazio sai do fluxo — senão o `gap` dobrava entre chips e painel — e o
   alerta nasce `mb-0` no JS: a margem do Bootstrap é `!important` e somaria
   com o `gap`. */
.page[data-pagina="crm-usuarios"] > #us-aviso:empty { display: none; }
.page[data-pagina="crm-usuarios"] > .card { flex: 1; min-height: 0; }
.page[data-pagina="crm-usuarios"] > .card > .card-body {
  height: 100%; display: flex; flex-direction: column; min-height: 0;
}
/* O contêiner de rolagem é ESTE, e não a janela: é o que faz o `position:
   sticky` dos dois cabeçalhos grudar no topo da grade em vez de sumir com a
   página. */
.page[data-pagina="crm-usuarios"] .table-responsive-md {
  flex: 1; min-height: 0; overflow: auto;
}
[data-pagina="crm-usuarios"] .us-amarrar { display: flex; gap: .35rem;
                                           align-items: center; }
/* O chip de "representantes sem conta" CONTA e não recorta — nenhum deles é
   linha desta grade. Ele não é botão, então também não finge ser um. */
[data-pagina="crm-usuarios"] .cl-aba--informativa { cursor: default;
                                                    border-style: dashed; }

/* ═══ CRM · CLASSIFICAÇÃO ═════════════════════════════════════════════════
   Duas colunas: eixos à esquerda, opções do eixo selecionado à direita
   (item 24, dono 08/09/2026). A grade ocupa a janela inteira — mesmo padrão
   de `/crm/usuarios/` acima (medido lá: sobrava 37% de chão cinza sem isto).
   ============================================================ */
.page[data-pagina="crm-classificacao"] {
  display: flex; flex-direction: column;
  height: calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b));
}
[data-pagina="crm-classificacao"] .cls-grade {
  display: grid; grid-template-columns: 280px 1fr; gap: 16px;
  flex: 1; min-height: 0;
}
[data-pagina="crm-classificacao"] .cls-coluna-eixos,
[data-pagina="crm-classificacao"] .cls-coluna-opcoes { min-height: 0; display: flex; flex-direction: column; }
[data-pagina="crm-classificacao"] .cls-coluna-eixos .card-body,
[data-pagina="crm-classificacao"] .cls-coluna-opcoes .card-body { flex: 1; min-height: 0; overflow: auto; }
[data-pagina="crm-classificacao"] .cls-titulo-coluna {
  font-size: var(--fonte-rotulo); letter-spacing: .04em; text-transform: uppercase;
  color: var(--crm-tinta-2); margin-bottom: .5rem;
}
[data-pagina="crm-classificacao"] #cls-eixos { display: flex; flex-direction: column; gap: 2px; }
[data-pagina="crm-classificacao"] .cls-eixo {
  display: flex; justify-content: space-between; align-items: center; gap: .5rem;
  width: 100%; border: 0; background: none; padding: .5rem .6rem; border-radius: 6px;
  text-align: left; cursor: pointer; color: var(--crm-tinta);
}
[data-pagina="crm-classificacao"] .cls-eixo:hover { background: var(--surf-2); }
/* Eixo selecionado: fundo sólido, não borda — é o mesmo destaque de aba
   ativa que o resto do CRM usa (`.cl-aba--ativa`), sem introduzir um segundo
   vocabulário de "selecionado". */
[data-pagina="crm-classificacao"] .cls-eixo--ativo { background: var(--crm-borda); font-weight: 500; }
[data-pagina="crm-classificacao"] .cls-eixo__cadeado { margin-left: .35rem; color: var(--crm-tinta-2); }
[data-pagina="crm-classificacao"] .cls-eixo__conta {
  font-size: var(--fonte-corpo); color: var(--crm-tinta-2); font-variant-numeric: tabular-nums; white-space: nowrap;
}
[data-pagina="crm-classificacao"] .cls-nova-opcao { display: flex; gap: .4rem; margin-bottom: .75rem; }
[data-pagina="crm-classificacao"] .cls-tabela-opcoes td,
[data-pagina="crm-classificacao"] .cls-tabela-opcoes th { vertical-align: middle; }
/* Inativa fica NA MESMA lista, só apagada — esconder a linha esconderia
   exatamente a que o gerente precisa achar para reativar. */
[data-pagina="crm-classificacao"] .cls-opcao--inativa { color: var(--crm-tinta-2); }
[data-pagina="crm-classificacao"] .cls-opcao__uso { text-align: right; font-variant-numeric: tabular-nums; }
[data-pagina="crm-classificacao"] .cls-opcao__acoes { display: flex; gap: .35rem; justify-content: flex-end; }
[data-pagina="crm-classificacao"] .cls-situacao { font-size: var(--fonte-corpo); padding: 1px 8px; border-radius: 10px; }
[data-pagina="crm-classificacao"] .cls-situacao--ativa { background: #e6f4ea; color: var(--crm-ok); }
[data-pagina="crm-classificacao"] .cls-situacao--inativa { background: var(--surf-3); color: var(--crm-tinta-2); }

@media (max-width: 768px) {
  [data-pagina="crm-classificacao"] .cls-grade { grid-template-columns: 1fr; }
}

/* ==========================================================================
   CRM · Fita de variantes da proposta (tela do negócio)
   Um negócio pode ter propostas IRMÃS — a A e a B: recotar sem apagar a
   cotação anterior, ou partir o orçamento por família. A fita é a linha de
   abas acima do bloco de itens; ela só desenha as abas quando há mais de uma
   variante (quem decide é o backend, `_fita_de_variantes`), e as duas ações
   ficam sempre à mão porque é por elas que a segunda proposta nasce.
   ========================================================================== */
.crm-variantes { display: flex; flex-wrap: wrap; align-items: center;
  gap: .35rem; margin-bottom: .85rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--crm-borda); }
.crm-variante { display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: .05rem; padding: .3rem .6rem; border-radius: 8px;
  background: var(--crm-superficie); border: 1px solid var(--crm-borda);
  color: var(--crm-tinta-2); cursor: pointer; text-align: left;
  transition: border-color .15s ease, background .15s ease, color .15s ease; }
.crm-variante:hover { border-color: var(--crm-borda-forte); color: var(--crm-tinta); }
/* A em foco é a que a tela está falando: borda no verde do funil e tinta
   cheia. Fundo continua branco — cinza aqui leria como desabilitada. */
.crm-variante--foco { border-color: var(--crm-tom-2); color: var(--crm-tinta);
  box-shadow: inset 0 0 0 1px var(--crm-tom-2); cursor: default; }
.crm-variante__nome { font-size: var(--fonte-corpo); font-weight: 500; }
.crm-variante__estado { font-size: var(--fonte-pequena); color: var(--crm-tinta-3); }
.crm-variante__acao { margin-left: .2rem; }
.crm-variantes__aviso { flex-basis: 100%; font-size: var(--fonte-pequena);
  color: var(--crm-tinta-3); }

/* ===== E-MAIL MARKETING ===== */
/* Canvas de "Nova campanha" carrega assunto + remetente + corpo HTML +
   segmentação de listas — a largura padrão (22.5rem) espreme o textarea do
   corpo. Mesmo padrão de largura por classe do CRM (.crm-oc--larga etc.). */
[data-pagina="email-marketing"] .fem-canvas--larga { --bs-offcanvas-width: min(34rem, 96vw); }
/* Base de contatos é grade de dados (5 colunas, uma delas com form de edição
   inline) — a largura de formulário (34rem) fica cheia de scroll horizontal. */
[data-pagina="email-marketing"] .fem-canvas--xlarga { --bs-offcanvas-width: min(64rem, 96vw); }

/* A GRADE É A TELA (regra dura, mesmo padrão de .page[data-pagina="crm-usuarios"]):
   ocupa a janela inteira mesmo vazia — nunca só a altura do conteúdo. Os
   offcanvas são irmãos do .card dentro de .page, mas `position:fixed` do
   Bootstrap os tira do fluxo — não competem pela altura flex. */
.page[data-pagina="email-marketing"] {
  display: flex; flex-direction: column;
  height: calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b));
}
.page[data-pagina="email-marketing"] > .card { flex: 1; min-height: 0; }
.page[data-pagina="email-marketing"] > .card > .card-body {
  height: 100%; display: flex; flex-direction: column; min-height: 0;
}
.page[data-pagina="email-marketing"] .table-responsive { flex: 1; min-height: 0; overflow: auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   DESPESAS (`/despesas/` e variantes; nasceu em `/despesas/nova/`, #404)

   PORTE FIEL do mockup "Os Três Baldes" (`docs/redesign/mockups/
   despesas-tres-baldes.html`), aprovado pelo dono. As regras abaixo são as DO
   MOCKUP, valor por valor: nenhum tamanho, peso, cor, raio ou espaçamento foi
   reinterpretado. Não editar por gosto — mudança aqui é divergência do desenho
   aprovado; mude o mockup primeiro, que é o gabarito.

   O porte é MECÂNICO, feito por script (`scratchpad/portar_css.py`), e só faz
   três coisas:

     1. Toda classe `.foo` vira `.dnv-foo`. O mockup inventou 133 classes com
        nomes ultracurtos (`.k .n .cel .bt .dir .obs`), e `.grade` sozinha
        colide com 104 regras deste arquivo, que é lido por ~28 telas.
     2. Todo token vira `--dnv-*`. Seis dos 24 (`--ink`, `--ink-2/3/4`,
        `--sans`, `--mono`) já são nomes do `:root` daqui; prefixar só esses
        deixaria armadilha para o próximo token global. `DESIGN.md`: sequestrar
        nome global é proibido.
     3. Todo seletor nasce em `.page[data-pagina="despesas-nova"]`, e o
        `:root`/`html`/`body` do mockup viram esse mesmo seletor.

   O CABEÇALHO do mockup (`.trilho`: marca, Período, Segmento) NÃO está aqui.
   Ele é a L3 — o piloto do shell novo. Nesta aterrissagem o período e o
   segmento continuam vindo da barra de filtros do shell, já ligada ao
   `biFiltros`; desenhar os dois seria duplicar o controle.

   Logo abaixo, e separado de propósito, o único lugar onde o porte não é
   literal: o que o SHELL obriga a mudar.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── O PORTE, literal daqui para baixo ──────────────────────────────────── */
/* ════════════════════════════════════════════════════════════════
   Instrumento, não painel. Tinta + uma cor de estado. Cantos retos.
   Sem rolagem de página: os painéis rolam por dentro.
   ════════════════════════════════════════════════════════════════ */
/* Relatórios entra na LISTA DE SELETORES desta regra e não copia os 24 valores
   (seção RELATÓRIOS, no fim do arquivo): o dono pediu a mesma pele para o
   construtor (15/09/2026), e um segundo jogo de tokens com os mesmos números
   seriam duas verdades sobre a mesma cor. O alcance é o menor possível: só o
   CONSTRUTOR (`.rel-construtor`) e a barra que carrega o seletor dele — a
   LISTA divide a chave `relatorios` mas é a grade da casa e não lê nenhum
   `--dnv-*`. Nada mais da seção DESPESAS (porte literal do mockup aprovado) é
   tocado. A Reunião Semanal entra na mesma lista pelo mesmo motivo (dono,
   17/09/2026): mesma pele, uma verdade só sobre cada cor. O Painel Comex (#209)
   também (o Painel Financeiro saiu da lista na fatia 1d do #208: fala o design system). O seletor de período
   canônico (`.fcds-seletor`, seção SELETOR DE PERÍODO) também: nasceu no trilho de
   despesas/nova e leva a pele dele para onde for montado (24/09/2026). */
.page[data-pagina="despesas-nova"], #topbar:has(.dnv-sel),
.page[data-pagina="relatorios"].rel-construtor, #topbar:has(.rel-sel),
.page[data-pagina="reuniao_semanal"],
.page[data-pagina="tarefas"],
.page[data-pagina="painel_comex"], #topbar:has(.pcx-trilho),
.page[data-pagina="compras"][data-tela="painel"],
.fcds-seletor{ --dnv-ground:#E9EBEE; --dnv-surface:#FFFFFF;  --dnv-surface-2:#F5F6F8;  --dnv-surface-3:#EEF0F3; --dnv-ink:#0B0E12;     --dnv-ink-2:#525A66;    --dnv-ink-3:#666E7A;      --dnv-ink-4:#666E7A; --dnv-rule:#D8DCE1;    --dnv-rule-2:#C2C8D0;   --dnv-rule-3:#9AA2AC; --dnv-mark:#1A3E7A;    --dnv-mark-wash:#E7EDF6; --dnv-risco:#9E1B10;   --dnv-risco-wash:#FBEDEB; --dnv-risco-rule:#E4B6B0; --dnv-risco-tinta:#FFFFFF; --dnv-wash:#DFE3E8; --dnv-graf:#3B5F96;    --dnv-graf-area:#CFDAEA;  --dnv-graf-area-2:#E4EBF4; --dnv-graf-eixo:#C6CDD6; --dnv-sans:var(--sans);   /* a fonte é a do shell (decisão do dono, 12/09) */ --dnv-mono:var(--dnv-sans); color-scheme:light; }
/* Tema escuro removido: o projeto tem tema claro fixo ("Tema claro é fixo.
   Não existe modo escuro neste produto." — PRODUCT.md). Eram dois blocos, o
   segundo cópia literal do primeiro. */
.page[data-pagina="despesas-nova"] *{ box-sizing:border-box }
.page[data-pagina="despesas-nova"]{ height:100% }
.page[data-pagina="despesas-nova"]{ margin:0; background:var(--dnv-ground); color:var(--dnv-ink); font-family:var(--dnv-sans); -webkit-font-smoothing:antialiased; overflow:hidden; }
/* O filtro de coluna da casa (`colfilter-multi`) fica FORA desta limpeza: sem
   borda e sem fundo o gatilho virava três peças soltas na largura da coluna —
   funil à esquerda, "Todos" no meio, seta na ponta. `:where` mantém a
   especificidade da regra, então nenhum outro botão da tela muda. */
.page[data-pagina="despesas-nova"] button:not(:where(.colfilter-multi__trigger, .btn)){ padding:0; text-align:left }
.page[data-pagina="despesas-nova"] :focus-visible{ outline:2px solid var(--dnv-mark); outline-offset:1px }
@media (prefers-reduced-motion:reduce){
  .page[data-pagina="despesas-nova"] *{ transition:none!important }
}
.page[data-pagina="despesas-nova"] .dnv-n, .page[data-pagina="despesas-nova"] .dnv-faixa__v, .page[data-pagina="despesas-nova"] .dnv-total, .page[data-pagina="despesas-nova"] .dnv-comp__p, .page[data-pagina="despesas-nova"] .dnv-comp__a, .page[data-pagina="despesas-nova"] .dnv-risco__n, .page[data-pagina="despesas-nova"] .dnv-pux__v, .page[data-pagina="despesas-nova"] .dnv-cel, .page[data-pagina="despesas-nova"] .dnv-faixa__ref, .page[data-pagina="despesas-nova"] .dnv-faixa__d b, .page[data-pagina="despesas-nova"] .dnv-faixa__x{ font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1, "lnum" 1; }
.page[data-pagina="despesas-nova"] .dnv-k{ font-size:var(--fonte-rotulo); letter-spacing:.11em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-sobe{ color:var(--dnv-risco) }
.page[data-pagina="despesas-nova"] .dnv-cai{ color:var(--dnv-ink-2) }
/* ── ESTRUTURA ─────────────────────────────────────────────────── */
.page[data-pagina="despesas-nova"] .dnv-app{ height:100dvh; display:grid; grid-template-rows:auto 1fr; grid-template-columns:clamp(300px, 22vw, 352px) 1fr; grid-template-areas:"trilho trilho" "lado palco"; background:var(--dnv-rule); gap:1px; }
/* ── TRILHO ────────────────────────────────────────────────────── */
/* ── LADO: a leitura do período ────────────────────────────────── */
.page[data-pagina="despesas-nova"] .dnv-lado{ grid-area:lado; background:var(--dnv-surface); overflow-y:auto; display:flex; flex-direction:column; }
.page[data-pagina="despesas-nova"] .dnv-bloco{ padding:26px 24px }
.page[data-pagina="despesas-nova"] .dnv-nota{ padding:16px 24px 22px; margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-total{ font-size:var(--fonte-heroi); font-weight:500; letter-spacing:-.035em; line-height:40px; margin:10px 0 0; white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-total__sub{ margin:12px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-parcial{ display:inline-block; margin-left:2px; padding:1px 6px; font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2); background:var(--dnv-wash); }
.page[data-pagina="despesas-nova"] .dnv-livro{ margin:16px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-livro b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-livro__x{ display:block; margin-top:6px; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-trata__aviso{ margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); line-height:1.5; padding-left:11px; border-left:2px solid var(--dnv-rule-3); }
/* comparação */
.page[data-pagina="despesas-nova"] .dnv-comp__n{ display:flex; align-items:baseline; gap:11px; margin-top:8px }
.page[data-pagina="despesas-nova"] .dnv-comp__p{ font-size:var(--fonte-heroi); font-weight:500; letter-spacing:-.03em }
.page[data-pagina="despesas-nova"] .dnv-comp__a{ font-size:var(--fonte-corpo); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-comp__b{ margin:10px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-comp__b b{ color:var(--dnv-ink-2); font-weight:500 }
/* suspeita */
.page[data-pagina="despesas-nova"] .dnv-risco{ display:block; width:100%; padding:12px 0 0; text-align:left }
.page[data-pagina="despesas-nova"] .dnv-risco:hover .dnv-risco__n{ text-decoration:underline }
.page[data-pagina="despesas-nova"] .dnv-risco__l{ display:flex; align-items:baseline; gap:11px }
.page[data-pagina="despesas-nova"] .dnv-risco__n{ font-size:var(--fonte-heroi); font-weight:500; color:var(--dnv-risco); letter-spacing:-.03em }
.page[data-pagina="despesas-nova"] .dnv-risco__v{ font-size:var(--fonte-corpo); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-risco__t{ margin:8px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-risco__t b{ color:var(--dnv-ink-2); font-weight:500 }
/* barras de composição da fila */
/* ── PALCO: os três baldes como painéis de expansão ────────────── */
/* Aviso de falha de render. Nasce escondido (só existe quando algo lançou) e
   fica no topo do palco, por cima da leitura anterior. */
.page[data-pagina="despesas-nova"] .dnv-falhou{ margin:0; padding:10px 16px; background:var(--dnv-risco-wash); border-bottom:1px solid var(--dnv-risco-rule); color:var(--dnv-risco); font-size:var(--fonte-corpo); font-weight:500; }
/* O palco é SEMPRE a caixa que rola (#453). Era `overflow:hidden`, e só a faixa
   de rankings ligava a rolagem: com um balde aberto, o que passava da janela
   ficava cortado sem caminho até ele. */
.page[data-pagina="despesas-nova"] .dnv-palco{ grid-area:palco; display:flex; flex-direction:column; gap:1px; overflow-x:hidden; overflow-y:auto; background:var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-pan{ background:var(--dnv-surface); display:flex; flex-direction:column; min-height:0; overflow:hidden }
/* Repartição da altura: as faixas fechadas crescem COM a tela até um teto (o
   gráfico de 12 meses cabia em 64px e agora respira), e o painel aberto fica
   com o resto. Antes o aberto comia tudo e sobravam 373px de branco sob uma
   tabela de 8 linhas numa tela de 1920; depois eu inverti e esmaguei o painel.
   O teto nas fechadas é o que equilibra. */
/* #453: o aberto tem a altura do que contém e NÃO encolhe. Com `flex-shrink`
   ele era espremido até caber na janela, e o palco (sem rolagem) cortava o
   resto — conta aberta, Financeiras, Gerenciais. Quem rola agora é o palco. */
.page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="1"]{ flex:0 0 auto; min-height:0; max-height:calc(100dvh - var(--dnv-topo, 46px) - 45px) }
/* ...com teto de UMA janela (menos a barra de abas): uma conta com 500
   lançamentos não empurra Financeiras 5.000px para baixo — o miolo rola por
   dentro, e o palco rola até os outros baldes. */
/* Só a faixa FECHADA estica — na aberta, `height:100%` fazia a faixa comer o
   painel inteiro e o miolo sobrava com 270px. */
.page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="0"]{ flex:0 0 auto; height:clamp(118px, 15vh, 176px) }
.page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="0"] .dnv-faixa{ height:100% }
/* NADA aberto (é o estado inicial, por ordem do dono): as três faixas dividem a
   altura em vez de ficarem no teto com 547px de vazio embaixo numa tela de 1920.
   O teto existe para equilibrar com um painel ABERTO ao lado; sem nenhum aberto
   ele só empurra a tela para um rodapé branco. O gráfico de 12 meses é quem
   ganha a folga — é a leitura que a faixa fechada existe para dar. */
/* `min-height` e não só `flex:1 1 0`: no celular o palco ROLA em vez de ter
   altura fixa, e a base flexível de 0 colapsava as três faixas para 0px. O piso
   é o mesmo teto de antes, então no estreito nada muda. */
.page[data-pagina="despesas-nova"] .dnv-palco:not(:has(.dnv-pan[data-aberto="1"])) .dnv-pan{ flex:1 1 auto; height:auto; max-height:none; min-height:clamp(118px, 15vh, 176px); }
/* ...e o preenchimento de sobra para de crescer, senão ele disputa a folga com
   as faixas e sobram 259px de branco justamente no estado inicial da tela. */
.page[data-pagina="despesas-nova"] .dnv-palco:not(:has(.dnv-pan[data-aberto="1"]))::after{ flex:0 0 auto }
/* O cinza é a cor do VÃO de 1px entre painéis, não um fundo. A sobra de altura
   ganha um preenchimento próprio em superfície — antes ela aparecia como uma
   faixa cinza de 78px colada no rodapé. Só funciona porque o painel aberto
   deixou de ser elástico: um `flex:1 1 0` roubaria esta folga de volta. */
.page[data-pagina="despesas-nova"] .dnv-palco::after{ content:""; flex:1 1 auto; min-height:0; background:var(--dnv-surface) }
.page[data-pagina="despesas-nova"] .dnv-pan:last-child .dnv-faixa{ padding-bottom:10px }
/* faixa fechada — sempre visível, densa */
.page[data-pagina="despesas-nova"] .dnv-faixa{ display:grid; align-items:center; gap:20px; width:100%; padding:0 18px 0 20px; height:106px; flex:0 0 auto; /* Toda coluna com minmax(0,…) para poder encolher: com larguras fixas a faixa media 780px numa caixa de 557 e a seta era desenhada FORA do painel de ~900px a ~1400px — some justamente o único sinal de que a faixa abre. */ grid-template-columns:minmax(0,172px) minmax(0,152px) minmax(0,128px) minmax(140px,1fr) minmax(0,62px) minmax(0,132px) 20px; border-left:3px solid transparent; }
.page[data-pagina="despesas-nova"] .dnv-faixa:hover{ background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="1"] .dnv-faixa{ border-left-color:var(--dnv-mark); background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-faixa__nome{ font-size:var(--fonte-corpo); font-weight:500; letter-spacing:-.01em }
.page[data-pagina="despesas-nova"] .dnv-faixa__v{ font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-.025em }
.page[data-pagina="despesas-nova"] .dnv-faixa__d{ font-size:var(--fonte-pequena); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-faixa__d b{ font-weight:500; font-size:var(--fonte-corpo); display:block; letter-spacing:-.015em }
.page[data-pagina="despesas-nova"] .dnv-faixa__d span{ color:var(--dnv-ink-3); font-size:var(--fonte-pequena) }
.page[data-pagina="despesas-nova"] .dnv-faixa__g{ display:flex; flex-direction:column; gap:4px; min-width:0; height:100%; padding-block:14px; justify-content:center }
/* Sem teto: com os três baldes fechados a 1080px cada faixa tem ~340px e o gráfico
   parava em 150, deixando uma faixa branca em cima e embaixo. */
.page[data-pagina="despesas-nova"] .dnv-faixa__g-d{ display:block; flex:1 1 auto; min-height:56px }
.page[data-pagina="despesas-nova"] .dnv-faixa__g-d svg{ width:100%; height:100%; display:block }
.page[data-pagina="despesas-nova"] .dnv-faixa__x{ position:relative; height:13px; font-size:var(--fonte-pequena); color:var(--dnv-ink-4) }
.page[data-pagina="despesas-nova"] .dnv-faixa__x span{ position:absolute; top:0; transform:translateX(-50%); white-space:nowrap; padding-top:4px }
.page[data-pagina="despesas-nova"] .dnv-faixa__x span::before{ content:""; position:absolute; top:0; left:50%; width:1px; height:3px; background:var(--dnv-rule-2) }
.page[data-pagina="despesas-nova"] .dnv-faixa__x--mudo span{ color:transparent }
.page[data-pagina="despesas-nova"] .dnv-faixa__ref{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3); white-space:nowrap; line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-faixa__leg{ display:block; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); white-space:normal; max-width:74px }
.page[data-pagina="despesas-nova"] .dnv-faixa__r{ font-size:var(--fonte-pequena); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-faixa__r b{ color:var(--dnv-risco); font-weight:500; font-family:var(--dnv-mono) }
.page[data-pagina="despesas-nova"] .dnv-faixa__r span{ color:var(--dnv-ink-3); display:block; font-size:var(--fonte-pequena) }
.page[data-pagina="despesas-nova"] .dnv-pux__mais{ margin:9px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-cursor{ display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; font-size:var(--fonte-corpo); color:var(--dnv-ink-2); text-align:center; transition:transform .15s ease }
.page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="1"] .dnv-cursor{ transform:rotate(90deg); color:var(--dnv-mark) }
/* miolo aberto */
/* A coluna da esquerda cede até 300px antes de a grade empilhar: fixa em 376px,
   o nome da conta ficava com 152px em 1281. */
.page[data-pagina="despesas-nova"] .dnv-miolo{ flex:1 1 auto; min-height:0; display:grid; grid-template-columns:clamp(300px, 26vw, 376px) 1fr; border-top:1px solid var(--dnv-rule); background:var(--dnv-rule); gap:1px }
.page[data-pagina="despesas-nova"] .dnv-miolo__e{ background:var(--dnv-surface-2); overflow-y:auto; padding:22px 24px 28px }
.page[data-pagina="despesas-nova"] .dnv-miolo__d{ background:var(--dnv-surface); overflow-y:auto; min-height:0; display:flex; flex-direction:column }
.page[data-pagina="despesas-nova"] .dnv-miolo__d > div{ display:flex; flex-direction:column; min-height:100% }
.page[data-pagina="despesas-nova"] .dnv-miolo__d table{ flex:0 0 auto }
.page[data-pagina="despesas-nova"] .dnv-miolo__d .dnv-pe{ margin-top:auto }
.page[data-pagina="despesas-nova"] .dnv-sec + .dnv-sec{ margin-top:26px; padding-top:22px; border-top:1px solid var(--dnv-rule) }
/* Coluna estreita (1281–1400px): o alternador desce inteiro em vez de os botões
   quebrarem em "Mês / anterior". */
.page[data-pagina="despesas-nova"] .dnv-sec__cab{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:11px; flex-wrap:wrap; row-gap:8px }
.page[data-pagina="despesas-nova"] .dnv-pux{ display:flex; flex-direction:column }
.page[data-pagina="despesas-nova"] .dnv-pux__l{ display:grid; grid-template-columns:1fr auto; gap:12px; align-items:baseline; padding:7px 0 }
.page[data-pagina="despesas-nova"] .dnv-pux__l + .dnv-pux__l{ border-top:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-pux__t{ display:flex; align-items:baseline; gap:0; min-width:0; font-size:var(--fonte-corpo) }
.page[data-pagina="despesas-nova"] .dnv-pux__t > .dnv-marca-t{ flex:none }
.page[data-pagina="despesas-nova"] .dnv-pux__c{ flex:none; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); margin-right:8px; font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-pux__v{ font-size:var(--fonte-corpo); font-weight:500; white-space:nowrap; font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-marca-t{ display:inline-block; margin-left:7px; padding:0 5px; font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2); background:var(--dnv-wash); border-left:2px solid var(--dnv-rule-3); }
.page[data-pagina="despesas-nova"] .dnv-marca-t--r{ color:var(--dnv-risco); background:var(--dnv-risco-wash); border-left-color:var(--dnv-risco) }
/* veredito + tira de pontos (substituiu o medidor com cara de slider) */
.page[data-pagina="despesas-nova"] .dnv-vered{ margin:0 0 6px; font-size:var(--fonte-corpo); font-weight:500; line-height:1.5; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-vered__e{ margin:0 0 12px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-vered__e b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-tira{ display:block; width:100%; height:auto; overflow:visible }
.page[data-pagina="despesas-nova"] .dnv-tira text{ font-family:var(--dnv-sans) }
.page[data-pagina="despesas-nova"] .dnv-tira__c{ margin:6px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-mudo{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2); line-height:1.5; margin:0 }
.page[data-pagina="despesas-nova"] .dnv-mudo b{ color:var(--dnv-ink); font-weight:500 }
/* tabela de contas — larguras na própria tabela, não em dois grids paralelos */
.page[data-pagina="despesas-nova"] .dnv-grade{ width:100%; border-collapse:collapse; table-layout:fixed }
/* O gabarito não declara `<!doctype>` e roda em quirks mode, onde tabela NÃO
   herda `line-height`: as linhas foram aprovadas com `normal` (33px). Aqui, em
   modo padrão, herdavam 1.45 e cada linha saía 4px mais alta — oito contas, 32px
   a mais de grade. A medição achou; o olho não. */
.page[data-pagina="despesas-nova"] .dnv-grade, .page[data-pagina="despesas-nova"] .dnv-lanc__wrap table{ line-height:normal }
.page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-exp{ width:34px }
/* Os números são curtos ("31,1%", "+R$ 227.265", "R$ 1.283.515"); com 376px
   reservados para eles, o nome da conta ficava com 91px em 1280. */
.page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-pct{ width:92px }
.page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-delta{ width:108px }
.page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-val{ width:116px }
.page[data-pagina="despesas-nova"] .dnv-grade > thead > tr > th, .page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-arvore__cab > th{ position:sticky; top:0; z-index:2; background:var(--dnv-surface-3); padding:9px 14px; font-size:var(--fonte-rotulo); letter-spacing:.1em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500; border-bottom:1px solid var(--dnv-rule-2); white-space:nowrap; text-align:left; }
.page[data-pagina="despesas-nova"] .dnv-grade > * > tr > th.dnv-dir, .page[data-pagina="despesas-nova"] .dnv-grade > * > tr > td.dnv-dir{ text-align:right }
.page[data-pagina="despesas-nova"] .dnv-grade > tbody > tr > th, .page[data-pagina="despesas-nova"] .dnv-grade > tbody > tr > td{ padding:9px 14px; border-bottom:1px solid var(--dnv-rule); font-weight:400; text-align:left; }
.page[data-pagina="despesas-nova"] .dnv-grade > tbody > tr > th{ font-size:var(--fonte-corpo); overflow:hidden }
.page[data-pagina="despesas-nova"] .dnv-linha{ border-left:2px solid transparent; cursor:pointer }
.page[data-pagina="despesas-nova"] .dnv-linha:hover{ background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-linha--aberta{ background:var(--dnv-mark-wash) }
.page[data-pagina="despesas-nova"] .dnv-linha--aberta > *:first-child{ box-shadow:inset 2px 0 0 var(--dnv-mark) }
.page[data-pagina="despesas-nova"] .dnv-cel-exp{ padding-right:0!important; width:34px }
/* Código e nome em DUAS COLUNAS fixas. Em flex com quebra, o nome que não cabia
   ao lado do código descia inteiro para baixo dele: a coluna ficava torta (uns
   nomes em x=871, outros em x=827) e, cortado com reticências, "Custos de frete
   internaci…" não dizia que conta era. Agora o nome quebra DENTRO da coluna. */
.page[data-pagina="despesas-nova"] .dnv-cel-nome__in{ display:grid; grid-template-columns:44px minmax(0,1fr); align-items:baseline; row-gap:3px; min-width:0 }
.page[data-pagina="despesas-nova"] .dnv-conta__c{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3); font-variant-numeric:tabular-nums }
/* O nome tem PISO e a etiqueta cede. Entre 1181 e 1280px o flex descontava tudo
   do nome — 0 a 8px de 97 — e a linha mostrava "1061" ao lado de "142 sob
   suspeita", sem dizer que conta era. A etiqueta é contexto; o nome é a
   identidade da linha, e identidade não cede primeiro. */
.page[data-pagina="despesas-nova"] .dnv-conta__n{ min-width:0; overflow-wrap:anywhere }
.page[data-pagina="despesas-nova"] .dnv-cel-nome__in > .dnv-conta__n:first-child{ grid-column:1/-1 }
/* A etiqueta cede DESCENDO, não encolhendo: espremida a 12px ela vira três
   pontinhos que não informam nada, e é justamente onde ela mais importa (é ela
   que diz QUAL conta concentra a suspeita — a faixa só diz o total do balde).
   Quebrar para a linha de baixo custa altura e preserva a leitura. */
.page[data-pagina="despesas-nova"] .dnv-cel-nome__in > .dnv-marca-t{ grid-column:2; justify-self:start; white-space:nowrap }
/* O `›` é 4×12px — a linha inteira reencaminha o clique, mas o alvo FOCÁVEL
   (e portanto o anel de foco do teclado) era esse retângulo de 48px². Padding
   negativo não muda o layout da célula e triplica a área. */
.page[data-pagina="despesas-nova"] .dnv-conta{ display:block; padding:10px 12px; margin:-10px -12px; line-height:1 }
.page[data-pagina="despesas-nova"] .dnv-cur{ display:inline-block; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); transition:transform .15s ease }
.page[data-pagina="despesas-nova"] .dnv-conta[aria-expanded="true"] .dnv-cur{ transform:rotate(90deg); color:var(--dnv-mark) }
.page[data-pagina="despesas-nova"] .dnv-cel{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2); font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-cel--v{ font-size:var(--fonte-corpo); color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-grade > tfoot > tr > th, .page[data-pagina="despesas-nova"] .dnv-grade > tfoot > tr > td{ padding:11px 14px; border-top:1px solid var(--dnv-rule-2); background:var(--dnv-surface-2); font-weight:500; font-size:var(--fonte-pequena); text-align:left; }
.page[data-pagina="despesas-nova"] .dnv-grade > tfoot > tr > td.dnv-dir{ text-align:right }
.page[data-pagina="despesas-nova"] .dnv-grade > tfoot{ position:sticky; bottom:0 }
/* lançamentos */
.page[data-pagina="despesas-nova"] .dnv-lanc{ background:var(--dnv-surface-2); padding:0!important }
.page[data-pagina="despesas-nova"] .dnv-lanc-linha[hidden]{ display:none }
.page[data-pagina="despesas-nova"] .dnv-lanc table{ width:100%; border-collapse:collapse; font-size:var(--fonte-pequena) }
.page[data-pagina="despesas-nova"] .dnv-lanc th{ text-align:left; padding:6px 8px; font-size:var(--fonte-rotulo); letter-spacing:.1em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500; border-bottom:1px solid var(--dnv-rule); white-space:nowrap; }
.page[data-pagina="despesas-nova"] .dnv-lanc td{ padding:7px 8px; border-bottom:1px solid var(--dnv-rule); vertical-align:top }
/* A observação traz tokens sem espaço (chave de CT-e de 44 dígitos, `RCTR-C-…|RC-DC…`)
   e, com `table-layout:auto`, a coluna nunca ficava mais estreita que eles: entre
   1300 e 1700px a tabela passava da gaveta e o VALOR saía cortado à direita. Pelo
   mesmo motivo os rótulos do cabeçalho podem quebrar; a linha de filtros não muda. */
.page[data-pagina="despesas-nova"] .dnv-lanc td{ overflow-wrap:break-word }
.page[data-pagina="despesas-nova"] .dnv-lanc thead tr:first-child th, .page[data-pagina="despesas-nova"] .dnv-lanc thead tr:first-child th *{ white-space:normal }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-dir{ white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-grade > * > tr > td.dnv-dir, .page[data-pagina="despesas-nova"] .dnv-grade > * > tr > th.dnv-dir{ white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-lanc tr:last-child td{ border-bottom:none }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-dir{ text-align:right }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-obs{ color:var(--dnv-ink-2); max-width:300px }
.page[data-pagina="despesas-nova"] .dnv-lanc tr.dnv-viciada td{ background:var(--dnv-risco-wash) }
/* Lançamentos em BRANCO (dono, 15/09): o cinza da gaveta lia como bloco desligado.
   Escurecem o que está sob o mouse e o que está selecionado — caixa marcada ou
   painel de tratamento aberto. */
.page[data-pagina="despesas-nova"] .dnv-lanc tbody tr:not(.dnv-viciada):not(.dnv-trata) > td{ background:var(--dnv-surface) }
.page[data-pagina="despesas-nova"] .dnv-lanc tbody tr:not(.dnv-trata):is(:hover, :has(.grade-selecao:checked), :has([data-dnv-tratar][aria-expanded="true"])) > td{ background:var(--dnv-surface-3) }
.page[data-pagina="despesas-nova"] .dnv-lanc__nota{ margin:0; padding:11px 14px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-lanc__nota b{ color:var(--dnv-ink-2); font-weight:500 }
/* Sem suspeita a barra de lote vem vazia — e com 10px de respiro em cima e embaixo
   era uma faixa branca de 21px entre a conta aberta e o cabeçalho da gaveta. */
.page[data-pagina="despesas-nova"] .dnv-lote:empty{ display:none }
.page[data-pagina="despesas-nova"] .dnv-lote{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:10px 14px; border-bottom:1px solid var(--dnv-rule); background:var(--dnv-surface); }
.page[data-pagina="despesas-nova"] .dnv-lote > *{ min-width:0 }
.page[data-pagina="despesas-nova"] .dnv-lote__f{ flex:0 1 auto;}
.page[data-pagina="despesas-nova"] .dnv-lote__e{ flex:1 1 auto }
.page[data-pagina="despesas-nova"] .dnv-lote__n{ flex:1 0 100%; margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); line-height:1.5 }
/* A ação principal da tela media 29×13px no desktop — abaixo de qualquer alvo
   razoável, e a regra de `(hover:none)` só a socorria em aparelho de toque.
   O padding cresce a área sem mudar a caixa da célula. */
.page[data-pagina="despesas-nova"] .dnv-tratar{ font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-risco); white-space:nowrap; border-bottom:1px solid currentColor; padding:6px 4px; }
.page[data-pagina="despesas-nova"] .dnv-tratado{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3); white-space:nowrap }
/* tratamento na linha */
.page[data-pagina="despesas-nova"] .dnv-trata td{ background:var(--dnv-risco-wash)!important; padding:0!important; border-left:3px solid var(--dnv-risco); white-space:normal; overflow-wrap:break-word }
.page[data-pagina="despesas-nova"] .dnv-trata__in{ padding:14px 16px; display:flex; flex-direction:column; gap:11px }
.page[data-pagina="despesas-nova"] .dnv-trata__h{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap }
.page[data-pagina="despesas-nova"] .dnv-trata__h b{ font-size:var(--fonte-corpo); color:var(--dnv-risco) }
.page[data-pagina="despesas-nova"] .dnv-trata__h span{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-trata__h span b{ color:var(--dnv-ink); font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-trata__m{ margin:0; font-size:var(--fonte-corpo); line-height:1.5; color:var(--dnv-ink); max-width:68ch; background:var(--dnv-surface); border:1px solid var(--dnv-risco-rule); padding:11px 13px; }
.page[data-pagina="despesas-nova"] .dnv-trata__f{ display:flex; flex-wrap:wrap; gap:5px 22px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-trata__f b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-trata__a{ display:flex; flex-wrap:wrap; gap:8px; align-items:center }
/* Confirmação de ação destrutiva e contraprova do falso positivo: a pergunta ou o
   formulário ocupa o lugar dos botões da barra (tratamento ou lote) enquanto
   existe; sem eles, os botões voltam. */
.page[data-pagina="despesas-nova"] :has(> .dnv-confirma, > .dnv-contraprova) > :not(.dnv-confirma, .dnv-contraprova){ display:none!important }
.page[data-pagina="despesas-nova"] .dnv-confirma{ flex:1 1 100%; display:flex; flex-wrap:wrap; gap:8px; align-items:center }
.page[data-pagina="despesas-nova"] .dnv-confirma__p{ flex:1 1 260px; margin:0; font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-cx-campo{ flex:1 1 260px; max-width:440px; display:block }
.page[data-pagina="despesas-nova"] .dnv-trata__c{ margin:0; padding:9px 12px; background:var(--dnv-surface); border-left:2px solid var(--dnv-mark); font-size:var(--fonte-corpo); color:var(--dnv-ink); line-height:1.5; }
.page[data-pagina="despesas-nova"] .dnv-trata__c .dnv-k{ display:block; margin-bottom:3px }
/* Contraprova do falso positivo (15/09/2026): o formulário (marca e lote) e a
   exibição na marca fechada. O texto guarda as quebras de linha de quem escreveu. */
.page[data-pagina="despesas-nova"] .dnv-contraprova{ flex:1 1 100%; display:flex; flex-direction:column; gap:8px; max-width:640px }
.page[data-pagina="despesas-nova"] .dnv-contraprova__lote{ margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__lote:empty{ display:none }
.page[data-pagina="despesas-nova"] .dnv-contraprova__rotulo{ margin:0; font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__print, .page[data-pagina="despesas-nova"] .dnv-contraprova__escolhido, .page[data-pagina="despesas-nova"] .dnv-contraprova__botoes{ display:flex; flex-wrap:wrap; align-items:center; gap:8px }
.page[data-pagina="despesas-nova"] .dnv-contraprova__escolhido[hidden]{ display:none }
/* O input de arquivo é invisível e continua no Tab: o anel de foco vai no rótulo que o veste de botão. */
.page[data-pagina="despesas-nova"] .dnv-contraprova__anexar{ margin:0 }
.page[data-pagina="despesas-nova"] .dnv-contraprova__anexar:has(:focus-visible){ outline:2px solid var(--ds-acao); outline-offset:1px }
.page[data-pagina="despesas-nova"] .dnv-contraprova__dica{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__escolhido img{ width:48px; height:48px; object-fit:cover; border:1px solid var(--dnv-rule-2) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__nome{ max-width:24ch; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__erro{ margin:0; font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-risco) }
.page[data-pagina="despesas-nova"] .dnv-contraprova [data-dnv-enviar-contraprova]:disabled{ opacity:.4; cursor:not-allowed }
/* O do lote abre acima da tabela e não pode escondê-la: quem marca precisa ver o
   que está marcando. Rótulo e frase numa linha, print e botões numa fileira que
   quebra no estreito, miniatura menor. O da marca individual não muda. */
.page[data-pagina="despesas-nova"] .dnv-contraprova--lote{ gap:6px; max-width:none }
.page[data-pagina="despesas-nova"] .dnv-contraprova__cabeca{ display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 10px }
.page[data-pagina="despesas-nova"] .dnv-contraprova--lote .dnv-contraprova__lote{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-contraprova__acoes{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 16px }
.page[data-pagina="despesas-nova"] .dnv-contraprova__acoes .dnv-contraprova__botoes{ margin-left:auto }
.page[data-pagina="despesas-nova"] .dnv-contraprova--lote .dnv-contraprova__escolhido img{ width:28px; height:28px }
.page[data-pagina="despesas-nova"] .dnv-lote:has(> .dnv-contraprova--lote){ padding-block:6px }
/* Com o print já anexado, a dica de colar cumpriu o papel: sair dá à fileira os
   ~100px que a faziam quebrar em 1366. */
.page[data-pagina="despesas-nova"] .dnv-contraprova--lote .dnv-contraprova__print:has(.dnv-contraprova__escolhido:not([hidden])) .dnv-contraprova__dica{ display:none }
.page[data-pagina="despesas-nova"] .dnv-trata__contraprova-texto{ margin:0; max-width:68ch; white-space:pre-wrap }
.page[data-pagina="despesas-nova"] .dnv-trata__contraprova img{ display:block; margin-top:6px; max-width:160px; max-height:120px; border:1px solid var(--dnv-rule-2) }
.page[data-pagina="despesas-nova"] .visually-hidden{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.page[data-pagina="despesas-nova"] .dnv-feito{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-feito b{ color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-vazio{ padding:28px 14px; text-align:center; color:var(--dnv-ink-3); font-size:var(--fonte-pequena) }
.page[data-pagina="despesas-nova"] .dnv-recorte-aviso{ margin:0; padding:10px 14px; background:var(--dnv-surface-2); border-bottom:1px solid var(--dnv-rule); font-size:var(--fonte-pequena); color:var(--dnv-ink-2); line-height:1.5; }
.page[data-pagina="despesas-nova"] .dnv-recorte-aviso b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-bloco--fila{ border-left:2px solid var(--dnv-risco) }
.page[data-pagina="despesas-nova"] .dnv-risco__esc{ margin:10px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-risco__d{ display:block; margin-top:4px; color:var(--dnv-mark); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-semdados{ background:var(--dnv-surface); flex:1; display:flex; align-items:center; justify-content:center; padding:40px 24px }
.page[data-pagina="despesas-nova"] .dnv-semdados__in{ max-width:60ch }
.page[data-pagina="despesas-nova"] .dnv-semdados h2{ margin:0 0 12px; font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-.01em }
.page[data-pagina="despesas-nova"] .dnv-semdados p{ margin:0 0 12px; font-size:var(--fonte-corpo); color:var(--dnv-ink-2); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-semdados b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-semdados ul{ margin:0 0 16px; padding-left:18px; font-size:var(--fonte-corpo); color:var(--dnv-ink-2); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-semdados code{ font-size:var(--fonte-pequena); background:var(--dnv-wash); padding:1px 5px; color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-pe{ display:grid; align-items:center; gap:14px; padding:10px 14px; grid-template-columns:14px minmax(0,1fr) 96px 124px 132px; border-top:1px solid var(--dnv-rule-2); background:var(--dnv-surface-2); position:sticky; bottom:0; font-weight:500; font-size:var(--fonte-pequena); }
/* ── ESTREITO ──────────────────────────────────────────────────── */
@media (max-width:1400px){
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:minmax(0,168px) minmax(0,140px) minmax(0,120px) minmax(110px,1fr) minmax(0,54px) minmax(0,116px) 20px; gap:13px }
}
@media (max-width:1120px){
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:minmax(0,160px) minmax(0,132px) minmax(0,112px) minmax(0,126px) 20px; gap:12px }
  .page[data-pagina="despesas-nova"] .dnv-faixa__g, .page[data-pagina="despesas-nova"] .dnv-faixa__ref{ display:none }
}
/* Rótulos do eixo de 12 meses colidiam quando a faixa aperta — cinco marcas
   num eixo que encolhe. Some com as intercaladas antes de elas se empilharem:
   três marcas legíveis dizem mais que cinco sobrepostas. */
@media (max-width:1240px){
  .page[data-pagina="despesas-nova"] .dnv-faixa__x span:nth-child(even){ visibility:hidden }
}
/* Até 1280px, e não 1180: entre os dois a grade ao lado da coluna de 376px dava
   52 a 151px ao nome da conta, que quebrava em até 34 linhas. */
@media (max-width:1280px){
  .page[data-pagina="despesas-nova"] .dnv-miolo{ grid-template-columns:1fr }
  .page[data-pagina="despesas-nova"] .dnv-miolo__e{ max-height:240px }
}
/* Alvo de toque decidido pelo APARELHO, não pela largura: num tablet de 768px
   o dedo é o mesmo, e a regra de ≤760px não o alcançava — "Comentar" ficava
   com 28px de altura. */
@media (hover:none){
  .page[data-pagina="despesas-nova"] .dnv-tratar, .page[data-pagina="despesas-nova"] .dnv-tratado{ min-height:44px }
  /* As linhas de "Maiores credores" e "Maiores variações" são botões (abrem os
     lançamentos) e tinham ~33px. */
  .page[data-pagina="despesas-nova"] .dnv-pux__l{ min-height:44px; align-content:center }
}
@media (max-width:760px){
  .page[data-pagina="despesas-nova"] .dnv-esc2{ display:none!important }
  /* `auto` deixava o conteúdo empurrar a tabela para 365px num contêiner de
     360 — 5px de transbordo. Fixed com a coluna de valor estreita, e o nome
     trunca, que é o que já faz no desktop.

     As larguras seguem a POSIÇÃO das células que sobram, não o nome da coluna:
     `.esc2{display:none}` tira as células de "% do balde" e "Δ na janela", mas
     NÃO tira os `<col>` — em `table-layout:fixed` as três células restantes
     (abrir, conta, valor) mapeiam para os `<col>` 1, 2 e 3. Antes, a de valor
     herdava `c-pct{width:0}`: a coluna de dinheiro nascia com 0px, o texto
     vazava para a direita e cada número começava no mesmo x — uma coluna de
     dinheiro desalinhada por dígito, num arquivo que usa `tabular-nums` de
     propósito. O `<th>Valor</th>` ficava fora de registro pelo mesmo motivo. */
  .page[data-pagina="despesas-nova"] .dnv-grade{ table-layout:fixed }
  .page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-exp{ width:30px }
  .page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-pct{ width:104px }
  /* 3ª posição = a célula de VALOR */
  .page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-delta, .page[data-pagina="despesas-nova"] .dnv-grade col.dnv-c-val{ width:0 }
  /* fora do fluxo visível */
  .page[data-pagina="despesas-nova"] .dnv-grade > thead > tr > th, .page[data-pagina="despesas-nova"] .dnv-grade > tbody > tr > th, .page[data-pagina="despesas-nova"] .dnv-grade > tbody > tr > td, .page[data-pagina="despesas-nova"] .dnv-grade > tfoot > tr > th, .page[data-pagina="despesas-nova"] .dnv-grade > tfoot > tr > td{ padding:10px 12px }
  .page[data-pagina="despesas-nova"] .dnv-cel-nome{ font-size:13px }
  .page[data-pagina="despesas-nova"] .dnv-cel-nome__in{ grid-template-columns:40px minmax(0,1fr) }
  /* A grade de lançamentos não cabe e não rolava: "Tratar" ficava em x=666 num
     viewport de 390 e o código da conta se imprimia por cima do valor. Abaixo
     de 760px cada lançamento vira um cartão, com o alvo de toque inteiro. */
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap table{ display:block }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead{ display:none }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap tbody{ display:block }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap tbody tr{ display:grid; grid-template-columns:1fr auto; gap:2px 10px; padding:12px 14px; border-bottom:1px solid var(--dnv-rule); }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap tbody tr.dnv-trata{ display:block; padding:0 }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td{ display:block; padding:0!important; border:none!important }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(1){ grid-column:1; grid-row:1 }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(2){ grid-column:2; font-size:11px; color:var(--dnv-ink-3) }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(11){ grid-column:3; grid-row:1; text-align:right; font-weight:500 }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap tbody tr{ grid-template-columns:auto 1fr auto }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(3){ grid-column:1/-1; font-size:13px; font-weight:500 }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(4){ grid-column:1/-1; font-size:11.5px; color:var(--dnv-ink-2) }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:is(:nth-child(5), :nth-child(6), :nth-child(7), :nth-child(8), :nth-child(9), :nth-child(10)){ grid-column:auto; font-size:11px; color:var(--dnv-ink-3); }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(12){ grid-column:1/-1; margin-top:8px }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(12) .dnv-tratar, .page[data-pagina="despesas-nova"] .dnv-lanc__wrap td:nth-child(12) .dnv-tratado{ display:block; width:100%; min-height:44px; line-height:44px; text-align:center; border:1px solid var(--dnv-risco); border-bottom-width:1px; font-size:13px; }
  .page[data-pagina="despesas-nova"] .dnv-trata__in{ padding:12px 14px }
  .page[data-pagina="despesas-nova"] .dnv-trata__m{ font-size:13px }
}
@media (max-width:900px){
  .page[data-pagina="despesas-nova"]{ overflow:auto }
  .page[data-pagina="despesas-nova"] .dnv-app{ height:auto; grid-template-columns:1fr; grid-template-areas:"trilho" "lado" "palco" }
  /* O cinza é a cor do vão entre painéis; empilhado, o vão vira o fundo da
     página inteira abaixo do último balde. */
  .page[data-pagina="despesas-nova"] .dnv-app{ background:var(--dnv-surface) }
  .page[data-pagina="despesas-nova"] .dnv-palco{ gap:1px; background:var(--dnv-rule) }
  .page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="1"]{ flex:none }
  /* Empilhado, a faixa fechada não divide altura com ninguém: presa em
     clamp(118px,15vh,176px) ela cortava a variação (conteúdo de 175px em 127). */
  .page[data-pagina="despesas-nova"] .dnv-pan[data-aberto="0"]{ height:auto }
  .page[data-pagina="despesas-nova"] .dnv-miolo__d{ max-height:520px }
  /* A página já rola: a coluna da esquerda numa caixa de 240px com rolagem
     própria escondia "Maiores variações" atrás de um segundo rolar. */
  .page[data-pagina="despesas-nova"] .dnv-miolo__e{ max-height:none; overflow:visible }
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:1fr 30px; height:auto; padding-block:14px; gap:10px }
  .page[data-pagina="despesas-nova"] .dnv-faixa__v, .page[data-pagina="despesas-nova"] .dnv-faixa__d, .page[data-pagina="despesas-nova"] .dnv-faixa__g, .page[data-pagina="despesas-nova"] .dnv-faixa__ref{ grid-column:1/-1 }
  .page[data-pagina="despesas-nova"] .dnv-faixa__g{ height:40px }
}

/* ── PEÇAS QUE O GABARITO NÃO TEM, e por que existem ───────────────────────
   Duas, e as duas nasceram de defeito medido, não de gosto. */

/* O aviso de seleção vazia: sem segmento marcado a tela volta zerada, e zero
   por filtro é indistinguível de zero por falta de despesa. */
.page[data-pagina="despesas-nova"] .dnv-vazio-filtro{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:10px 24px; background:var(--dnv-surface-2);
  border-bottom:1px solid var(--dnv-rule); font-size:var(--fonte-corpo); color:var(--dnv-ink-2);
}
/* A gaveta rola por dentro. `/linhas/` devolve 50 lançamentos por página e o
   gabarito mostra uma amostra de 5: sem teto, o painel aberto ficava 3.130px
   mais alto que o desenho e a grade de contas sumia da tela. O teto preserva o
   acesso a todos eles — rola —, sem o painel engolir a página. */
.page[data-pagina="despesas-nova"] .dnv-lanc__wrap{
  max-height:min(52vh, 420px); overflow-y:auto;
}

/* O bloco da fila virou <a> (era um <button> que não fazia nada e prometia
   "Abrir a fila →"). Ancora leva sublinhado e cor do shell; aqui ele continua
   lendo como bloco, e só o call-to-action se comporta como link. */
/* #404: a fila abre no próprio palco — o bloco volta a ser botão, e de verdade. */
.page[data-pagina="despesas-nova"] button.dnv-risco{ border:0; background:none; color:inherit; font:inherit; cursor:pointer }
.page[data-pagina="despesas-nova"] button.dnv-risco:hover .dnv-risco__ir, .page[data-pagina="despesas-nova"] button.dnv-risco[aria-expanded="true"] .dnv-risco__ir{ text-decoration:underline }
.page[data-pagina="despesas-nova"] .dnv-risco__t{ display:block }
.page[data-pagina="despesas-nova"] .dnv-risco__ir{ display:block; margin-top:4px; color:var(--dnv-mark); font-weight:500; font-size:var(--fonte-corpo) }
/* A fila no topo do palco: indicadores (os de balde são botões), omitidas, grade. */
.page[data-pagina="despesas-nova"] .dnv-fila__inds{ display:flex; flex-wrap:wrap; gap:1px; background:var(--dnv-rule); border-bottom:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-fila__ind{ flex:1 1 140px; display:flex; flex-direction:column; gap:3px; padding:10px 16px; background:var(--dnv-surface); border:0; border-left:3px solid transparent; text-align:left; font:inherit; color:inherit }
.page[data-pagina="despesas-nova"] .dnv-fila__ind b{ font-size:var(--fonte-destaque); font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-fila__ind--balde{ cursor:pointer }
.page[data-pagina="despesas-nova"] .dnv-fila__ind--balde:hover{ background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-fila__ind--balde[aria-pressed="true"]{ border-left-color:var(--dnv-mark); background:var(--dnv-mark-wash) }
.page[data-pagina="despesas-nova"] .dnv-fila__omitidas{ margin:0; padding:8px 14px 0; font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2) }
/* Marcar uma linha limpa: discreto, em tinta — o vermelho é de quem já está sob suspeita. */
.page[data-pagina="despesas-nova"] .dnv-marcar{ font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-3); white-space:nowrap; border:0; border-bottom:1px dotted currentColor; background:none; padding:6px 4px; cursor:pointer }
.page[data-pagina="despesas-nova"] .dnv-marcar:hover, .page[data-pagina="despesas-nova"] .dnv-marcar[aria-expanded="true"]{ color:var(--dnv-mark) }
/* Descrição (observação) da despesa no painel Tratar e no de marcação. */
.page[data-pagina="despesas-nova"] .dnv-trata__obs{ margin:0; font-size:var(--fonte-corpo); line-height:1.5; color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-trata__obs .dnv-k{ display:block; margin-bottom:2px }

/* ── ADAPTAÇÕES DE SHELL — no FIM da seção, e é de propósito ────────────────
   O mockup é um documento inteiro e manda na janela (`html,body{height:100%}`,
   `body{overflow:hidden}`, `.app{height:100dvh}`). Aqui ele é filho de
   `.content`, que já tem topbar acima e respiro em volta.

   Estas regras vêm DEPOIS do porte porque a especificidade é a mesma dos dois
   lados (`.page[data-pagina="despesas-nova"]`) e quem decide é a ordem de
   origem: postas antes, o `margin:0` e o `height:100%` que o porte herdou do
   `body` do mockup as apagavam em silêncio — a tela nascia 88px mais estreita
   e 76px mais alta que o desenho, e quem contou isso foi a medição, não o olho.

   Nenhuma muda o desenho: mudam de quem é a altura e onde fica a borda. */
/* A tela SANGRA até a borda do `.content` e ocupa a janela inteira abaixo da
   topbar, como o mockup ocupa a dele. A margem negativa devolve exatamente o
   respiro que o shell deu — os dois lados saem do mesmo token, então não há
   número mágico a envelhecer —, e por isso a altura desconta SÓ a topbar: com o
   padding anulado, descontá-lo de novo tirava 52px a mais e encurtava as três
   faixas em 27px cada. */
.page[data-pagina="despesas-nova"]{
  margin-inline:calc(-1 * var(--content-pad-x));
  margin-block:calc(-1 * var(--content-pad-y)) calc(-1 * var(--content-pad-b));
  width:auto;
  height:calc(100dvh - 52px);   /* 52px = `.topbar`, 3.25rem */
  display:flex; flex-direction:column;
  /* A `.page` global tem `padding-bottom:24px`, que é o respiro de uma página
     que ROLA. Esta não rola: o mockup vai até o pé da janela e quem rola são os
     painéis, por dentro. Os 24px saíam da altura dos três baldes. */
  padding:0;
}
/* ESTREITO: o gabarito empilha e a PÁGINA rola (`body{overflow:auto}`,
   `.app{height:auto}` em ≤900px). Travar a altura da janela aqui espremia o
   rail de 878px para 283px e escondia o resto atrás de uma rolagem interna que
   ninguém vê. A tela volta a ter a altura do seu conteúdo e rola inteira.

   E a margem negativa passa a copiar a EXPRESSÃO do respiro, não o token: em
   ≤767.98px o `.content` troca o padding por `max(0.5rem, env(safe-area-*))` e
   não mexe em `--content-pad-x`, então puxar 20px de cada lado estourava 12px
   para fora da tela — que o `overflow-x:clip` do shell corta em silêncio, em
   vez de deixar rolar. */
@media (max-width:900px){
  .page[data-pagina="despesas-nova"]{ height:auto; }
  .page[data-pagina="despesas-nova"] .dnv-app{ height:auto; }
}
@media (max-width:767.98px){
  .page[data-pagina="despesas-nova"]{
    margin-inline:calc(-1 * max(0.5rem, env(safe-area-inset-left)))
                  calc(-1 * max(0.5rem, env(safe-area-inset-right)));
    margin-block:-0.5rem calc(-1 * max(1.5rem, env(safe-area-inset-bottom)));
  }
}

/* O `.dnv-app` fica com o que sobrar depois do host de filtros (1px) e do aviso
   de seleção vazia — `height:100%` mediria a página inteira e estouraria 24px
   por baixo quando o aviso estivesse na tela. */
.page[data-pagina="despesas-nova"] .dnv-app{
  flex:1 1 auto; min-height:0;
  grid-template-rows:1fr; grid-template-areas:"lado palco";
}
@media (max-width:900px){
  .page[data-pagina="despesas-nova"] .dnv-app{ grid-template-areas:"lado" "palco"; }
}
/* O branco da folha parava na borda da `.page`: o padding do `.content` em
   volta (o cinza `--surface-app` do resto do app) continuava aparecendo como
   moldura, e o `.main` tem `min-height:calc(100vh - 52px)`, então sobrava uma
   faixa cinza no rodapé quando o conteúdo era mais curto que a janela. `:has()`
   já é usado pelo shell (`content--altura-cheia`); aqui ele só pinta quando é
   ESTA página — as outras 27 não enxergam. */
.content:has(> .page[data-pagina="despesas-nova"]){ background:#fff; }
.main:has(> .content > .page[data-pagina="despesas-nova"]){ background:#fff; }

/* ── TRILHO: Período, Segmento, versão, formato e busca na barra do shell ──
   Mora nos blocos que o `base_fcds.html` já expõe (`crumb`, `topbar_filters`,
   `topbar_actions`); `#topbar:has(.dnv-sel)` só casa na barra desta tela. Os
   controles são os de fábrica no `-sm` (#454), na altura dos outros da barra;
   aqui fica só a barra de 46px e o popover do Segmento. */
#topbar:has(.dnv-sel){
  height:46px; padding:0 12px 0 16px;
  background:var(--dnv-surface); border-bottom:1px solid var(--dnv-rule);
  font-family:var(--dnv-sans); color:var(--dnv-ink);
}
#topbar:has(.dnv-sel) .dnv-pop :where(button){ font:inherit; color:inherit; background:none; border:none; padding:0; cursor:pointer; text-align:left }
#topbar:has(.dnv-sel) .dnv-sel{ position:relative }
#topbar:has(.dnv-sel) .dnv-pop{
  position:absolute; top:100%; left:0; z-index:60; background:var(--dnv-surface);
  border:1px solid var(--dnv-rule-2); box-shadow:0 14px 34px -14px rgba(0,0,0,.3);
  padding:18px 20px 16px; min-width:320px; font-size:var(--fonte-corpo); line-height:1.5; cursor:default;
}
#topbar:has(.dnv-sel) .dnv-pop--seg{ width:min(340px, calc(100vw - 28px)) }
#topbar:has(.dnv-sel) .dnv-pop__nota{ margin:16px 0 0; padding-top:13px; border-top:1px solid var(--dnv-rule); font-size:var(--fonte-pequena); color:var(--dnv-ink-3); line-height:1.5 }
#topbar:has(.dnv-sel) .dnv-pop__nota b{ color:var(--dnv-ink-2); font-weight:500 }
/* PERÍODO: é o seletor canônico da casa (`.fcds-seletor`, seção SELETOR DE PERÍODO),
   extraído daqui em 24/09/2026 com os mesmos valores. Neste trilho só o empilhamento
   do estreito, abaixo, o trata como os outros seletores. */
/* SEGMENTO = `colfilterMulti` EMBUTIDO (#113, D3): as opções (`.colfilter-multi__opt`) e o
   detalhe (valor · quantidade) são do componente; aqui só o desenho do trilho, no escopo
   `.dnv-pop--seg`. Substitui `.dnv-segl*` e `.dnv-pop__acoes*`. O "Voltar para todos"
   virou as ações do componente ("Selecionar todos"/"Limpar seleção"). */
#topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__opt{ gap:10px; padding:8px 0; border-bottom:1px solid var(--dnv-rule); border-radius:0; background:none; font-size:12.5px; color:var(--dnv-ink) }
#topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__opt:hover{ background:none; color:var(--dnv-mark) }
#topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__opt:last-of-type{ border-bottom:none }
#topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__opt input{ accent-color:var(--dnv-mark) }
#topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__detalhe{ font-size:11px; color:var(--dnv-ink-4) }
#topbar:has(.dnv-sel) .dnv-pop--seg [data-colfilter-acao]{ font-size:11.5px; color:var(--dnv-mark); font-weight:600; text-decoration:none }
#topbar:has(.dnv-sel) .dnv-trilho__fim{ position:relative; display:flex; align-items:center; gap:.5rem }
/* Reportar vira ícone aqui — mantém o vermelho que o dono escolheu, mas cede a
   largura ao trilho, como já faz abaixo de 992px em todo o app. */
#topbar:has(.dnv-sel) .fcds-reportar{ width:2rem; padding-inline:0; justify-content:center }
#topbar:has(.dnv-sel) .fcds-reportar span{ display:none !important }

/* ── A FAIXA EM CINCO CÉLULAS — divergência do gabarito, ordem do dono (14/09) ─
   O gabarito tem sete trilhas: nome, valor, variação, gráfico, média, suspeita,
   seta. As duas antes da seta roubavam ~250px do gráfico numa tela de 1920,
   enquanto sobrava branco sob o nome e o valor. A suspeita desce para baixo do
   nome do balde, a média para baixo do valor, e o gráfico vai até a seta. De
   quebra some a coluna que aparecia e sumia conforme houvesse suspeita — o
   gráfico deixa de mudar de largura com o dado. */
.page[data-pagina="despesas-nova"] .dnv-faixa{
  grid-template-columns:minmax(0,172px) minmax(0,152px) minmax(0,128px) minmax(140px,1fr) 20px;
}
.page[data-pagina="despesas-nova"] .dnv-faixa__id,
.page[data-pagina="despesas-nova"] .dnv-faixa__val{ display:flex; flex-direction:column; gap:3px; min-width:0 }
.page[data-pagina="despesas-nova"] .dnv-faixa__id .dnv-faixa__r span{ display:inline; margin-left:6px }
.page[data-pagina="despesas-nova"] .dnv-faixa__val .dnv-faixa__leg{ max-width:none }
@media (max-width:1400px){
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:minmax(0,168px) minmax(0,140px) minmax(0,120px) minmax(110px,1fr) 20px }
}
@media (max-width:1120px){
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:minmax(0,160px) minmax(0,132px) minmax(0,1fr) 20px }
  .page[data-pagina="despesas-nova"] .dnv-faixa__ref{ display:block }
}
@media (max-width:900px){
  .page[data-pagina="despesas-nova"] .dnv-faixa{ grid-template-columns:1fr 30px }
  .page[data-pagina="despesas-nova"] .dnv-faixa__val{ grid-column:1/-1 }
  /* A seta ao lado do nome, na primeira linha. Pela ordem natural ela caía
     sozinha numa quarta linha, embaixo da variação — o gabarito tem o mesmo
     defeito a 390px. */
  .page[data-pagina="despesas-nova"] .dnv-cursor{ grid-column:2; grid-row:1 }
}

/* ── A DICA DO GRÁFICO DE 12 MESES ─────────────────────────────────────────
   O gabarito tinha só o `<title>` nativo: aparece depois de ~1s com o mouse
   parado e não marca o ponto. A dica é imediata, com guia vertical e ponto no
   mês — tema claro, a mesma superfície dos popovers do trilho. */
.page[data-pagina="despesas-nova"] .dnv-faixa__g-d{ position:relative }
.page[data-pagina="despesas-nova"] .dnv-guia{
  position:absolute; top:0; bottom:0; width:0; border-left:1px dashed var(--dnv-ink-3); pointer-events:none;
}
.page[data-pagina="despesas-nova"] .dnv-ponto{
  position:absolute; width:9px; height:9px; margin:-4.5px 0 0 -4.5px; border-radius:50%;
  background:var(--dnv-graf); box-shadow:0 0 0 2px var(--dnv-surface); pointer-events:none;
}
.page[data-pagina="despesas-nova"] .dnv-dica{
  position:fixed; z-index:70; pointer-events:none; display:flex; flex-direction:column; gap:2px;
  padding:8px 11px; background:var(--dnv-surface); border:1px solid var(--dnv-rule-2);
  box-shadow:0 10px 24px -12px rgba(0,0,0,.35); font-size:var(--fonte-pequena); color:var(--dnv-ink-2); white-space:nowrap;
}
.page[data-pagina="despesas-nova"] .dnv-dica b{ font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink); letter-spacing:-.01em }
.page[data-pagina="despesas-nova"] .dnv-dica__k{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-dica__m{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }

/* ── OS MESES EM TODOS OS GRÁFICOS — divergência do gabarito, ordem do dono ──
   O gabarito rotulava só a última faixa, de três em três. Agora cada faixa tem
   os 13 meses; o corte para os trimestrais é decidido pela largura do PRÓPRIO
   gráfico (container query), não da janela — a mesma janela dá gráficos de
   larguras diferentes conforme o rail e a barra lateral. */
.page[data-pagina="despesas-nova"] .dnv-faixa__g{ container-type:inline-size }
.page[data-pagina="despesas-nova"] .dnv-faixa__x span:nth-child(even){ visibility:visible }
@container (max-width:760px){
  .page[data-pagina="despesas-nova"] .dnv-faixa__x .dnv-x-meio{ color:transparent }
}

/* ── O CREDOR COMO CAMINHO (dono, 14/09) ───────────────────────────────────
   Cada um dos maiores credores abre os lançamentos dele no topo do palco. A
   linha continua lendo como lista; só ganha cursor, destaque ao passar e o
   estado "aberto" com a mesma marca azul das contas abertas. */
.page[data-pagina="despesas-nova"] .dnv-cred{ width:calc(100% + 12px); margin-inline:-6px; padding-inline:6px; cursor:pointer; text-align:left }
.page[data-pagina="despesas-nova"] .dnv-cred:hover .dnv-pux__n{ color:var(--dnv-mark) }
.page[data-pagina="despesas-nova"] .dnv-cred[aria-pressed="true"]{ box-shadow:inset 2px 0 0 var(--dnv-mark); background:var(--dnv-mark-wash) }
/* Não encolhe: com um balde aberto ao mesmo tempo, os dois painéis disputavam a
   altura e o do credor era espremido até sobrar só o cabeçalho — sem tabela e
   sem o carregamento. A tabela dele já tem teto e rola por dentro. */
.page[data-pagina="despesas-nova"] .dnv-pan.dnv-pan--credor[data-aberto]{ border-bottom:1px solid var(--dnv-rule); flex:0 0 auto }
.page[data-pagina="despesas-nova"] .dnv-credor__cab{
  display:flex; align-items:baseline; gap:14px; padding:14px 20px 12px;
  border-left:3px solid var(--dnv-mark); background:var(--dnv-surface-2);
}
.page[data-pagina="despesas-nova"] .dnv-credor__n{ font-size:var(--fonte-corpo); font-weight:500; letter-spacing:-.01em }
.page[data-pagina="despesas-nova"] .dnv-credor__v{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-credor__cab .btn{ margin-left:auto }
.page[data-pagina="despesas-nova"] .dnv-credor__corpo{ padding:0 }

/* ── #404 · gaveta com as colunas da tela anterior e "Todos os lançamentos" ── */
/* Segunda linha de uma célula (cliente final, grupo da conta, R$/container). */
.page[data-pagina="despesas-nova"] .dnv-lanc__sub{ display:block; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); max-width:220px;}
/* Status: texto em tinta, só o ponto leva a cor (situação = pílula + ponto). */
.page[data-pagina="despesas-nova"] .dnv-st{ display:inline-flex; align-items:center; gap:6px; white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-st::before{ content:""; flex:none; width:7px; height:7px; border-radius:50%; background:var(--ds-tinta-3, #7C7D7F) }
.page[data-pagina="despesas-nova"] .dnv-st--ok::before{ background:var(--ds-sucesso, #14743C) }
/* Pé da gaveta: o split contabilizado × não e o Copiar. */
.page[data-pagina="despesas-nova"] .dnv-lanc__pe{ display:flex; align-items:center; gap:14px; padding:8px 14px; border-top:1px solid var(--dnv-rule); background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-lanc__pe:empty{ display:none }
.page[data-pagina="despesas-nova"] .dnv-lanc__pe .btn{ margin-left:auto }
.page[data-pagina="despesas-nova"] .dnv-lanc__split{ margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
/* A entrada "Todos os lançamentos", sob os baldes. */
/* ── ABAS DO PALCO (#453): Visão geral · Todos os lançamentos · Fila ──
   Grudam no topo do palco enquanto ele rola. Alvo de 40px; a ativa se declara
   pelo filete de ação embaixo, como as abas da casa. */
.page[data-pagina="despesas-nova"] .dnv-abas{ position:sticky; top:0; z-index:3; flex:0 0 auto; display:flex; gap:4px; padding:0 16px; background:var(--dnv-surface); border-bottom:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-abas .dnv-aba{ display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:0 14px; font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink-2); border-bottom:3px solid transparent; margin-bottom:-1px; white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-abas .dnv-aba:hover{ color:var(--dnv-ink); background:var(--dnv-surface-2) }
.page[data-pagina="despesas-nova"] .dnv-abas .dnv-aba[aria-pressed="true"]{ color:var(--dnv-ink); font-weight:500; border-bottom-color:var(--ds-acao) }
.page[data-pagina="despesas-nova"] .dnv-aba__n{ font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-aba__n--risco{ color:var(--dnv-risco) }
/* Todos e Fila abertos são a visão inteira: a lista estica até o pé da janela e
   rola por dentro, com o cabeçalho da tabela à vista. Sem a sobra de altura do
   `::after`, que dividiria a folga com ela. */
.page[data-pagina="despesas-nova"] .dnv-palco:has(> :is(.dnv-todos, .dnv-fila, .dnv-arvore, .dnv-metas))::after{ display:none }
.page[data-pagina="despesas-nova"] .dnv-palco > .dnv-pan:is(.dnv-todos, .dnv-fila, .dnv-arvore, .dnv-metas)[data-aberto]{ flex:1 1 0; min-height:420px; max-height:none }
/* ── AS METAS DE DESPESAS (#460): a planilha das metas, inteira, no palco. As
   regras dela (`.met-*`) valem como na tela própria; aqui só a altura (a folha
   rola por dentro até o pé da janela) e as abas de segmento, que o reset de
   botão desta página (`button{ padding:0 … }`) apagaria. */
/* Meta × Realizado (#405): a meta na faixa do balde e a linha com a conta, dentro do balde. */
.page[data-pagina="despesas-nova"] .dnv-faixa__meta{ display:block }
.page[data-pagina="despesas-nova"] .dnv-meta{ margin:0; padding:8px 20px; font-size:var(--fonte-corpo); color:var(--dnv-ink-2) }
.page[data-pagina="despesas-nova"] .dnv-meta .conta-calc-vaga{ display:inline-block }
.page[data-pagina="despesas-nova"] .dnv-miolo__d > .dnv-meta{ display:block; flex:0 0 auto; min-height:0 }
.page[data-pagina="despesas-nova"] .dnv-metas__corpo{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; padding:8px 20px 0; background:var(--dnv-surface) }
.page[data-pagina="despesas-nova"] .dnv-metas .met-folha{ flex:1 1 0; min-height:0; overflow:auto }
.page[data-pagina="despesas-nova"] .dnv-metas .met-aba{ padding:.45rem .9rem; font-size:var(--fonte-corpo); color:var(--ink-2); border-bottom:2px solid transparent }
.page[data-pagina="despesas-nova"] .dnv-metas .met-aba[aria-selected="true"]{ color:var(--ink); font-weight:500; border-bottom-color:var(--bs-primary) }
.page[data-pagina="despesas-nova"] .dnv-metas .met-ocultos button{ padding:.2rem .5rem; color:var(--bs-primary) }
/* ── A ÁRVORE DO CONSOLIDADO (#453): o Detalhamento por Grupo da tela anterior.
   Uma tabela, um corpo por grupo. Rola por dentro com o cabeçalho grudado no
   topo e o TOTAL DO PERÍODO grudado no pé; sem moldura — fio de 1px entre
   linhas, faixa de 3px sobre cada grupo, régua dupla sobre o total. */
.page[data-pagina="despesas-nova"] .dnv-arvore__acoes{ margin-left:auto; display:flex; gap:8px }
.page[data-pagina="despesas-nova"] .dnv-arvore__acoes .btn{ margin-left:0 }
.page[data-pagina="despesas-nova"] .dnv-arvore__rolar{ flex:1 1 0; min-height:0; overflow:auto; background:var(--dnv-surface) }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-arvore__grupo > *{ background:var(--dnv-surface-2); border-top:3px solid var(--dnv-rule-2); font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink); cursor:pointer }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-arvore__grupo:hover > *{ background:var(--dnv-surface-3) }
/* Cada grupo traz o seu cabeçalho (#479): a linha do grupo e o cabeçalho dela ficam presos no topo enquanto o grupo está à vista. Fio em box-shadow: a borda de tabela não acompanha a célula presa. */
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-arvore__grupo > *{ position:sticky; top:0; z-index:3; border-top:0; border-bottom:0; box-shadow:inset 0 3px var(--dnv-rule-2), inset 0 -1px var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-arvore__cab > th{ top:35px; z-index:3; border-bottom:0; box-shadow:inset 0 -1px var(--dnv-rule-2) }  /* 35px = altura medida da linha do grupo, que fica presa acima */
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-linha > th.dnv-cel-nome{ padding-left:30px }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tbody > tr.dnv-linha > *{ font-size:var(--fonte-corpo) }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tfoot > tr > *{ border-top:3px double var(--dnv-ink); background:var(--dnv-surface); font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-arvore__tab > tfoot > tr > th{ text-transform:uppercase; letter-spacing:.06em; font-size:var(--fonte-rotulo) }
/* Na árvore o TOTAL DO PERÍODO fica grudado no pé mesmo com uma conta aberta
   (na grade do balde ele desgruda, ver "UMA rolagem"); a linha de total da
   gaveta, que também gruda no pé, para logo acima dele em vez de cobri-lo. */
.page[data-pagina="despesas-nova"] .dnv-arvore .dnv-arvore__tab:has(.dnv-lanc__wrap) > tfoot{ position:sticky; bottom:0; z-index:7 }
.page[data-pagina="despesas-nova"] .dnv-arvore .dnv-lanc .grade-tabela tfoot th{ bottom:var(--dnv-arvore-total, 42px) }
.page[data-pagina="despesas-nova"] :is(.dnv-todos__corpo, .dnv-fila > .dnv-credor__corpo){ flex:1 1 auto; min-height:0; display:flex; flex-direction:column }
.page[data-pagina="despesas-nova"] .dnv-fila .dnv-lanc__wrap{ flex:1 1 0; min-height:200px; max-height:none }
.page[data-pagina="despesas-nova"] .dnv-todos__barra{ display:flex; align-items:center; gap:12px; padding:10px 20px; border-bottom:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-todos__busca{ flex:1 1 auto; max-width:420px }
.page[data-pagina="despesas-nova"] .dnv-todos__barra .btn{ margin-left:auto }
.page[data-pagina="despesas-nova"] .dnv-todos__corpo[aria-busy="true"]{ opacity:.6 }
.page[data-pagina="despesas-nova"] .dnv-todos__contador{ margin:0; padding:10px 14px 0; font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-todos__corpo > .dnv-lanc__split{ padding:2px 14px 8px }
/* A lista enche a visão (#453): era uma caixa de min(52vh, 420px) com 4 linhas à vista. */
.page[data-pagina="despesas-nova"] .dnv-todos__rolar{ flex:1 1 0; min-height:200px; overflow:auto }
/* Letra das gavetas em tamanho de leitura (era 11,5px), a mesma em toda largura (#454: nada de letra menor
   numa tela só). Coluna curta não quebra; o texto quebra entre palavras e aparece inteiro; só a Observação
   (16ch, `text-break`) parte o token sem espaço. Onde nem assim cabe (1366), a lista rola de lado com a
   primeira coluna (Grupo / Conta) presa à esquerda. */
.page[data-pagina="despesas-nova"] .dnv-lanc table.dnv-todos__tab{ font-size:var(--fonte-corpo) }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-todos__tab th{ font-size:var(--fonte-rotulo) }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-todos__tab td{ padding:9px 8px }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-todos__tab .dnv-todos__curta{ white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-lanc .dnv-todos__tab td.dnv-todos__longa{ min-width:16ch }
.page[data-pagina="despesas-nova"] .dnv-todos__tab .dnv-st{ white-space:normal }
.page[data-pagina="despesas-nova"] .dnv-todos__tab td > .dnv-n{ white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-todos__tab .dnv-lanc__sub{ white-space:normal }
.page[data-pagina="despesas-nova"] .dnv-todos__tab thead th{ position:sticky; top:0; background:var(--dnv-surface-2); z-index:1 }
.page[data-pagina="despesas-nova"] .dnv-todos__tab tr:not(.dnv-trata) > :first-child{ position:sticky; left:0; z-index:1 }
.page[data-pagina="despesas-nova"] .dnv-todos__tab thead th:first-child{ z-index:2 }
.page[data-pagina="despesas-nova"] .dnv-todos__pag{ display:flex; align-items:center; justify-content:center; gap:12px; padding:8px 14px; font-size:var(--fonte-pequena); border-top:1px solid var(--dnv-rule) }

/* O desenho OCUPA a sobra da faixa, não impõe a própria altura. O SVG estica na
   largura e, sem teto, a altura intrínseca (520×74 esticado a 926px = 132px)
   empurrava o bloco do gráfico para 177px dentro de uma faixa ABERTA de 106 —
   e o eixo, agora com os meses visíveis em toda faixa, caía 57px por cima da
   primeira linha da grade. Base flexível zero: quem manda é a faixa. */
.page[data-pagina="despesas-nova"] .dnv-faixa__g-d{ flex:1 1 0; min-height:0; overflow:hidden }
.page[data-pagina="despesas-nova"] .dnv-faixa__g{ min-height:0; max-height:100% }

/* ── CARREGANDO: um para a tela, um por pedido menor (dono, 14/09) ─────────
   Eram quatro logos girando juntos a cada troca de recorte, e nenhum sinal ao
   abrir uma conta, um credor, o painel de tratamento, buscar ou tratar. Agora:
   · a tela inteira — UM logo, sobre `#dnv-app` (período, segmento, 1ª carga);
   · gaveta de conta, de credor e painel de tratamento — o mesmo logo, pequeno,
     no lugar que está buscando;
   · busca — um fio correndo sob o campo enquanto o servidor procura;
   · ação na marca — o botão ocupado, com o mesmo fio;
   · contadores recalculando depois de tratar — os números esmaecem. */
.page[data-pagina="despesas-nova"] .dnv-carregando{ position:relative; min-height:96px }
.page[data-pagina="despesas-nova"] .dnv-trata__in .dnv-carregando{ min-height:64px }
.page[data-pagina="despesas-nova"] .dnv-carregando .logo-loader{ background:transparent }
@keyframes dnv-fio{ from{ background-position:-40% 0 } to{ background-position:140% 0 } }
.page[data-pagina="despesas-nova"] .btn[aria-busy="true"]::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:linear-gradient(90deg, transparent, var(--dnv-mark), transparent) no-repeat;
  background-size:40% 100%; animation:dnv-fio 1s linear infinite;
}
.page[data-pagina="despesas-nova"] .btn[aria-busy="true"]{ position:relative; cursor:progress }
.page[data-pagina="despesas-nova"] .dnv-app[aria-busy="true"] :is(.dnv-risco__n, .dnv-risco__v, .dnv-faixa__r, .dnv-cel-nome .dnv-marca-t--r){
  opacity:.45; transition:opacity .2s;
}
@media (prefers-reduced-motion:reduce){
  .page[data-pagina="despesas-nova"] .btn::after{ animation:none }
}

/* ── GRADES QUE ORDENAM E FILTRAM (dono, 14/09) ────────────────────────────
   Cabeçalho vira botão; a seta aparece SEMPRE — apagada na coluna inativa (diz
   "dá para ordenar"), cheia na ativa (diz o sentido). Na gaveta de lançamentos,
   a segunda linha do cabeçalho traz os filtros de coluna da casa (colfilter-multi)
   e um filtro de texto; o rodapé diz quantos sobraram, de quantos, e quanto somam. */
.page[data-pagina="despesas-nova"] .dnv-ordenar{
  display:inline-flex; flex-wrap:wrap; align-items:center; gap:5px; font:inherit; color:inherit;
  letter-spacing:inherit; text-transform:inherit; cursor:pointer; white-space:nowrap;
}
.page[data-pagina="despesas-nova"] th.dnv-dir .dnv-ordenar{ justify-content:flex-end; width:100% }
.page[data-pagina="despesas-nova"] .dnv-ordenar:hover{ color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-seta{ font-size:var(--fonte-pequena); color:var(--dnv-rule-3); line-height:1 }
.page[data-pagina="despesas-nova"] .dnv-ordenar--ativa{ color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-ordenar--ativa .dnv-seta{ color:var(--dnv-mark) }
/* O cabeçalho da gaveta gruda (sticky, com z-index): a célula seguinte
   (Documento) era pintada por cima do painel de filtro aberto e cortava o canto
   dele. Quem tem o painel aberto sobe. */
.page[data-pagina="despesas-nova"] thead th:has(.colfilter-multi__panel:not([hidden])){ z-index:4 }
/* A gaveta é a grade da casa embutida (reporte #201). As regras da `.dnv-grade`
   acima valem só para as linhas DELA (`>`): antes, sem o combinador, pintavam
   também a tabela da gaveta que mora numa célula dela. Aqui, o que a gaveta
   pede à grade: a caixa do lote só na linha que pode entrar nele (a grade
   desenha a das outras desabilitada), e a linha de total no tom do resto da
   gaveta, com o valor alinhado à direita da coluna. */
.page[data-pagina="despesas-nova"] .dnv-lanc .grade-selecao:disabled{ visibility:hidden }
.page[data-pagina="despesas-nova"] .dnv-lanc .grade-selecao{ width:16px; height:16px; accent-color:var(--dnv-risco); cursor:pointer }
.page[data-pagina="despesas-nova"] .dnv-lanc .grade-tabela tfoot th{ text-transform:none; letter-spacing:0; font-size:11.5px; color:var(--dnv-ink); background:var(--dnv-surface-2); border-top:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-lanc .grade-tabela tfoot th.dnv-dir{ text-align:right }

/* UMA rolagem, não duas. Dentro da grade de contas, a gaveta rolava sozinha
   (420px de 5.954) dentro do painel que também rola (446 de 761): o rodapé da
   gaveta — com "Mostrar mais" — ficava fora das duas. Ali a gaveta cresce e quem
   rola é o painel; o rodapé dela gruda embaixo enquanto ela está na tela, e o
   "Total do balde" desgruda para os dois não se sobreporem. A gaveta do credor
   não mora num painel que rola, e mantém o teto próprio. */
.page[data-pagina="despesas-nova"] .dnv-grade .dnv-lanc__wrap{ max-height:none; overflow:visible }
.page[data-pagina="despesas-nova"] .dnv-grade:has(.dnv-lanc__wrap) > tfoot{ position:static }

/* No telefone os lançamentos viram cartões e o <thead> sumia — levando junto a
   ordenação e os filtros. Ali ele vira uma barra acima dos cartões: os botões de
   ordenar numa linha que quebra, os filtros na seguinte. */
@media (max-width:760px){
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead{ display:block; background:var(--dnv-surface-2); border-bottom:1px solid var(--dnv-rule) }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead tr{ display:flex; flex-wrap:wrap; gap:6px 12px; padding:8px 14px }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead th{ display:block; padding:0 !important; border:none !important; background:none !important; position:static }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead th:empty,
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead th:has(> .visually-hidden){ display:none }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap .grade-filtros-col{ padding-top:0 !important }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap .grade-filtros-col th{ flex:1 1 140px }
  .page[data-pagina="despesas-nova"] .dnv-lanc__wrap thead th.dnv-esc{ display:block }
}

/* ── O RAIL CABE NA JANELA — divergência do gabarito, ordem do dono (14/09) ──
   Rolagem no rail só em caso extremo. Com 26px acima e abaixo de cada bloco, o
   rail de setembro media 934px numa janela de 860 (814 úteis) e rolava sem
   motivo. O respiro vira 14px; as frases que só repetiam regra da tela saíram
   (a explicação de lançado × contabilizado virou dica, "Os 6 maiores por valor"
   e o escopo da fila sumiram). */
.page[data-pagina="despesas-nova"] .dnv-bloco{ padding:14px 24px }

/* A barra encolheu de 52px para os 46px do desenho: quem se posiciona abaixo
   dela precisa saber. */
/* `--dnv-topo` é a altura MEDIDA da barra (o `despesas-nova.js` a publica com um
   ResizeObserver): no estreito o trilho empilha em quatro linhas, e um 46 fixo
   escondia o topo da barra lateral atrás dele. */
body:has(#topbar .dnv-sel) .side{ top:var(--dnv-topo, 46px); height:calc(100vh - var(--dnv-topo, 46px)) }
body:has(#topbar .dnv-sel) .scrim{ inset:var(--dnv-topo, 46px) 0 0 0 }
.main:has(> .content > .page[data-pagina="despesas-nova"]){ min-height:calc(100vh - 46px) }
.page[data-pagina="despesas-nova"]{ height:calc(100dvh - 46px) }
/* Reporte #33: o mês da janela escolhida se lê no eixo; "Maiores variações"
   mostra valor e diferença. O "consolidado não abre" do #33 caiu no #453: ele
   abre a árvore, com mão e hover como as outras faixas. */
.page[data-pagina="despesas-nova"] .dnv-faixa__x .dnv-x-dest{ z-index:1; color:var(--dnv-surface); background:var(--dnv-mark); font-weight:500; padding:2px 6px; margin-top:2px; border-radius:3px; line-height:1 }
.page[data-pagina="despesas-nova"] .dnv-faixa__x .dnv-x-dest::before{ display:none }
.page[data-pagina="despesas-nova"] .dnv-marca-mes{ position:absolute; width:11px; height:11px; margin:-5.5px 0 0 -5.5px; border-radius:50%; background:var(--dnv-mark); box-shadow:0 0 0 2.5px var(--dnv-surface); pointer-events:none }
.page[data-pagina="despesas-nova"] .dnv-pux__cab{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:12px; padding:0 0 5px; border-bottom:1px solid var(--dnv-rule); font-size:var(--fonte-rotulo); letter-spacing:.1em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-pux--dupla :is(.dnv-pux__l, .dnv-pux__cab){ grid-template-columns:minmax(0,1fr) auto auto }
.page[data-pagina="despesas-nova"] .dnv-pux__a{ font-size:var(--fonte-corpo); white-space:nowrap; color:var(--dnv-ink-2); font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-pux__cab span{ text-align:right }
/* Compras de embalagem (#404, só logística): abaixo dos baldes e FORA de todo
   total — um filete neutro à esquerda, sem a marca azul do que soma na tela. */
.page[data-pagina="despesas-nova"] .dnv-embalagem{ flex:0 1 auto; min-height:0; max-height:36%; overflow-y:auto; background:var(--dnv-surface); padding:14px 20px 16px; border-left:3px solid var(--dnv-rule-3) }
.page[data-pagina="despesas-nova"] .dnv-embalagem__cab{ display:flex; align-items:baseline; justify-content:space-between; gap:16px; flex-wrap:wrap }
.page[data-pagina="despesas-nova"] .dnv-embalagem__nota{ margin:4px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-embalagem__total{ font-size:var(--fonte-corpo); font-weight:500; white-space:nowrap }
.page[data-pagina="despesas-nova"] .dnv-embalagem__vazio{ margin-top:10px }
.page[data-pagina="despesas-nova"] .dnv-embalagem__tab{ width:100%; margin-top:10px; border-collapse:collapse; font-size:var(--fonte-pequena) }
.page[data-pagina="despesas-nova"] .dnv-embalagem__tab th{ padding:0 8px 5px 0; border-bottom:1px solid var(--dnv-rule); font-size:var(--fonte-rotulo); letter-spacing:.1em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500; text-align:left }
.page[data-pagina="despesas-nova"] .dnv-embalagem__tab td{ padding:6px 8px 6px 0; border-bottom:1px solid var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-embalagem__tab .dnv-dir{ text-align:right; white-space:nowrap; padding-right:0 }
/* Rail da v2, paridade com a tela anterior (#404, fatia B). */
/* "Formatar número?" no trilho, antes da busca. */
#topbar:has(.dnv-sel) .dnv-formato{ display:flex; align-items:center; gap:6px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
#topbar:has(.dnv-sel) .dnv-formato .form-check-input{ margin:0; float:none }
/* Composição Realizado × Não contabilizado: a barra cresce pelo % do serviço. */
.page[data-pagina="despesas-nova"] .dnv-compo__barra{ display:flex; height:6px; margin:12px 0 8px; background:var(--dnv-wash) }
.page[data-pagina="despesas-nova"] .dnv-compo__barra > span{ flex-basis:0; flex-shrink:1 }
.page[data-pagina="despesas-nova"] .dnv-compo__r{ background:var(--dnv-graf) }
.page[data-pagina="despesas-nova"] .dnv-compo__n{ background:var(--dnv-graf-area) }
.page[data-pagina="despesas-nova"] .dnv-compo__l{ display:flex; align-items:center; gap:6px; margin:2px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-compo__l b{ color:var(--dnv-ink); font-weight:500 }
.page[data-pagina="despesas-nova"] .dnv-compo__m{ display:inline-block; width:8px; height:8px; flex:none }
/* Destaques: filete à esquerda; vermelho só para o que subiu. */
.page[data-pagina="despesas-nova"] .dnv-destaque{ margin:8px 0 0; padding:2px 0 2px 10px; border-left:2px solid var(--dnv-rule-3); font-size:var(--fonte-pequena); line-height:1.5 }
.page[data-pagina="despesas-nova"] .dnv-destaque b{ display:block; font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="despesas-nova"] .dnv-destaque span{ color:var(--dnv-ink-3) }
.page[data-pagina="despesas-nova"] .dnv-destaque--alta{ border-left-color:var(--dnv-risco) }
.page[data-pagina="despesas-nova"] .dnv-destaque--alta b{ color:var(--dnv-risco) }
/* Ranking numa linha só (#404): posição · nome · % · valor (· série, no credor).
   A barra é um fio sob a linha, do tamanho do % do serviço. Credores no rail;
   segmentos e contas na faixa do palco. O nome nunca corta: quebra em linhas, e onde
   não cabe ao lado dele, % · valor · série descem para a linha de baixo, à direita (#454). */
.page[data-pagina="despesas-nova"] .dnv-rank{ position:relative; display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px; padding:5px 0 6px }
.page[data-pagina="despesas-nova"] .dnv-rank > .dnv-pux__t{ flex:1 1 auto; min-width:0; max-width:calc(100% - 22px) }
.page[data-pagina="despesas-nova"] .dnv-rank > .dnv-pux__v{ flex:none }
.page[data-pagina="despesas-nova"] .dnv-rank__i{ flex:none; width:14px; font-size:var(--fonte-pequena); color:var(--dnv-ink-4); font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-rank__barra{ position:absolute; left:22px; right:0; bottom:0; height:2px }
.page[data-pagina="despesas-nova"] .dnv-rank__barra > span{ display:block; height:100%; background:var(--dnv-graf); opacity:.55 }
.page[data-pagina="despesas-nova"] .dnv-rank__barra > .dnv-rank__contra{ margin-left:auto; background:repeating-linear-gradient(135deg, var(--dnv-graf) 0 3px, transparent 3px 5px) }
.page[data-pagina="despesas-nova"] .dnv-rank__p{ flex:none; margin-left:auto; min-width:38px; text-align:right; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); font-variant-numeric:tabular-nums }
.page[data-pagina="despesas-nova"] .dnv-rank__s{ flex:none; align-self:center; line-height:0 }
.page[data-pagina="despesas-nova"] .dnv-rank__s svg{ width:40px; height:12px }
.page[data-pagina="despesas-nova"] .dnv-rank__fora{ flex:none; align-self:center; width:6px; height:6px; margin-right:6px; border-radius:50%; background:var(--dnv-risco) }
/* A faixa Segmentos | Maiores contas, sob os baldes. */
.page[data-pagina="despesas-nova"] .dnv-rankings{ flex:0 0 auto; display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:1px; background:var(--dnv-rule) }
.page[data-pagina="despesas-nova"] .dnv-ranking{ min-width:0; padding:12px 20px 10px; background:var(--dnv-surface) }
.page[data-pagina="despesas-nova"] .dnv-ranking .dnv-k{ margin-bottom:2px }
.page[data-pagina="despesas-nova"] .dnv-ranking .dnv-rank{ padding:2px 0 3px }
/* Com a faixa, a leitura geral passa da altura do palco num notebook (≈60px a
   1366×768): o palco rola em vez de cortar a entrada "Todos os lançamentos". */
.page[data-pagina="despesas-nova"] .dnv-pux--linha .dnv-rank{ padding:2px 0 3px }
/* Altura do rail a 1366×768 (#404): o livro vazio não guarda a margem, e a fila fica justa. */
.page[data-pagina="despesas-nova"] .dnv-livro:empty{ display:none }
.page[data-pagina="despesas-nova"] .dnv-bloco--fila .dnv-risco{ padding-top:6px }
.page[data-pagina="despesas-nova"] .dnv-bloco--fila .dnv-risco__t{ margin-top:4px }
@media (max-width:900px){
  .page[data-pagina="despesas-nova"] .dnv-rankings{ grid-template-columns:minmax(0,1fr) }
}
.page[data-pagina="despesas-nova"] .dnv-faixa__parte{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2); white-space:nowrap; font-variant-numeric:tabular-nums }

@media (hover:none){
  #topbar:has(.dnv-sel) .dnv-pop--seg .colfilter-multi__opt{ min-height:44px }
}
/* ESTREITO: o gabarito empilha o trilho — marca, Período, Segmento e a busca,
   cada um na sua linha. Aqui a primeira linha é a do shell (☰ + marca + ícones),
   e a barra deixa de ser grudada: com quatro linhas ela comeria meia tela. */
@media (max-width:900px){
  #topbar:has(.dnv-sel){ height:auto; flex-wrap:wrap; padding:0 12px 8px }
  #topbar:has(.dnv-sel) > .crumb{ order:0; flex:1 1 auto; min-height:46px }
  #topbar:has(.dnv-sel) > .fcds-reportar, #topbar:has(.dnv-sel) > .fcds-sino{ order:1 }
  #topbar:has(.dnv-sel) > .fcds-sino{ margin-right:12px }
  #topbar:has(.dnv-sel) > :is(.dnv-sel, .fcds-seletor){ order:2; flex:1 0 100%; position:relative }
  #topbar:has(.dnv-sel) :is(.dnv-sel__bt, .fcds-seletor__botao){ width:100% }
  #topbar:has(.dnv-sel) :is(.dnv-pop, .fcds-seletor__popover){ left:14px; right:14px; width:auto!important; min-width:0 }
  #topbar:has(.dnv-sel) .fcds-seletor__popover .colfilter-range__field input{ flex:1; width:auto }
  #topbar:has(.dnv-sel) > .dnv-trilho__fim{ order:3; flex:1 0 100% }
  .page[data-pagina="despesas-nova"]{ height:auto }
}
/* Sem barra lateral fixa (ela vira gaveta), a barra de quatro linhas deixa de ser
   grudada: no telefone ela comeria um quarto da tela o tempo todo. */
@media (max-width:767.98px){
  #topbar:has(.dnv-sel){ position:relative }
}


/* ==========================================================================
   TAXA DE FRETE — /taxa-frete/
   ==========================================================================
   PORTE FIEL do protótipo aprovado em 10/09/2026, decisão do dono: "o MOCKUP
   ERA MUITO SUPERIOR EM VÁRIOS ASPECTOS, implemente o mockup, pixel perfect".

   As regras abaixo são as DO PROTÓTIPO, valor por valor. A única mudança é
   mecânica: todo seletor nasce dentro de `.page[data-pagina="taxa_frete"]`,
   e o `:root`/`body` dele viraram esse mesmo seletor — o `custom.css` é lido
   por ~28 telas e token em `:root` vaza no app inteiro. Nenhum tamanho, peso,
   cor, raio ou espaçamento foi reinterpretado.

   Não editar por gosto: mudança aqui é divergência do desenho aprovado.
   ========================================================================== */
.page[data-pagina="taxa_frete"] {/* Neutro frio com viés de zinco — a cor do arame galvanizado, não cinza de framework.
     Recusa deliberada do creme+terracota: três direções de design chegaram nele, e é
     justamente o visual que hoje denuncia página gerada. *//* Uma cor só carrega quantidade de frete, e ela é azul-petróleo: profunda o
     bastante para a barra ter peso sobre o branco, dessaturada o bastante para não
     virar botão. Sem semáforo — a Four não tem meta de frete aprovada, e pintar
     faixa de bom e ruim inventaria um julgamento que ninguém fez. O tijolo entra
     só onde há defeito de dado (peso que não fecha), nunca como avaliação. */
  color-scheme: light;
  
  --zinco:#f1f3f6; --branco:#ffffff; --trilho-bg:#e6eaef;
  --linha:#dbe1e8; --linha-2:#eaeef2;
  --tinta:#16202b; --tinta-2:#48596a; --tinta-3:#76889a; --tinta-4:#a6b4c1;
  
  --frete:#1c5f8b; --frete-forte:#134a6e; --frete-fraco:#d3e4f0;
  --alerta:#9e3a2a;
  --sans:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
.page[data-pagina="taxa_frete"], .page[data-pagina="taxa_frete"] * { box-sizing:border-box; }
.page[data-pagina="taxa_frete"] {
  margin:0; background:var(--zinco); color:var(--tinta);
  font-family:var(--sans);
  -webkit-font-smoothing:antialiased;
}
.page[data-pagina="taxa_frete"] .txf-tela { max-width:1220px; margin:0 auto; padding:26px 20px 48px; }
.page[data-pagina="taxa_frete"] .txf-caps { font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; }/* ── a frase ── */


.page[data-pagina="taxa_frete"] .txf-topo { display:flex; justify-content:space-between; align-items:flex-end; gap:32px; flex-wrap:wrap; margin-bottom:22px; }
.page[data-pagina="taxa_frete"] .txf-frase { margin:0; font-size:var(--fonte-heroi); font-weight:400; line-height:40px; max-width:24ch; letter-spacing:-.01em; }
.page[data-pagina="taxa_frete"] .txf-frase b { font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-heroi {
  font-family:var(--mono); font-size:var(--fonte-heroi); font-weight:500; color:var(--frete-forte);
  letter-spacing:-.03em; line-height:40px; display:inline-block; vertical-align:-6px; margin:0 2px;
}
.page[data-pagina="taxa_frete"] .txf-ficha { text-align:right; display:flex; flex-direction:column; gap:3px; }
.page[data-pagina="taxa_frete"] .txf-ficha .txf-caps { color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-ficha b { font-family:var(--mono); font-weight:500; font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] .txf-rascunho {
  align-self:flex-start; border:1px dashed var(--linha); border-radius:99px;
  padding:4px 10px; color:var(--tinta-3);
}/* ── régua de meses ── */


.page[data-pagina="taxa_frete"] .txf-regua { margin-bottom:20px; }
.page[data-pagina="taxa_frete"] .txf-regua-topo { display:flex; justify-content:space-between; align-items:baseline; gap:20px; margin-bottom:2px; }
.page[data-pagina="taxa_frete"] .txf-regua-topo .txf-caps { color:var(--tinta-2); }
.page[data-pagina="taxa_frete"] .txf-legenda-ref {
  font-style:normal; font-weight:500; letter-spacing:.02em; text-transform:none;
  color:var(--tinta-3); margin-left:10px; font-size:var(--fonte-pequena);
}
.page[data-pagina="taxa_frete"] .txf-regua-topo p { margin:0; font-size:var(--fonte-pequena); color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-moldura { overflow-x:auto; }
.page[data-pagina="taxa_frete"] .txf-moldura svg { display:block; width:100%; height:auto; }
.page[data-pagina="taxa_frete"] .txf-barra { fill:var(--frete); }
.page[data-pagina="taxa_frete"] .txf-barra-parcial { fill:var(--frete-fraco); }
.page[data-pagina="taxa_frete"] .txf-topo-aberto { stroke:var(--frete); stroke-width:1.5; stroke-dasharray:3 3; }
.page[data-pagina="taxa_frete"] .txf-aguardando { stroke:var(--tinta-4); stroke-width:2; }
.page[data-pagina="taxa_frete"] .txf-linha-base { stroke:var(--linha); stroke-width:1; }
.page[data-pagina="taxa_frete"] .txf-ref { stroke:var(--tinta-3); stroke-width:1; stroke-dasharray:4 4; }
.page[data-pagina="taxa_frete"] .txf-ref-rot.txf-fim { text-anchor:end; }
.page[data-pagina="taxa_frete"] .txf-ref-rot { font-family:var(--sans); font-size:var(--fonte-pequena); font-weight:500; letter-spacing:.07em; fill:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-num-mes { font-family:var(--mono); font-size:var(--fonte-pequena); font-weight:500; fill:var(--tinta-2); text-anchor:middle; }
.page[data-pagina="taxa_frete"] .txf-num-mes.txf-parcial { fill:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-mes-rot { font-family:var(--sans); font-size:var(--fonte-pequena); font-weight:500; letter-spacing:.06em; fill:var(--tinta-4); text-anchor:middle; }
.page[data-pagina="taxa_frete"] .txf-mes-rot.txf-destaque { fill:var(--tinta-2); }
.page[data-pagina="taxa_frete"] .txf-ano-rot { font-family:var(--sans); font-size:var(--fonte-pequena); font-weight:500; letter-spacing:.08em; fill:var(--tinta-2); text-anchor:middle; }/* ── navegador de profundidade ── */


.page[data-pagina="taxa_frete"] .txf-navegador {
  display:flex; align-items:stretch; gap:0; background:var(--branco);
  border:1px solid var(--linha); border-radius:12px; overflow:hidden; max-height:600px;
}
.page[data-pagina="taxa_frete"] .txf-navegador + .txf-navegador { margin-top:16px; }
.page[data-pagina="taxa_frete"] .txf-trilho {
  width:72px; flex:none; background:var(--trilho-bg); border-right:1px solid var(--linha);
  padding:14px 8px; display:flex; flex-direction:column; align-items:center; gap:10px;
  cursor:pointer; position:relative;
}
.page[data-pagina="taxa_frete"] .txf-trilho:hover { background:#dde4ec; }
.page[data-pagina="taxa_frete"] .txf-trilho::after {
  content:""; position:absolute; right:0; top:0; bottom:0; width:3px; background:var(--frete);
}
.page[data-pagina="taxa_frete"] .txf-trilho .txf-nivel {/* 'RECORTE' em 10px estourava os 58px do trilho */
  color:var(--tinta-3); font-size:var(--fonte-pequena); letter-spacing:.05em; text-align:center;
  line-height:1.2; 
}
.page[data-pagina="taxa_frete"] .txf-trilho .txf-escolha {/* break-all picotava "Arame Enfardamento" em "Enfar/damen/to"; quebra por
     palavra e três linhas no máximo. */
  font-family:var(--mono); font-size:var(--fonte-pequena); font-weight:500; text-align:center;
  
  overflow-wrap:anywhere; hyphens:none; line-height:1.2;

}
.page[data-pagina="taxa_frete"] .txf-trilho .txf-medida { font-family:var(--mono); font-size:var(--fonte-pequena); color:var(--frete-forte); font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-coluna { flex:1 1 0; min-width:0; border-right:1px solid var(--linha); display:flex; flex-direction:column; }
.page[data-pagina="taxa_frete"] .txf-coluna:last-child { border-right:none; }
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca { padding:13px 16px 10px; border-bottom:1px solid var(--linha-2); }
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca .txf-caps { color:var(--tinta-3); display:block; margin-bottom:5px; }
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca h2 { margin:0; font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-.01em; }
.page[data-pagina="taxa_frete"] .txf-resumo { display:flex; gap:18px; flex-wrap:wrap; margin-top:8px; }
.page[data-pagina="taxa_frete"] .txf-resumo div { display:flex; flex-direction:column; }
.page[data-pagina="taxa_frete"] .txf-resumo .txf-caps { margin-bottom:1px; color:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-resumo b { font-family:var(--mono); font-size:var(--fonte-corpo); font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-resumo b.txf-forte { color:var(--frete-forte); font-size:var(--fonte-destaque); }
.page[data-pagina="taxa_frete"] .txf-lista { list-style:none; margin:0; padding:6px 8px 12px; overflow-y:auto; flex:1; }
.page[data-pagina="taxa_frete"] .txf-linha {
  display:grid; grid-template-columns:1fr auto; align-items:center; gap:2px 10px;
  padding:7px 8px; border-radius:7px; cursor:pointer;
}
.page[data-pagina="taxa_frete"] .txf-linha:hover { background:var(--zinco); }
.page[data-pagina="taxa_frete"] .txf-linha.txf-escolhido { background:#e9f1f7; box-shadow:inset 2px 0 0 var(--frete); }
.page[data-pagina="taxa_frete"] .txf-linha .txf-rot { font-weight:500; font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] .txf-linha .txf-ident { font-family:var(--mono); font-size:var(--fonte-corpo); font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-linha .txf-val { font-family:var(--mono); font-size:var(--fonte-corpo); font-weight:500; text-align:right; }
.page[data-pagina="taxa_frete"] .txf-linha .txf-val.txf-fino { font-weight:500; color:var(--tinta-2); }
.page[data-pagina="taxa_frete"] .txf-linha .txf-sub { grid-column:1/-1; font-size:var(--fonte-pequena); color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-linha.txf-bloco { grid-template-columns:1fr auto; }/* Estado: sigla, barra e percentual na MESMA faixa — em três alturas, 18 estados
   viravam uma coluna de rolagem infinita. */

.page[data-pagina="taxa_frete"] .txf-linha.txf-uf { grid-template-columns:30px 1fr auto; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf .txf-regua-linha { grid-column:auto; height:7px; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf .txf-sub { grid-column:2/-1; }
.page[data-pagina="taxa_frete"] .txf-regua-linha { grid-column:1/-1; background:var(--linha-2); border-radius:2px; height:5px; overflow:hidden; }
.page[data-pagina="taxa_frete"] .txf-regua-linha i { display:block; height:100%; background:var(--frete); border-radius:2px; }
.page[data-pagina="taxa_frete"] .txf-regua-linha.txf-fina { height:3px; }
.page[data-pagina="taxa_frete"] .txf-regua-linha.txf-fina i { background:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-linha .txf-sub b { font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-deduzido, .page[data-pagina="taxa_frete"] .txf-suspeito {
  margin-left:7px; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.05em; text-transform:uppercase;
  border-radius:3px; padding:1px 5px;
}
.page[data-pagina="taxa_frete"] .txf-deduzido { color:var(--frete-forte); background:var(--frete-fraco); }
.page[data-pagina="taxa_frete"] .txf-suspeito { color:var(--alerta); background:#f6e7e3; cursor:help; }
.page[data-pagina="taxa_frete"] .txf-obs { font-family:var(--mono); font-size:var(--fonte-pequena); }
.page[data-pagina="taxa_frete"] .txf-pe-coluna {
  padding:10px 16px 14px; border-top:1px solid var(--linha-2); font-size:var(--fonte-pequena);
  color:var(--tinta-2); line-height:1.5;
}
.page[data-pagina="taxa_frete"] .txf-pe-coluna b { color:var(--tinta); }/* ── seletores dentro do trilho zero ── */


.page[data-pagina="taxa_frete"] .txf-coluna.txf-recorte .txf-lista { padding-top:10px; }
.page[data-pagina="taxa_frete"] .txf-grupo-rot { display:block; padding:10px 8px 4px; color:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-item {
  display:flex; align-items:center; gap:9px; padding:6px 8px; border-radius:7px; cursor:pointer; font-size:var(--fonte-corpo);
}
.page[data-pagina="taxa_frete"] .txf-item:hover { background:var(--zinco); }
.page[data-pagina="taxa_frete"] .txf-item .txf-marca {
  width:14px; height:14px; flex:none; border-radius:4px; border:1.5px solid var(--linha);
  background:var(--branco); display:grid; place-items:center; font-size:var(--fonte-pequena); color:var(--branco);
}
.page[data-pagina="taxa_frete"] .txf-item.txf-ligado .txf-marca { background:var(--frete); border-color:var(--frete); }
.page[data-pagina="taxa_frete"] .txf-item .txf-nome { flex:1; }
.page[data-pagina="taxa_frete"] .txf-item:not(.txf-ligado) .txf-nome { color:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-item .txf-medida { font-family:var(--mono); font-size:var(--fonte-pequena); color:var(--tinta-3); }

.page[data-pagina="taxa_frete"] .txf-explica { margin:14px 0 0; font-size:var(--fonte-corpo); color:var(--tinta-2); line-height:1.5; max-width:96ch; }
.page[data-pagina="taxa_frete"] .txf-explica b { color:var(--tinta); }
.page[data-pagina="taxa_frete"] .txf-rodape { margin-top:22px; font-size:var(--fonte-pequena); color:var(--tinta-3); line-height:1.5; max-width:110ch; }
.page[data-pagina="taxa_frete"] .txf-rodape b { color:var(--tinta-2); }
@media (prefers-reduced-motion:reduce) { .page[data-pagina="taxa_frete"], .page[data-pagina="taxa_frete"] * { transition:none !important; } }

/* ── protótipo clicável ── */


.page[data-pagina="taxa_frete"] .txf-linha { transition:background .12s ease; }
.page[data-pagina="taxa_frete"] .txf-linha:focus-visible, .page[data-pagina="taxa_frete"] .txf-trilho:focus-visible { outline:2px solid var(--frete); outline-offset:-2px; }
.page[data-pagina="taxa_frete"] .txf-coluna.txf-fantasma { opacity:.38; pointer-events:none; background:var(--zinco); }
.page[data-pagina="taxa_frete"] .txf-coluna.txf-fantasma h2 { font-size:var(--fonte-corpo); color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-alternadores { display:flex; gap:10px; flex-wrap:wrap; margin-top:10px; }
.page[data-pagina="taxa_frete"] .txf-dica-uso {
  margin:0 0 12px; font-size:var(--fonte-corpo); color:var(--tinta-2); background:var(--branco);
  border:1px solid var(--linha); border-left:3px solid var(--frete);
  border-radius:8px; padding:10px 14px; line-height:1.5;
}
.page[data-pagina="taxa_frete"] .txf-dica-uso b { color:var(--tinta); }
.page[data-pagina="taxa_frete"] .txf-dica-uso kbd {
  font-family:var(--mono); font-size:var(--fonte-pequena); background:var(--zinco); border:1px solid var(--linha);
  border-radius:4px; padding:1px 5px;
  color:var(--tinta-2);
}
.page[data-pagina="taxa_frete"] #txf-migalha {
  font-family:var(--mono); font-size:var(--fonte-pequena); color:var(--tinta-3); margin:0 0 8px; min-height:17px;
}
.page[data-pagina="taxa_frete"] #txf-navegador { min-height:520px; }
.page[data-pagina="taxa_frete"] .txf-recorte-corpo { padding:10px 14px 14px; overflow-y:auto; flex:1; }
.page[data-pagina="taxa_frete"] .txf-recorte-corpo .txf-caps { display:block; color:var(--tinta-4); margin:12px 0 5px; }
.page[data-pagina="taxa_frete"] .txf-recorte-corpo .txf-caps:first-child { margin-top:0; }
.page[data-pagina="taxa_frete"] .txf-fecha-recorte {
  margin-top:12px; border:1px solid var(--linha); background:var(--branco); border-radius:8px;
  padding:6px 12px; font-family:inherit; font-size:var(--fonte-pequena); font-weight:500; color:var(--tinta-2); cursor:pointer;
}
.page[data-pagina="taxa_frete"] .txf-fecha-recorte:hover { background:var(--zinco); }/* ── o contrário na linha ── */


.page[data-pagina="taxa_frete"] .txf-contra {
  grid-column:1/-1; font-family:var(--mono); font-size:var(--fonte-pequena); color:var(--frete-forte);
  letter-spacing:.01em;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-escolhido .txf-contra { color:#0f3d5c; }/* Rótulo longo (nome de família) ocupa a faixa inteira e empurra a barra para
   baixo — em 30px ele escrevia por cima do gráfico. */



.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo { grid-template-columns:1fr auto; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-regua-linha { grid-column:1/-1; margin-top:3px; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-rot { font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-sub { grid-column:1/-1; }
.page[data-pagina="taxa_frete"] .txf-linha .txf-rot { min-width:0; }/* ── régua clicável ── */



.page[data-pagina="taxa_frete"] .txf-mes .txf-alvo { fill:transparent; }
.page[data-pagina="taxa_frete"] .txf-mes.txf-clicavel { cursor:pointer; }
.page[data-pagina="taxa_frete"] .txf-mes.txf-clicavel:hover .txf-alvo { fill:rgba(28,95,139,.08); }
.page[data-pagina="taxa_frete"] .txf-mes.txf-clicavel:focus-visible .txf-alvo { fill:rgba(28,95,139,.15); outline:none; }
.page[data-pagina="taxa_frete"] .txf-mes.txf-apagado { opacity:.3; }
.page[data-pagina="taxa_frete"] .txf-mes.txf-selecionado .txf-barra { fill:var(--frete-forte); }
.page[data-pagina="taxa_frete"] .txf-mes.txf-selecionado .txf-num-mes { fill:var(--frete-forte); font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-mes.txf-selecionado .txf-mes-rot { fill:var(--frete-forte); font-weight:500; }
.page[data-pagina="taxa_frete"] #txf-mes-escolhido {
  margin:0 0 8px; font-size:var(--fonte-corpo); color:var(--tinta-2);
}
.page[data-pagina="taxa_frete"] #txf-mes-escolhido:empty { display:none; }
.page[data-pagina="taxa_frete"] #txf-mes-escolhido b { color:var(--frete-forte); }
.page[data-pagina="taxa_frete"] #txf-limpar-mes {
  margin-left:8px; border:1px solid var(--linha); background:var(--branco); border-radius:7px;
  padding:3px 10px; font-family:inherit; font-size:var(--fonte-pequena); font-weight:500; color:var(--tinta-2); cursor:pointer;
}
.page[data-pagina="taxa_frete"] #txf-limpar-mes:hover { background:var(--zinco); border-color:var(--frete); }/* ── busca pelos dois lados ── */


.page[data-pagina="taxa_frete"] .txf-barra-busca { position:relative; margin:0 0 10px; max-width:520px; }
.page[data-pagina="taxa_frete"] #txf-busca {
  width:100%; font-family:var(--mono); font-size:var(--fonte-corpo); color:var(--tinta);
  background:var(--branco); border:1px solid var(--linha); border-radius:9px;
  padding:10px 13px 10px 38px;
}
.page[data-pagina="taxa_frete"] #txf-busca:focus { outline:none; border-color:var(--frete); box-shadow:0 0 0 3px var(--frete-fraco); }
.page[data-pagina="taxa_frete"] #txf-busca::placeholder { color:var(--tinta-4); font-family:var(--sans); }
.page[data-pagina="taxa_frete"] .txf-lupa {
  position:absolute; left:13px; top:50%; transform:translateY(-50%);
  width:14px; height:14px; border:1.8px solid var(--tinta-4); border-radius:50%;
}
.page[data-pagina="taxa_frete"] .txf-lupa::after {
  content:""; position:absolute; right:-5px; bottom:-3px; width:6px; height:1.8px;
  background:var(--tinta-4); transform:rotate(45deg);
}
.page[data-pagina="taxa_frete"] #txf-achados { list-style:none; margin:6px 0 0; padding:0; display:grid; gap:3px; }
.page[data-pagina="taxa_frete"] #txf-achados li {
  display:grid; grid-template-columns:auto auto 1fr; align-items:baseline; gap:10px;
  background:var(--branco); border:1px solid var(--linha); border-radius:8px;
  padding:8px 12px; cursor:pointer; font-size:var(--fonte-corpo);
}
.page[data-pagina="taxa_frete"] #txf-achados li:hover { border-color:var(--frete); background:#f5f9fc; }
.page[data-pagina="taxa_frete"] #txf-achados b { font-family:var(--mono); font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] #txf-achados span:last-child { color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-uf-achado {
  font-size:var(--fonte-pequena); font-weight:500; letter-spacing:.06em; color:var(--tinta-2);
  background:var(--zinco); border-radius:4px; padding:2px 6px;
}
.page[data-pagina="taxa_frete"] #txf-achados li.txf-vazio { cursor:default; color:var(--tinta-3); grid-template-columns:1fr; }
.page[data-pagina="taxa_frete"] #txf-achados li.txf-vazio:hover { border-color:var(--linha); background:var(--branco); }

/* ── acréscimos do redesenho de 10/09/2026 ──────────────────────────────────
   Vindos da leitura da /despesas/nova/, que o dono apontou como referência:
   recorte na topbar, constatação no lugar da instrução, e o drill ACIMA da
   evolução (o trabalho é investigar; a série é contexto do recorte). ────── */


/* A constatação é UMA LINHA de texto entre o número e o drill. Sem moldura: o
   que a separa é o fio de cima e o respiro, como tudo mais nesta tela. */
.page[data-pagina="taxa_frete"] .txf-constatacao {
  margin:0 0 16px; padding:12px 0 0; border-top:1px solid var(--linha);
  font-size:var(--fonte-corpo); color:var(--tinta-2); line-height:1.5;
}
.page[data-pagina="taxa_frete"] .txf-constatacao b { color:var(--tinta); font-weight:500; }
.page[data-pagina="taxa_frete"] .txf-constatacao button {
  border:0; background:none; padding:0; margin-left:6px; font:inherit;
  font-weight:500; color:var(--frete); cursor:pointer; text-decoration:underline;
}
.page[data-pagina="taxa_frete"] .txf-constatacao button:hover { color:var(--frete-forte); }

/* O total fecha a página sob fio grosso, como na /despesas/nova/. */
.page[data-pagina="taxa_frete"] .txf-total {
  display:flex; justify-content:space-between; align-items:baseline; gap:20px;
  border-top:2px solid var(--tinta); margin-top:18px; padding-top:10px;
}
.page[data-pagina="taxa_frete"] .txf-total-rot { font-size:var(--fonte-rotulo); font-weight:500;
  letter-spacing:.09em; text-transform:uppercase; }
.page[data-pagina="taxa_frete"] .txf-total-sub { font-size:var(--fonte-pequena); color:var(--tinta-3); }
.page[data-pagina="taxa_frete"] .txf-total b { font-family:var(--mono); font-size:var(--fonte-titulo);
  font-weight:500; }

/* A evolução passa a fechar a página, não a abri-la. */
.page[data-pagina="taxa_frete"] .txf-regua { margin:22px 0 0; padding-top:14px;
  border-top:1px solid var(--linha); }

/* ── largura inteira, altura da janela (10/09/2026) ─────────────────────────
   Cobrança do dono: "não aproveita largura total da tela, ainda tem muita
   rolagem vertical, o drill precisa ser melhor espalhado". O protótipo nasceu
   como página de leitura — 1220px centrados, tudo empilhado e a página rolando.
   Aqui ele vira TELA DE TRABALHO: quatro faixas numa janela só, e quem rola é a
   lista dentro da coluna, nunca a página.

   O que saiu para caber: a migalha (o trilho já é o caminho, e dizia a mesma
   coisa duas vezes) e o rodapé de quatro linhas (a fonte foi para a
   constatação, que é onde o dono lê). ─────────────────────────────────────── */
.page[data-pagina="taxa_frete"] .txf-tela {
  max-width:none; margin:0; padding:0;
  height:calc(100dvh - 52px - var(--content-pad-y) - var(--content-pad-b));
  /* cabeça · famílias · evolução · drill — a evolução subiu para cima do drill
     em 10/09/2026, decisão do dono. Quem fica com toda a altura que sobra
     continua sendo o drill: é nele que se rola. */
  display:grid; grid-template-rows:auto auto auto minmax(0,1fr); gap:8px;
}

/* PLAIN, de novo e por escrito: nada de raio nesta tela ("eliminem botões com
   raio arredondado; pill redondo; o uso de cards, quero tu plain"). O porte do
   protótipo tinha trazido os raios de volta. */
.page[data-pagina="taxa_frete"] .txf-navegador,
.page[data-pagina="taxa_frete"] .txf-linha,
.page[data-pagina="taxa_frete"] .txf-item,
.page[data-pagina="taxa_frete"] .txf-regua-linha,
.page[data-pagina="taxa_frete"] .txf-regua-linha i,
.page[data-pagina="taxa_frete"] .txf-deduzido,
.page[data-pagina="taxa_frete"] .txf-suspeito,
.page[data-pagina="taxa_frete"] .txf-uf-achado,
.page[data-pagina="taxa_frete"] .txf-fecha-recorte,
.page[data-pagina="taxa_frete"] #txf-limpar-mes,
.page[data-pagina="taxa_frete"] #txf-busca,
.page[data-pagina="taxa_frete"] #txf-achados li { border-radius:0; }

/* ── faixa 1: o número, a ficha e a constatação ── */
.page[data-pagina="taxa_frete"] .txf-topo {
  display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:end;
  gap:4px 28px; margin:0;
}
.page[data-pagina="taxa_frete"] .txf-frase { max-width:none; font-size:var(--fonte-destaque); line-height:1.2; }
.page[data-pagina="taxa_frete"] .txf-heroi { font-size:var(--fonte-heroi); vertical-align:-3px; }
.page[data-pagina="taxa_frete"] .txf-ficha {
  flex-direction:row; align-items:baseline; gap:26px; text-align:right;
}
.page[data-pagina="taxa_frete"] .txf-ficha > div { display:flex; flex-direction:column; gap:1px; }
.page[data-pagina="taxa_frete"] .txf-constatacao {
  grid-column:1/-1; margin:0; padding:5px 0 0; font-size:var(--fonte-corpo);
}

/* ── faixa 2: as famílias que entram na variação mensal ──────────────────────
   O seletor do recorte fica NO TOPO e manda na régua: marcar famílias troca o
   numerador para o frete amarrado às notas delas. Texto sublinhado, não pílula
   — pílula cinza lê como botão desabilitado. */
.page[data-pagina="taxa_frete"] .txf-faixa {
  display:flex; align-items:center; gap:8px 14px; padding:5px 0;
  border-top:1px solid var(--linha); border-bottom:1px solid var(--linha);
}
.page[data-pagina="taxa_frete"] .txf-faixa-rot { color:var(--tinta-3); flex:none; }
.page[data-pagina="taxa_frete"] .txf-familias {
  display:flex; flex-wrap:wrap; gap:2px 14px; flex:1; min-width:0;
  max-height:46px; overflow-y:auto;
}
.page[data-pagina="taxa_frete"] .txf-fam {
  border:0; background:none; padding:2px 0; font:inherit; font-size:var(--fonte-pequena);
  color:var(--tinta-4); cursor:pointer; border-bottom:2px solid transparent;
  white-space:nowrap;
}
.page[data-pagina="taxa_frete"] .txf-fam.txf-on { color:var(--tinta); border-bottom-color:var(--frete); }
.page[data-pagina="taxa_frete"] .txf-fam:hover { color:var(--tinta-2); }
.page[data-pagina="taxa_frete"] .txf-fam b {
  font-family:var(--mono); font-weight:500; font-size:var(--fonte-pequena); margin-left:5px; color:var(--frete-forte);
}
.page[data-pagina="taxa_frete"] .txf-fam:not(.txf-on) b { color:var(--tinta-4); }
.page[data-pagina="taxa_frete"] .txf-fam--todas { font-weight:500; }

/* A busca desce da própria faixa, sobre o conteúdo: campo largo de 520px em
   linha própria era 60px de altura para um campo que se usa uma vez por dia. */
.page[data-pagina="taxa_frete"] .txf-barra-busca { margin:0; flex:none; width:260px; }
.page[data-pagina="taxa_frete"] #txf-busca { padding:5px 10px 5px 30px; font-size:var(--fonte-pequena); }
.page[data-pagina="taxa_frete"] .txf-lupa { left:10px; width:12px; height:12px; }
.page[data-pagina="taxa_frete"] #txf-achados {
  position:absolute; z-index:6; top:calc(100% + 4px); left:0; right:0;
  max-height:52vh; overflow-y:auto; background:var(--branco); border:1px solid var(--linha);
}
.page[data-pagina="taxa_frete"] #txf-achados:empty { display:none; }
.page[data-pagina="taxa_frete"] #txf-achados li { border:0; border-bottom:1px solid var(--linha-2); }

/* ── faixa 3: o drill, que fica com TODA a altura que sobrar ── */
.page[data-pagina="taxa_frete"] #txf-navegador,
.page[data-pagina="taxa_frete"] .txf-navegador {
  min-height:0; max-height:none; height:100%; border-left:0; border-right:0;
}
.page[data-pagina="taxa_frete"] .txf-coluna { min-height:0; }
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca { padding:9px 14px 8px; }
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca h2 { font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] .txf-resumo { gap:14px; margin-top:6px; }
.page[data-pagina="taxa_frete"] .txf-resumo b.txf-forte { font-size:var(--fonte-corpo); }
.page[data-pagina="taxa_frete"] .txf-lista { padding:4px 6px 8px; }
.page[data-pagina="taxa_frete"] .txf-linha { padding:5px 8px; }
.page[data-pagina="taxa_frete"] .txf-pe-coluna { padding:7px 14px 8px; font-size:var(--fonte-pequena); }
.page[data-pagina="taxa_frete"] .txf-trilho { width:64px; padding:10px 6px; }

/* ── faixa 3: a evolução, com o total na mesma linha do título ──────────────
   O total sob fio grosso ocupava uma faixa inteira só para ele. Aqui ele
   fecha a linha de cima da régua, que já estava com metade da largura vazia. */
.page[data-pagina="taxa_frete"] .txf-regua {
  margin:0; padding:2px 0 6px; border-top:0; border-bottom:1px solid var(--linha);
}
.page[data-pagina="taxa_frete"] .txf-regua-topo {
  display:flex; align-items:baseline; gap:6px 18px; flex-wrap:wrap; margin-bottom:0;
}
.page[data-pagina="taxa_frete"] .txf-regua-topo #txf-mes-escolhido { margin:0; flex:1; }
.page[data-pagina="taxa_frete"] .txf-total {
  border-top:0; margin:0 0 0 auto; padding:0; gap:10px;
}
.page[data-pagina="taxa_frete"] .txf-total b { font-size:var(--fonte-destaque); }
.page[data-pagina="taxa_frete"] .txf-moldura { overflow:hidden; }
/* O `.page` da casa fecha com 24px de padding embaixo, e era exatamente esse o
   resto de rolagem que sobrava depois da grade de altura de janela. */
.page[data-pagina="taxa_frete"] { padding-bottom:0; }
.page[data-pagina="taxa_frete"] .txf-tela { overflow:hidden; }

.page[data-pagina="taxa_frete"] .txf-fonte {
  display:block; margin-top:2px; font-style:normal; font-size:var(--fonte-pequena); color:var(--tinta-4);
}

/* Linha de rótulo longo (família, mês): o percentual sobe para a linha do NOME
   e a barra passa a ocupar a faixa inteira embaixo. Antes o número ficava à
   direita da BARRA, e cada linha comia 80px — seis famílias por tela numa
   coluna que cabe quinze. */
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo { row-gap:2px; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-rot { grid-column:1; grid-row:1; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-val { grid-column:2; grid-row:1; }
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-regua-linha {
  grid-column:1/-1; grid-row:2; margin-top:0;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-uf.txf-longo .txf-sub { grid-column:1/-1; grid-row:3; }

/* Fora da raiz, a coluna que já foi escolhida encolhe e a ÚLTIMA fica com a
   folga: uma lista de 3 estados não precisa de 800px, e a lista de CT-e sim. */
.page[data-pagina="taxa_frete"] .txf-coluna:not([data-eixo-raiz]):not(:last-of-type) {
  flex:0 0 clamp(260px, 24%, 400px);
}

/* ── o acerto visual de 11/09/2026 ("a tela tá feia") ───────────────────────
   Três coisas faziam a página parecer cheia e mal-arrumada: o número herói com
   a vírgula solta, a faixa de famílias quebrando em linha rasgada, e a linha do
   eixo gastando três alturas para dizer sigla, barra e percentual. ────────── */

/* O `letter-spacing:-.03em` do protótipo descolava a vírgula do 3,63% em
   IBM Plex Mono. Número é para ler, não para apertar. */
.page[data-pagina="taxa_frete"] .txf-heroi {
  letter-spacing:0; font-variant-numeric:tabular-nums; margin:0 4px;
}
.page[data-pagina="taxa_frete"] .txf-ficha b { font-variant-numeric:tabular-nums; }

/* A fonte volta para o FIM da constatação, na mesma linha: era a terceira
   linha de texto cinza seguida, e três linhas de prosa antes do primeiro
   número é o que fazia o topo parecer um parágrafo. */
.page[data-pagina="taxa_frete"] .txf-fonte {
  display:inline; margin-left:10px; font-size:var(--fonte-pequena); color:var(--tinta-4);
}

/* A faixa de famílias vira GRADE: colunas do mesmo tamanho, nomes alinhados uns
   sob os outros. Em `flex-wrap` os 21 nomes quebravam em linha rasgada — o
   olho não achava onde uma família terminava e a outra começava. */
.page[data-pagina="taxa_frete"] .txf-familias {
  display:grid; grid-template-columns:repeat(auto-fill, minmax(156px, 1fr));
  gap:1px 18px; align-content:start; max-height:66px; padding-right:2px;
  scrollbar-width:thin;
}
.page[data-pagina="taxa_frete"] .txf-fam {
  display:flex; align-items:baseline; gap:6px;
  font-size:var(--fonte-pequena); letter-spacing:.01em; padding:1px 0; min-width:0;
}
.page[data-pagina="taxa_frete"] .txf-fam > span {
 min-width:0;
}
.page[data-pagina="taxa_frete"] .txf-fam b { margin:0; flex:none; }
.page[data-pagina="taxa_frete"] .txf-fam--todas { grid-column:1; }

/* A linha do eixo cabe numa linha: rótulo · barra · percentual · faturado.
   Antes eram três alturas (nome+barra / percentual / "Faturado: R$ 3,8 M"), e a
   barra atravessava 800px como se fosse progresso de download. */
/* A barra fica com a folga (`1fr`): a coluna tem 800px e travar a barra em
   220px deixava 300px de branco no meio da linha. */
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo {
  align-items:center; column-gap:14px; row-gap:0; padding:6px 8px;
  grid-template-columns:34px minmax(120px, 1fr) 62px 104px;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo {
  grid-template-columns:minmax(0, 180px) minmax(120px, 1fr) 62px 104px;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha .txf-rot,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo .txf-rot {
  grid-column:1; grid-row:1;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha .txf-regua-linha,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf .txf-regua-linha,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo .txf-regua-linha {
  grid-column:2; grid-row:1; margin:0; height:6px;
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha .txf-val,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo .txf-val {
  grid-column:3; grid-row:1; font-size:var(--fonte-corpo);
}
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha .txf-sub,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf .txf-sub,
.page[data-pagina="taxa_frete"] .txf-linha.txf-faixa-linha.txf-uf.txf-longo .txf-sub {
  grid-column:4; grid-row:1; text-align:right; font-family:var(--mono);
  font-size:var(--fonte-pequena); color:var(--tinta-3);
}

/* Sem a linha de caps repetindo o título, o cabeçalho da coluna encolhe. */
.page[data-pagina="taxa_frete"] .txf-coluna-cabeca .txf-caps:empty { display:none; }

/* ══════════════════════════════════════════════════════════════════════════
   GRADE DA CASA — reto e sóbrio
   ══════════════════════════════════════════════════════════════════════════
   Reescrita do zero em 11/09/2026. A primeira tentativa empilhou quatro
   gramáticas (chip em pílula petróleo, botão azul do Bootstrap, pílula cinza
   do DataTables, caixa crua de fábrica), inventou um lugar novo para Copiar e
   Colunas, e arredondou tudo. O dono odiou, com razão: cada controle falava um
   sotaque, e a forma redonda dizia "botão" onde o elemento só rotula.

   Três regras, e nada fora delas:
     1. RETO — nenhum raio em lugar nenhum desta seção;
     2. SÓBRIO — só a paleta neutra do FCDS: papel branco, tinta #212529,
        secundária #495057, fio #dee2e6. Cor é para o estado da campanha, que
        é a única informação aqui que tem cor própria;
     3. NADA MUDA DE LUGAR — o `dom` do DataTables é o da casa, então Copiar,
        Colunas, busca e "por pág." ficam onde estão nas outras telas.

   A grade também deixou de morar num cartão: ela É a tela. O par
   `tbl-wrapper datatable` é o que o `esticarGradeUnica` do biUtils procura
   para medir a janela e esticar a lista até embaixo.                      */
.grade {
  --grade-papel: #ffffff;
  --grade-tinta: var(--ds-tinta);
  --grade-tinta-2: var(--ds-tinta-2);
  --grade-fio: var(--ds-filete);
  --grade-fio-forte: var(--ds-filete-2);
  --grade-realce: #f8f9fa;
}

/* ── chips de recorte: `btn-group btn-group-sm` de botões `btn-outline-primary` (grade.js, #454). A contagem vem do
   SERVIDOR e descreve o recorte inteiro. */
.grade > .grade-chips { margin-bottom: .75rem; }

/* ── a barra do DataTables ────────────────────────────────────────────────
   Posição é a da casa; aqui só se apaga o arredondado e a cor de marca, para
   a barra falar a mesma língua da tabela logo abaixo. */
/* A barra da maquete A/C (#454): 16px em cima, 8px entre controles, sem fio (o do cabeçalho já separa). */
.grade .datatable-toolbar { padding: 16px 0 0; gap: 8px; border-bottom: 0; }
.grade .datatable-toolbar :is(.datatable-toolbar__left, .datatable-toolbar__right) { gap: 8px; }
/* Os chips moram na barra, à esquerda (o `grade.js` os leva para lá). */
.grade .datatable-toolbar__left { flex-wrap: wrap; min-width: 0; }
/* Período na barra e resumo no rodapé (o `pedidos.js` os leva): um campo a
   mais na fileira das ferramentas, com a mesma altura e o mesmo fio. */
[data-pagina="crm-pedidos"] .grade .pd-periodo { display: flex; align-items: center; gap: .5rem; flex: 0 0 auto; }
/* O Cliente "tomava a sobra" (`width:100%`, sem teto) quando a lista cabia na
   folha; com 16 colunas e rolagem lateral, a sobra virava 500px e empurrava o
   Valor para fora da janela. */
[data-pagina="crm-pedidos"] .grade .pd-col-cliente { width: auto; max-width: 16rem; }
[data-pagina="crm-pedidos"] .grade .datatable-bottom .pd-resumo {
  margin-left: 1.25rem; font-size: .8125rem;
}
/* Nenhuma opção escondida (dono, 18/10/2026, #454): sem largura para tudo, os chips ficam numa linha e as
   ferramentas descem para a outra — nunca rolagem lateral nem chip cortado. */
.grade .datatable-toolbar { flex-wrap: wrap; }
.grade .datatable-toolbar__left,
.grade .datatable-toolbar__right { flex-wrap: nowrap; white-space: nowrap; }
.grade .datatable-toolbar .dt-buttons,
.grade .datatable-toolbar .grade-chips > .btn,
.grade .datatable-toolbar .dataTables_length { flex-wrap: nowrap; flex-shrink: 0; }
.grade .datatable-toolbar .grade-chips { flex-wrap: wrap; }
/* O grupo da direita não cede: o `.btn-group` dos botões quebra linha no
   mínimo de conteúdo, então o grupo encolhia abaixo da largura real e o
   Colunas vazava 7-9px pela borda a 1280. */
.grade .datatable-toolbar__right { margin-left: auto; flex-shrink: 0; }
/* Quem cede quando falta largura é a BUSCA (até 7rem), não a linha: chips,
   período e botões têm tamanho de palavra, o campo de busca não. */
.grade .datatable-toolbar__left { flex: 1 1 auto; }
.grade .datatable-toolbar .dataTables_filter { flex: 0 1 14rem; min-width: 7rem; }
.grade .datatable-toolbar .dataTables_filter label { display: flex; width: 100%; min-width: 0; margin: 0; }
/* `min-width: 0`: o `<input>` tem largura mínima nativa (~20 caracteres), que
   segurava o encolhimento e fazia a barra estourar a 1280. */
.grade .dataTables_wrapper .datatable-toolbar .dataTables_filter input { width: 100%; min-width: 0; margin: 0; }
/* MUDANÇA GLOBAL (justificativa, #220, 14/10/2026): o menu Colunas de TODA grade (medido em /processos-comex/ e
   /estoque/produtos/ a 1366px) saía cortado à direita e pintava cada coluna visível com o retângulo cheio de tinta
   do chip ativo — uma parede preta. Na barra da casa o botão mora à direita, então o menu se alinha pela borda
   direita dele, e a lista longa rola por dentro. O resto é o dropdown do Bootstrap com o ✓ do DataTables. */
.grade .datatable-toolbar__right .dt-button-collection { left: auto !important; right: 0 !important; }
.grade .dt-button-collection { max-height: 70vh; overflow-y: auto; }
.grade .dataTables_filter input { width: 18rem; max-width: 100%; }
.grade .dataTables_filter label,
.grade .dataTables_length label {
  color: var(--grade-tinta-2); font-size: .8125rem; margin: 0; gap: .4rem;
}

/* ── a tabela ─────────────────────────────────────────────────────────────
   Densidade por ESPAÇAMENTO, nunca por fonte menor: texto miúdo não é
   densidade, é perda de legibilidade. O cabeçalho ancora a coluna, então não
   pode pesar menos que o dado que nomeia. */
/* Um modelo de borda só: `separate`. O DataTables já impõe `separate !important`
   em toda grade com ele; as tabelas sem DataTables seguem o mesmo modelo, e o
   fio mora na célula (no `separate` a borda do `<tr>` não pinta). */
.grade .grade-tabela { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 14px; line-height: 20px; margin: 0; }
/* A casa mede caixa por `border-box` (`.stm-shell *`); o DataTables põe `content-box`
   nas células (0,1,2) e o teto da coluna saía o padding maior que o declarado.
   (0,2,1) vence sem `!important`: largura e teto declarados valem com o padding dentro. */
.grade .grade-tabela :is(th, td) { box-sizing: border-box; }
/* O DataTables fecha a tabela sem rodapé com um fio escuro (`.no-footer`):
   linha solta embaixo da última linha, que o dono não quer. */
.grade table.dataTable.grade-tabela.no-footer { border-bottom: 0; }
.grade .grade-tabela thead th {
  position: sticky; top: 0; z-index: 2;
  text-align: left; font-weight: 500; text-transform: uppercase;
  color: var(--ds-tinta-3); font-size: 11px; line-height: 16px; letter-spacing: .06em;
  height: 34px; padding: 12px 8px 6px; white-space: nowrap;
  border-bottom: 1px solid var(--grade-fio-forte); background: var(--grade-papel);
}
/* Linha de filtros: os controles são form-control/form-select-sm (31px), numa linha só; a coluna alarga para o filtro caber inteiro (dono, #454). */
.grade .grade-tabela thead tr.grade-filtros-col th {
  top: 34px; height: 39px;
  text-transform: none; font-weight: 400; padding: 0 8px 8px; max-width: none !important; /* vence o teto de coluna das telas */
  border-bottom: 1px solid var(--grade-fio-forte);
}
/* Coluna estreita (Un.): a seta do form-select fica no canto e sobra lugar para o texto. */
.grade .grade-tabela thead tr.grade-filtros-col .form-select { padding-right: 1.25rem; background-position: right .25rem center; }
/* Um traço só ancora o cabeçalho, embaixo dos FILTROS. O fio entre rótulos e
   filtros cortava o cabeçalho ao meio e lia como linha voando (dono,
   15/09/2026). */
.grade .grade-tabela thead tr:first-child th { border-bottom: 0; }
/* O filtro de texto segura a coluna em 4rem (era 5rem): com célula de travessão
   ele ditava a largura e Leads passava 48px em 1366 (#454). */
.grade .grade-filtro-texto { min-width: 4rem; }

/* A seta aparece SEMPRE: apagada na coluna inativa diz "dá para ordenar por
   aqui"; cheia na ativa diz "está ordenado por aqui, neste sentido".
   Afordância que só aparece depois de usada não é afordância. A do DataTables
   é imagem de fundo — apagada, porque a nossa é texto e segue a cor. */
.grade .grade-tabela thead tr:first-child th { cursor: pointer; }
.grade .grade-tabela thead th.sorting,
.grade .grade-tabela thead th.sorting_asc,
.grade .grade-tabela thead th.sorting_desc { background-image: none !important; }
/* Caret cheio do Font Awesome, não seta de texto: a ↕ era "magrinha e feia"
   para o dono (15/09/2026), em todas as telas. */
/* O DataTables desenha o par ▲▼ com `::before`/`::after` em posição absoluta
   na borda direita da coluna e reserva 26px para ele: aqui o `::before` sai e
   o `::after` volta a correr junto do rótulo. */
.grade .grade-tabela thead tr:first-child th::before { content: none; }
.grade .grade-tabela thead tr:first-child :is(th.sorting, th.sorting_asc, th.sorting_desc) { padding-right: 8px; }
.grade .grade-tabela thead tr:first-child th::after {
  content: '\f0dc'; font-family: 'Font Awesome 6 Free'; font-weight: 900;
  position: static; display: inline; line-height: inherit;
  margin-left: .35rem; font-size: .8125rem; color: var(--grade-tinta-2); opacity: .35;
}
.grade .grade-tabela thead tr:first-child th.sorting_asc::after { content: '\f0de'; color: var(--grade-tinta); opacity: 1; }
.grade .grade-tabela thead tr:first-child th.sorting_desc::after { content: '\f0dd'; color: var(--grade-tinta); opacity: 1; }
.grade .grade-tabela thead tr.grade-filtros-col th::after { content: none; }
/* Coluna que não ordena (ações, caixa de marcar) não ganha seta: sem isto a
   coluna "Ações" da separação mostrava um caret que não fazia nada. */
.grade .grade-tabela thead tr:first-child th.sorting_disabled::after { content: none; }

/* Sem fio vertical e sem zebra: a coluna já é separada pelo alinhamento, e
   cada linha de tinta a mais é ruído sobre o dado. Só o fio horizontal fica,
   no tom mais fraco que ainda separa, na célula. */
.grade .grade-tabela tbody td { border-bottom: 1px solid var(--grade-fio); }
/* A mão só na linha que abre algo (`aoAbrir` ou `detalheDaLinha`): em toda
   linha ela prometia um clique que não fazia nada (reporte #102). */
.grade .grade-tabela tbody tr.grade-linha--abre { cursor: pointer; }
/* Coluna congelada SEM fio na borda (dono, 15/09/2026: "tem uma linha de
   separação que não deveria existir, e o conteúdo toca a linha"). O divisor da
   casa (`::after` no td, `border-right` no th) sai; quem separa o painel preso
   do que rola por baixo é uma folga branca maior à direita da última coluna
   presa — o conteúdo que rola some atrás do papel, não atrás de um traço. */
.grade table.stickcols.grade-tabela td.stick--edge::after { content: none; }
.grade table.stickcols.grade-tabela th.stick--edge { border-right: 0; }
.grade table.stickcols.grade-tabela .stick--edge { padding-right: 1.5rem; }
/* O respiro também do outro lado (reporte #102): a primeira coluna que rola
   começava colada no painel preso — o painel cobria a borda esquerda do filtro
   e o texto encostava num corte sem traço. Vale para toda grade congelada. */
.grade table.stickcols.grade-tabela .stick--edge + :is(th, td) { padding-left: .75rem; }
/* A linha sob o cursor ganha um banho sutil na linha INTEIRA (dono, 29/10/2026, #706: "deveria ser a linha toda
   e uma cor mais sutil"; o traço preto à esquerda saiu). `--ds-fundo` é opaco, então a coluna congelada não fica
   transparente. O foco é o anel azul de fábrica, e só aparece para quem navega pelo teclado (`:focus-visible`);
   a moldura preta saiu. */
.grade .grade-tabela tbody tr:hover > td { background-color: var(--ds-fundo); }
.grade .grade-tabela tbody tr:focus-visible { outline: 2px solid rgba(var(--bs-primary-rgb), .5); outline-offset: -2px; }
.grade .grade-tabela tbody td {
  height: 36px; padding: 0 8px; vertical-align: middle; color: var(--grade-tinta-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O corte do texto mora no invólucro, não no `<td>`: o Chrome ignora
   `max-width` numa célula de tabela automática, e a coluna abria até caber o
   nome inteiro (Cliente com 502px). O teto que a tela declara na célula chega
   aqui por herança. */
.grade .grade-tabela .grade-celula {
  max-width: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Coluna que quebra linha em vez de abrir a tabela: o `text-wrap` de fábrica na
   coluna chega ao invólucro (#454). */
.grade .grade-tabela .text-wrap .grade-celula { white-space: normal; }
/* Número se compara de cima a baixo: à direita e com algarismo de largura
   fixa, senão a coluna dança a cada linha. */
.grade .grade-tabela .text-end { text-align: right; font-variant-numeric: tabular-nums; }
/* Teto, não largura fixa: assunto curto fica curto, comprido trunca no
   `ellipsis` — nunca abre a coluna até empurrar as vizinhas para longe. */
.grade .grade-col-larga { font-weight: 600; max-width: 26rem; }
/* O estado é a única informação da grade com cor própria, e ela tem ordem:
   rascunho é ausência, enviando é meio do caminho, concluída é fim. Retângulo
   de fio fino e letra na cor — o badge sólido gritava mais que o assunto. */

/* ── rodapé: contagem e páginas ───────────────────────────────────────── */
.grade .datatable-bottom { padding: .75rem 0; color: var(--grade-tinta-2); font-size: .8125rem; }
.grade .dataTables_info { font-variant-numeric: tabular-nums; }
/* Paginador: quadrados do mesmo tamanho para número e seta, sem caixa em
   volta. A página corrente é a ÚNICA coisa pintada; as setas são chevrons do
   Font Awesome (o `‹ ›` de texto era um fio quase invisível — dono,
   15/09/2026). No bootstrap5 do DataTables o elemento é
   `<li.page-item><a.page-link>`. */
/* O seletor sobe até vencer o `div.dataTables_wrapper div.dataTables_paginate
   ul.pagination{margin:2px 0}` do DataTables (0,3,3) pela especificidade. */
.grade .dataTables_wrapper .dataTables_paginate ul.pagination { gap: .25rem; margin: 0; align-items: center; }
.grade .dataTables_paginate .page-item .page-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2rem; height: 2rem; padding: 0 .5rem !important; margin: 0;
  border: 0 !important; box-shadow: none !important;
  background: transparent !important; color: var(--grade-tinta-2) !important;
  font-size: .875rem; font-variant-numeric: tabular-nums;
}
.grade .dataTables_paginate .page-item.previous .page-link,
.grade .dataTables_paginate .page-item.next .page-link {
  color: var(--grade-tinta) !important; font-size: .75rem;
}
.grade .dataTables_paginate .page-item:not(.active):not(.disabled) .page-link:hover {
  background: var(--grade-realce) !important; color: var(--grade-tinta) !important;
}
/* #740 (dono, 30/10/2026): a página corrente é azul cheio de fábrica, como
   todo estado selecionado da régua; o hover acima não a alcança (`:not(.active)`). */
.grade .dataTables_paginate .page-item.active .page-link {
  background: var(--bs-primary) !important; color: #fff !important;
  font-weight: 600;
}
/* O `box-shadow: none` acima apaga o anel de foco do Bootstrap; o teclado
   ganha o contorno no lugar. */
.grade .dataTables_paginate .page-item .page-link:focus-visible {
  outline: 2px solid var(--bs-primary); outline-offset: 2px;
}
.grade .dataTables_paginate .page-item.disabled .page-link {
  color: var(--grade-fio-forte) !important; background: transparent !important; cursor: default;
}

/* ── vazio ────────────────────────────────────────────────────────────────
   O bloco toma o lugar da grade (que fica `hidden`), e a notícia é dada UMA
   vez. Cabeçalho e filtros sobre nada são um esqueleto, e o dono leu isso
   como tela quebrada (03/09/2026). */
.grade .grade-vazio { padding: 4rem 1rem; text-align: center; border-top: 1px solid var(--grade-fio); }
/* Vazio do servidor com a barra à vista (13/10/2026): some só a tabela e o rodapé. */
.grade .grade-tela--sem-nada .datatable-scroll,
.grade .grade-tela--sem-nada .datatable-bottom { display: none; }
.grade .grade-vazio__titulo { margin: 0; font-size: 1.0625rem; font-weight: 600; color: var(--grade-tinta); }
.grade .grade-vazio__dica { margin: .35rem 0 0; font-size: .875rem; color: var(--grade-tinta-2); }
.grade .grade-vazio__acao { margin-top: 1.25rem; }
/* #387: o vazio da caixa de busca oferece a busca do topo. Link de ação do DS
   (#1268AB, sem fundo), antes do "Limpar o recorte". */
.grade .grade-vazio__sistema {
  margin: 1.25rem .75rem 0 0; border: 0; border-radius: 2px; background: none; padding: .35rem .5rem;
  font: inherit; font-size: .875rem; font-weight: 600; color: var(--ds-acao); cursor: pointer;
}
.grade .grade-vazio__sistema:hover { background: color-mix(in srgb, var(--ds-acao) 8%, white); text-decoration: underline; }
.grade .grade-vazio__sistema:focus-visible { outline: 2px solid var(--ds-acao); outline-offset: 2px; }
/* Recorte vazio: a frase entra na linha única que o DataTables põe no corpo.
   `sticky` + `left:50%` a centra na parte VISÍVEL da folha, mesmo numa grade
   mais larga que a janela. */
.grade .grade-tabela tbody tr:has(> td.dataTables_empty) { cursor: default; }
.grade .grade-tabela tbody tr:has(> td.dataTables_empty):hover > td { box-shadow: none; }
.grade .grade-tabela tbody td.dataTables_empty { padding: 0; white-space: normal; overflow: visible; text-align: left; border-bottom: 0; }
.grade .grade-vazio--no-recorte {
  display: inline-block; position: sticky; left: 50%; transform: translateX(-50%);
  border-top: 0; padding: 3rem 1rem;
  /* Numa grade estreita (lista num cartão) a frase mais larga que a tabela
     saía pela esquerda: ela quebra linha dentro da metade do meio. */
  white-space: normal; max-width: 50%;
}

/* ── a grade É a tela ─────────────────────────────────────────────────────
   Três correções do dono em 11/09/2026, no mesmo lugar porque são o mesmo
   assunto — a grade não é um bloco DENTRO da página, ela é a página.

   1. Fundo branco de ponta a ponta. O gelo (`--bg`, #f6f7f9) é o cinza do
      shell aparecendo em volta; numa tela que é só tabela ele vira uma moldura
      sem função. A folha sangra na VERTICAL para cobrir o recuo do `.content`
      — só na vertical, porque sangrar na horizontal joga a folha para baixo da
      barra lateral.
   2. Altura da janela inteira, mesmo com oito linhas. Sem isto sobra uma faixa
      branca embaixo da última linha e a lista parece cortada no meio do nada.
      É `flex` puro, não medição em JS: o que se mede a cada `draw` descola no
      dia em que a barra muda de altura.
   3. O loader para de parecer cartão: sem raio e sem superfície própria, ele é
      só a marca sobre o branco que já está lá.                            */
[data-pagina="email-marketing"] {
  background: #fff;
  margin: calc(var(--content-pad-y) * -1) 0 calc(var(--content-pad-b) * -1);
  padding: var(--content-pad-y) 0 0;
  min-height: calc(100dvh - 52px);
  box-sizing: border-box;
  display: flex; flex-direction: column;
}
.content:has([data-pagina="email-marketing"]) { background: #fff; }

/* A cadeia inteira precisa ceder altura: basta um elo sem `min-height: 0`
   para o `flex: 1` do fim virar altura do conteúdo e a faixa voltar. */
.grade,
.grade .tbl-wrapper,
.grade .dataTables_wrapper {
  display: flex; flex-direction: column; flex: 1; min-height: 0;
}
.grade .datatable-scroll {
  flex: 1; min-height: 0; overflow: auto; max-height: none;
}
/* Grade que NÃO é a tela (numa aba ou abaixo de painéis, numa página que rola):
   sem altura dada pela cadeia, o `none` acima deixava a lista crescer até o
   conteúdo, o scroller não rolava e o cabeçalho não grudava. O contêiner marca
   `grade-com-teto`: o teto é o espaço que sobra na janela abaixo da lista
   (`--bi-dt-scroll-max`, medido pelo `esticarGradeUnica`); sem espaço que
   chegue ao piso, o teto da casa. */
.grade-com-teto .datatable-scroll { max-height: var(--bi-dt-scroll-max, var(--bi-dt-scroll-cap)); }
/* Sem fio em cima do rodapé: o dono quer a grade sem moldura e sem linha
   solta (15/09/2026). `margin-top:auto` é o que o empurra para o pé. */
.grade .datatable-bottom { margin-top: auto; justify-content: flex-start; gap: 1rem; }
/* Contagem (e resumo) à esquerda; "N por pág." e as páginas juntos à direita. */
.grade .datatable-bottom .dataTables_length { margin-left: auto; }
.grade .datatable-bottom .dataTables_length label { display: inline-flex; align-items: center; gap: .4rem; margin: 0; }
/* A casa põe `border-top` no rodapé do DataTables: era a segunda linha voando. */
.grade .dataTables_wrapper .datatable-bottom { border-top: 0; }

.grade .logo-loader {
  background: #fff; border-radius: 0;
}
.grade [data-bi-loading] { min-height: 0; }

/* ── grade embaixo de um painel ───────────────────────────────────────────
   Previsão de caixa tem gráfico e cartões em cima e a grade
   embaixo. A grade NÃO mora num cartão (dono, 15/09/2026: sem moldura): a
   folha da página fica branca, os cartões de cima seguem com o fio deles, e o
   bloco da grade tem a altura da janela — rolando até ela, cabeçalho e rodapé
   ficam à vista e só as linhas rolam. */
.content:has(> .page[data-pagina="previsao_caixa"]),
.content:has(> .page[data-pagina="separacao_faturamento"]),
.content:has(> .page[data-pagina="processos_comex"]),
.page[data-pagina="previsao_caixa"],
.page[data-pagina="separacao_faturamento"],
.page[data-pagina="processos_comex"] { background: #fff; }
/* O bloco da grade (abas, barra, linhas, rodapé) na altura da área que rola
   (dono, #498, 19/10/2026: "altura total da viewport, mesmo que fique com barra
   de rolagem"). Sem piso por página: com painel em cima, a página rola até a
   lista em vez de espremê-la em 3 linhas. Página que rola na janela: a janela
   menos a topbar. Tela de altura cheia: a área que rola é o pai do bloco, e
   `100%` é a altura dela (a janela pode ter barra de filtro parada em cima). */
.grade-na-altura-da-janela { flex: none; height: calc(100dvh - 52px); min-height: 420px; }
.content--altura-cheia .grade-na-altura-da-janela { height: 100%; min-height: 0; }
.page[data-pagina="previsao_caixa"] .pc-abas { display: flex; flex-direction: column; }
.page[data-pagina="previsao_caixa"] .pc-abas > [data-tab-pane]:not([hidden]) {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}

/* ── grade em janela (`compacta`) ─────────────────────────────────────────
   Dentro de um modal a grade não estica: tem a altura do que mostra (10 por
   página), e só passa a rolar por dentro quando a lista não cabe na janela. */
.grade--compacta,
.grade--compacta .tbl-wrapper,
.grade--compacta .dataTables_wrapper { flex: none; }
.grade--compacta .datatable-scroll { flex: none; max-height: 60vh; }
.grade--compacta .datatable-bottom { margin-top: 0; }
/* Janela de inadimplência do faturamento: com o texto livre da observação
   solto, a tabela passava da largura da janela e os valores iam para fora. */
#modalbox-inadimplencia .grade .inad-col-nome { max-width: 11rem; }
#modalbox-inadimplencia .grade .inad-col-observacao { max-width: 9rem; }
/* Janela "ver registros" do cockpit: cliente e item de nota passam de 600px
   numa linha só; com teto, o valor fica dentro da janela. */
#modalbox-registros .grade .registros-col-texto { max-width: 20rem; }

/* ── linha expansível ─────────────────────────────────────────────────────
   A linha-filha é um painel da linha de cima, não outra linha de dados: sem
   listra, sem a barra de hover, com o fundo de realce da grade. */
.grade .grade-tabela tbody tr.grade-detalhe > td {
  padding: .75rem 1rem; background: var(--grade-realce);
  border-bottom: 1px solid var(--grade-fio); white-space: normal;
}
.grade .grade-tabela tbody tr.grade-detalhe:hover > td { box-shadow: none; }
.grade .grade-detalhe__espera { color: var(--grade-tinta-2); font-size: .8125rem; }

/* ── linha de total ───────────────────────────────────────────────────────
   Presa no pé da folha, como o cabeçalho no topo: o total fica à vista com a
   lista rolando. Fio forte em cima, o mesmo que ancora o cabeçalho.
   Com altura fracionária (total por unidade em linhas, 37,5px), o Chrome
   arredonda o grude e 1px da linha de baixo aparecia sob o Total: 1px de papel
   logo abaixo do Total cobre essa fresta e, fora dela, cai além da borda da
   rolagem. Pseudo e não sombra: a sombra mudava o antisserrilhado do texto. */
.grade .grade-tabela tfoot th {
  position: sticky; bottom: 0; z-index: 3;
  height: 32px; padding: 0 8px; vertical-align: middle; background: var(--grade-papel);
  border-top: 1px solid var(--grade-fio-forte); border-bottom: 0;
  font-weight: 500; color: var(--grade-tinta); white-space: nowrap;
}
.grade .grade-tabela tfoot th:first-child { color: var(--ds-tinta-3); font-weight: 400; }
.grade .grade-tabela tfoot th::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 1px;
  background: var(--grade-papel); pointer-events: none;
}
.grade table.stickcols.grade-tabela tfoot th[class*="stick--"] { z-index: 6; }


/* Estado na célula: ponto + palavra, nunca pílula colorida (dono, requisito da
   grade global). Cor só para o que pede ação — o estado normal é neutro, como
   o estágio de Pedidos. Uma classe por tom; a tela mapeia a chave do serviço
   para o tom. */
.grade .grade-status { white-space: nowrap; }
.grade .grade-status::before {
  content: ''; display: inline-block; width: .5rem; height: .5rem; border-radius: 50%;
  margin-right: .45rem; vertical-align: baseline; background: var(--neutral);
}
.grade .grade-status--ok::before { background: var(--positive-text); }
.grade .grade-status--atencao { color: var(--warning-text); }
.grade .grade-status--atencao::before { background: var(--warning); }
.grade .grade-status--erro { color: var(--negative-text); }
.grade .grade-status--erro::before { background: var(--negative-text); }


/* Etiqueta de estado: aqui SÓ a geometria — centrada e com largura mínima,
   porque numa coluna o que se lê é o bloco, e blocos de larguras diferentes
   leem como coisas diferentes. A COR vem dos modificadores canônicos do FCDS
   (`badge--primary`, `badge--neutro`, `badge--info`), que já resolvem esta
   semântica. Chumbar cor aqui foi como o mostarda #8a5a00 voltou: ele é
   exatamente o tom que o `custom.css` já tinha expulsado por ser "uma terceira
   família para dizer atenção". */
/* Etiqueta de estado: preenchida, centrada e de largura mínima — numa coluna
   o que se lê é o bloco, e blocos de larguras diferentes leem como coisas
   diferentes.

   A cor sai dos tokens da casa, nunca de hex escolhido na hora: foi assim que
   o mostarda `#8a5a00` voltou à tela depois de o `custom.css` já o ter
   expulsado por ser "uma terceira família para dizer atenção".

     concluída → `--positive-text`, o verde da casa. Decisão do dono em
                 11/09/2026, contra o que o `badge--neutro` recomenda — o
                 argumento de lá continua escrito, e ele olhou a tela real;
     enviando  → `--info-text`, família de informação. Em curso não é alerta,
                 e o âmbar era justamente o que lia como marrom;
     rascunho  → `--ink-2`, tinta neutra: nada aconteceu ainda.            */
/* MUDANÇA GLOBAL (justificativa): regra de caixa do dono (06/10/2026, #273) — a etiqueta de
   estado NOMEIA um estado ("A SEPARAR", "CONCLUÍDA"): CAIXA ALTA em toda grade da casa. */
.grade .grade-tabela .badge { text-transform: uppercase; letter-spacing: .04em; font-size: .875rem; font-weight: 600; line-height: 1.15; }
/* grade fora do #476 (dono, 19/10) */
.grade { word-spacing: .1rem; } /* o .1em do body era calculado sobre 16px e herdado como 1,6px */
.grade :is(small, .small) { font-size: .875em; }
.grade .grade-tabela .fcds-siglink { font-weight: 600; }
[data-pagina="email-marketing"] .grade .grade-tabela .badge {
  justify-content: center; min-width: 6.25rem; line-height: 1.2;
  border: 0; color: #fff !important; font-weight: 600;
}
[data-pagina="email-marketing"] .grade .grade-estado--concluida { background: var(--positive-text) !important; }
[data-pagina="email-marketing"] .grade .grade-estado--enviando { background: var(--info-text) !important; }
[data-pagina="email-marketing"] .grade .grade-estado--rascunho { background: var(--ink-2) !important; }

/* ==========================================================================
   REPORTES — o botão do megafone (shell), o modal de reportar (shell) e a
   fila da triagem (`/reportes/triagem/`); no fim, o mural de chamados.

   Escopo em três níveis, de propósito:
     · `.fcds-reportar` é SHELL — vive na topbar de todas as telas, e por isso
       herda exatamente a forma do sino ao lado (mesma caixa, mesma borda,
       mesmo cinza). Dois botões vizinhos com gramáticas diferentes leem como
       dois sistemas;
     · `.reportar-*` é o modal, que também é shell, mas só existe aberto;
     · `[data-pagina="reportes"]` é a tela de triagem — escopo de página,
       livre.
   ========================================================================== */

/* ── o botão: `btn btn-danger btn-sm` de fábrica (#454) ─────────────────── */
.fcds-reportar{flex-shrink:0}
.fcds-reportar[aria-busy="true"]{cursor:progress;opacity:.75}

.reportar-rotulo{display:block;margin:0 0 .25rem;font-size:var(--fonte-corpo);font-weight:500;color:var(--ink-2)}
/* O destino do "Não" (reporte #124): logo abaixo da pergunta, antes do tipo. */
.reportar-destino{display:flex;flex-direction:column;gap:.5rem;margin:-.5rem 0 1rem}
.reportar-destino[hidden],.reportar-destino [hidden]{display:none}
.reportar-mural__todos{float:right;font-weight:400}
.reportar-dica{align-self:center;font-size:var(--fonte-corpo);color:var(--ink-3)}
.reportar-erro{margin:.75rem 0 0;font-size:var(--fonte-corpo);color:var(--bs-danger)}
/* O erro que a tela mostrou, dito de volta à pessoa. Família de INFORMAÇÃO, não
   de alerta: aqui não está acontecendo nada de errado — está sendo avisado que
   uma prova já foi anexada. Vermelho aqui seria um segundo susto. */
/* Confirmação depois de enviar: verde de sucesso, na mesma gramática de faixa
   lateral da faixa de erro logo abaixo. */
.reportar-enviado{display:flex;align-items:flex-start;gap:.5rem;margin:0 0 1rem;
  padding:.625rem .75rem;border-left:3px solid var(--positive-text);
  background:var(--positive-subtle);font-size:var(--fonte-corpo);color:var(--ink)}
.reportar-enviado i{color:var(--positive-text);font-size:var(--fonte-destaque);line-height:20px}
.reportar-enviado span{display:block;color:var(--ink-2)}
.reportar-erro-app{display:flex;align-items:flex-start;gap:.375rem;margin:0 0 .75rem;
  padding:.375rem .5rem;border-left:3px solid var(--info-text);background:var(--surf-2);
  font-size:var(--fonte-corpo);color:var(--ink-2)}

/* ── modal: anexos ─────────────────────────────────────────────────────── */
.reportar-anexos{display:flex;flex-wrap:wrap;gap:.5rem;margin:.75rem 0}
.reportar-anexos__vazio{margin:0;font-size:var(--fonte-corpo);color:var(--ink-3)}
/* Miniatura grande e presa ao TOPO: a captura agora é a página inteira, e o
   topo é onde a pessoa reconhece a tela. */
.reportar-anexo{position:relative;margin:0;width:14rem}
.reportar-anexo img{display:block;width:100%;height:9rem;object-fit:cover;object-position:top;
  border:var(--bs-border-width) solid var(--line);border-radius:var(--bs-border-radius)}
.reportar-anexo figcaption{margin-top:.125rem;font-size:var(--fonte-pequena);color:var(--ink-3)}
.reportar-anexo__x{position:absolute;top:.25rem;right:.25rem;width:1.25rem;height:1.25rem;
  display:flex;align-items:center;justify-content:center;padding:0;line-height:1;
  border:0;border-radius:var(--bs-border-radius-sm);background:rgba(0,0,0,.55);color:#fff;cursor:pointer}
.reportar-acoes{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.5rem}
/* "Editar captura" fica SOBRE a miniatura, no rodapé dela: é a única ação que só faz
   sentido com aquela imagem na frente, e um botão solto embaixo perderia a
   qual das cinco ele se refere. */
.reportar-anexo__marcar{position:absolute;left:0;right:0;bottom:1.125rem;
  padding:.125rem 0;border:0;line-height:1;
  background:rgba(0,0,0,.55);color:#fff;font-size:var(--fonte-pequena);font-weight:500;cursor:pointer}
.reportar-anexo__marcar:hover{background:rgba(0,0,0,.75)}
/* Arquivo que não é imagem (PDF, planilha, documento — #375): nome e tamanho,
   sem miniatura. Serve ao modal, ao mural e à página do chamado. */
.reportar-arquivo{display:inline-flex;align-items:center;gap:.375rem;max-width:100%;
  padding:.25rem .5rem;border:var(--bs-border-width) solid var(--line);
  border-radius:var(--bs-border-radius-sm);background:var(--surf);
  font-size:var(--fonte-corpo);color:var(--ink);text-decoration:none}
a.reportar-arquivo:hover{border-color:var(--line-3);color:var(--ink)}
.reportar-arquivo i{color:var(--ink-3)}
.reportar-arquivo__nome{max-width:16rem}
.reportar-arquivo__tamanho{flex:none;color:var(--ink-3);font-size:var(--fonte-pequena)}
.reportar-anexo--arquivo{width:auto;padding-right:1.75rem}

/* ── modal: o marcador ─────────────────────────────────────────────────── */
.reportar-marcador{margin:.75rem 0;padding:.75rem;border:var(--bs-border-width) solid var(--line);
  border-radius:var(--bs-border-radius);background:var(--surf-2)}
.reportar-marcador__topo{position:sticky;top:-1rem;z-index:2;display:flex;flex-wrap:wrap;
  align-items:center;justify-content:space-between;gap:.5rem;margin:-.75rem -.75rem .5rem;
  padding:.75rem;background:var(--surf-2);border-bottom:var(--bs-border-width) solid var(--line);
  font-size:var(--fonte-corpo);color:var(--ink-2)}
.reportar-marcador__topo span{display:block;color:var(--ink-3)}
/* Editando: o modal vira tela cheia e só o editor fica — sem o formulário, o
   mural e o rodapé disputando a altura com o print. */
.reportar-editando #reportar-form > :not(#reportar-marcador),
.reportar-editando #reportar-enviado,
.reportar-editando #reportar-mural,
.reportar-editando .modal-footer{display:none !important}
.reportar-editando .reportar-marcador{margin:0}
/* `crosshair` porque o gesto é desenhar, não clicar; `touch-action:none` porque
   sem ele o dedo ROLA a página em vez de desenhar o retângulo. */
.reportar-marcador__tela{display:block;max-width:100%;touch-action:none;cursor:crosshair;
  border:var(--bs-border-width) solid var(--line-3);background:var(--surf)}
.reportar-marcador__acoes{display:flex;flex-wrap:wrap;gap:.5rem}

/* ── modal: o mural da tela ────────────────────────────────────────────── */
.reportar-mural{margin-top:1.25rem;padding-top:1rem;border-top:var(--bs-border-width) solid var(--line)}
.reportar-mural__titulo{margin:0 0 .5rem;font-size:var(--fonte-rotulo);font-weight:500;color:var(--ink-2);
  text-transform:uppercase;letter-spacing:.04em}
.reportar-mural__lista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.reportar-mural__vazio{font-size:var(--fonte-corpo);color:var(--ink-3)}
.reportar-item{padding:.625rem .75rem;border:var(--bs-border-width) solid var(--line);
  border-radius:var(--bs-border-radius);background:var(--surf)}
/* O próprio reporte da pessoa marcado pela BORDA, não pelo fundo: fundo
   colorido numa lista de dez vira mancha, e aqui o destaque precisa apenas
   dizer "este é o seu". */
.reportar-item--meu{border-left:3px solid var(--acc)}
.reportar-item__topo{display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;margin-bottom:.25rem}
.reportar-item__quem{margin-left:auto;font-size:var(--fonte-pequena);color:var(--ink-3)}
.reportar-item__texto{margin:0;font-size:var(--fonte-corpo);color:var(--ink);white-space:pre-wrap}
.reportar-item__nota{margin:.375rem 0 0;padding-left:.5rem;border-left:2px solid var(--line-3);
  font-size:var(--fonte-corpo);color:var(--ink-2)}
.reportar-item__pe{display:flex;align-items:center;gap:.5rem;margin-top:.5rem}
.reportar-item__print img{width:3rem;height:2rem;object-fit:cover;
  border:var(--bs-border-width) solid var(--line);border-radius:var(--bs-border-radius-sm)}

.reportar-marca,.reportar-estado{display:inline-flex;align-items:center;padding:.0625rem .375rem;
  border-radius:var(--bs-border-radius-sm);font-size:var(--fonte-rotulo);font-weight:500;
  text-transform:uppercase;letter-spacing:.03em}
.reportar-marca--bug{background:var(--bs-danger);color:#fff}
.reportar-marca--melhoria{background:var(--acc);color:#fff}
.reportar-estado{background:var(--surf-3);color:var(--ink-2)}
.reportar-estado--aguardando{background:var(--ds-atencao);color:#161616}
.reportar-estado--fila{background:var(--surf-3);color:var(--ink-2)}
.reportar-estado--andamento{background:var(--info-text);color:#fff}
.reportar-estado--deploy{background:var(--info-text);color:#fff}
.reportar-estado--execucao{background:var(--info-text);color:#fff}
.reportar-estado--adiado{background:var(--surf-3);color:var(--ink-2)}
.reportar-estado--fechado{background:var(--ink-2);color:#fff}

/* Mural colaborativo (15/09/2026): gestos em texto, discretos ao lado do "+1",
   para não competir com o reporte; excluído vira uma linha recolhida, porque
   some da vista mas não do registro. */
.reportar-item__gestos{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem;margin-left:auto}
.reportar-link{padding:0;border:0;background:none;font-size:var(--fonte-pequena);color:var(--acc-ink);cursor:pointer;margin:0}
.reportar-link:hover{text-decoration:underline}
.reportar-link--perigo{color:var(--negative-text)}
.reportar-item--excluido{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;
  background:var(--surf-2);border-style:dashed;font-size:var(--fonte-pequena);color:var(--ink-3)}
.reportar-item--excluido .reportar-link{margin-left:auto}
.reportar-edicao{display:flex;flex-direction:column;gap:.375rem}
.reportar-edicao__tipos{display:flex;gap:1rem;font-size:var(--fonte-corpo)}
.reportar-edicao__dica{margin:0;font-size:var(--fonte-pequena);color:var(--ink-3)}
.reportar-edicao__acoes{display:flex;gap:.5rem}
.reportar-historico{margin-top:.5rem;font-size:var(--fonte-pequena);color:var(--ink-2)}
.reportar-historico summary{cursor:pointer;color:var(--ink-3)}
.reportar-historico ul{margin:.375rem 0 0;padding-left:1rem}
.reportar-historico li{margin-bottom:.25rem}
.reportar-historico__antes{display:block;color:var(--ink-3);white-space:pre-wrap}

/* ── tela de triagem ───────────────────────────────────────────────────── */
/* A grade é a de /crm/pedidos/ (ver o cabeçalho de CRM · PEDIDOS). Aqui só o
   que é da fila: o ponto do status enche conforme a triagem anda — novo vazio,
   aguardando e adiado 1/4 (parados), em planejamento meio, execução 3/4, em
   implementação 13/16, na fila para deploy 7/8, fechado cheio (reporte #132) —, num tom só, como o
   estágio do pedido. Excluído sai da jornada: ponto e texto apagados. */
/* A folha branca vai de borda a borda como a do Pedidos: o recuo lateral do
   `.content` sai e volta como respiro da própria página — senão sobra um
   filete cinza do shell dos dois lados. */
.content:has(> .page[data-pagina="reportes"]){padding-inline:0}
.content > .page[data-pagina="reportes"]{padding-inline:var(--content-pad-x)}
[data-pagina="reportes"] .rp-e-aguardando .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 25%, transparent 25%)}
[data-pagina="reportes"] .rp-e-fila .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 37.5%, transparent 37.5%)}
[data-pagina="reportes"] .rp-e-andamento .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 50%, transparent 50%)}
[data-pagina="reportes"] .rp-e-adiado .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 25%, transparent 25%)}
[data-pagina="reportes"] .rp-e-execucao .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 75%, transparent 75%)}
[data-pagina="reportes"] .rp-e-implementacao .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 81.25%, transparent 81.25%)}
[data-pagina="reportes"] .rp-e-deploy .pd-estagio-marca{
  background:linear-gradient(90deg, var(--pedido-petroleo) 87.5%, transparent 87.5%)}
[data-pagina="reportes"] .rp-e-fechado .pd-estagio-marca{background:var(--pedido-petroleo)}
[data-pagina="reportes"] .rp-e-excluido{color:var(--pedido-tinta-2)}
/* O ritmo da fila (reporte #79): texto de apoio ao lado dos chips, sem
   competir com eles. */
/* O topo da triagem (reporte #400): placar de Bug e Melhoria à esquerda e, ao
   lado, um gráfico por tipo com Abertos e Fechados dia a dia. Bug e Melhoria são --chart-2 e
   --chart-3 de design-system/tokens/charts.css: matizes distintos, sem par
   vermelho/verde, e o nome do tipo vai sempre escrito junto. */
[data-pagina="reportes"]{--rp-bug:#B42727;--rp-melhoria:#1585D7}
[data-pagina="reportes"] .rp-topo{flex:0 0 auto;display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,1fr);gap:1.75rem;align-items:stretch;margin:0 0 .75rem}
[data-pagina="reportes"] .rp-topo[hidden]{display:none}
[data-pagina="reportes"] .rp-placares{display:flex;flex-direction:column;gap:.75rem}
[data-pagina="reportes"] .rp-placar{border-left:4px solid var(--rp-cor);padding:.125rem 0 .125rem .875rem}
[data-pagina="reportes"] .rp-placar--bug{--rp-cor:var(--rp-bug)}
[data-pagina="reportes"] .rp-placar--melhoria{--rp-cor:var(--rp-melhoria)}
[data-pagina="reportes"] .rp-placar p{margin:0}
[data-pagina="reportes"] .rp-placar__tipo{font-size:var(--fonte-corpo);font-weight:500;color:var(--rp-cor)}
[data-pagina="reportes"] .rp-placar__aberto{display:flex;align-items:baseline;gap:.5rem;color:var(--ink)}
[data-pagina="reportes"] .rp-placar__rotulo{font-size:var(--fonte-corpo);color:var(--ink-2)}
[data-pagina="reportes"] .rp-placar__seta{font-size:var(--fonte-corpo);font-weight:500;white-space:nowrap}
[data-pagina="reportes"] .rp-placar__fluxo{font-size:var(--fonte-corpo);color:var(--ink)}
[data-pagina="reportes"] .rp-numero{all:unset;cursor:pointer;font-weight:500;font-size:var(--fonte-titulo);color:var(--ink);font-variant-numeric:tabular-nums}
[data-pagina="reportes"] .rp-numero--grande{font-size:var(--fonte-heroi);line-height:40px}
[data-pagina="reportes"] .rp-numero:hover{text-decoration:underline}
[data-pagina="reportes"] .rp-numero:focus-visible{outline:2px solid var(--acc);outline-offset:1px}
[data-pagina="reportes"] .rp-diario{margin:0;min-width:0;display:flex;flex-direction:column}
[data-pagina="reportes"] .rp-diario__titulo{font-size:var(--fonte-destaque);font-weight:500;margin:0 0 .25rem}
[data-pagina="reportes"] .rp-diario--bug .rp-diario__titulo{color:var(--rp-bug)}
[data-pagina="reportes"] .rp-diario--melhoria .rp-diario__titulo{color:var(--rp-melhoria)}
[data-pagina="reportes"] .rp-diario__tela{position:relative;flex:1;min-height:11rem}
[data-pagina="reportes"] .rp-e-excluido .pd-estagio-marca{box-shadow:inset 0 0 0 1.25px var(--pedido-fio-forte)}
/* "O que" fica com a sobra da linha e corta no fim; `max-width:0` é o que deixa
   a reticência agir numa tabela de largura automática. */
[data-pagina="reportes"] .rp-col-descricao{width:100%;max-width:0;min-width:16rem}
/* O invólucro da célula herda o teto da coluna (`max-width: inherit`, na
   GRADE DA CASA); aqui o teto é o `0` do truque acima, e herdado ele sumia com
   o texto inteiro (visto em produção, 15/09/2026). O corte já é do `td`. */
[data-pagina="reportes"] .rp-col-descricao .grade-celula{max-width:none}
/* Urgente fura a fila do planejamento (reporte #132): só a triagem o vê. */
.rp-urgente{color:var(--negative-text);font-weight:500}

/* Lista | Etapas (reporte #132): a mesma fila, em grade ou em colunas por
   etapa. As colunas enchem a altura da janela e rolam cada uma por si. */
[data-pagina="reportes"] #rp-lista[hidden],[data-pagina="reportes"] .rp-etapas[hidden]{display:none}
[data-pagina="reportes"] .rp-etapas{flex:1 1 auto;min-height:0;display:grid;grid-auto-flow:column;
  grid-auto-columns:minmax(14rem,1fr);gap:.75rem;overflow-x:auto;padding-bottom:.75rem}
[data-pagina="reportes"] .rp-etapa{display:flex;flex-direction:column;min-height:0;
  border-top:2px solid var(--pedido-petroleo);background:var(--surf-2)}
[data-pagina="reportes"] .rp-etapa__titulo{display:flex;align-items:center;gap:.375rem;margin:0;
  padding:.5rem .625rem;font-size:var(--fonte-corpo);font-weight:500;color:var(--ink)}
[data-pagina="reportes"] .rp-etapa__quantos{margin-left:auto;font-weight:400;color:var(--ink-3)}
[data-pagina="reportes"] .rp-etapa__cartoes{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;
  flex-direction:column;gap:.375rem;padding:0 .5rem .5rem}
[data-pagina="reportes"] .rp-cartao{display:flex;flex-direction:column;gap:.25rem;padding:.5rem .625rem;
  border:var(--bs-border-width) solid var(--line);background:var(--surf);text-align:left;cursor:pointer}
[data-pagina="reportes"] .rp-cartao:hover{border-color:var(--acc)}
[data-pagina="reportes"] .rp-cartao__topo{font-size:var(--fonte-pequena);color:var(--ink-3)}
[data-pagina="reportes"] .rp-cartao__topo b{color:var(--ink)}
/* Reporte #175: a etiqueta do tipo no cartão. Bug em vermelho, melhoria em verde; reta. */
[data-pagina="reportes"] .rp-tipo{display:inline-block;padding:0 .3125rem;border-radius:0;font-size:var(--fonte-pequena);font-weight:500;line-height:1.2}
[data-pagina="reportes"] .rp-tipo--bug{background:var(--negative-subtle);color:var(--negative-text)}
[data-pagina="reportes"] .rp-tipo--melhoria{background:var(--positive-subtle);color:var(--positive-text)}
[data-pagina="reportes"] .rp-cartao__texto{font-size:var(--fonte-corpo);color:var(--ink);
}
[data-pagina="reportes"] .rp-cartao__pe{font-size:var(--fonte-pequena);color:var(--ink-3)}

/* ── página de um chamado (`/reportes/mural/<id>/`, reporte #124) ─────────
   A LISTA é a grade padrão com a pele da triagem (`data-pagina="reportes"`,
   acima). Esta é a página de um chamado, montada com o kit
   `design-system/ui_kits/fourcloud-v2`: o `Selo`, o `Botao` e a tipografia da
   Reunião. Folha branca de borda a borda; a conversa ocupa a largura e a
   altura, a ficha fica à direita separada por um fio.

   Os tokens do design system ainda não entraram no app: cada um entra aqui,
   escopado na tela, com o NOME do token (`--ds-*` = `--*` do kit). */
[data-pagina="reportes"] .mc-folha{
  --ds-surface-app:#FFFFFF; --ds-surface-field:#FFFFFF;
  --ds-text-primary:#161616; --ds-text-secondary:#595A5C; --ds-text-muted:#7C7D7F;
  --ds-border-subtle:#E1E5E9; --ds-border-default:#CBD2D9; --ds-border-field:#B0B1B2;
  --ds-negative-text:#8F1F1F; --ds-positive-text:#0F5C2F;
  --ds-font:'Neue Haas Display','Helvetica Neue',Helvetica,Arial,sans-serif;
  --ds-tracking-eyebrow:.18em; --ds-tracking-heading:-.02em;
  --bs-offcanvas-width:min(88rem, 96vw);
  display:flex; flex-direction:column; background:var(--ds-surface-app);
  color:var(--ds-text-primary); font-family:var(--ds-font); font-size:var(--fonte-corpo); line-height:1.5;
  -webkit-font-smoothing:antialiased; font-variant-numeric:tabular-nums;
}
[data-pagina="reportes"] .mc-folha *{ box-sizing:border-box }
[data-pagina="reportes"] .mc-folha :where(button, input, select, textarea):not(.btn, .form-control){ font:inherit; color:inherit }
[data-pagina="reportes"] .mc-folha :focus-visible{ outline:2px solid var(--ds-acao); outline-offset:1px }
[data-pagina="reportes"] .mc-folha .mc-mudo{ color:var(--ds-text-muted) }

/* cabeçalho: o título do chamado e o atalho para a tela */
[data-pagina="reportes"] .mc-folha .mc-barra{
  flex:0 0 auto; display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:16px 28px 14px; border-bottom:1px solid var(--ds-border-subtle);
}
[data-pagina="reportes"] .mc-folha .mc-barra .mc-titulo{ flex:1 1 auto }
/* o título é a 1ª linha do pedido, e o pedido inteiro abre a conversa logo
   abaixo: aqui ele corta numa linha só em vez de repetir o parágrafo */
[data-pagina="reportes"] .mc-folha .mc-titulo{
  margin:0; min-width:0;
  font-family:var(--ds-font); font-size:var(--fonte-titulo); font-weight:500; letter-spacing:var(--ds-tracking-heading); line-height:1.2;
}
[data-pagina="reportes"] .mc-folha .mc-titulo .mc-mudo{ font-weight:400 }

/* corpo: conversa (sobra) | ficha (320px), fio entre as duas */
[data-pagina="reportes"] .mc-folha .mc-chamado{ flex:1 1 auto; min-height:0; overflow:hidden; display:flex }
[data-pagina="reportes"] .mc-folha .mc-colunas{ flex:1 1 auto; min-height:0; display:grid; grid-template-columns:minmax(0,1fr) 320px }
[data-pagina="reportes"] .mc-folha .mc-bloco{ display:flex; flex-direction:column; gap:10px; min-width:0; min-height:0 }
[data-pagina="reportes"] .mc-folha .mc-bloco h2{
  margin:0; font-family:var(--ds-font); font-size:var(--fonte-destaque); font-weight:500; letter-spacing:var(--ds-tracking-heading);
}
[data-pagina="reportes"] .mc-folha .mc-colunas > .mc-bloco{ padding:16px 28px 20px }
[data-pagina="reportes"] .mc-folha .mc-colunas > .mc-bloco > .mc-tempo{ flex:1 1 auto; min-height:0; overflow:auto }
[data-pagina="reportes"] .mc-folha .mc-lado{ display:flex; flex-direction:column; min-width:0; min-height:0; overflow:auto;
  border-left:1px solid var(--ds-border-subtle) }
/* A coluna lateral rola inteira: o bloco não encolhe. Com o `min-height:0` do
   `.mc-bloco` (preciso só na Conversa), Detalhes encolhia e o Plano seguinte
   era pintado por cima de "Aberto por" (reporte #618). */
[data-pagina="reportes"] .mc-folha .mc-lado > .mc-bloco{ flex:0 0 auto; padding:16px 20px; border-bottom:1px solid var(--ds-border-subtle) }

/* a conversa: o pedido abre, depois comentários e mudanças de status */
[data-pagina="reportes"] .mc-folha .mc-tempo{ position:relative; display:flex; flex-direction:column; gap:14px; margin:0; padding:0 4px 4px 0; list-style:none }
/* o fio: de um evento ao seguinte, pelo centro dos círculos (28px → 14px);
   o último não puxa fio, senão ele descia até o pé da página */
[data-pagina="reportes"] .mc-folha .mc-ev:not(:last-child)::before{ content:""; position:absolute; top:14px; bottom:-14px; left:13.5px; width:1px; background:var(--ds-border-default) }
[data-pagina="reportes"] .mc-folha .mc-ev{ position:relative; display:grid; grid-template-columns:28px minmax(0,1fr); gap:12px; align-items:start }
[data-pagina="reportes"] .mc-folha .mc-ev__marca{
  position:relative; z-index:1; display:grid; place-items:center; width:28px; height:28px; border-radius:50%;
  background:var(--ds-surface-app); box-shadow:inset 0 0 0 1px var(--ds-border-default);
  font-size:var(--fonte-pequena); font-weight:500; color:var(--ds-text-secondary);
}
[data-pagina="reportes"] .mc-folha .mc-ev__caixa{ min-width:0; max-width:110ch; border:1px solid var(--ds-border-subtle) }
[data-pagina="reportes"] .mc-folha .mc-ev__quem{ display:block; padding:6px 12px; border-bottom:1px solid var(--ds-border-subtle); font-size:var(--fonte-pequena); color:var(--ds-text-muted) }
[data-pagina="reportes"] .mc-folha .mc-ev__quem b{ margin-right:4px; font-weight:500; color:var(--ds-text-primary) }
[data-pagina="reportes"] .mc-folha .mc-ev__texto{ margin:0; padding:10px 12px 12px; white-space:pre-wrap; line-height:1.5; text-wrap:pretty }
/* quem abriu o chamado: o círculo cheio na tinta de ação */
[data-pagina="reportes"] .mc-folha .mc-ev__quem:last-child{ border-bottom:0 }
[data-pagina="reportes"] .mc-folha .mc-ev--pedido .mc-ev__marca{ background:var(--ds-acao); box-shadow:none; color:#fff }
/* mudança de status: ponto no fio e uma frase, sem caixa */
[data-pagina="reportes"] .mc-folha .mc-ev--nota{ align-items:center; font-size:var(--fonte-pequena); color:var(--ds-text-secondary) }
[data-pagina="reportes"] .mc-folha .mc-ev__ponto{ position:relative; z-index:1; justify-self:center; width:9px; height:9px; border-radius:50%;
  background:var(--ds-surface-app); box-shadow:0 0 0 3px var(--ds-surface-app), inset 0 0 0 2px var(--ds-text-muted) }
[data-pagina="reportes"] .mc-folha .mc-ev--nota b{ font-weight:500; color:var(--ds-text-primary) }
[data-pagina="reportes"] .mc-folha .mc-antes summary{ display:inline; margin-left:6px; color:var(--ds-acao); cursor:pointer }
[data-pagina="reportes"] .mc-folha .mc-antes p{ margin:6px 0 0; max-width:110ch; white-space:pre-wrap; color:var(--ds-text-secondary) }
[data-pagina="reportes"] .mc-folha .mc-prints{ display:flex; flex-wrap:wrap; gap:8px; padding:0 12px 12px }
[data-pagina="reportes"] .mc-folha .mc-prints img{ display:block; height:96px; border:1px solid var(--ds-border-subtle) }
[data-pagina="reportes"] .mc-folha .mc-responder{ display:flex; flex-direction:column; gap:8px; padding-top:12px; border-top:1px solid var(--ds-border-default) }
/* no topo da conversa, a resposta fica acima do evento mais recente */
[data-pagina="reportes"] .mc-folha .mc-responder--topo{ padding:0 0 14px; border-top:0; border-bottom:1px solid var(--ds-border-default) }
[data-pagina="reportes"] .mc-folha .mc-responder__pe{ display:flex; justify-content:flex-end; align-items:center; gap:8px }
[data-pagina="reportes"] .mc-folha .mc-responder--topo .mc-responder__pe{ justify-content:flex-start }
[data-pagina="reportes"] .mc-folha .mc-responder--topo .btn-primary{ margin-left:auto }
[data-pagina="reportes"] .mc-folha .mc-dica{ font-size:var(--fonte-pequena); color:var(--ds-text-muted) }
/* Reporte #132: o que só a triagem vê — o comentário interno ganha fio e fundo
   de atenção, para ela ver de relance o que o autor não vê; o plano é texto
   corrido em mono, como foi escrito no repositório, e só se lê (a triagem é
   agêntica, pela skill `reportes-prod`). */
[data-pagina="reportes"] .mc-folha .mc-ev--interno .mc-ev__caixa{ border-left:3px solid var(--ds-border-default); background:#F5F5F5 }
[data-pagina="reportes"] .mc-folha .mc-ev--nota.mc-ev--interno > span:last-child{ color:var(--ds-text-primary) }
[data-pagina="reportes"] .mc-folha .mc-plano h2{ display:flex; align-items:center; gap:6px }
[data-pagina="reportes"] .mc-folha .mc-plano__texto{ margin:0; max-height:50vh; overflow:auto; padding:8px 9px;
  border:1px solid var(--ds-border-subtle); background:#FAFAFA; font-size:var(--fonte-pequena); line-height:1.5; white-space:pre-wrap }
[data-pagina="reportes"] .mc-folha .mc-urgente{ margin-left:4px; font-weight:500; color:var(--ds-negative-text) }
[data-pagina="reportes"] .mc-folha .mc-plano code{ font-size:var(--fonte-pequena); overflow-wrap:anywhere }
[data-pagina="reportes"] .mc-folha .mc-triagem__excluido{ color:var(--ds-negative-text) }
[data-pagina="reportes"] .mc-folha .mc-triagem__contexto summary{ cursor:pointer; color:var(--ds-acao); font-size:var(--fonte-pequena) }
[data-pagina="reportes"] .mc-folha .mc-triagem__contexto dl{ display:grid; grid-template-columns:auto 1fr; gap:2px 8px; margin:8px 0 0; font-size:var(--fonte-pequena) }
[data-pagina="reportes"] .mc-folha .mc-triagem__contexto dt{ color:var(--ds-text-muted); font-weight:400 }
[data-pagina="reportes"] .mc-folha .mc-triagem__contexto dd{ margin:0; overflow-wrap:anywhere }
/* Reporte #438: as sessões do Claude no chamado — link e id, uma por linha. */
[data-pagina="reportes"] .mc-folha .mc-sessoes h2{ display:flex; align-items:center; gap:6px }
[data-pagina="reportes"] .mc-folha .mc-sessoes__lista{ margin:0; padding:0; list-style:none; display:grid; gap:8px; font-size:var(--fonte-pequena) }
[data-pagina="reportes"] .mc-folha .mc-sessoes__lista li{ display:grid; gap:2px }
[data-pagina="reportes"] .mc-folha .mc-sessoes__lista a{ display:inline-flex; align-items:center; gap:4px; overflow-wrap:anywhere }
[data-pagina="reportes"] .mc-folha .mc-sessoes__lista code{ font-size:var(--fonte-pequena); color:var(--ds-text-primary); overflow-wrap:anywhere }
/* os prints do próximo comentário, antes de enviar */
[data-pagina="reportes"] .mc-folha .mc-anexando{ display:flex; flex-wrap:wrap; gap:8px }
[data-pagina="reportes"] .mc-folha .mc-anexando[hidden]{ display:none }
[data-pagina="reportes"] .mc-folha .mc-anexando__item{ position:relative; display:block }
[data-pagina="reportes"] .mc-folha .mc-anexando__item img{ display:block; height:64px; border:1px solid var(--ds-border-subtle) }
[data-pagina="reportes"] .mc-folha .mc-anexando__tirar{
  position:absolute; top:-7px; right:-7px; display:grid; place-items:center; width:20px; height:20px; padding:0;
  border:1px solid var(--ds-border-default); border-radius:50%; background:var(--ds-surface-app); cursor:pointer;
}

/* a ficha: rótulo em cima, valor embaixo */
[data-pagina="reportes"] .mc-folha .mc-ficha{ display:flex; flex-direction:column; margin:0 }
[data-pagina="reportes"] .mc-folha .mc-ficha div{ display:flex; flex-direction:column; gap:2px; padding:8px 0; border-top:1px solid var(--ds-border-subtle) }
[data-pagina="reportes"] .mc-folha .mc-ficha div:first-child{ border-top:0; padding-top:0 }
[data-pagina="reportes"] .mc-folha .mc-ficha dt{ font-size:var(--fonte-rotulo); font-weight:400; letter-spacing:var(--ds-tracking-eyebrow); text-transform:uppercase; color:var(--ds-text-muted) }
[data-pagina="reportes"] .mc-folha .mc-ficha dd{ margin:0; font-size:var(--fonte-corpo) }
[data-pagina="reportes"] .mc-folha .mc-gestos{ display:flex; flex-direction:column; gap:8px }
[data-pagina="reportes"] .mc-folha .mc-nota-lado{ margin:0; font-size:var(--fonte-pequena); color:var(--ds-text-secondary) }
[data-pagina="reportes"] .mc-folha .mc-erro{ margin:0; padding:0 20px 16px; font-size:var(--fonte-pequena); color:var(--ds-negative-text) }

/* Selo (kit ReuniaoScreen `SELO`): 19px, 11px médio, tom de fundo + tinta do mesmo tom */
[data-pagina="reportes"] .mc-folha .mc-selo{
  display:inline-flex; align-items:center; height:19px; padding:0 6px;
  font-size:var(--fonte-pequena); font-weight:500; white-space:nowrap;
}
[data-pagina="reportes"] .mc-folha .mc-selo--neutra{ background:#EAEAEA; color:var(--ds-text-secondary) }
[data-pagina="reportes"] .mc-folha .mc-selo--info{ background:var(--ds-acao-tinta); color:var(--ds-acao-hover) }
[data-pagina="reportes"] .mc-folha .mc-selo--ok{ background:#E4EFE7; color:var(--ds-positive-text) }
[data-pagina="reportes"] .mc-folha .mc-selo--aviso{ background:var(--ds-atencao); color:var(--ds-text-primary) }
[data-pagina="reportes"] .mc-folha .mc-selo--erro{ background:#F6E2E2; color:var(--ds-negative-text) }

[data-pagina="reportes"] .mc-folha .mc-icone{ flex:0 0 auto }
[data-pagina="reportes"] .mc-folha .btn{ display:inline-flex; align-items:center; justify-content:center; gap:6px }

@media (max-width: 899.98px){
  [data-pagina="reportes"] .mc-folha{ height:auto; overflow:visible }
  /* Coluna única (Detalhes, Reabrir): sem isto o `overflow:hidden` do
     desktop (as duas colunas rolam cada uma por si) clipa a segunda metade
     que agora vem abaixo da conversa. */
  [data-pagina="reportes"] .mc-folha .mc-chamado{ overflow:auto }
  [data-pagina="reportes"] .mc-folha .mc-barra{ padding:12px 14px }
  [data-pagina="reportes"] .mc-folha .mc-colunas{ grid-template-columns:minmax(0,1fr) }
  [data-pagina="reportes"] .mc-folha .mc-colunas > .mc-bloco{ padding:12px 14px }
  [data-pagina="reportes"] .mc-folha .mc-lado{ border-left:0; border-top:1px solid var(--ds-border-subtle) }
}

/* ═══ TAREFAS E PROJETOS ([data-pagina="tarefas"]) ═══════════════════════════
   /tarefas/ redesenhada em 17/09/2026 na pele TERMINAL CLARO — a mesma da
   Reunião Semanal e de /despesas/nova/ — com o vocabulário de interação do
   Microsoft To-Do. Gabarito: docs/redesign/mockups/tarefas-terminal-claro.html
   (variante A, aprovada pelo dono). Não mexer por gosto: mude o gabarito e
   depois meça a tela contra ele.

   A tela É a janela: `content--altura-cheia` no template dá a altura, e quem
   rola é o rail, a lista e o painel — nunca a página. Por isso toda a cadeia
   abaixo carrega `min-height:0` (sem ele o filho flex não encolhe e o rolo
   vaza para fora da janela).

   Os tokens são os `--dnv-*` já declarados na seção de despesas/reunião; esta
   tela só entra na lista de quem os recebe. Nenhuma cor nova. */

/* Recuo só à ESQUERDA: a barra lateral do shell se pinta até x=64 mas `.main`
   começa em x=48, então com `padding:0` os 16px iniciais do rail nascem ATRÁS
   dela (o "PROJETOS" virava "ROJETOS"). À direita não há recuo de propósito —
   é ali que o painel de detalhe encosta na janela. */
.page[data-pagina="tarefas"]{
  position:relative; padding:0 0 0 var(--content-pad-x) !important; overflow:hidden;
  background:var(--dnv-surface); color:var(--dnv-ink);
 line-height:1.2; -webkit-font-smoothing:antialiased;
}
.page[data-pagina="tarefas"] *{ box-sizing:border-box }
/* O filtro de coluna da casa (`colfilter-multi`, usado pelo seletor de
   responsáveis) fica FORA da limpeza de botões: sem borda e sem fundo o
   gatilho vira três peças soltas. Mesmo `:where` da seção de despesas. */
.page[data-pagina="tarefas"] button:not(:where(.colfilter-multi__trigger, .btn)){
  font:inherit; color:inherit; background:none; border:0; padding:0; cursor:pointer; text-align:left;
}
.page[data-pagina="tarefas"] :focus-visible{ outline:2px solid var(--dnv-mark); outline-offset:1px }
.page[data-pagina="tarefas"] h1,
.page[data-pagina="tarefas"] h2,
.page[data-pagina="tarefas"] h3,
.page[data-pagina="tarefas"] h4{ margin:0 }
.page[data-pagina="tarefas"] .mudo{ color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .risco{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-prazo,
.page[data-pagina="tarefas"] .tf-et-n{ font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1,"lnum" 1 }

/* ── a folha: rail | centro | (painel cobre) ─────────────────────────────── */
.page[data-pagina="tarefas"] .tf{ flex:1 1 auto; min-height:0; min-width:0; display:flex }

/* ── rail: visões salvas, projetos com fases, pessoas ────────────────────── */
.page[data-pagina="tarefas"] .tf-rail{
  flex:0 0 218px; min-height:0; display:flex; flex-direction:column;
  background:var(--dnv-surface-2); border-right:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-rail__rolo{
  flex:1 1 auto; min-height:0; overflow:auto; overscroll-behavior:contain; padding:8px 0 4px;
}
.page[data-pagina="tarefas"] .tf-rail h2{
  padding:8px 12px 3px; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em;
  text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-rail h2 + .tf-vis{ border-top:1px solid var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-vis{
  display:grid; grid-template-columns:14px minmax(0,1fr) auto; gap:8px; align-items:center;
  width:100%; padding:5px 12px; border-left:2px solid transparent;
}
.page[data-pagina="tarefas"] .tf-vis:hover{ background:var(--dnv-surface-3) }
.page[data-pagina="tarefas"] .tf-vis[aria-current="true"]{
  background:var(--dnv-surface); border-left-color:var(--dnv-ink); font-weight:500;
}
.page[data-pagina="tarefas"] .tf-vis .g{ color:var(--dnv-ink-3); font-size:var(--fonte-pequena); line-height:1; text-align:center }
.page[data-pagina="tarefas"] .tf-vis[aria-current="true"] .g{ color:var(--dnv-ink) }
.page[data-pagina="tarefas"] .tf-vis .n{
  min-width:0; font-size:var(--fonte-corpo);
}
.page[data-pagina="tarefas"] .tf-vis .q{ font-variant-numeric:tabular-nums; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-vis .q.risco{ color:var(--dnv-risco); font-weight:500 }

/* projeto no rail: nome + progresso DO SERVIDOR + fases dobráveis */
.page[data-pagina="tarefas"] .tf-pj{ border-top:1px solid var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-pj:first-of-type{ border-top:0 }
.page[data-pagina="tarefas"] .tf-pj__cab{
  display:grid; grid-template-columns:14px minmax(0,1fr) auto; gap:8px; align-items:center;
  width:100%; padding:6px 12px 2px; border-left:2px solid transparent;
}
.page[data-pagina="tarefas"] .tf-pj[data-atual] .tf-pj__cab{
  background:var(--dnv-surface); border-left-color:var(--dnv-ink);
}
.page[data-pagina="tarefas"] .tf-pj__cab:hover{ background:var(--dnv-surface-3) }
.page[data-pagina="tarefas"] .tf-pj__cab .ca{
  width:14px; text-align:center; font-size:var(--fonte-pequena); color:var(--dnv-ink-3);
  transition:transform .12s; display:inline-block;
}
.page[data-pagina="tarefas"] .tf-pj[data-aberto] .tf-pj__cab .ca{ transform:rotate(90deg) }
.page[data-pagina="tarefas"] .tf-pj__cab .n{
  min-width:0;
  font-size:var(--fonte-corpo); font-weight:500;
}
.page[data-pagina="tarefas"] .tf-pj__cab .q{ font-variant-numeric:tabular-nums; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-pj__prog{ height:3px; margin:0 12px 5px 34px; background:var(--dnv-surface-3) }
.page[data-pagina="tarefas"] .tf-pj__prog i{ display:block; height:100%; background:var(--rs-seg-1,#2B323C) }
.page[data-pagina="tarefas"] .tf-pj__fases[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-fase{
  display:grid; grid-template-columns:minmax(0,1fr) auto; gap:8px; align-items:center;
  width:100%; padding:3px 12px 3px 34px; border-left:2px solid transparent;
  font-size:var(--fonte-pequena); color:var(--dnv-ink-2);
}
.page[data-pagina="tarefas"] .tf-fase:hover{ background:var(--dnv-surface-3) }
.page[data-pagina="tarefas"] .tf-fase[aria-current="true"]{
  background:var(--dnv-surface); border-left-color:var(--dnv-ink); color:var(--dnv-ink); font-weight:500;
}
.page[data-pagina="tarefas"] .tf-fase .n{ min-width:0;}
.page[data-pagina="tarefas"] .tf-fase .n small{ display:block; font-size:var(--fonte-pequena); font-weight:400; color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-fase .q{ font-variant-numeric:tabular-nums; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-fase-nova{
  display:block; width:calc(100% - 46px); margin:2px 12px 4px 34px; height:1.5rem; padding:0 5px;
  border:1px solid transparent; border-radius:0; background:none; color:var(--dnv-ink);
  font:inherit; font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-fase-nova:hover{ border-color:var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-fase-nova:focus{ outline:0; border-color:var(--dnv-mark); background:var(--dnv-surface) }
.page[data-pagina="tarefas"] .tf-rail__pe{ flex:0 0 auto; border-top:1px solid var(--dnv-rule); padding:6px 12px }
.page[data-pagina="tarefas"] .tf-rail__pe button{ font-size:var(--fonte-pequena); color:var(--dnv-mark); font-weight:500 }
.page[data-pagina="tarefas"] .tf-rail__pe button:hover{ text-decoration:underline }

/* ── centro ──────────────────────────────────────────────────────────────── */
.page[data-pagina="tarefas"] .tf-centro{
  flex:1 1 auto; min-width:0; min-height:0; display:flex; flex-direction:column; padding:12px 18px 10px;
}
/* A LISTA tem largura máxima, e as duas razões são medidas: linha de 1.650px
   é longa demais para o olho varrer do título (à esquerda) até o prazo (à
   direita); e, como o painel COBRE a folha, a régua faz a faixa da direita da
   linha (etapas · responsáveis · prazo) cair fora do painel a partir de
   ~1.600px de janela. É a geometria do próprio To-Do. */
.page[data-pagina="tarefas"] .tf-centro > .tf-cab,
.page[data-pagina="tarefas"] .tf-centro > .tf-barra,
.page[data-pagina="tarefas"] .tf-centro > .tf-novo,
.page[data-pagina="tarefas"] .tf-centro > .tf-rolo{ max-width:1180px }

.page[data-pagina="tarefas"] .tf-cab{ flex:0 0 auto; display:flex; align-items:baseline; gap:12px; flex-wrap:wrap }
.page[data-pagina="tarefas"] .tf-cab h2{ font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-.01em }
.page[data-pagina="tarefas"] .tf-cab__titulo{
  font:inherit; font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-.01em; color:var(--dnv-ink);
  background:none; border:0; border-bottom:1px solid transparent; padding:1px 0; min-width:12rem;
}
.page[data-pagina="tarefas"] .tf-cab__titulo:hover{ border-bottom-color:var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-cab__titulo:focus{ outline:0; border-bottom-color:var(--dnv-mark) }
.page[data-pagina="tarefas"] .tf-cab .sub{
  font-size:var(--fonte-pequena); color:var(--dnv-ink-3); font-variant-numeric:tabular-nums;
}
.page[data-pagina="tarefas"] .tf-cab .sub b{ font-weight:500; color:var(--dnv-ink-2) }
.page[data-pagina="tarefas"] .tf-cab .sub .risco{ font-weight:500 }
.page[data-pagina="tarefas"] .tf-cab__fim{ margin-left:auto; display:flex; align-items:center; gap:4px }

.page[data-pagina="tarefas"] .tf-erro[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-erro{
  margin-top:6px; padding:5px 8px; border:1px solid var(--dnv-risco-rule);
  background:var(--dnv-risco-wash); color:var(--dnv-risco); font-size:var(--fonte-pequena);
}

/* barra agrupar / ordenar */
.page[data-pagina="tarefas"] .tf-barra{
  flex:0 0 auto; display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  padding:7px 0 6px; margin-top:6px;
  border-top:1px solid var(--dnv-rule); border-bottom:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-sel{ display:inline-flex; align-items:center; gap:6px }
.page[data-pagina="tarefas"] .tf-sel > span{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-barra__fim{ margin-left:auto; display:flex; align-items:center; gap:14px }
.page[data-pagina="tarefas"] .tf-marca{
  display:inline-flex; align-items:center; gap:5px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); margin:0;
}

/* a linha "+ nova tarefa": o To-Do põe no TOPO, e é onde o olho já está */
.page[data-pagina="tarefas"] .tf-novo{
  flex:0 0 auto; display:flex; align-items:center; gap:6px; padding:7px 0 6px;
  border-bottom:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-novo .sinal{
  width:15px; text-align:center; color:var(--dnv-ink-3); font-size:var(--fonte-corpo); line-height:1;
}
.page[data-pagina="tarefas"] .tf-novo .form-control{ flex:1 1 auto; min-width:0 }
.page[data-pagina="tarefas"] .tf-estado{
  flex:0 0 auto; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase;
  color:var(--dnv-ink-3); white-space:nowrap;
}
.page[data-pagina="tarefas"] .tf-estado.risco{
  color:var(--dnv-risco); text-transform:none; letter-spacing:0; font-weight:400; font-size:var(--fonte-pequena);
}

/* ── LISTA ───────────────────────────────────────────────────────────────── */
.page[data-pagina="tarefas"] .tf-rolo{ flex:1 1 auto; min-height:0; overflow:auto; overscroll-behavior:contain }
.page[data-pagina="tarefas"] .tf-grupo-cab{
  display:flex; align-items:center; gap:7px; width:100%; padding:9px 2px 3px;
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase;
  color:var(--dnv-ink-2); border-bottom:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-grupo:first-child .tf-grupo-cab{ padding-top:4px }
.page[data-pagina="tarefas"] .tf-grupo-cab .ca{
  width:9px; text-align:center; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); transition:transform .12s; display:inline-block;
}
.page[data-pagina="tarefas"] .tf-grupo[data-aberto] .tf-grupo-cab .ca{ transform:rotate(90deg) }
.page[data-pagina="tarefas"] .tf-grupo-cab .n{ min-width:0;}
.page[data-pagina="tarefas"] .tf-grupo-cab b{
  margin-left:auto; font-weight:500; color:var(--dnv-ink-3); font-variant-numeric:tabular-nums;
}
.page[data-pagina="tarefas"] .tf-grupo-corpo[hidden]{ display:none }

/* A LINHA: [○] título / meta … etapas  responsáveis  prazo  ⋯ */
.page[data-pagina="tarefas"] .tf-li{
  display:grid; grid-template-columns:16px minmax(0,1fr) auto; gap:8px; align-items:start;
  padding:5px 4px 5px 2px; border-bottom:1px solid var(--rs-fio,#ECEEF1); cursor:pointer; position:relative;
}
.page[data-pagina="tarefas"] .tf-li:hover{ background:var(--dnv-surface-2) }
.page[data-pagina="tarefas"] .tf-li[aria-selected="true"]{ background:var(--dnv-mark-wash) }
.page[data-pagina="tarefas"] .tf-li.arrastando{ opacity:.35 }
.page[data-pagina="tarefas"] .tf-li.alvo{ box-shadow:inset 0 2px 0 0 var(--dnv-mark) }

/* o círculo: o único canto redondo desta tela, e é controle, não moldura */
.page[data-pagina="tarefas"] .tf-cx{
  width:15px; height:15px; margin-top:1px; border:1px solid var(--dnv-ink-3); border-radius:50%;
  flex:none; position:relative; background:none; transition:background-color .12s, border-color .12s;
}
.page[data-pagina="tarefas"] .tf-cx::before{ content:""; position:absolute; inset:-6px -7px }
.page[data-pagina="tarefas"] .tf-cx:hover{ border-color:var(--dnv-mark) }
.page[data-pagina="tarefas"] .tf-cx::after{
  content:""; position:absolute; left:4px; top:1px; width:4px; height:8px;
  border:solid #fff; border-width:0 1.5px 1.5px 0; transform:rotate(42deg); opacity:0;
}
.page[data-pagina="tarefas"] .tf-li.feito .tf-cx,
.page[data-pagina="tarefas"] .tf-cx[aria-pressed="true"],
.page[data-pagina="tarefas"] .tf-detalhe--feito .tf-cx{ background:var(--dnv-mark); border-color:var(--dnv-mark) }
.page[data-pagina="tarefas"] .tf-li.feito .tf-cx::after,
.page[data-pagina="tarefas"] .tf-cx[aria-pressed="true"]::after{ opacity:1 }
/* No toque (iPad) a área do círculo cresce para ~44px; o desenho fica igual. */
@media (pointer: coarse){
  .page[data-pagina="tarefas"] .tf-cx::before{ inset:-14px }
}

.page[data-pagina="tarefas"] .tf-corpo{ min-width:0 }
.page[data-pagina="tarefas"] .tf-tt{ display:block; min-width:0; overflow-wrap:anywhere }
.page[data-pagina="tarefas"] .tf-li.feito .tf-tt{ color:var(--dnv-ink-3); text-decoration:line-through }
.page[data-pagina="tarefas"] .tf-meta{
  display:flex; align-items:center; flex-wrap:wrap; gap:0 4px; margin-top:1px;
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.06em; text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-meta s{ text-decoration:none; color:var(--dnv-rule-2); padding:0 2px }
.page[data-pagina="tarefas"] .tf-meta .tf-bloq{ color:var(--dnv-risco) }

/* a direita da linha: etapas, responsáveis, prazo, menu */
.page[data-pagina="tarefas"] .tf-dir{ display:flex; align-items:center; gap:9px; padding-top:1px; white-space:nowrap }
.page[data-pagina="tarefas"] .tf-et-n{ font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2) }
.page[data-pagina="tarefas"] .tf-et-n i{
  display:inline-block; width:22px; height:3px; margin-left:4px; vertical-align:2px; background:var(--dnv-surface-3);
}
.page[data-pagina="tarefas"] .tf-et-n i b{ display:block; height:100%; background:var(--rs-seg-1,#2B323C) }
/* Primeiro nome, não iniciais (decisão do dono): quem é dono se lê sem passar
   o mouse. Teto de 13rem para um bando de responsáveis não empurrar o prazo. */
.page[data-pagina="tarefas"] .tf-resp{
  max-width:13rem;
  font-size:var(--fonte-pequena); color:var(--dnv-ink-2);
}
.page[data-pagina="tarefas"] .tf-prazo{
  font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2); min-width:34px; text-align:right;
}
.page[data-pagina="tarefas"] .tf-prazo.tf-prazo--atrasado{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-prazo.tf-prazo--hoje{ color:var(--dnv-ink); border-bottom:2px solid var(--dnv-ink) }
.page[data-pagina="tarefas"] .tf-mm{
  width:18px; height:18px; line-height:16px; text-align:center; color:var(--dnv-rule-2); font-size:var(--fonte-corpo);
}
.page[data-pagina="tarefas"] .tf-li:hover .tf-mm,
.page[data-pagina="tarefas"] .tf-li[aria-selected="true"] .tf-mm,
.page[data-pagina="tarefas"] .tf-mm:focus-visible{ color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-mm:hover{ color:var(--dnv-ink) }

/* DESFAZER: some sozinho em 6 s. Concluir e excluir não perguntam (dono). */
.page[data-pagina="tarefas"] .tf-desf{
  display:inline-flex; align-items:center; gap:6px; margin-left:8px;
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-mark);
}
.page[data-pagina="tarefas"] .tf-desf:hover{ text-decoration:underline }
.page[data-pagina="tarefas"] .tf-desfeito{
  display:flex; align-items:center; gap:8px; padding:6px 4px 6px 2px;
  border-bottom:1px solid var(--rs-fio,#ECEEF1); background:var(--dnv-mark-wash); font-size:var(--fonte-pequena);
}

/* pergunta inline (excluir de vez, só dentro da lixeira): no lugar da linha,
   foco em CANCELAR. Nenhuma caixa do navegador nesta tela. */
.page[data-pagina="tarefas"] .tf-perg{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:6px 4px 6px 2px;
  border-bottom:1px solid var(--rs-fio,#ECEEF1); background:var(--dnv-risco-wash);
}
.page[data-pagina="tarefas"] .tf-perg p{ margin:0; flex:1 1 100%; font-size:var(--fonte-pequena) }
.page[data-pagina="tarefas"] .tf-perg p b{ font-weight:500 }

/* a lixeira: o que saiu, por quem e quando */
.page[data-pagina="tarefas"] .tf-li--lixo{ grid-template-columns:minmax(0,1fr) auto; cursor:default }
.page[data-pagina="tarefas"] .tf-li--lixo:hover{ background:none }
.page[data-pagina="tarefas"] .tf-li--lixo .tf-dir{ gap:6px }

/* menu de contexto da linha (⋯) */
.page[data-pagina="tarefas"] .tf-menu{
  position:fixed; z-index:20; min-width:220px; background:var(--dnv-surface);
  border:1px solid var(--dnv-rule-2); padding:3px 0;
}
.page[data-pagina="tarefas"] .tf-menu[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-menu button{
  display:flex; align-items:center; gap:8px; width:100%; padding:4px 11px; font-size:var(--fonte-pequena); white-space:nowrap;
}
.page[data-pagina="tarefas"] .tf-menu button:hover{ background:var(--dnv-surface-2) }
.page[data-pagina="tarefas"] .tf-menu button .g{ width:13px; color:var(--dnv-ink-3); text-align:center }
.page[data-pagina="tarefas"] .tf-menu button.risco{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-menu hr{ margin:3px 0; border:0; border-top:1px solid var(--dnv-rule) }

/* vazio por visão: convite, não lamento */
.page[data-pagina="tarefas"] .tf-vazio{ padding:26px 2px; max-width:58ch }
.page[data-pagina="tarefas"] .tf-vazio b{ display:block; font-size:var(--fonte-corpo); font-weight:500; margin-bottom:3px }
.page[data-pagina="tarefas"] .tf-vazio p{ margin:0 0 9px; color:var(--dnv-ink-3) }

/* ── QUADRO ──────────────────────────────────────────────────────────────── */
.page[data-pagina="tarefas"] .tf-quadro{
  flex:1 1 auto; min-height:0; min-width:0; display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:0;
}
/* Com o painel aberto o quadro NÃO reflui: vira faixa rolável, e a coluna que
   ficou sob o painel continua alcançável. */
body[data-painel-tarefa] .page[data-pagina="tarefas"] .tf-quadro{
  overflow-x:auto; overscroll-behavior-x:contain; grid-template-columns:repeat(4, minmax(230px,1fr));
}
.page[data-pagina="tarefas"] .tf-qcol{
  min-width:0; min-height:0; display:flex; flex-direction:column;
  border-left:1px solid var(--dnv-rule); padding:0 10px;
}
.page[data-pagina="tarefas"] .tf-qcol:first-child{ border-left:0; padding-left:0 }
.page[data-pagina="tarefas"] .tf-qcol:last-child{ padding-right:0 }
.page[data-pagina="tarefas"] .tf-qcol__cab{
  flex:0 0 auto; display:flex; align-items:center; gap:7px; padding:6px 8px; margin:8px 0 0;
  background:var(--dnv-surface-2);
}
.page[data-pagina="tarefas"] .tf-qcol__cab h3{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase;
}
.page[data-pagina="tarefas"] .tf-qcol__cab b{
  margin-left:auto; font-weight:500; color:var(--dnv-ink-3); font-variant-numeric:tabular-nums;
}
.page[data-pagina="tarefas"] .tf-qcol[data-coluna="bloqueado"] .tf-qcol__cab h3{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-qcol__rolo{
  flex:1 1 auto; min-height:0; overflow:auto; overscroll-behavior:contain; padding-top:2px;
}
.page[data-pagina="tarefas"] .tf-qcol.alvo .tf-qcol__rolo{ background:var(--dnv-mark-wash) }
.page[data-pagina="tarefas"] .tf-qcol .tf-li{ grid-template-columns:16px minmax(0,1fr) }
.page[data-pagina="tarefas"] .tf-qcol .tf-dir{ grid-column:2; padding-top:3px }
.page[data-pagina="tarefas"] .tf-qcol__vazio{ padding:10px 2px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-raia{ border-top:1px solid var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-raia:first-child{ border-top:0 }
.page[data-pagina="tarefas"] .tf-raia__cab{
  display:flex; align-items:center; gap:7px; padding:7px 0 3px;
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-2);
}
.page[data-pagina="tarefas"] .tf-raia__cab b{
  margin-left:auto; font-weight:500; color:var(--dnv-ink-3); font-variant-numeric:tabular-nums;
}

/* ── faixa de atalhos, rodapé da tela ────────────────────────────────────── */
.page[data-pagina="tarefas"] .tf-pe{
  flex:0 0 auto; display:flex; align-items:center; gap:14px; padding-top:6px; margin-top:6px;
  border-top:1px solid var(--dnv-rule);
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.07em; text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-pe kbd{
  font:inherit; font-size:var(--fonte-pequena); border:1px solid var(--dnv-rule-2); border-radius:0; background:none;
  padding:0 4px; color:var(--dnv-ink-2); margin-right:3px;
}
.page[data-pagina="tarefas"] .tf-pe .fim{ margin-left:auto; text-align:right }

/* ── O PAINEL DE DETALHE — COBRE a folha (decisão do dono, 17/09/2026) ───── */
.page[data-pagina="tarefas"] .tf-scrim{
  position:absolute; inset:0; z-index:25; background:rgba(11,14,18,.18);
  opacity:0; visibility:hidden; transition:opacity .16s, visibility .16s;
}
.page[data-pagina="tarefas"] .tf-scrim[data-aberto]{ opacity:1; visibility:visible }
.page[data-pagina="tarefas"] .tf-painel{
  position:absolute; top:0; right:0; bottom:0; width:clamp(340px, 27vw, 430px); z-index:30;
  display:flex; flex-direction:column; min-height:0;
  background:var(--dnv-surface); border-left:1px solid var(--dnv-rule-2);
  box-shadow:-1px 0 0 0 rgba(11,14,18,.05);
  transform:translateX(100%); visibility:hidden;
  transition:transform .18s cubic-bezier(.22,1,.36,1), visibility .18s;
}
.page[data-pagina="tarefas"] .tf-painel[data-aberto]{ transform:none; visibility:visible }
.page[data-pagina="tarefas"] .tf-det__hd{
  flex:0 0 auto; display:flex; align-items:center; gap:8px; padding:7px 12px;
  background:var(--dnv-surface-2); border-bottom:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-det__hd h2{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
  min-width:0;
}
.page[data-pagina="tarefas"] .tf-det__hd .x{
  margin-left:auto; width:22px; height:22px; text-align:center; line-height:20px; font-size:var(--fonte-corpo);
  color:var(--dnv-ink-3); flex:none;
}
.page[data-pagina="tarefas"] .tf-det__hd .x:hover{ color:var(--dnv-ink) }
.page[data-pagina="tarefas"] .tf-det__corpo{ flex:1 1 auto; min-height:0; overflow:auto; padding:12px 14px 16px }

/* ── O PAINEL DE TAREFAS NA REUNIÃO SEMANAL (17/09/2026) ──────────────────
   A Reunião Semanal abre o MESMO painel (`_tarefas_detalhe.html` +
   `tarefas-detalhe.js`). Como toda a pele acima está escopada em
   `.page[data-pagina="tarefas"] .tf-…`, o hospedeiro na Reunião carrega essa
   chave só para os seletores casarem — e estas quatro linhas desmancham o que
   ele herdaria de FOLHA (fundo, recuo, posição): ali ele é uma moldura
   transparente colada na janela, que não captura clique nenhum enquanto o
   painel está fechado. Zero mudança nos seletores de `/tarefas/`. */
.page[data-pagina="tarefas"].rs-tarefas-host{
  position:fixed; inset:0; z-index:1040; padding:0 !important;
  background:none; pointer-events:none;
}
.rs-tarefas-host .tf-scrim,
.rs-tarefas-host .tf-painel{ position:fixed; pointer-events:auto }

/* o corpo do painel (desenhado por tarefas-detalhe.js) */
.page[data-pagina="tarefas"] .tf-detalhe__banner[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-detalhe__banner{
  margin-bottom:8px; padding:5px 8px; border:1px solid var(--dnv-risco-rule);
  background:var(--dnv-risco-wash); color:var(--dnv-risco); font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-detalhe__titulo-linha{ display:flex; align-items:flex-start; gap:9px }
.page[data-pagina="tarefas"] .tf-detalhe__titulo{
  flex:1 1 auto; min-width:0; font:inherit; font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-.01em;
  color:var(--dnv-ink); background:none; border:0; border-bottom:1px solid transparent; padding:1px 0;
}
.page[data-pagina="tarefas"] .tf-detalhe__titulo:hover{ border-bottom-color:var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-detalhe__titulo:focus{ outline:0; border-bottom-color:var(--dnv-mark) }
.page[data-pagina="tarefas"] .tf-detalhe__confirmacao{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-mark);
}
.page[data-pagina="tarefas"] .tf-detalhe__confirmacao[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-detalhe__erro{ font-size:var(--fonte-pequena); color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-detalhe__erro[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-detalhe__meta{
  display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:9px 14px; margin-top:11px;
}
.page[data-pagina="tarefas"] .tf-detalhe__campo{ display:flex; flex-direction:column; gap:2px; min-width:0; margin:0 }
.page[data-pagina="tarefas"] .tf-detalhe__campo[data-campo="responsaveis"],
.page[data-pagina="tarefas"] .tf-detalhe__campo[data-campo="prazo"]{ grid-column:1 / -1 }
.page[data-pagina="tarefas"] .tf-detalhe__rotulo{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
}
/* atalhos de prazo: Hoje / Amanhã / Próxima semana / Sem prazo */
.page[data-pagina="tarefas"] .tf-prazo-at{ display:flex; align-items:center; gap:5px; flex-wrap:wrap; margin-top:3px }
.page[data-pagina="tarefas"] .tf-detalhe__bloqueio{
  margin-top:9px; padding:5px 8px; border:1px solid var(--dnv-risco-rule);
  background:var(--dnv-risco-wash); color:var(--dnv-risco); font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-detalhe__secao{ margin-top:15px }
.page[data-pagina="tarefas"] .tf-detalhe__secao-titulo,
.page[data-pagina="tarefas"] .tf-detalhe__secao > .tf-detalhe__rotulo{
  display:flex; align-items:center; gap:8px; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em;
  text-transform:uppercase; color:var(--dnv-ink-2); padding-bottom:3px;
  border-bottom:1px solid var(--dnv-rule); margin:0;
}
.page[data-pagina="tarefas"] .tf-detalhe__contagem{
  margin-left:auto; font-weight:500; color:var(--dnv-ink-3); font-variant-numeric:tabular-nums;
}
.page[data-pagina="tarefas"] .tf-detalhe__acoes{ display:flex; align-items:center; gap:8px; margin-top:6px }
.page[data-pagina="tarefas"] .tf-detalhe__checklist-item{
  display:grid; grid-template-columns:15px minmax(0,1fr) 16px; gap:7px; align-items:start; padding:3px 0;
}
.page[data-pagina="tarefas"] .tf-detalhe__checklist-item input{ margin:2px 0 0 }
.page[data-pagina="tarefas"] .tf-detalhe__checklist-item label{
  min-width:0; overflow-wrap:anywhere; font-size:var(--fonte-pequena); cursor:pointer; margin:0;
}
.page[data-pagina="tarefas"] .tf-detalhe__remover{
  width:16px; text-align:center; color:var(--dnv-ink-3); font-size:var(--fonte-corpo); line-height:1;
}
.page[data-pagina="tarefas"] .tf-detalhe__remover:hover{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-detalhe__dependencias{ list-style:none; margin:7px 0 0; padding:0 }
.page[data-pagina="tarefas"] .tf-detalhe__dependencia{
  display:flex; align-items:center; gap:7px; padding:3px 0; font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-detalhe__dependencia .tf-detalhe__remover{ margin-left:auto }
.page[data-pagina="tarefas"] .tf-detalhe__subtarefas{ list-style:none; margin:7px 0 0; padding:0 }
.page[data-pagina="tarefas"] .tf-detalhe__subtarefa{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto; gap:10px; align-items:baseline;
  width:100%; padding:3px 0; border:0; background:none; text-align:left; font:inherit; font-size:var(--fonte-pequena);
  color:var(--dnv-ink); cursor:pointer;
}
.page[data-pagina="tarefas"] .tf-detalhe__subtarefa:hover .tf-detalhe__subtarefa-titulo{ text-decoration:underline }
.page[data-pagina="tarefas"] .tf-detalhe__subtarefa-titulo{ min-width:0; overflow-wrap:anywhere }
.page[data-pagina="tarefas"] .tf-detalhe__subtarefa-dono,
.page[data-pagina="tarefas"] .tf-detalhe__subtarefa-coluna{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3); white-space:nowrap }
.page[data-pagina="tarefas"] .tf-detalhe__pai{
  padding:0; border:0; background:none; font:inherit; font-size:var(--fonte-pequena); color:var(--dnv-ink);
  text-align:left; text-decoration:underline; cursor:pointer;
}
.page[data-pagina="tarefas"] .tf-detalhe__pai:hover{ color:var(--dnv-mark) }
.page[data-pagina="tarefas"] .tf-detalhe__anexo-arquivo,
.page[data-pagina="tarefas"] .tf-detalhe__anexo-imagem{
  display:flex; align-items:center; gap:7px; padding:3px 0; margin:0; font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-detalhe__anexo-imagem{ flex-wrap:wrap }
.page[data-pagina="tarefas"] .tf-detalhe__anexo-imagem img{ max-width:100%; height:auto; border:1px solid var(--dnv-rule) }
.page[data-pagina="tarefas"] .tf-detalhe__anexo-tamanho{ color:var(--dnv-ink-3); font-size:var(--fonte-pequena) }
.page[data-pagina="tarefas"] .tf-detalhe__anexo-arquivo .tf-detalhe__remover,
.page[data-pagina="tarefas"] .tf-detalhe__anexo-imagem .tf-detalhe__remover{ margin-left:auto }
.page[data-pagina="tarefas"] .tf-detalhe__recusas{ margin-top:5px; font-size:var(--fonte-pequena); color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-detalhe__dropzone{
  margin-top:8px; padding:11px 9px; border:1px dashed var(--dnv-rule-2); text-align:center;
  font-size:var(--fonte-pequena); color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-detalhe__anexo-rotulo{ color:var(--dnv-mark); cursor:pointer; margin:0 }
.page[data-pagina="tarefas"] .tf-detalhe__comentarios{ list-style:none; margin:0; padding:0 }
.page[data-pagina="tarefas"] .tf-detalhe__comentario{
  display:flex; gap:7px; padding:5px 0; border-bottom:1px solid var(--rs-fio,#ECEEF1); font-size:var(--fonte-pequena);
}
.page[data-pagina="tarefas"] .tf-detalhe__comentario-corpo{ min-width:0 }
.page[data-pagina="tarefas"] .tf-detalhe__comentario-cabeca{ display:flex; gap:7px; align-items:baseline }
.page[data-pagina="tarefas"] .tf-detalhe__comentario-autor,
.page[data-pagina="tarefas"] .tf-detalhe__comentario-quando{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-detalhe__comentario-texto{ margin:1px 0 0; overflow-wrap:anywhere }
.page[data-pagina="tarefas"] .tf-avatar{
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:19px; height:19px; border-radius:50%; background:var(--dnv-surface-3); color:var(--dnv-ink-2);
  font-size:var(--fonte-pequena); font-weight:500;
}
.page[data-pagina="tarefas"] .tf-detalhe__historico{ margin-top:15px }
.page[data-pagina="tarefas"] .tf-detalhe__historico summary{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-2);
  padding-bottom:3px; border-bottom:1px solid var(--dnv-rule); cursor:pointer;
}
.page[data-pagina="tarefas"] .tf-detalhe__historico ul{
  margin:7px 0 0; padding-left:15px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2);
}
.page[data-pagina="tarefas"] .tf-detalhe__rodape{
  display:flex; align-items:center; gap:8px; margin-top:16px; padding-top:7px;
  border-top:1px solid var(--dnv-rule);
}
.page[data-pagina="tarefas"] .tf-detalhe__criada{ font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tf-detalhe__rodape .btn{ margin-left:auto }
.page[data-pagina="tarefas"] .tf-vazio.tf-vazio--linha,
.page[data-pagina="tarefas"] li.tf-vazio{ padding:5px 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); list-style:none }

/* esqueleto de carga */
.page[data-pagina="tarefas"] .tf-esqueleto__linha{
  height:9px; margin:8px 0; background:var(--dnv-surface-3); animation:tf-pulso 1.1s ease-in-out infinite;
}
.page[data-pagina="tarefas"] .tf-esqueleto__linha--curta{ width:62% }
@keyframes tf-pulso{ 50%{ opacity:.45 } }

/* ── novo projeto: o <dialog> nativo, vestido ────────────────────────────── */
.page[data-pagina="tarefas"] .tf-dialogo{
  border:1px solid var(--dnv-rule-2); border-radius:0; padding:14px 16px; min-width:min(420px, 92vw);
  background:var(--dnv-surface); color:var(--dnv-ink); font:inherit; font-size:var(--fonte-corpo);
}
.page[data-pagina="tarefas"] .tf-dialogo::backdrop{ background:rgba(11,14,18,.18) }
.page[data-pagina="tarefas"] .tf-dialogo h2{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
  padding-bottom:4px; border-bottom:1px solid var(--dnv-rule); margin-bottom:10px;
}
.page[data-pagina="tarefas"] .tf-dialogo .tf-campo{ display:flex; flex-direction:column; gap:2px; margin-bottom:9px }
.page[data-pagina="tarefas"] .tf-dialogo .tf-campo > span{
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.09em; text-transform:uppercase; color:var(--dnv-ink-3);
}
.page[data-pagina="tarefas"] .tf-dialogo__fase{ display:flex; align-items:center; gap:6px; margin-bottom:4px }
.page[data-pagina="tarefas"] .tf-dialogo__fase input{ flex:1 1 auto }
.page[data-pagina="tarefas"] .tf-dialogo__fase .rm{ color:var(--dnv-ink-3); font-size:var(--fonte-corpo); line-height:1; width:16px; text-align:center }
.page[data-pagina="tarefas"] .tf-dialogo__fase .rm:hover{ color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-dialogo__erro{ margin:6px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-risco) }
.page[data-pagina="tarefas"] .tf-dialogo__erro[hidden]{ display:none }
.page[data-pagina="tarefas"] .tf-dialogo__acoes{ display:flex; justify-content:flex-end; gap:8px; margin-top:12px }

/* ── visão geral (todos os projetos, em árvore) ──────────────────────────── */
/* A grade da casa corta o texto em uma linha; aqui o nome vem INTEIRO (#192),
   então Nome e Dono quebram linha. O recuo é por nível e a seta só abre e
   fecha as linhas filhas. Atrasado: texto de atenção, nunca marrom. */
.page[data-pagina="tarefas"] .tf-centro > .tvg{ flex:1 1 auto; min-height:0; margin-top:8px }
.page[data-pagina="tarefas"] .tvg .grade-tabela :is(.tvg-col-nome, .tvg-col-dono) .grade-celula{
  max-width:none; white-space:normal; overflow:visible }
.page[data-pagina="tarefas"] .tvg .tvg-col-nome{ min-width:20rem }
.page[data-pagina="tarefas"] .tvg .tvg-nome{ display:flex; align-items:baseline; gap:4px }
.page[data-pagina="tarefas"] .tvg .tvg-nivel-1{ padding-left:20px }
.page[data-pagina="tarefas"] .tvg .tvg-nivel-2{ padding-left:40px }
.page[data-pagina="tarefas"] .tvg .tvg-linha--projeto .tvg-titulo{ font-weight:500 }
.page[data-pagina="tarefas"] .tvg .tvg-seta{
  flex:0 0 16px; width:16px; padding:0; border:0; background:none; color:var(--dnv-ink-3);
  font-size:var(--fonte-pequena); line-height:1; cursor:pointer; transition:transform .12s }
.page[data-pagina="tarefas"] .tvg .tvg-seta[aria-expanded="true"]{ transform:rotate(90deg) }
.page[data-pagina="tarefas"] .tvg .tvg-seta--vazia{ cursor:default }
.page[data-pagina="tarefas"] .tvg .tf-cx{ align-self:center; margin:0 4px 0 0 }
.page[data-pagina="tarefas"] .tvg .tvg-dono{ display:inline-block; margin-right:10px }
.page[data-pagina="tarefas"] .tvg .tvg-dono b{ font-weight:500; color:var(--dnv-ink-3); font-size:var(--fonte-pequena) }
.page[data-pagina="tarefas"] .tvg .tvg-sem-dono{ color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tvg td.tvg-atrasado{ color:var(--warning-text); font-weight:500 }
/* burndown: mini-gráfico na visão geral e cartão na visão do projeto (#192) */
.page[data-pagina="tarefas"] .tbd-celula{ display:inline-flex; align-items:center; gap:8px; white-space:nowrap }
.page[data-pagina="tarefas"] .tbd-svg{ display:block; max-width:100%; overflow:visible }
.page[data-pagina="tarefas"] .tbd-real{ stroke:var(--ds-acao); stroke-width:2; stroke-linejoin:round }
.page[data-pagina="tarefas"] .tbd-ideal{ stroke:var(--dnv-ink-3); stroke-width:1.5; stroke-dasharray:4 3 }
.page[data-pagina="tarefas"] circle.tbd-real{ fill:var(--ds-acao) }
.page[data-pagina="tarefas"] circle.tbd-ideal{ fill:var(--dnv-ink-3); stroke-dasharray:none }
.page[data-pagina="tarefas"] .tbd-situacao{ font-size:var(--fonte-pequena); color:var(--dnv-ink-2) }
.page[data-pagina="tarefas"] .tbd-situacao--atrasado{ color:var(--warning-text); font-weight:500 }
.page[data-pagina="tarefas"] .tbd-desvio{ margin-left:4px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3);
  font-variant-numeric:tabular-nums }
.page[data-pagina="tarefas"] .tbd-cartao{ margin:0 0 12px; padding:12px 16px; background:#fff;
  border:1px solid var(--dnv-rule) }
.page[data-pagina="tarefas"] .tbd-cartao h3{ margin:0 0 8px; font-size:var(--fonte-corpo); font-weight:500; color:var(--dnv-ink) }
.page[data-pagina="tarefas"] .tbd-corpo{ display:flex; flex-wrap:wrap; align-items:center; gap:24px }
.page[data-pagina="tarefas"] .tbd-numeros{ display:flex; flex-wrap:wrap; gap:24px; margin:0 }
.page[data-pagina="tarefas"] .tbd-numeros dt{ font-size:var(--fonte-pequena); font-weight:400; color:var(--dnv-ink-3) }
.page[data-pagina="tarefas"] .tbd-numeros dd{ margin:0; font-size:var(--fonte-destaque); font-variant-numeric:tabular-nums }
.page[data-pagina="tarefas"] .tbd-nota,
.page[data-pagina="tarefas"] .tbd-nada{ margin:8px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3) }
@media (prefers-reduced-motion:reduce){
  .page[data-pagina="tarefas"] .tf-painel,
  .page[data-pagina="tarefas"] .tf-scrim,
  .page[data-pagina="tarefas"] .tf-cx,
  .page[data-pagina="tarefas"] .ca{ transition:none }
  .page[data-pagina="tarefas"] .tf-esqueleto__linha{ animation:none }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RELATÓRIOS (`/relatorios/`, `/relatorios/novo/`, `/relatorios/<id>/`)

   Duas telas na mesma chave: a LISTA do que está salvo (a grade da casa, sem
   nada de novo além do que a situação "excluído" pede) e o CONSTRUTOR, que o
   dono mandou vestir com a pele de `/despesas/nova/` (15/09/2026):
   "instrumento, não painel" — tinta, uma cor de estado, cantos retos, painéis
   separados por vão de 1px, rótulo pequeno, e a barra do shell vestida pelos
   blocos que o `base_fcds.html` já expõe.

   Os tokens são os MESMOS (`--dnv-*`): a regra que os define, lá em cima,
   ganhou `.page[data-pagina="relatorios"]` e `#topbar:has(.rel-sel)` na lista
   de seletores. Aqui não se declara nem se copia valor de token nenhum — só se
   usa. As classes novas levam o prefixo `rel-`.
   ═══════════════════════════════════════════════════════════════════════════ */

/* A folha é branca até a borda do `.content`, nas duas telas — o cinza do shell
   em volta leria como moldura, e o `.main` tem `min-height`, então sobraria uma
   faixa cinza no rodapé. Mesmo `:has()` de `/despesas/nova/`: só pinta quando é
   ESTA página. */
.content:has(> .page[data-pagina="relatorios"]){ background:#fff; }
.main:has(> .content > .page[data-pagina="relatorios"]){ background:#fff; }

/* ── A LISTA ───────────────────────────────────────────────────────────────
   A grade da casa faz o resto (barra numa linha só, chips, busca, Copiar,
   Colunas). Só duas coisas são desta tela. */
/* Sem "por página" e sem paginação: a lista de relatórios salvos vem inteira
   (é o padrão da grade para tela que não é janela) e quem rola é a caixa da
   lista, esticada até o pé da janela. */
.rel-lista .dataTables_length,
.rel-lista .dataTables_paginate{ display:none; }
/* A grade É a tela: ocupa a janela inteira mesmo com duas linhas (memória
   `tela-usa-janela-inteira`). A altura vem do gancho do shell
   (`content--altura-cheia`, declarado no template); daqui para baixo é só
   repassá-la — quem rola é a caixa da lista, não a página. */
.rel-lista{ display:flex; flex-direction:column; min-height:0; }
.rel-lista .grade,
.rel-lista .dataTables_wrapper{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.rel-lista .datatable-scroll{ flex:1 1 auto; min-height:0; }
/* O excluído fica na lista, apagado, e não abre: o construtor busca a definição
   num endpoint que responde 404 a quem foi excluído. Quem o traz de volta é o
   Restaurar da própria linha. */
.rel-lista .rel-linha--excluida{ color:var(--ink-3); cursor:default; }
.rel-lista .rel-linha--excluida .grade-acao{ color:var(--ink); }

/* ── O CONSTRUTOR: lado × palco ────────────────────────────────────────────
   A tela ocupa a janela inteira abaixo da topbar e NÃO rola: quem rola é o
   lado (por dentro) e a grade do resultado. A margem negativa devolve
   exatamente o respiro que o shell deu, pelo mesmo token dos dois lados — por
   isso a altura desconta só a topbar. */
.rel-construtor *{ box-sizing:border-box; }
.rel-construtor{
  margin-inline:calc(-1 * var(--content-pad-x));
  margin-block:calc(-1 * var(--content-pad-y)) calc(-1 * var(--content-pad-b));
  width:auto; padding:0;
  /* A barra DESTA tela tem 46px (`#topbar:has(.rel-sel)`), não os 52px do
     shell: com 52 sobravam 6px de faixa morta no pé da janela — o que a
     memória `tela-usa-janela-inteira` proíbe. O token é o mesmo de
     `/despesas/nova/`; o 46px é só o piso enquanto ninguém mediu. Quando o
     `construtor.js` (8b) publicar `--dnv-topo` com um ResizeObserver (como o
     `despesas-nova.js` faz), o trilho empilhado no estreito passa a caber
     sozinho. */
  height:calc(100dvh - var(--dnv-topo, 46px));
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--dnv-ground); color:var(--dnv-ink);
  font-family:var(--dnv-sans); font-size:var(--fonte-corpo); line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
/* Quem se posiciona abaixo da barra precisa saber que ela encolheu: a barra
   lateral nascia em 52px e deixava 6px do fundo da página aparecendo por cima
   dela, e o `.main` continuava com um piso de 52px — a mesma faixa morta, agora
   embaixo. */
body:has(#topbar .rel-sel) .side{
  top:var(--dnv-topo, 46px); height:calc(100vh - var(--dnv-topo, 46px));
}
body:has(#topbar .rel-sel) .scrim{ inset:var(--dnv-topo, 46px) 0 0 0; }
.main:has(> .content > .page[data-pagina="relatorios"].rel-construtor){
  min-height:calc(100vh - 46px);
}
.rel-construtor button:not(.btn, .colfilter-multi__trigger){
  font:inherit; color:inherit; background:none; border:none;
  padding:0; cursor:pointer; text-align:left;
}
.rel-construtor :focus-visible{ outline:2px solid var(--dnv-mark); outline-offset:1px; }
/* O rótulo pequeno dos blocos do lado. */
.rel-construtor .rel-k{
  font-size:var(--fonte-rotulo); letter-spacing:.11em; text-transform:uppercase;
  color:var(--dnv-ink-3); font-weight:500;
}

/* O vão de 1px entre lado e palco é o FUNDO da grade aparecendo, não uma
   borda: é o que separa os painéis no desenho do dono. */
.rel-construtor .rel-app{
  flex:1 1 auto; min-height:0;
  display:grid; grid-template-columns:352px 1fr; grid-template-areas:"lado palco";
  background:var(--dnv-rule); gap:1px;
}
.rel-construtor .rel-lado{
  grid-area:lado; background:var(--dnv-surface);
  display:flex; flex-direction:column; overflow-y:auto;
}
.rel-construtor .rel-bloco{ padding:22px 24px; }
.rel-construtor .rel-bloco + .rel-bloco{ border-top:1px solid var(--dnv-rule); }
.rel-construtor .rel-palco{
  grid-area:palco; background:var(--dnv-surface);
  display:flex; flex-direction:column; min-height:0; overflow:hidden;
}
/* O topo do palco é a LEITURA do que está montado: a frase-resumo do filtro e
   a contagem ao vivo. Fica sempre visível — é o que responde "o que eu pedi?". */
.rel-construtor .rel-topo{ padding:16px 20px; border-bottom:1px solid var(--dnv-rule); }
.rel-construtor .rel-frase{ margin:0; font-size:var(--fonte-corpo); color:var(--dnv-ink); }
.rel-construtor .rel-contagem{
  margin:6px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3);
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1, "lnum" 1;
}
.rel-construtor .rel-recado{
  margin:10px 0 0; padding:8px 12px; font-size:var(--fonte-pequena);
  background:var(--dnv-mark-wash); color:var(--dnv-ink-2);
}
.rel-construtor .rel-resultado{ flex:1 1 auto; min-height:0; overflow:auto; }
.rel-construtor .rel-pe{
  margin:0; padding:10px 20px; border-top:1px solid var(--dnv-rule);
  font-size:var(--fonte-pequena); color:var(--dnv-ink-4);
}
/* ESTREITO: empilha e a PÁGINA volta a rolar — travar a altura da janela aqui
   espremeria o lado e esconderia o resto atrás de uma rolagem que ninguém vê.
   A margem copia a EXPRESSÃO do respiro (o `.content` troca o padding em
   ≤767.98px e não mexe no token), senão sobra o que o shell corta em silêncio. */
@media (max-width:900px){
  .rel-construtor{ height:auto; overflow:visible; }
  .rel-construtor .rel-app{ grid-template-columns:1fr; grid-template-areas:"lado" "palco"; }
  .rel-construtor .rel-lado{ overflow-y:visible; }
}
@media (max-width:767.98px){
  .rel-construtor{
    margin-inline:calc(-1 * max(0.5rem, env(safe-area-inset-left)))
                  calc(-1 * max(0.5rem, env(safe-area-inset-right)));
    margin-block:-0.5rem calc(-1 * max(1.5rem, env(safe-area-inset-bottom)));
  }
}

/* ── O TRILHO: nome, Base e ações na barra do shell ────────────────────────
   Mora nos blocos que o `base_fcds.html` já expõe (`crumb`, `topbar_filters`,
   `topbar_actions`); `#topbar:has(.rel-sel)` só casa na barra desta tela. Os
   controles são os de fábrica no `-sm` (#454); aqui fica a barra de 46px, o
   campo do nome que cresce com ela e o popover da Base. Gerar é a única ação
   cheia: consulta livre pode custar, então o resultado só sai quando alguém manda. */
#topbar:has(.rel-sel){
  height:46px; padding:0 12px 0 16px;
  background:var(--dnv-surface); border-bottom:1px solid var(--dnv-rule);
  font-family:var(--dnv-sans); color:var(--dnv-ink);
}
#topbar:has(.rel-sel) .rel-pop :where(button){
  font:inherit; color:inherit; background:none; border:none;
  padding:0; cursor:pointer; text-align:left;
}
/* O nome do relatório é um campo, não um rótulo: renomear é o gesto mais comum
   da tela. Ele CRESCE com a barra (`min-width:0` deixa o item flex encolher sem
   empurrar as ações para fora); o nome inteiro fica no `title` (posto pelo JS). */
#topbar:has(.rel-sel) .rel-nome{ display:flex; align-items:center; gap:.5rem; flex:1 1 auto; min-width:0; }
#topbar:has(.rel-sel) .rel-nome__campo{ flex:1 1 auto; min-width:8rem; max-width:34rem; }
#topbar:has(.rel-sel) .rel-sel{ position:relative; }
#topbar:has(.rel-sel) .rel-pop{
  position:absolute; top:100%; left:0; z-index:60; background:var(--dnv-surface);
  border:1px solid var(--dnv-rule-2); box-shadow:0 14px 34px -14px rgba(0,0,0,.3);
  padding:14px 16px; min-width:320px; font-size:13.5px; line-height:1.45; cursor:default;
}
#topbar:has(.rel-sel) .rel-acoes{ display:flex; align-items:center; gap:.5rem; }

/* ── O LADO: os três blocos do construtor ─────────────────────────────────
   Controles de fábrica no -sm (#454); o que separa um bloco do outro é o fio do painel. */
.rel-construtor .rel-campo{ width:auto; max-width:100%; }
.rel-construtor .rel-campo--curto{ width:6.5rem; }
.rel-construtor .rel-campo--lista{ min-width:10rem; }
.rel-construtor .rel-nada{ margin:4px 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); }
.rel-construtor .rel-fila{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.rel-construtor .rel-marca{
  display:inline-flex; align-items:center; gap:6px; font-size:var(--fonte-corpo); margin:0;
}

/* A ÁRVORE. O aninhamento se lê pelo fio à esquerda, não por moldura (memória
   `grade-minimalista-sem-moldura`): um grupo dentro do outro é um recuo e um
   traço, não uma caixa dentro de outra caixa. */
.rel-construtor .rel-grupo--aninhado{
  margin:6px 0 6px 2px; padding-left:10px; border-left:2px solid var(--dnv-rule);
}
.rel-construtor .rel-grupo__topo{ display:flex; align-items:center; gap:6px; }
.rel-construtor .rel-item{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:6px 0;
}
.rel-construtor .rel-item--relacao{ display:block; }
.rel-construtor .rel-relacao{ font-size:var(--fonte-corpo); }
.rel-construtor .rel-agregado{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:6px 0 0 12px;
}
.rel-construtor .rel-valor-agregado{ display:flex; align-items:center; gap:6px; }
/* O "entre" é o filtro de intervalo da casa (`colfilterRange`). */
.rel-construtor .rel-intervalo{ min-width:11rem; }
.rel-construtor .rel-add{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:8px; }

/* COLUNAS: uma linha por coluna, com a ordem no próprio item (subir/descer).
   Arrastar ficaria bonito e seria inacessível pelo teclado. */
.rel-construtor .rel-col{ padding:4px 0; border-bottom:1px solid var(--dnv-rule); }
.rel-construtor .rel-col__topo{ gap:4px; }
.rel-construtor .rel-col__nome{ flex:1 1 auto; font-size:var(--fonte-corpo); }
/* A coluna AGREGADA se edita no lugar (relação, função, campo, rótulo e o
   subfiltro inteiro), e por isso ganha corpo: mesmo recuo com fio da árvore,
   para ler como "isto está dentro daquela coluna". */
.rel-construtor .rel-col__agregado{
  margin:6px 0 2px 2px; padding-left:10px; border-left:2px solid var(--dnv-rule);
  display:flex; flex-direction:column; gap:6px;
}
.rel-construtor .rel-col__agregado .rel-grupo--aninhado{ margin-left:0; }

/* AGRUPAR E TOTALIZAR: a coluna à esquerda, a função de total à direita. Só
   aparecem as funções que o servidor aceita para aquela coluna. */
.rel-construtor .rel-agr{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:4px 0; border-bottom:1px solid var(--dnv-rule);
}
.rel-construtor .rel-agr input:disabled + span{ color:var(--dnv-ink-3); }

/* O RECADO do palco carrega pergunta (duplicata, exclusão) e histórico. */
.rel-construtor .rel-historico{ margin:6px 0 0; padding-left:16px; }

/* O POPOVER da Base: uma entidade por linha; a atual fica marcada. */
#topbar:has(.rel-sel) .rel-opcoes-base{ display:flex; flex-direction:column; max-height:60vh; overflow:auto; }
#topbar:has(.rel-sel) .rel-opcao-base{ padding:5px 8px; font-size:13px; }
#topbar:has(.rel-sel) .rel-opcao-base:hover{ background:var(--dnv-surface-2); }
#topbar:has(.rel-sel) .rel-opcao-base[aria-current="true"]{ font-weight:600; box-shadow:inset 2px 0 0 var(--dnv-mark); }
#topbar:has(.rel-sel) .rel-confirma{
  margin-top:10px; padding-top:10px; border-top:1px solid var(--dnv-rule); font-size:12.5px;
}
#topbar:has(.rel-sel) .rel-confirma .btn{ margin-left:6px; }

/* ── O RESULTADO: a grade da casa dentro do palco ──────────────────────── */
/* A grade ocupa a altura toda do palco e rola por dentro (mesma escolha da
   lista): quem rola é a caixa, não a página. */
.rel-construtor .rel-resultado .grade,
.rel-construtor .rel-resultado .dataTables_wrapper{
  display:flex; flex-direction:column; min-height:0; height:100%;
}
.rel-construtor .rel-resultado .datatable-scroll{ flex:1 1 auto; min-height:0; }
/* O CABEÇALHO DE GRUPO. Rótulo, quantidade e subtotais vêm PRONTOS do
   servidor (`envelope.grupos`) — aqui é só onde eles pousam. */
.rel-construtor .rel-grupo-linha > td{
  background:var(--dnv-surface-2); border-top:1px solid var(--dnv-rule-2);
  padding:5px 10px; font-size:var(--fonte-pequena);
}
.rel-construtor .rel-grupo-linha__conta{
  margin-left:8px; color:var(--dnv-ink-3);
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1, "lnum" 1;
}
.rel-construtor .rel-grupo-linha__total{
  margin-left:14px; color:var(--dnv-ink-2);
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1, "lnum" 1;
}
/* O palco antes do primeiro Gerar: uma frase, não uma folha em branco. */
.rel-construtor .rel-palco-vazio{ margin:0; padding:22px 20px; font-size:var(--fonte-corpo); color:var(--dnv-ink-3); }
/* Sem resultado não há "Gerado às": o fio do rodapé sozinho seria uma faixa morta. */
.rel-construtor .rel-pe:empty{ display:none; }
/* ── Cobertura de Representantes: o quadro do canal na grade da casa ──────
   Teto nas duas colunas de texto. Sem ele o nome de uma cooperativa (80
   caracteres) abria a coluna até empurrar "Última venda" para fora da grade,
   e quem chegava na página 2 só via metade da linha. Teto, não largura fixa:
   nome curto fica curto, comprido corta na reticência do `.grade-celula`. */
[data-pagina="cobertura_representantes"] .grade .cr-col-nome{width:100%;max-width:0;min-width:14rem}
/* O invólucro herda o teto da coluna (`max-width:inherit` na grade da casa), e
   aqui o teto é o `0` do truque acima: herdado, ele sumiria com o texto. Quem
   corta é o `td` (mesmo caso de `.rp-col-descricao`). */
[data-pagina="cobertura_representantes"] .grade .cr-col-nome .grade-celula{max-width:none}
[data-pagina="cobertura_representantes"] .grade .cr-col-carteira{max-width:15rem}

/* === CAIXA EM TEMPO REAL (/banking/) — Four Group Design System =============
   Tela do design system (ordem do dono, 24/09/2026: só esta tela, fonte e
   ícones só nela; ícones Font Awesome). Desde a fatia 1d do #208 (29/09) é a
   aba Caixa do Painel Financeiro, e os tokens e as regras `ds-*` valem também
   na aba Visão (`painel_financeiro`); o layout `bnk-*` segue só daqui. Valores copiados de
   design-system/tokens/*.css com o token de origem no comentário — o mesmo
   padrão do mural (#124). As TABELAS continuam a grade da casa: o DataTable do
   design system fica de fora ("o datagrid é superior"). A página cabe na
   janela (content--altura-cheia): só os cartões rolam. A fonte Neue Haas
   Display já tem @font-face (seção das telas do galpão, static/fonts/).
   ========================================================================== */
.page[data-pagina="banking"],
.page[data-pagina="painel_financeiro"],
body:has(.page[data-pagina="painel_financeiro"]) #fcds-lateral .pfin-detalhe-estado,
#topbar .bnk-topbar {
  --ds-regra:#161616;          /* --border-strong */
  --ds-dado:#103F6A;           /* --chart-1 (--family-dark) */
  --ds-trilho:#EAEAEA;         /* --chart-track */
  --ds-aviso:#F5A300;          /* --status-warning: preenchimento, tinta preta */
  /* Séries de gráfico (design-system/tokens/charts.css) — a aba Visão (#208, fatia 1d). */
  --ds-grafico-1:#103F6A;      /* --chart-1 */
  --ds-grafico-2:#B42727;      /* --chart-2 */
  --ds-grafico-3:#1585D7;      /* --chart-3 */
  --ds-grafico-6:#82C4F7;      /* --chart-6 */
  --ds-grafico-8:#14743C;      /* --chart-8 */
  --ds-grafico-demais:rgba(16,63,106,.28); /* --chart-mono-7: "demais", nunca cinza */
  --ds-grafico-eixo:#D5D5D6;   /* --chart-axis */
  --ds-grafico-rotulo:#7C7D7F; /* --chart-label */
}

/* ── casca: altura da janela ──────────────────────────────────────────────── */
.content--altura-cheia > .page[data-pagina="banking"] {
  padding:12px var(--content-pad-x); gap:12px; color:var(--ds-tinta); } /* fundo branco do shell (dono, 28/09) */
.page[data-pagina="banking"] .bnk-kpis { flex:0 0 auto; display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:12px; }
.page[data-pagina="banking"] .bnk-meio {
  flex:1 1 0; min-height:0; display:grid; grid-template-columns:minmax(0,2fr) minmax(300px,1fr); gap:12px; }
/* Lateral: o gráfico fica com o que sobra; os alertas, no máximo 150px (rolam por dentro). Em 900px de
   janela, meio a meio deixava ~17px de desenho ao gráfico. */
.page[data-pagina="banking"] .bnk-lateral { min-height:0; display:grid; grid-template-rows:minmax(0,1fr) auto; gap:12px; }
.page[data-pagina="banking"] .bnk-lateral > .ds-cartao { max-height:150px; min-height:0; }
.page[data-pagina="banking"] .bnk-rodape {
  flex:0 0 clamp(150px,26vh,250px); min-height:0; display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.page[data-pagina="banking"] .bnk-rolagem { flex:1 1 auto; min-height:0; overflow:auto; }

/* ── Card / Bloco (cartão reto de filete) ─────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-cartao,
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro {
  background:var(--ds-superficie); border:1px solid var(--ds-filete); border-radius:0; /* --radius-card */
  box-shadow:none; padding:14px 18px; display:flex; flex-direction:column; gap:10px; min-height:0; min-width:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-cartao__cabecalho { display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex:0 0 auto; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-cartao__titulo { margin:0; font-size:var(--fonte-destaque); font-weight:500; letter-spacing:-0.02em; color:var(--ds-tinta); } /* Bloco h2 */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-cartao__meta { font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-rotulo { font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.18em; text-transform:uppercase; color:var(--ds-tinta-2); } /* Eyebrow, --text-micro */

/* ── KpiTile ──────────────────────────────────────────────────────────────── */
/* Padding vertical enxuto (achado 2, revisão final): a posição por banco
   perde para o KPI e o rodapé fixo na disputa por altura em 1600x900 — nada
   de informação sai daqui, só a folga em volta dela. */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi {
  background:var(--ds-superficie); border:1px solid var(--ds-filete); border-radius:0;
  padding:10px 18px; display:flex; flex-direction:column; gap:6px; min-width:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__rotulo {
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.18em; text-transform:uppercase; color:var(--ds-tinta-2);
 }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__valor {
  font-size:var(--fonte-heroi); font-weight:500; letter-spacing:-0.03em; line-height:40px; color:var(--ds-tinta); white-space:nowrap; } /* --text-heading-1, ajustado para 6 na linha */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__unidade { font-size:var(--fonte-corpo); font-weight:500; letter-spacing:0; color:var(--ds-tinta-2); margin-left:5px; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__comparacao { display:flex; align-items:center; gap:6px; font-size:var(--fonte-pequena); min-width:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__delta { font-weight:500; white-space:nowrap; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__delta--positivo { color:var(--ds-positivo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__delta--negativo { color:var(--ds-negativo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__delta--neutro { color:var(--ds-tinta-2); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-kpi__legenda { color:var(--ds-tinta-3); }
/* KPI clicável (25/09/2026): o cartão é um botão que abre a composição conta a conta. */
.page[data-pagina="banking"] button.bnk-kpi { font:inherit; color:inherit; text-align:left; width:100%; cursor:pointer; }
.page[data-pagina="banking"] button.bnk-kpi:hover { border-color:var(--ds-filete-2); }
.page[data-pagina="banking"] button.bnk-kpi:focus-visible { outline:1px solid var(--ds-acao); outline-offset:-1px; }
/* Composição: o mesmo painel lateral do extrato, estreito (uma linha por conta, cinco colunas). */
.page[data-pagina="banking"] .bnk-composicao-painel { width:min(760px,92vw); }
.page[data-pagina="banking"] .bnk-composicao { margin:0; font-size:var(--fonte-corpo); }
.page[data-pagina="banking"] .bnk-composicao tfoot th { border-top:1px solid var(--ds-regra); }

/* ── ProgressMeter ────────────────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-medidor__trilho { position:relative; display:flex; height:6px; background:var(--ds-trilho); border-radius:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-medidor--tabela .ds-medidor__trilho { height:4px; width:88px; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-medidor__preenchimento { height:100%; background:var(--ds-dado); }

/* ── Badge ────────────────────────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge {
  display:inline-flex; align-items:center; gap:4px; height:20px; padding:0 8px; font-size:var(--fonte-rotulo); font-weight:500;
  letter-spacing:.08em; text-transform:uppercase; line-height:1; border-radius:2px; white-space:nowrap; } /* --radius-xs */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge i { font-size:var(--fonte-pequena); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge--neutral { background:#EAEAEA; color:var(--ds-tinta); }       /* --fg-gray-100 */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge--tint { background:var(--ds-acao-tinta); color:var(--ds-tinta); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge--danger { background:var(--ds-perigo); color:#FFFFFF; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-badge--warning { background:var(--ds-aviso); color:var(--ds-tinta); } /* tinta preta sobre o âmbar */

/* ── números e textos de apoio ────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-numero--positivo { color:var(--ds-positivo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-numero--negativo { color:var(--ds-negativo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-texto--apoio { color:var(--ds-tinta-3); }

/* ── posição por banco: a grade da casa dentro do cartão, rolando nele ─────── */
.page[data-pagina="banking"] .bnk-posicao .grade { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.page[data-pagina="banking"] #bnk-posicao-tela { flex:1 1 auto; min-height:0; overflow:auto; }
/* Achado 2 (revisão final): no máximo ~15 bancos — a grade da casa não tem uma
   opção para desligar a linha de filtro por coluna ou a barra de paginação
   (static/js/grade.js sempre desenha as duas), então aqui elas ficam mas SEM
   ALTURA: sem `tipoDeFiltro` no banking.js a linha de filtros já nasce vazia
   (nenhum `<input>`/`colfilter-multi` dentro), e com `porPagina` no padrão -1
   a paginação nunca faz nada (uma página só, sempre com as ~15 linhas) — a
   barra de baixo só repetia "1–15 de 15" sem função de navegação nenhuma.
   Escondê-las devolve a altura ao que a lista realmente usa: as linhas. */
.page[data-pagina="banking"] #bnk-posicao-cabecalho tr.grade-filtros-col { display:none; }
.page[data-pagina="banking"] #bnk-posicao-tela .datatable-bottom { display:none; }
/* Reporte #189: numa lista de ~15 bancos sem filtro de coluna, "Colunas" e "Limpar filtros" só tiravam
   altura das linhas; ficam a busca e o Copiar. */
.page[data-pagina="banking"] .bnk-posicao .buttons-colvis,
.page[data-pagina="banking"] .bnk-posicao .grade-limpar-filtros { display:none !important; }
.page[data-pagina="banking"] .bnk-linha--sem-saldo td { color:var(--ds-tinta-3); }
/* ── contas do banco: sub-linha da própria grade, não mais tabela aninhada ───
   Dono, 24/09/2026: "gasta muito espaço para pouca informação". A sub-linha é
   um <tr> de verdade dentro da MESMA tabela — herda de `.grade-tabela tbody td`
   o padding/altura/fio que já valem para a linha de banco (nenhuma regra nova
   de altura aqui); só o fundo muda, com um token de página já em uso na
   casca (`--ds-fundo`), sem borda extra. */
.page[data-pagina="banking"] .bnk-linha-conta td { background:var(--ds-fundo); }
.page[data-pagina="banking"] .bnk-linha-conta .bnk-conta__nome { padding-left:14px; }
.page[data-pagina="banking"] .bnk-linha-conta--clicavel { cursor:pointer; }
.page[data-pagina="banking"] .bnk-linha-conta--clicavel:hover td,
.page[data-pagina="banking"] .bnk-linha-conta--clicavel[aria-expanded="true"] td { background:var(--ds-trilho); }
.page[data-pagina="banking"] .bnk-linha-conta--clicavel:focus-visible { outline:1px solid var(--ds-acao); outline-offset:-1px; }
/* Retido e fora do caixa (25/09/2026): bloco sob a grade, fora do Total — dentro da grade a linha de total o somaria. */
/* Reporte #189: recolhido numa linha; aberto, divide a altura com a grade (no máximo 40%) e rola por dentro —
   antes, `flex:0 0 auto` não encolhia e a grade ficava só com o Total. */
.page[data-pagina="banking"] .bnk-retidas {
  flex:0 1 auto; min-height:0; max-height:40%; overflow:auto; border-top:1px solid var(--ds-filete); padding-top:8px; }
.page[data-pagina="banking"] .bnk-retidas__titulo {
  display:flex; align-items:baseline; justify-content:space-between; gap:12px; cursor:pointer; margin:0 0 4px; }
.page[data-pagina="banking"] .bnk-retidas__titulo::-webkit-details-marker { display:none; }
.page[data-pagina="banking"] .bnk-retidas__seta { font-size:var(--fonte-pequena); margin-right:4px; transition:transform .15s; }
.page[data-pagina="banking"] .bnk-retidas__grupo[open] .bnk-retidas__seta { transform:rotate(90deg); }
.page[data-pagina="banking"] .bnk-retidas__tabela { margin:0; }
.page[data-pagina="banking"] .bnk-extrato-origem { flex:none; font-size:var(--fonte-pequena); white-space:nowrap; }

/* ── extrato: painel lateral largo (offcanvas) ───────────────────────────────
   Pedido do dono (24/09/2026): "bem largo, para não ficar aprisionado dentro
   da janela" — revogou a regra antiga de detalhe sempre na linha. Topo/altura
   abaixo da topbar já vêm do shell (`body.stm-shell .offcanvas-end`, §5
   acima); aqui só a largura e o corpo, que ocupa a altura inteira do painel e
   rola por dentro (o cabeçalho com período fica fixo).
   Largura (achado do dono, 24/09/2026): `min(1280px,80vw)` cortava a coluna
   Crédito da grade do extrato em 1920px. A janela toda, menos a largura REAL
   da barra lateral de ícones em repouso — `.side{width:4rem}` (§ shell,
   acima; não é `--side-w-aberta`, essa é só a largura no hover/travada).
   Abaixo de 768px o shell já troca a barra por uma gaveta (`.side` sai da
   tela com `transform`, `.main{margin-left:0}`), então o painel ocupa a
   janela inteira. */
.page[data-pagina="banking"] .bnk-extrato-painel { width:calc(100vw - 4rem); }
@media(max-width:767.98px){
  .page[data-pagina="banking"] .bnk-extrato-painel { width:100%; }
}
/* Cabeçalho numa linha só: "Extrato · <apelido>" · seletor de período (o canônico,
   `.fcds-seletor`) · X. O popover abre para a esquerda: o seletor mora na borda direita. */
.page[data-pagina="banking"] .bnk-extrato-painel .offcanvas-header { flex-wrap:nowrap; gap:1rem; }
.page[data-pagina="banking"] .bnk-extrato-painel .offcanvas-title { min-width:0; }
.page[data-pagina="banking"] .bnk-extrato-periodo { margin-left:auto; flex:none; }
.page[data-pagina="banking"] .bnk-extrato-periodo .fcds-seletor__popover { left:auto; right:0; }
.page[data-pagina="banking"] .bnk-extrato-painel .offcanvas-body { display:flex; flex-direction:column; min-height:0; overflow:hidden; }
.page[data-pagina="banking"] .bnk-extrato-painel .grade { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.page[data-pagina="banking"] #bnk-extrato-tela { flex:1 1 auto; min-height:0; overflow:auto; }

/* ── ChartFrame ───────────────────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro__cabecalho { display:flex; align-items:baseline; gap:10px; flex:0 0 auto; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro__valor { margin-left:auto; font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-0.03em; line-height:1; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro__meta { font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro__corpo { position:relative; flex:1 1 auto; min-height:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-quadro__nota { flex:0 0 auto; border-top:1px solid var(--ds-filete); padding-top:8px; font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }
.page[data-pagina="banking"] .bnk-grafico-quadro .ds-quadro__cabecalho { flex-wrap:wrap; row-gap:4px; }
.page[data-pagina="banking"] .bnk-grafico-resumo { flex:1 0 100%; margin:0; }
/* Gráfico do saldo: a gramática do "Faturamento diário" da Reunião Semanal (.rs-graf). O SVG é
   desenhado em pixel pelo banking.js e redesenhado quando o quadro muda de tamanho. */
.page[data-pagina="banking"] .bnk-grafico { position:absolute; inset:0; outline:none; }
.page[data-pagina="banking"] .bnk-grafico:focus-visible { outline:1px solid var(--ds-acao); outline-offset:2px; }
.page[data-pagina="banking"] .bnk-grafico svg { position:absolute; inset:0; overflow:visible; }
.page[data-pagina="banking"] .bnk-grafico text { font-family:inherit; font-size:var(--fonte-pequena); fill:var(--ds-tinta-3); }
.page[data-pagina="banking"] .bnk-grafico .bnk-g-forte { fill:var(--ds-tinta); font-weight:500; }
.page[data-pagina="banking"] .bnk-g-grade { stroke:var(--ds-filete); }
.page[data-pagina="banking"] .bnk-g-base { stroke:var(--ds-tinta-3); }
.page[data-pagina="banking"] .bnk-g-hoje { stroke:var(--ds-tinta-3); stroke-dasharray:2 3; }
.page[data-pagina="banking"] .bnk-g-area { fill:var(--ds-trilho); }
.page[data-pagina="banking"] .bnk-g-realizado { fill:none; stroke:var(--ds-tinta); stroke-width:2; stroke-linejoin:round; }
.page[data-pagina="banking"] .bnk-g-previsto { fill:none; stroke:var(--ds-tinta); stroke-width:1.5; stroke-dasharray:5 3; }
.page[data-pagina="banking"] .bnk-g-negativo path { stroke:var(--ds-perigo); }
.page[data-pagina="banking"] .bnk-g-ponto { fill:var(--ds-tinta); }
.page[data-pagina="banking"] .bnk-g-ponto--negativo,
.page[data-pagina="banking"] .bnk-g-menor--negativo { fill:var(--ds-perigo); }
.page[data-pagina="banking"] .bnk-g-menor { fill:var(--ds-superficie); stroke:var(--ds-tinta); stroke-width:1.5; }
.page[data-pagina="banking"] .bnk-g-menor--negativo { stroke:var(--ds-perigo); }
.page[data-pagina="banking"] .bnk-g-mira { stroke:var(--ds-filete-2); }
.page[data-pagina="banking"] .bnk-g-zona { fill:transparent; }
/* Balão do gráfico: o mesmo comportamento do .rs-balao (fixo, preso à janela). */
.page[data-pagina="banking"] .bnk-balao { position:fixed; z-index:70; pointer-events:none; display:flex; flex-direction:column; gap:2px;
  min-width:12rem; padding:8px 11px; background:var(--ds-superficie); border:1px solid var(--ds-filete-2);
  box-shadow:0 10px 24px -12px rgba(0,0,0,.35); font-size:var(--fonte-pequena); color:var(--ds-tinta-2); white-space:nowrap; }
.page[data-pagina="banking"] .bnk-balao[hidden] { display:none; }
.page[data-pagina="banking"] .bnk-balao__titulo { margin-bottom:2px; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.06em; text-transform:uppercase; color:var(--ds-tinta-3); }
.page[data-pagina="banking"] .bnk-balao__linha--forte { font-weight:500; color:var(--ds-tinta); }

/* ── alertas ──────────────────────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-alerta { display:flex; align-items:flex-start; gap:10px; padding:10px 0; border-bottom:1px solid var(--ds-filete); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-alerta:last-child { border-bottom:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-alerta__texto strong { display:block; font-size:var(--fonte-corpo); font-weight:500; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-alerta__texto p { margin:2px 0 0; font-size:var(--fonte-pequena); line-height:1.5; color:var(--ds-tinta-2); }

/* ── listas do rodapé ─────────────────────────────────────────────────────── */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista { list-style:none; margin:0; padding:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__item,
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__grupo > summary {
  display:grid; grid-template-columns:44px 110px minmax(0,1fr) auto auto; align-items:center; gap:12px;
  padding:8px 0; border-bottom:1px solid var(--ds-filete); font-size:var(--fonte-corpo); }
/* Movimentos: a etiqueta ERP/API vem depois do banco, numa coluna própria de largura
   fixa — cada linha é uma grade, e só largura fixa alinha a etiqueta entre as linhas.
   Sem isso ela caía na coluna elástica e virava barra (#212). */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista--movimentos > .ds-lista__item { grid-template-columns:44px 110px 68px minmax(0,1fr) auto; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista--movimentos .ds-badge { justify-self:start; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__item:has(> .ds-lista__grupo) { display:block; padding:0; border-bottom:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__grupo > summary { cursor:pointer; list-style:none; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__grupo > summary::-webkit-details-marker { display:none; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__grupo > summary:hover { background:var(--ds-acao-tinta); } /* hover = tinta de ação, nunca cinza */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__data { color:var(--ds-tinta-3); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__banco { font-weight:500; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__texto { min-width:0; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__valor { text-align:right; white-space:nowrap; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__itens { list-style:none; margin:0; padding:4px 0 8px 56px; font-size:var(--fonte-pequena); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-lista__itens li { display:flex; justify-content:space-between; gap:12px; padding:3px 0; }

/* ── EmptyState (vazio / erro) ────────────────────────────────────────────── */
/* A variante "carregando" saiu (24/09/2026): o carregamento passou a ser o
   logo-loader padrão do app (`biUtils.carregando`/`pronto`, `.logo-loader`),
   não este spinner próprio da tela. */
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio {
  height:100%; min-height:96px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
  text-align:center; padding:16px; border:1px dashed var(--ds-filete-2); background:var(--ds-superficie); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio__marca { width:22px; height:22px; border:1px solid var(--ds-filete-2); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio--erro .ds-vazio__marca { border-color:var(--ds-perigo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio__titulo { font-size:var(--fonte-corpo); font-weight:500; }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio--erro .ds-vazio__titulo { color:var(--ds-perigo); }
:is(.page[data-pagina="banking"], .page[data-pagina="painel_financeiro"]) .ds-vazio__descricao { font-size:var(--fonte-pequena); color:var(--ds-tinta-2); max-width:320px; line-height:1.5; }


/* ── topbar desta tela ────────────────────────────────────────────────────── */
#topbar .bnk-topbar.bnk-hoje { font-size:var(--fonte-corpo); color:var(--ds-tinta-2); margin-right:8px; white-space:nowrap; }

/* ── abaixo de 992px a página volta a rolar (desenho de celular: depois) ──── */
@media (max-width:991.98px) {
  .content--altura-cheia > .page[data-pagina="banking"] { overflow-y:auto; }
  .page[data-pagina="banking"] .bnk-kpis { grid-template-columns:repeat(3,minmax(0,1fr)); }
  .page[data-pagina="banking"] .bnk-meio,
  .page[data-pagina="banking"] .bnk-rodape { display:flex; flex-direction:column; flex:0 0 auto; }
  .page[data-pagina="banking"] .bnk-posicao { height:70vh; }
  .page[data-pagina="banking"] .bnk-lateral { grid-template-rows:260px auto; }
}

/* ==========================================================================
   LOGÍSTICA · DESOVA (`[data-pagina="desova"]`, chamado #141, 25/09/2026)
   — em andamento, as grades Por processo e Por container (a grade da casa)
   e o Quadro (v4.1); "Ver encerrados", a mesma grade; e o painel lateral.
   Escopo de página: nada aqui mexe em token nem em componente compartilhado.
   A folha da etiqueta (`.etiquetas-desova`) mora logo abaixo, com `@page`
   NOMEADA: o `@page` anônimo pertence à proposta do CRM.
   ========================================================================== */
/* A grade não mora num cartão: a folha da página é branca (mesma regra das
   outras telas de grade), senão o cinza do shell aparece embaixo das linhas. */
.content:has(> .page[data-pagina="desova"]),
.page[data-pagina="desova"] { background: #fff; }
/* ── Em andamento: grades de abertos e Quadro (v4.1; tokens do mockup v7) ──
   Four Group Design System (design-system/tokens), só nesta página: Neue Haas
   Display (declarada acima, nas telas do WMS); ação a da casa (--ds-acao); tinta
   #161616/#595A5C/#7C7D7F (--text-primary/secondary/muted); fios #EAEAEA/
   #D5D5D6 (--border-subtle/default) e o preto do cabeçalho (--border-strong);
   #F5F5F5 (--fg-gray-50); #E9ECF0 (--surface-app-rail); vermelho só para
   freetime vencido (--status-danger #B42727), laranja vivo para vence em até
   3 dias (--figure-attention #FF7B00). Raio 0; botões e campos de fábrica. Sem moldura: fica
   o fio do cabeçalho e o das linhas. A grade ocupa a altura que sobra. */
.page[data-pagina="desova"] {
  --desova-acao:var(--ds-acao); --desova-acao-clara:var(--ds-acao-tinta);
  --desova-tinta:#161616; --desova-tinta-2:#595A5C; --desova-tinta-3:#7C7D7F;
  --desova-fio:#EAEAEA; --desova-fio-2:#D5D5D6; --desova-fio-forte:#161616;
  --desova-cinza:#F5F5F5; --desova-trilho:#E9ECF0;
  --desova-vermelho:#B42727; /* --status-danger: só freetime vencido */
  --desova-laranja:#FF7B00;  /* --figure-attention: vence em até 3 dias */
  --desova-fonte:'Neue Haas Display', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-family:var(--desova-fonte); color:var(--desova-tinta);
}
/* Em andamento: régua + barra + Quadro ocupam a altura que sobra; nas grades
   (Quadro escondido) quem ocupa é a grade da casa, logo abaixo. */
.page[data-pagina="desova"] .desova-andamento { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.page[data-pagina="desova"] .desova-andamento:has(> .desova-quadro[hidden]) { flex:none; }
.page[data-pagina="desova"] .desova-andamento[hidden] { display:none; }
/* Grades de abertos: o item cede (o resto vai na dica); na Ação (2ª coluna,
   congelada), o botão azul e o de etiquetas lado a lado, numa linha só. O
   aviso do Conexos vai na segunda linha do container sem alargar a coluna
   (largura 0 + mínimo 100%: não entra na medida da coluna, ocupa a dela). */
.page[data-pagina="desova"] .grade-tabela td.desova-grade__item { max-width:200px; }
.page[data-pagina="desova"] .grade-tabela td.desova-grade__acao .grade-celula { display:flex; align-items:center; gap:6px; overflow:visible; }
.page[data-pagina="desova"] .grade-tabela .desova-painel__numero-aviso {
  display:block; width:0; min-width:100%; margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:12px; font-weight:500; line-height:1.2;
}
.page[data-pagina="desova"] .desova-lista__barra { flex:none; display:flex; flex-wrap:wrap; align-items:center; gap:6px 18px; min-height:44px; font-size:var(--fonte-corpo); }
.page[data-pagina="desova"] .desova-lista__vencidos { color:#B42727; font-weight:500; }
.page[data-pagina="desova"] .desova-lista__so-vencidos { display:inline-flex; align-items:center; gap:6px; margin:0; cursor:pointer; }
.page[data-pagina="desova"] .desova-lista__nome {
  padding:0; border:0; background:none; font:inherit; font-weight:500; color:var(--desova-tinta);
  text-decoration:underline; text-decoration-color:var(--desova-fio-2); text-underline-offset:3px;
}
.page[data-pagina="desova"] .desova-lista__nome:hover { color:var(--desova-acao); text-decoration-color:var(--desova-acao); }
.page[data-pagina="desova"] .desova-lista__linha-do-item { display:block; color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-lista__codigo { margin-right:4px; font-weight:500; color:var(--desova-tinta); }
.page[data-pagina="desova"] .desova-lista__freetime { font-weight:500; }
.page[data-pagina="desova"] .desova-lista__freetime--vencido { color:#B42727; }
.page[data-pagina="desova"] .desova-lista__freetime--vence { color:#FF7B00; } /* tinta viva de limiar (design-system/readme.md): o número diz "vence em N dias" */
.page[data-pagina="desova"] .desova-lista__informar { padding:0; border:0; background:none; font:inherit; color:var(--desova-acao); }
.page[data-pagina="desova"] .desova-lista__informar:hover { text-decoration:underline; }
.page[data-pagina="desova"] :is(.grade-tabela, .desova-quadro) :is(.desova-lista__nome, .desova-lista__informar, a):focus-visible { outline:2px solid var(--desova-acao); outline-offset:-2px; } /* Quadro também: o cartão não tinha foco visível */
/* Topbar desta página (mockup v7): "Desova · Araquari", Por processo | Por container | Colunas, a busca, "Ver encerrados" e "+ Novo processo" — no design system. */
#topbar:has(#ds-alternar) .crumb b { font-family:'Neue Haas Display', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight:500; white-space:nowrap; color:#161616; }
#topbar #ds-titulo-armazem { color:inherit; font:inherit; } /* "Desova · Araquari" é um título só, não um crumb de dois níveis */
/* Busca das Colunas e "Sincronizar agora" à direita da barra de vencidos (#259: no topo, a barra passava da janela em 1280/1366). */
.page[data-pagina="desova"] .desova-lista__acoes { margin-left:auto; display:flex; align-items:center; gap:8px; }
.page[data-pagina="desova"] .desova-busca-da-lista { width:260px; }
.page[data-pagina="desova"] .desova-busca-da-lista[hidden] { display:none; }
/* Barra da grade ("Ver encerrados"): o seletor da base (Encerrados/Lixeira). */
[data-pagina="desova"] .grade .desova-visao { flex: 0 0 auto; margin: 0; }
[data-pagina="desova"] .grade .desova-visao select { width: auto; }
/* "Ver por: Processo | Container" (v3), no topo ao lado de "Nova desova": o btn-group de fábrica. */
.desova-por { display: flex; align-items: center; gap: .5rem; margin-right: .5rem; }
.desova-por__rotulo { font-size: var(--fonte-corpo); color: var(--ink-2); white-space: nowrap; }
/* O texto compacto não empurra a lista para a rolagem lateral: corta, e a dica mostra. */
[data-pagina="desova"] .grade .desova-col-containers { max-width: 12rem; }
/* Célula "Containers": "4 de 4 desovados" (compacto, do servidor) abre a linha; o resumo cheio vira dica/aria-label. */
[data-pagina="desova"] .desova-abrir-containers { padding: 0; border: 0; background: none; color: var(--acc); font: inherit; white-space: nowrap; }
[data-pagina="desova"] .desova-abrir-containers::before { content: '\25B8'; display: inline-block; width: .875rem; transition: transform .12s; }
[data-pagina="desova"] .desova-abrir-containers[aria-expanded="true"]::before { transform: rotate(90deg); }
[data-pagina="desova"] .desova-abrir-containers:hover { text-decoration: underline; }
/* Digitar na linha (v3): a célula de data/armazém do processo é campo. Parada,
   é texto; sob o cursor, um fio embaixo diz "digite aqui"; com foco, o
   contorno do foco da casa. Editando, o form-control-sm ocupa a célula. */
[data-pagina="desova"] .desova-celula[tabindex] { display: block; cursor: text; }
[data-pagina="desova"] .desova-celula[tabindex="0"]:hover { box-shadow: inset 0 -1px 0 var(--grade-tinta-2); }
[data-pagina="desova"] .desova-celula[tabindex]:focus-visible { outline: 0; box-shadow: inset 0 0 0 2px var(--acc); }
[data-pagina="desova"] .grade-tabela td:has(.desova-celula--editando),
[data-pagina="desova"] .grade-tabela .grade-celula:has(.desova-celula--editando) { overflow: visible; }
[data-pagina="desova"] .desova-celula--editando { position: relative; }
[data-pagina="desova"] .desova-celula__campo { min-width: 8.5rem; }
[data-pagina="desova"] .desova-celula__campo[aria-invalid="true"] { border-color: var(--negative-text); }
/* A recusa fica colada na célula, por cima da linha de baixo: a linha não cresce. */
[data-pagina="desova"] .desova-celula__erro {
  position: absolute; top: calc(100% + .1875rem); left: 0; z-index: 3; width: max-content; max-width: 18rem;
  padding: 2px 6px; border: 1px solid var(--negative-text); background: #fff; color: var(--negative-text);
  font-size: var(--fonte-pequena); white-space: normal;
}
/* A pergunta do Conexos (Task 5, regra da casa 8) colada na célula, como a recusa;
   cresce para a esquerda: a Devolução é das últimas colunas da grade. */
[data-pagina="desova"] .desova-celula__confirmacao {
  position: absolute; top: calc(100% + .1875rem); right: 0; z-index: 4; display: flex; flex-wrap: wrap;
  align-items: center; gap: 6px; width: max-content; max-width: 22rem; padding: 6px 8px;
  border: 1px solid #000; background: #fff; color: var(--ink); font-size: var(--fonte-pequena); white-space: normal;
}
/* Os containers do processo (linha expandida e seção do painel): uma linha
   por container, cada uma abre o painel dele. */
.desova-containers { list-style: none; margin: 0; padding: 0; }
.desova-containers__item {
  display: grid; grid-template-columns: minmax(8rem, 12rem) minmax(6rem, 8rem) minmax(8rem, 12rem) minmax(6rem, 10rem);
  justify-content: start; gap: 16px; width: 100%; padding: 6px 8px; border: 0; background: none; text-align: left; font-size: var(--fonte-corpo); color: var(--ink);
}
.desova-containers li + li .desova-containers__item { border-top: 1px solid var(--line-2); }
.desova-containers__item:hover .desova-containers__numero { color: var(--acc); text-decoration: underline; }
.desova-containers__numero { font-weight: 500; font-variant-numeric: tabular-nums; }
/* Visão vazia: a grade some com a barra; os botões das bases ficam sob a frase. */
[data-pagina="desova"] .desova-vazio-bases { display: flex; justify-content: center; gap: 8px; }
[data-pagina="desova"] .desova-vazio-bases[hidden] { display: none; }
[data-pagina="desova"] .grade .grade-vazio:has(+ .desova-vazio-bases:not([hidden])) { padding-bottom: 1.5rem; }
/* Painel: régua das etapas no cabeçalho, o bloco do próximo passo (a única
   mancha de cor e o único botão cheio), os fatos, as seções recolhíveis
   (separadas por fio, como linhas de uma lista) e o pé. Ritmo de 8px, raio 0. */
.desova-painel { --bs-offcanvas-width: min(46rem, 96vw); }
.desova-painel .offcanvas-header { align-items: flex-start; padding: 16px 24px 12px; }
.desova-painel .offcanvas-header > div { flex: 1 1 auto; min-width: 0; }
.desova-painel .offcanvas-title { font-size: var(--fonte-destaque); font-weight: 500; margin-bottom: 12px; }
.desova-painel .offcanvas-body { overflow-y: auto; padding: 4px 24px 24px; }
.desova-painel__sub { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; color: var(--ink-2); font-size: var(--fonte-pequena); }
.desova-rotulo { font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2); }
/* régua: quatro trechos iguais; feito e agora em azul, o agora também no texto */
.desova-regua { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); width: 100%; margin: 0; padding: 0; list-style: none; }
.desova-regua__passo { padding-top: 6px; border-top: 3px solid var(--line-3); font-size: var(--fonte-pequena); color: var(--ink-3); }
.desova-regua__passo + .desova-regua__passo { margin-left: 2px; }
.desova-regua__passo--feito { border-top-color: var(--acc); color: var(--ink); }
.desova-regua__passo--agora { border-top-color: var(--acc); color: var(--acc); font-weight: 500; }
.desova-painel__titulo { font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); margin: 0 0 8px; }
.desova-painel__nota { color: var(--ink-2); font-size: var(--fonte-pequena); margin: 0 0 8px; }
.desova-painel__acoes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
/* próximo passo: fundo azul-claro, sem moldura */
.desova-proximo { display: flex; flex-direction: column; gap: 12px; padding: 16px; margin-top: 8px; background: color-mix(in srgb, var(--acc) 7%, #fff); }
.desova-proximo__cabecalho { display: flex; flex-direction: column; gap: 2px; }
.desova-proximo__titulo { margin: 0; font-size: var(--fonte-destaque); font-weight: 500; color: var(--ink); }
.desova-proximo__campos { display: flex; flex-direction: column; gap: 12px; margin: 0; }
.desova-proximo__linha { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; }
.desova-proximo__linha .desova-campo { flex: 1 1 140px; max-width: 200px; }
.desova-proximo__etiquetas { display: flex; flex-direction: column; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid color-mix(in srgb, var(--acc) 18%, #fff); }
.desova-proximo__legenda { margin: 0; font-size: var(--fonte-pequena); color: var(--ink-2); }
.desova-proximo--lixeira { flex-direction: row; align-items: center; justify-content: space-between; font-size: var(--fonte-corpo); color: var(--ink-2); }
.desova-etiquetas { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin: 0; }
.desova-etiquetas .btn { display: inline-flex; align-items: center; gap: 8px; }
.desova-etiquetas__nota { align-self: center; font-size: 13px; font-weight: 600; color: var(--ink); min-width: 72px; }
.desova-etiquetas__quantidade input { width: 96px; }
.desova-etiquetas__texto { align-self: center; font-size: 12px; color: var(--ink-2); }
.desova-etiquetas--recusa { align-items: center; font-size: 13px; color: var(--ink-2); }
/* #504: imprimir um container por vez — uma linha por container do processo. */
.desova-etiquetas__por-container { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; }
.desova-etiquetas__por-container li { display: flex; align-items: center; gap: 12px; }
.desova-etiquetas__por-container form { margin: 0; }
.desova-etiquetas__por-container .btn { display: inline-flex; align-items: center; gap: 8px; }
.desova-etiquetas__container { min-width: 120px; font-size: 13px; font-weight: 600; color: var(--ink); }
/* fatos: o que se lê de relance */
.desova-fatos { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px 16px; margin: 0; padding: 16px 0; border-bottom: 1px solid var(--line); }
.desova-fatos dt { margin-bottom: 2px; }
.desova-fatos dd { margin: 0; font-size: var(--fonte-corpo); color: var(--ink); font-variant-numeric: tabular-nums; }
.desova-fato--pendente { color: #161616 !important; font-weight: 500; } /* pendência neutra, sem marrom */
/* seções recolhíveis: uma linha cada, o sinal à direita */
.desova-secao { border-bottom: 1px solid var(--line); }
.desova-secao > summary { display: flex; align-items: baseline; gap: 12px; padding: 12px 0; cursor: pointer; list-style: none; font-size: var(--fonte-corpo); color: var(--ink); }
.desova-secao > summary::-webkit-details-marker { display: none; }
.desova-secao > summary::after { content: '+'; margin-left: auto; font-size: var(--fonte-destaque); line-height: 1; color: var(--ink-2); }
.desova-secao[open] > summary::after { content: '\2212'; }
.desova-secao > summary:hover .desova-secao__titulo { color: var(--acc); }
.desova-secao__titulo { font-weight: 500; }
.desova-secao__resumo { min-width: 0; font-size: var(--fonte-pequena); color: var(--ink-2); }
.desova-secao__corpo { padding: 4px 0 16px; }
.desova-secao__corpo > .desova-proximo__etiquetas { margin-bottom: 16px; border-bottom-color: var(--line); }
/* dados: três grupos numa grade de 4 colunas */
.desova-form { display: flex; flex-direction: column; gap: 16px; }
.desova-grupo { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px 16px; margin: 0; padding: 0; border: 0; min-width: 0; }
.desova-grupo legend { grid-column: 1 / -1; float: none; width: auto; padding: 0; font-size: var(--fonte-corpo); font-weight: 500; color: var(--ink); margin: 0 0 4px; }
.desova-campo { display: flex; flex-direction: column; gap: 2px; font-size: var(--fonte-pequena); color: var(--ink-2); margin: 0; min-width: 0; }
.desova-campo--duplo { grid-column: span 2; }
.desova-form__acoes { display: flex; justify-content: flex-end; }
.desova-processo { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 16px; }
.desova-processo .desova-form__acoes { grid-column: 1 / -1; }
@media (max-width: 575.98px) { .desova-grupo, .desova-processo { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* NF e lotes: sem caixa; a NF fora do processo só perde a tinta */
.desova-nota { margin-bottom: 16px; }
.desova-nota--fora { color: var(--ink-2); }
.desova-nota__cabecalho { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; font-size: var(--fonte-corpo); }
.desova-nota__fornecedor { font-size: var(--fonte-pequena); color: var(--ink); margin-top: 2px; }
.desova-marca { font-size: var(--fonte-pequena); padding: 0 6px; border: 1px solid var(--line-3); color: var(--ink-2); }
.desova-lotes { width: 100%; font-size: var(--fonte-pequena); margin: 0 0 8px; border-collapse: collapse; }
.desova-lotes th { font-weight: 500; color: var(--ink-2); padding: 4px 8px 4px 0; border-bottom: 1px solid var(--line); }
.desova-lotes td { padding: 4px 8px 4px 0; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
.desova-busca summary { font-size: var(--fonte-pequena); color: var(--bs-link-color); cursor: pointer; width: max-content; }
.desova-busca-nota { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin: 8px 0; }
/* pé: voltar (link) à esquerda, excluir à direita */
.desova-pe { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 8px 16px; padding-top: 16px; font-size: var(--fonte-corpo); }
.desova-pe__exclusao { margin-left: auto; text-align: right; }
.desova-pe__exclusao .desova-painel__nota { margin-bottom: 8px; }
.desova-pe__exclusao .desova-painel__acoes { justify-content: flex-end; margin: 0; }
.desova-aviso { padding: 8px 12px; margin: 8px 0; font-size: var(--fonte-corpo); border: 1px solid var(--line-3); background: var(--surf); }
.desova-aviso--atencao { border-color: #D5D5D6; background: #fff; color: #161616; font-weight: 500; } /* pendência neutra, sem marrom/âmbar */
.desova-aviso--erro { border-color: var(--negative-text); background: var(--negative-subtle); color: var(--negative-text); }
/* ── Desova v4 (Task 4): etapas, Quadro, editor em linha, aviso e painel ──
   Mesmos tokens do bloco da tabela (acima, em .page[data-pagina="desova"]). */
/* Pendência que não é dinheiro (sem NF, sem código, falta conciliar): tinta neutra, peso 500 (marca servida). */
.page[data-pagina="desova"] .desova-lista__linha-do-item--pendente { color:var(--desova-tinta); font-weight:500; }
/* Faixa das etapas (só na Lista): uma linha, sem clique. */
.page[data-pagina="desova"] .desova-etapas { flex:none; display:flex; flex-wrap:wrap; border:1px solid var(--desova-fio); margin-top:4px; }
.page[data-pagina="desova"] .desova-etapas[hidden] { display:none; }
.page[data-pagina="desova"] .desova-etapa { flex:1 1 170px; display:flex; align-items:baseline; gap:8px; padding:8px 16px; border-right:1px solid var(--desova-fio); position:relative; }
.page[data-pagina="desova"] .desova-etapa:last-child { border-right:0; }
.page[data-pagina="desova"] .desova-etapa:not(:last-child)::after {
  content:''; position:absolute; right:-6px; top:50%; z-index:1; width:10px; height:10px; background:#fff;
  border-top:1px solid var(--desova-fio-2); border-right:1px solid var(--desova-fio-2); transform:translateY(-50%) rotate(45deg);
}
.page[data-pagina="desova"] .desova-etapa b { font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
.page[data-pagina="desova"] .desova-etapa span { color:var(--desova-tinta-2); }
/* Quadro: uma coluna por etapa, cada uma rola sozinha; a tela não rola.
   minmax(0, 1fr): as 5 colunas de Itajaí cabem em 1280 (com 240 px a quinta ficava cortada). */
.page[data-pagina="desova"] .desova-quadro {
  flex:1 1 auto; min-height:0; display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0, 1fr);
  gap:12px; overflow-x:auto; padding:4px 0 12px;
}
.page[data-pagina="desova"] .desova-quadro[hidden] { display:none; }
.page[data-pagina="desova"] .desova-quadro__coluna { display:flex; flex-direction:column; min-height:0; background:var(--desova-cinza); }
.page[data-pagina="desova"] .desova-quadro__cabecalho {
  display:flex; justify-content:space-between; align-items:baseline; gap:8px; padding:10px 12px;
  background:#fff; border-bottom:2px solid var(--desova-fio-forte);
}
.page[data-pagina="desova"] .desova-quadro__titulo { margin:0; font-size:var(--fonte-corpo); font-weight:500; letter-spacing:0; }
.page[data-pagina="desova"] .desova-quadro__quantidade { font-size:var(--fonte-titulo); font-weight:500; font-variant-numeric:tabular-nums; }
.page[data-pagina="desova"] .desova-quadro__cartoes { flex:1 1 auto; min-height:0; overflow-y:auto; display:flex; flex-direction:column; gap:8px; padding:8px; }
.page[data-pagina="desova"] .desova-quadro__vazio { margin:0; padding:8px 4px; color:var(--desova-tinta-3); }
.page[data-pagina="desova"] .desova-quadro__ver-mais { padding:4px 2px; font-weight:500; }
.page[data-pagina="desova"] .desova-cartao {
  display:flex; flex-direction:column; gap:6px; padding:10px 12px; background:#fff; border:1px solid var(--desova-fio);
  cursor:pointer; font-size:var(--fonte-corpo);
}
.page[data-pagina="desova"] .desova-cartao[hidden] { display:none; }
.page[data-pagina="desova"] .desova-cartao:hover { border-color:var(--desova-fio-2); }
.page[data-pagina="desova"] .desova-cartao--aberto { border-color:var(--desova-acao); box-shadow:inset 0 0 0 1px var(--desova-acao); }
.page[data-pagina="desova"] .desova-cartao--encerrado { color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-cartao__topo { display:flex; justify-content:space-between; align-items:baseline; gap:8px; }
.page[data-pagina="desova"] .desova-cartao__quantidade { color:var(--desova-tinta-2); font-size:var(--fonte-corpo); text-align:right; }
.page[data-pagina="desova"] .desova-cartao__container { font-weight:500; } /* título do cartão Por container (#259) */
.page[data-pagina="desova"] .desova-cartao__item { min-width:0; font-size:var(--fonte-corpo); }
.page[data-pagina="desova"] .desova-cartao__meta { display:flex; justify-content:space-between; gap:8px; font-size:var(--fonte-corpo); color:var(--desova-tinta-2); font-variant-numeric:tabular-nums; }
.page[data-pagina="desova"] .desova-cartao__meta .desova-lista__freetime--vencido { color:var(--desova-vermelho); }
.page[data-pagina="desova"] .desova-cartao__meta .desova-lista__freetime--vence { color:var(--desova-laranja); }
.page[data-pagina="desova"] .desova-cartao__meta .desova-cartao__previsto--vencido { color:var(--desova-laranja); font-weight:500; } /* "A caminho" com a ETA passada (2a, #259): pendência, nunca marrom */
.page[data-pagina="desova"] .desova-cartao__botoes { display:flex; flex-wrap:wrap; gap:6px; }
.page[data-pagina="desova"] .desova-cartao__botoes .btn { max-width:100%; white-space:normal; text-align:left; } /* coluna estreita: o verbo quebra, não vaza */
/* Editor em linha (o botão azul): fundo azul-claro, na linha-filha da grade
   (logo abaixo do processo) ou dentro do cartão. */
.page[data-pagina="desova"] .grade-tabela td.desova-editor-da-grade {
  height:auto; padding:12px 16px; background:var(--desova-acao-clara); border-bottom:1px solid var(--desova-acao); white-space:normal;
}
.page[data-pagina="desova"] .desova-editor-da-grade .desova-editor { position:sticky; left:16px; max-width:1100px; }
.page[data-pagina="desova"] .desova-editor { display:flex; flex-wrap:wrap; align-items:flex-end; gap:12px 24px; margin:0; cursor:auto; }
.page[data-pagina="desova"] .desova-cartao .desova-editor { flex-direction:column; align-items:stretch; gap:10px; margin:2px -12px -10px; padding:10px 12px; background:var(--desova-acao-clara); }
.page[data-pagina="desova"] .desova-editor__campos { display:flex; flex-wrap:wrap; align-items:flex-end; gap:12px 20px; }
.page[data-pagina="desova"] .desova-editor__campo { display:flex; flex-direction:column; gap:4px; margin:0; font-size:var(--fonte-pequena); color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-editor__campo[hidden] { display:none; }
.page[data-pagina="desova"] .desova-editor [aria-invalid="true"] { border-color:var(--desova-tinta); }
.page[data-pagina="desova"] .desova-editor__containers { display:flex; flex-wrap:wrap; align-items:center; gap:4px 14px; margin:0; padding:0; border:0; min-width:0; }
.page[data-pagina="desova"] .desova-editor__containers legend { width:100%; margin:0 0 4px; padding:0; float:none; font-size:var(--fonte-pequena); color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-editor__marca { display:inline-flex; align-items:center; gap:6px; margin:0; font-size:var(--fonte-corpo); color:var(--desova-tinta); cursor:pointer; }
/* "Devolução do vazio no mesmo dia" é outra pergunta, não mais um container: filete fino a separa da lista. */
.page[data-pagina="desova"] .desova-editor__containers + .desova-editor__marca { padding-left:20px; border-left:1px solid var(--desova-fio-2); }
.page[data-pagina="desova"] .desova-editor__recusa { flex-basis:100%; order:3; margin:0; color:var(--desova-tinta); font-weight:500; }
.page[data-pagina="desova"] .desova-editor__recusa[hidden] { display:none; }
.page[data-pagina="desova"] .desova-editor__botoes { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.page[data-pagina="desova"] .desova-editor__pergunta { font-weight:500; }
/* O processo que acabou de mudar de faixa/coluna: 2 s de realce. */
.page[data-pagina="desova"] .grade-tabela tr.desova-realce td,
.page[data-pagina="desova"] .desova-cartao.desova-realce { background:var(--desova-acao-clara); }
@media (prefers-reduced-motion:no-preference) {
  .page[data-pagina="desova"] .grade-tabela tr.grade-linha td,
  .page[data-pagina="desova"] .desova-cartao { transition:background-color .4s ease-out; }
}
/* Aviso "… · Desfazer": claro (fundo branco, filete preto), nunca escuro. */
.page[data-pagina="desova"] .desova-toast {
  position:fixed; left:50%; bottom:24px; z-index:1060; transform:translateX(-50%); display:flex; align-items:center; gap:8px;
  max-width:calc(100vw - 32px); padding:10px 16px; background:#fff; color:var(--desova-tinta);
  border:1px solid var(--desova-fio-forte); box-shadow:0 4px 16px rgba(22,22,22,.12); font-size:var(--fonte-corpo);
}
.page[data-pagina="desova"] .desova-toast[hidden], .page[data-pagina="desova"] .desova-toast [hidden] { display:none; }
.page[data-pagina="desova"] .desova-toast__separador { color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-toast button {
  padding:0; border:0; background:none; color:var(--desova-acao); font:inherit; font-weight:500; text-decoration:underline;
}
/* Painel do processo (decisão 15): 640 px, filete preto, sem rolagem lateral. */
.page[data-pagina="desova"] .desova-painel {
  --bs-offcanvas-width:min(640px, 100vw); border-left:1px solid var(--desova-fio-forte) !important;
  box-shadow:-8px 0 24px rgba(22,22,22,.08); font-family:var(--desova-fonte); color:var(--desova-tinta);
}
.page[data-pagina="desova"] .desova-painel .offcanvas-header { padding:16px 20px 10px; border-bottom:2px solid var(--desova-fio-forte); }
.page[data-pagina="desova"] .desova-painel .offcanvas-title { margin:0; font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-.02em; }
.page[data-pagina="desova"] .desova-painel__sub { margin-top:2px; font-size:var(--fonte-corpo); color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-painel .offcanvas-body { padding:0 20px 24px; overflow-x:hidden; }
.page[data-pagina="desova"] .desova-painel .desova-regua {
  display:flex; gap:0; margin:14px 0 4px; border:1px solid var(--desova-fio);
}
.page[data-pagina="desova"] .desova-painel .desova-regua__passo {
  flex:1; margin:0; padding:6px 10px; border:0; border-right:1px solid var(--desova-fio); font-size:var(--fonte-corpo); font-weight:400; color:var(--desova-tinta-3);
}
.page[data-pagina="desova"] .desova-painel .desova-regua__passo:last-child { border-right:0; }
.page[data-pagina="desova"] .desova-painel .desova-regua__passo--feito { color:var(--desova-tinta); }
.page[data-pagina="desova"] .desova-painel .desova-regua__passo--agora { background:var(--desova-acao-clara); color:var(--desova-acao); font-weight:500; }
.page[data-pagina="desova"] .desova-painel__secao { padding:14px 0; border-bottom:1px solid var(--desova-fio); }
.page[data-pagina="desova"] .desova-painel__secao-titulo { margin:0 0 10px; font-size:var(--fonte-destaque); font-weight:500; }
.page[data-pagina="desova"] .desova-painel__campos { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:10px 16px; }
.page[data-pagina="desova"] .desova-painel__campo { display:flex; flex-direction:column; gap:4px; margin:0; min-width:0; font-size:var(--fonte-pequena); color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-painel__campo--largo { grid-column:1 / -1; }
.page[data-pagina="desova"] .desova-painel__botoes { display:flex; flex-wrap:wrap; align-items:flex-end; gap:8px; margin-top:10px; }
.page[data-pagina="desova"] .desova-painel__tabela { width:100%; table-layout:fixed; border-collapse:collapse; font-size:var(--fonte-corpo); }
.page[data-pagina="desova"] .desova-painel__tabela th {
  padding:4px 4px 6px; border-bottom:1px solid var(--desova-fio-forte); font-size:var(--fonte-rotulo); font-weight:500;
  letter-spacing:.08em; text-transform:uppercase; color:var(--desova-tinta-2); text-align:left;
}
.page[data-pagina="desova"] .desova-painel__tabela th:first-child { width:38%; }
.page[data-pagina="desova"] .desova-painel__tabela td { padding:4px; border-bottom:1px solid var(--desova-fio); vertical-align:top; }
.page[data-pagina="desova"] .desova-painel__numero { padding:0; border:0; background:none; font:inherit; font-weight:500; color:var(--desova-tinta); letter-spacing:.02em; text-decoration:underline; text-decoration-color:var(--desova-fio-2); text-underline-offset:3px; }
.page[data-pagina="desova"] .desova-painel__numero:hover { color:var(--desova-acao); }
.page[data-pagina="desova"] .desova-painel__numero-aviso { margin-left:6px; font-size:var(--fonte-pequena); font-weight:500; color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-painel__agendada { display:block; margin-top:2px; font-size:var(--fonte-pequena); font-style:italic; color:var(--desova-tinta-2); } /* a Devolução vazia diz a agendada (R3), como a célula da lista */
.page[data-pagina="desova"] .desova-painel__item { display:block; min-width:0; font-size:var(--fonte-pequena); }
.page[data-pagina="desova"] .desova-painel__item .desova-lista__linha-do-item { display:block; }
.page[data-pagina="desova"] .desova-painel__nf { margin:0 0 10px; }
.page[data-pagina="desova"] .desova-painel__nf .desova-lista__linha-do-item { display:inline; }
.page[data-pagina="desova"] .desova-painel__texto { margin:0 0 10px; color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-painel__nova-nf { display:flex; flex-wrap:wrap; align-items:flex-end; gap:8px; }
.page[data-pagina="desova"] .desova-painel__lotes { margin-top:10px; }
.page[data-pagina="desova"] .desova-painel__lotes > summary { list-style:none; width:max-content; margin-bottom:10px; }
.page[data-pagina="desova"] .desova-painel__lotes > summary::-webkit-details-marker { display:none; }
/* Histórico (dono, 28/09): recolhido no botão; aberto, Quando | Quem | O que foi feito. */
.page[data-pagina="desova"] .desova-historico { width:100%; margin-top:10px; border-collapse:collapse; font-size:var(--fonte-corpo); }
.page[data-pagina="desova"] .desova-historico[hidden] { display:none; }
.page[data-pagina="desova"] .desova-historico th {
  padding:4px 10px 4px 0; border-bottom:1px solid var(--desova-fio-forte); color:var(--desova-tinta-2);
  font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.08em; text-transform:uppercase; text-align:left; white-space:nowrap;
}
.page[data-pagina="desova"] .desova-historico td { padding:6px 10px 6px 0; border-bottom:1px solid var(--desova-fio); vertical-align:top; overflow-wrap:anywhere; }
.page[data-pagina="desova"] .desova-historico__quando { white-space:nowrap; color:var(--desova-tinta-2); font-variant-numeric:tabular-nums; }
.page[data-pagina="desova"] .desova-historico__detalhe { display:block; margin-top:2px; font-size:var(--fonte-pequena); color:var(--desova-tinta-2); }
.page[data-pagina="desova"] .desova-painel .desova-lotes { table-layout:fixed; }
.page[data-pagina="desova"] .desova-painel .desova-lotes td { overflow-wrap:anywhere; }
/* Faixa só na linha urgente (freetime vencido ou vencendo, marca do serviço). */
[data-pagina="desova"] .desova-linha--urgente td:first-child { box-shadow: inset 3px 0 0 var(--negative-text); }
[data-pagina="desova"] .desova-freetime--vencido { color: var(--negative-text); font-weight: 500; }
[data-pagina="desova"] .desova-freetime--vence { color: #FF7B00; font-weight: 500; } /* --figure-attention: sem marrom de alerta */

/* Desova — folha de etiquetas (bi/templates/bi/desova_etiquetas.html).
   Zebra ZD230, papel 100×100 mm. `@page` NOMEADA: a anônima é da proposta do
   CRM. O logo da casa é cinza-claro (feito para fundo escuro): na térmica ele
   sumiria, então vai a preto pelo filtro. Nada aqui vale fora de
   `.etiquetas-desova`. */
@page etiqueta-desova { size: 100mm 100mm; margin: 0; }
body.etiquetas-desova { margin: 0; background: #fff; color: #000; font-family: Arial, Helvetica, sans-serif; }
.etiquetas-desova .etiqueta {
  page: etiqueta-desova; box-sizing: border-box; width: 100mm; height: 100mm; padding: 5mm;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.5mm;
  text-align: center; overflow: hidden; break-after: page;
}
.etiquetas-desova .etiqueta:last-of-type { break-after: auto; }
.etiquetas-desova .etiqueta__marca { display: flex; align-items: center; gap: 2mm; }
.etiquetas-desova .etiqueta__logo { height: 10mm; filter: brightness(0); }
.etiquetas-desova .etiqueta__marca-texto { font-size: 8mm; font-weight: 700; letter-spacing: .4mm; }
.etiquetas-desova .etiqueta__empresa { margin: 0; font-size: 4.6mm; font-weight: 700; }
.etiquetas-desova .etiqueta__contato { margin: 0; font-size: 3.4mm; line-height: 1.25; }
.etiquetas-desova .etiqueta__barras { display: block; margin: 2mm auto 0; }
.etiquetas-desova .etiqueta__codigo { margin: 0; font: 700 4.6mm/1.1 'Courier New', monospace; letter-spacing: .3mm; white-space: pre; }
.etiquetas-desova .etiqueta__detalhe { margin: 0; font-size: 3.2mm; line-height: 1.2; }
/* #504: o container fica fora do fluxo, na faixa livre de baixo (o conteúdo
   centralizado termina em ~81 mm): nada do que já existe se move. */
.etiquetas-desova .etiqueta { position: relative; }
.etiquetas-desova .etiqueta__container { position: absolute; left: 0; right: 0; bottom: 5mm; margin: 0;
  font-size: 3.4mm; font-weight: 700; line-height: 1.2; letter-spacing: .2mm; }
.etiquetas-desova__aviso, .etiquetas-desova__erro { font-size: 14px; padding: 12px; margin: 0; }
@media screen { .etiquetas-desova .etiqueta { border: 1px dashed #dee2e6; margin: 8px auto; } }
@media print { .etiquetas-desova__aviso { display: none; } }

/* ==========================================================================
   VENCIMENTOS — grade + ficha (#155). Um offcanvas só: criar, editar,
   renovar, mudar estado e excluir moram no mesmo `#canvas-vencimento`.
   ========================================================================== */
[data-pagina="vencimentos"] .venc-canvas { --bs-offcanvas-width: min(34rem, 95vw); }

/* Situação, na borda esquerda da linha — o mesmo sinal que a Desova usa para
   "urgente" (`.desova-linha--urgente`). O badge da própria célula já diz a
   cor; isto só reforça na varredura da coluna. */
[data-pagina="vencimentos"] .venc-linha--vencida td:first-child { box-shadow: inset 3px 0 0 var(--negative-text); }
[data-pagina="vencimentos"] .venc-linha--a_vencer td:first-child { box-shadow: inset 3px 0 0 #FF7B00; }

/* Badge "A vencer" — a etiqueta `atencao` do design system (#229): fundo
   laranja vivo, texto PRETO (6,97:1). Era texto laranja sobre branco (2,6:1,
   reprovado), que é o que a regra de um laranja só proíbe. */
[data-pagina="vencimentos"] .venc-badge--a-vencer {
  background: var(--ds-atencao);
  color: #161616;
  border: 0;
  border-radius: 0;
  font-weight: 500;
}

[data-pagina="vencimentos"] .venc-erro {
  padding: 8px 12px; margin: 0 0 16px; font-size: var(--fonte-corpo);
  border: 1px solid var(--negative-text); background: var(--negative-subtle); color: var(--negative-text);
}
[data-pagina="vencimentos"] .venc-arquivo-atual { margin: 0 0 8px; font-size: var(--fonte-corpo); color: var(--ink-2); }
[data-pagina="vencimentos"] .venc-renovar-bloco { padding: 12px; margin: 8px 0 16px; border: 1px solid var(--line-2); background: var(--surf-2); }

[data-pagina="vencimentos"] .venc-renovacoes,
[data-pagina="vencimentos"] .venc-historico { margin-top: 16px; }
[data-pagina="vencimentos"] .venc-historico summary { cursor: pointer; font-size: var(--fonte-corpo); font-weight: 500; }

[data-pagina="vencimentos"] .venc-renovacao,
[data-pagina="vencimentos"] .venc-evento { padding: 8px 0; border-bottom: 1px solid var(--line-2); font-size: var(--fonte-corpo); }
[data-pagina="vencimentos"] .venc-renovacao:last-child,
[data-pagina="vencimentos"] .venc-evento:last-child { border-bottom: 0; }
[data-pagina="vencimentos"] .venc-renovacao__cab,
[data-pagina="vencimentos"] .venc-evento__cab { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
[data-pagina="vencimentos"] .venc-evento__mudancas { margin: 4px 0 0; padding-left: 16px; color: var(--ink-2); }

[data-pagina="vencimentos"] .venc-confirmar-exclusao { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: var(--fonte-corpo); }

/* O aviso de desfazer entra direto em `document.body` (sobrevive ao offcanvas
   fechar), então fica fora do escopo `[data-pagina]` — o prefixo `venc-` já
   basta para não vazar em outra tela. */
.venc-desfazer {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 1080;
  display: flex; align-items: center; gap: 8px; padding: 10px 16px;
  background: #fff; color: #212529; border: 1px solid #dee2e6; border-radius: 0;
  font-size: var(--fonte-corpo); box-shadow: var(--bs-box-shadow);
}
.venc-desfazer .btn-link { text-decoration: underline; }

/* === PRODUÇÃO DE BOBINAS (/fabrica/producao-bobinas/) — Four Group Design System ===
   Spec docs/superpowers/specs/2026-09-28-producao-bobinas-design.md. A tabela é a grade da casa
   (fcdsGrade); botões e campos são os de fábrica (#454). Sem marrom de alerta (dono, 28/09). */
/* A grade não mora num cartão: a folha é branca (mesma regra da desova), senão o
   cinza do shell aparece atrás da tabela, da barra e da paginação. */
.content:has(> .page:is([data-pagina="producao_bobinas"], [data-pagina="analise_producao"])),
.page:is([data-pagina="producao_bobinas"], [data-pagina="analise_producao"]) { background: #fff; }
/* kg (à direita) não encosta no Lote acabado (à esquerda) da coluna seguinte. */
.page[data-pagina="producao_bobinas"] .grade-tabela :is(th, td).text-end { padding-right:1.5rem; }
#topbar .producao-bobinas-topbar { display:inline-flex; align-items:center; gap:var(--gap); }
/* === ANÁLISE DE PRODUÇÃO (/fabrica/analise-producao/, #364) — desenho aprovado em 15/10/2026 ===
   Plano docs/superpowers/plans/2026-10-15-reporte-364.md. Tokens e fonte do bloco acima (Four Group
   Design System): cartão 0px e filete 1px, sem sombra; a cor de dado é o azul fundo do DS (--chart-1
   #103F6A) e um degrau claro dele; verde/vermelho só no Δ dos cartões (direção). A grade é a da casa. */
.page[data-pagina="analise_producao"] { --ap-nua:#103F6A; --ap-insumos:#8DAACB; --ap-neutro:#F1F2F4; }
/* Janela baixa (1366×657): a folha rola e a grade guarda 24rem; janela alta: a grade fica com a sobra. */
.content--altura-cheia > .page[data-pagina="analise_producao"] { overflow-y:auto; }
.ap-indicadores { flex:0 0 auto; position:relative; padding-top:12px; }
.ap-cartoes { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:1px;
  background:var(--ds-filete); border:1px solid var(--ds-filete); }
/* #508: o cartão não é botão; o número abre a sua conta (.conta-calc, biUtils.numeroComConta). */
.ap-cartao { display:grid; align-content:start; gap:2px; min-width:0; padding:10px 16px 8px; border:0; border-radius:0;
  background:var(--ds-superficie); color:var(--ds-tinta); text-align:left; }
.ap-cartao__linhas { display:grid; gap:2px; font-size:var(--fonte-corpo); line-height:20px; }
.ap-cartao__linha { display:flex; justify-content:space-between; align-items:baseline; gap:12px; color:var(--ds-tinta-2); }
.ap-cartao__linha-valor { color:var(--ds-tinta); font-weight:500; white-space:nowrap; }
.ap-dica { margin-left:6px; font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }
.ap-cartao__rotulo, .ap-bloco__titulo { font-size:var(--fonte-rotulo); font-weight:500; text-transform:uppercase;
  letter-spacing:.04em; color:var(--ds-tinta-2); }
.ap-cartao__valor { font-size:var(--fonte-heroi); line-height:40px; font-weight:500; letter-spacing:-.02em; }
.ap-cartao__pe { display:flex; align-items:flex-end; justify-content:space-between; gap:8px; min-height:28px; }
.ap-delta__pct { margin-left:6px; font-weight:400; color:var(--ds-tinta-2); }
.ap-cartao__linha-valor.ap-delta--pior { color:var(--negative-text); }
.ap-cartao__linha-valor.ap-delta--melhor { color:var(--positive-text); }
.ap-spark { flex:none; color:var(--ap-nua); }
.ap-regua { margin:6px 0 10px; font-size:var(--fonte-corpo); color:var(--ds-tinta-2); }
.ap-link { padding:0; border:0; background:none; font:inherit; color:var(--ds-acao); text-decoration:underline; }
.ap-link:hover { color:var(--ds-acao-hover); }
.ap-vazio, .ap-nota { margin:8px 0; font-size:var(--fonte-corpo); color:var(--ds-tinta-2); }
.ap-blocos { display:grid; grid-template-columns:minmax(0, 1fr); gap:24px; }
.ap-bloco { min-width:0; }
.ap-bloco__titulo { margin:0 0 6px; }
/* Ponte: subtotal em negrito sob um filete preto; degrau como barra divergente em torno do zero. */
.ap-ponte { list-style:none; margin:0; padding:0; }
.ap-ponte__passo { display:grid; grid-template-columns:minmax(0, 15rem) minmax(4rem, 1fr) auto; align-items:center;
  gap:12px; padding:1px 4px; color:var(--ds-tinta); font-size:var(--fonte-corpo); line-height:20px; }
.ap-ponte__rotulo { min-width:0; overflow-wrap:anywhere; }
.ap-ponte__trilho { position:relative; height:10px; }
.ap-ponte__trilho::before { content:''; position:absolute; left:50%; top:-5px; bottom:-5px; border-left:1px solid var(--ds-filete); }
.ap-ponte__barra { position:absolute; top:0; height:100%; background:var(--ap-nua); }
.ap-ponte__barra--mais { left:50%; }
.ap-ponte__barra--menos { right:50%; }
.ap-ponte__valor { text-align:right; }
.ap-ponte__passo--total { font-weight:500; border-top:1px solid var(--ds-tinta); }
.ap-ponte__passo--total:first-child { border-top:0; }
.ap-ponte__passo--total .conta-aberta { font-weight:400; }
/* Custo por KG produzido, mês a mês: o eixo começa em zero (DS); tracejado = custo com o aço da ficha. */
.ap-meses { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0, 1fr); gap:12px; height:176px; padding-top:18px; }
.ap-meses__coluna { display:flex; flex-direction:column; min-width:0; min-height:0; padding:0; border:0; background:none; color:inherit; }
.ap-meses__area { position:relative; flex:1 1 auto; min-height:0; display:flex; flex-direction:column;
  justify-content:flex-end; align-items:center; border-bottom:1px solid var(--ds-tinta); }
.ap-meses__pilha { position:relative; display:flex; flex-direction:column; width:60%; max-width:56px; }
.ap-meses__valor { position:absolute; bottom:100%; left:50%; transform:translateX(-50%); padding-bottom:2px;
  font-size:var(--fonte-pequena); white-space:nowrap; }
.ap-meses__insumos { flex:none; background:var(--ap-insumos); }
.ap-meses__nua { flex:1 1 auto; background:var(--ap-nua); }
.ap-meses__estrutura { position:absolute; left:12%; right:12%; border-top:2px dashed var(--ds-tinta); }
.ap-meses__nada { margin-bottom:8px; font-size:var(--fonte-pequena); color:var(--ds-tinta-2); text-align:center; }
.ap-meses__rotulo { padding-top:4px; font-size:var(--fonte-pequena); color:var(--ds-tinta-2); }
.ap-meses__obs { min-height:16px; font-size:var(--fonte-pequena); line-height:16px; color:var(--ds-tinta-2); }
.ap-meses__coluna:hover .ap-meses__rotulo, .ap-meses__coluna--ativa .ap-meses__rotulo { color:var(--ds-acao); font-weight:500; }
.ap-legenda { list-style:none; display:flex; flex-wrap:wrap; gap:4px 16px; margin:6px 0 0; padding:0; font-size:var(--fonte-pequena); color:var(--ds-tinta-2); }
.ap-legenda li { display:flex; align-items:center; gap:6px; }
.ap-legenda__marca { display:inline-block; width:10px; height:10px; }
.ap-legenda__marca--estrutura { width:14px; height:0; border-top:2px dashed var(--ds-tinta); }
/* Embaixo: abas, a grade e o pane da OP lado a lado (padrão do #312, Representantes). */
.ap-base { display:flex; flex-direction:column; margin-top:14px; }
.ap-abas { display:flex; border-bottom:1px solid var(--ds-filete); }
.ap-aba { padding:8px 14px; border:0; border-bottom:2px solid transparent; background:none; color:var(--ds-tinta-2); font-size:var(--fonte-corpo); }
.ap-aba:hover { color:var(--ds-tinta); }
.ap-aba[aria-selected="true"] { border-bottom-color:var(--ds-acao); color:var(--ds-acao); font-weight:500; }
.ap-aba__n { margin-left:4px; font-size:var(--fonte-pequena); color:var(--ds-tinta-2); }
.ap-paines { flex:1 1 0; min-height:0; display:grid; grid-template-columns:minmax(0, 1fr); }
.ap-paines--com-op { grid-template-columns:minmax(0, 1fr) minmax(34rem, 46%); }
.ap-pane { min-width:0; min-height:0; }
/* A grade da casa é uma cadeia flex que ocupa a altura do pai e rola por dentro. */
.ap-pane--grade { display:flex; flex-direction:column; }
.ap-pane--op { padding:12px 0 12px 20px; border-left:1px solid var(--ds-filete); overflow:auto; }
.ap-pane--grade .grade-tabela :is(th, td).text-end { padding-right:1.25rem; }
.ap-op__topo { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.ap-op__titulo { margin:0; font-size:var(--fonte-titulo); font-weight:500; line-height:1.2; }
.ap-op__sub { margin:2px 0 0; font-size:var(--fonte-corpo); color:var(--ds-tinta-2); }
.ap-op__numeros { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px 16px; margin:12px 0 16px; }
.ap-op__numeros dt { font-size:var(--fonte-pequena); font-weight:400; color:var(--ds-tinta-2); }
.ap-op__numeros dd { margin:0; font-size:var(--fonte-destaque); font-weight:500; }
.ap-mini { width:100%; border-collapse:collapse; font-size:var(--fonte-corpo); }
.ap-mini th { padding:4px 8px; border-bottom:1px solid var(--ds-tinta); font-size:var(--fonte-pequena); font-weight:500; color:var(--ds-tinta-2); white-space:nowrap; }
.ap-mini td { padding:4px 8px; border-bottom:1px solid var(--ds-filete); }
.ap-mini td.text-end { white-space:nowrap; }
.ap-mini__item { max-width:14rem; }
/* OP fora da conta: pílula neutra com ponto (pendência não é alerta). */
.ap-fora-da-conta { display:inline-flex; align-items:center; gap:6px; padding:0 8px; border-radius:999px;
  background:var(--ap-neutro); color:var(--ds-tinta); white-space:nowrap; }
.ap-fora-da-conta::before { content:''; width:6px; height:6px; border-radius:50%; background:#9AA2AC; }
@media (min-width: 1200px) {
  .ap-cartoes { grid-template-columns:repeat(4, minmax(0, 1fr)); }
  .ap-blocos { grid-template-columns:minmax(0, 5fr) minmax(0, 7fr); }
}
@media (max-width: 991.98px) {
  .ap-paines--com-op { grid-template-columns:minmax(0, 1fr); }
  .ap-paines--com-op .ap-pane--grade { display:none; }
  .ap-pane--op { padding-left:0; border-left:0; }
}
/* Painel e modal: corpo do DS a 14px (--text-body-sm), 1.55, tracking 0; nada abaixo
   de 14px fora das legendas (12px). */
.producao-bobinas-painel { --bs-offcanvas-width: min(40rem, 96vw); }
.producao-bobinas-painel .offcanvas-header { align-items:flex-start; }
.producao-bobinas-painel .offcanvas-title { font-size:var(--fonte-titulo); font-weight:500; line-height:1.2; margin:0; }
.producao-bobinas-painel__cabecalho { flex:1 1 auto; min-width:0; display:flex; align-items:baseline;
  justify-content:space-between; gap:.25rem 1rem; margin-right:1rem; }
.producao-bobinas-painel__estado { flex:0 0 auto; white-space:nowrap; color:var(--ds-tinta); font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.08em; text-transform:uppercase; }
.producao-bobinas-painel .offcanvas-body,
#pb-modal .modal-body { font-size:var(--fonte-corpo); line-height:1.5; letter-spacing:0; }
.producao-bobinas-painel .offcanvas-body p { margin:0 0 .5rem; }
.producao-bobinas-painel__formulario { display:grid; gap:16px; }
.producao-bobinas-painel__formulario > .btn { justify-self:start; }
.producao-bobinas-painel__campo { display:flex; flex-direction:column; gap:4px; }
.producao-bobinas-painel__campo .form-label { margin:0; font-size:var(--fonte-corpo); font-weight:500; }
.producao-bobinas-painel .offcanvas-body p.producao-bobinas-painel__nota { color:var(--ds-tinta-2); font-size:var(--fonte-corpo); margin:0; }
.producao-bobinas-painel .offcanvas-body p.producao-bobinas-painel__erro,
.producao-bobinas-painel__erro { color:var(--ds-perigo); margin:var(--gap) 0; }
.producao-bobinas-painel__campo .producao-bobinas-painel__erro { margin:0; }
.producao-bobinas-painel__passos { list-style:none; padding:0; margin:var(--gap) 0; font-size:var(--fonte-corpo); line-height:1.5; }
.producao-bobinas-painel__passo { display:flex; align-items:baseline; gap:.5rem; color:var(--ds-tinta-2); }
.producao-bobinas-painel__passo + .producao-bobinas-painel__passo { margin-top:.25rem; }
.producao-bobinas-painel__passo > i { width:1rem; flex:0 0 1rem; text-align:center; font-size:12px; }
.producao-bobinas-painel__passo--feito { color:var(--ds-tinta); }
.producao-bobinas-painel__passo--feito > i { color:var(--positive-text); }
/* Apontada: grupo da etiqueta, depois a linha de ações, separados por 24px. */
.producao-bobinas-painel__grupo { margin:0 0 24px; }
.producao-bobinas-painel__grupo-titulo { margin:0 0 .5rem; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ds-tinta-2); line-height:1.5; }
/* Blocos PRODUÇÃO / CONSUMO / MOVIMENTOS (dono, 28/09): textos e números do servidor,
   números tabulares à direita; fundo branco, só o filete como divisão. */
.producao-bobinas-painel__linhas { display:grid; grid-template-columns:max-content 1fr auto; gap:.25rem 1rem; align-items:baseline; }
.producao-bobinas-painel__rotulo { color:var(--ds-tinta-2); }
.producao-bobinas-painel__numero { text-align:right; font-variant-numeric:tabular-nums; }
.producao-bobinas-painel__largo { grid-column:2 / -1; }
.producao-bobinas-painel__inteiro { grid-column:1 / -1; }
.producao-bobinas-painel__tabela { width:100%; border-collapse:collapse; font-variant-numeric:tabular-nums; }
.producao-bobinas-painel__tabela :is(th, td) { padding:.25rem .5rem; border-bottom:1px solid var(--ds-filete); vertical-align:baseline; }
.producao-bobinas-painel__tabela :is(th, td):first-child { padding-left:0; }
.producao-bobinas-painel__tabela :is(th, td):last-child { padding-right:0; }
.producao-bobinas-painel__tabela th { font-weight:500; color:var(--ds-tinta-2); white-space:nowrap; }
.producao-bobinas-painel__movimentos { list-style:none; margin:0; padding:0; font-variant-numeric:tabular-nums; }
.producao-bobinas-painel__movimentos li + li { margin-top:.25rem; }
.producao-bobinas-painel__etiqueta { display:flex; align-items:flex-end; gap:.75rem; margin:0; }
.producao-bobinas-painel__etiqueta .form-control { width:5rem; }
/* Lançar/reapontar (layout do dono, 28/09): passo 1 com os produtos em botões grandes; depois
   BOBINA-MÃE (a grade de lotes da casa, que recolhe para a linha do escolhido + Trocar) e FILHA,
   e UMA caixa de resumo logo acima do Lançar (números do servidor; não cabe = --ds-perigo).
   Durante o lançamento o painel alarga para a grade caber sem rolagem lateral. */
.producao-bobinas-painel--lancamento { --bs-offcanvas-width: min(56rem, 96vw); }
.producao-bobinas-painel__bloco { display:grid; gap:12px; }
.producao-bobinas-painel__bloco > .producao-bobinas-painel__grupo-titulo { margin:0; }
.producao-bobinas-painel .offcanvas-body p.producao-bobinas-painel__produto-escolhido { margin:0; font-weight:500; }
.producao-bobinas-painel .offcanvas-body p.producao-bobinas-painel__valor { margin:0; font-weight:500; }
.producao-bobinas-painel__motivo { display:block; color:var(--ds-tinta-2); font-size:var(--fonte-pequena); }
#pb-lotes-tabela tr.producao-bobinas-painel__lote--recusa td { color:var(--ds-tinta-2); cursor:not-allowed; }
.producao-bobinas-painel__escolhido { margin:0; font-variant-numeric:tabular-nums; }
.producao-bobinas-painel__escolhido th { font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; }
.producao-bobinas-painel__escolhido tbody td { background:var(--ds-acao-tinta); border-top:2px solid var(--ds-acao);
  border-bottom:2px solid var(--ds-acao); vertical-align:middle; }
.producao-bobinas-painel .offcanvas-body .producao-bobinas-painel__mae p { margin:.5rem 0 0; }
.producao-bobinas-painel__operador { display:flex; align-items:center; gap:.75rem; }
.producao-bobinas-painel__operador .form-select { width:auto; min-width:12rem; }
.producao-bobinas-painel__data-da-producao { display:flex; align-items:center; gap:.75rem; }
.producao-bobinas-painel__data-da-producao .form-control { width:auto; }
.producao-bobinas-painel__resumo { padding:.75rem 1rem; border:1px solid var(--ds-filete); border-radius:var(--bs-border-radius-sm);
  color:var(--ds-tinta); font-variant-numeric:tabular-nums; }
.producao-bobinas-painel__resumo strong { font-weight:500; }
.producao-bobinas-painel__resumo--perigo { color:var(--ds-perigo); border-color:var(--ds-perigo); }
.producao-bobinas-painel__resumo--acaba { font-weight:500; border-color:var(--ds-tinta); }
/* Peso mudou e o resumo do número novo ainda não chegou: esmaecida (aria-busy), Lançar travado. */
.producao-bobinas-painel__resumo--atualizando { opacity:.5; }
.producao-bobinas-painel__acoes { display:flex; flex-wrap:wrap; align-items:center; gap:.75rem; padding-top:16px;
  border-top:1px solid var(--ds-filete); }
.producao-bobinas-painel .offcanvas-body .producao-bobinas-painel__acoes p { margin:0; }
/* #256: "Aguardando o Sênior… N s" dentro do logo-loader, logo abaixo do ícone (que é absoluto,
   altura min(46%, 150px), centrado); no bloco de passos fica no fluxo. */
.producao-bobinas-painel .logo-loader > .producao-bobinas-painel__espera { position:absolute; left:0; right:0;
  top:calc(50% + min(23%, 75px) + 12px); text-align:center; }
.producao-bobinas-modal__bloqueios { color:var(--ds-perigo); }

/* === Etiqueta 100×100 da Produção de Bobinas (static/js/etiquetas.js) ===
   Zebra ZD230 (203 dpi), papel 100×100 mm. Layout aprovado pelo dono em
   28/09/2026: três faixas (empresa pequena; designação em destaque; massa e
   OP com rótulo à esquerda e valor à direita), código de barras na largura
   útil com o lote UMA vez embaixo, e o rodapé da impressão. Tudo alinhado à
   esquerda, só preto no branco, fonte ≥ 8 pt (2,9 mm). Os 5 mm de margem são
   a zona branca do Code 128. O logo da casa é claro (feito para fundo escuro):
   vai a preto pelo filtro. A folha não usa o design system: é térmica. */
@page etiqueta-100 { size: 100mm 100mm; margin: 0; }
.folha-de-etiquetas { margin: 0; background: #fff; color: #000; font-family: Arial, Helvetica, sans-serif; }
.folha-de-etiquetas .etiqueta {
  page: etiqueta-100; box-sizing: border-box; width: 100mm; height: 100mm; padding: 5mm;
  display: flex; flex-direction: column; gap: 1.6mm; overflow: hidden; break-after: page;
  font-size: 3.2mm; line-height: 1.2;
}
.folha-de-etiquetas .etiqueta:last-of-type { break-after: auto; }
.folha-de-etiquetas .etiqueta p { margin: 0; }
.folha-de-etiquetas .etiqueta__cabecalho { display: flex; align-items: flex-start; gap: 2.5mm;
  font-size: 2.9mm; padding-bottom: 1.6mm; border-bottom: .25mm solid #000; }
.folha-de-etiquetas .etiqueta__logo { height: 7mm; flex: none; filter: brightness(0); }
.folha-de-etiquetas .etiqueta__razao-social { font-weight: 700; }
.folha-de-etiquetas .etiqueta__produto { padding-bottom: 1.6mm; border-bottom: .25mm solid #000; }
.folha-de-etiquetas .etiqueta__designacao { font-size: 6.5mm; font-weight: 700; line-height: 1.1; }
.folha-de-etiquetas .etiqueta__pesagem { display: grid; grid-template-columns: auto 1fr; column-gap: 4mm;
  align-items: baseline; margin: 0; font-size: 4mm; }
.folha-de-etiquetas .etiqueta__pesagem dd { margin: 0; text-align: right; font-weight: 700; }
.folha-de-etiquetas .etiqueta__pesagem .etiqueta__massa { font-size: 6mm; }
.folha-de-etiquetas .etiqueta__barras { display: block; flex: none; margin-top: auto; }
.folha-de-etiquetas .etiqueta__codigo { font-weight: 700; font-size: 4.2mm; line-height: 1.1; white-space: nowrap; }
.folha-de-etiquetas .etiqueta__impressao { font-size: 2.9mm; text-align: right; }
.folha-de-etiquetas__aviso, .folha-de-etiquetas__erro { font-size: 14px; padding: 12px; margin: 0; }
@media screen { .folha-de-etiquetas .etiqueta { border: 1px dashed #dee2e6; margin: 8px auto; } }
@media print { .folha-de-etiquetas__aviso { display: none; } }

/* ── Painel Comex (#209) ──────────────────────────────────────────────────────
   Pele própria, a mesma do Painel Financeiro e de /despesas/nova/ (tokens
   `--dnv-*` pela lista de seletores da seção DESPESAS — VERSÃO NOVA, sem copiar
   valores): painéis brancos sobre filete de 1px (`gap:1px` num fundo
   `--dnv-rule`), rótulo 10px/600 em caixa alta, número 600 com tracking
   negativo, trilho de 46px no topbar. Não usa nenhuma classe `pfin-`.
   ========================================================================== */
.content:has(> .page[data-pagina="painel_comex"]),
.main:has(> .content > .page[data-pagina="painel_comex"]) { background:#fff; }
.page[data-pagina="painel_comex"] { --pcx-cor-egito: color-mix(in srgb, var(--chart-azul) 40%, var(--dnv-surface)); --pcx-cor-outras: rgba(16,63,106,.28); /* --chart-mono-7 do design system (charts.css não é carregado no app; mesmo padrão do Financeiro) */
  background:var(--dnv-surface); color:var(--dnv-ink); font-family:var(--dnv-sans); }
.pcx-pagina { display:grid; gap:1px; background:var(--dnv-rule); border:1px solid var(--dnv-rule); max-width:100%; min-width:0; }
.pcx-pagina [hidden] { display:none; }
.pcx-k, .pcx-cartao__rotulo, .pcx-etapa__rotulo, .pcx-bloco__cabecalho h2 { margin:0; font-size:var(--fonte-rotulo); letter-spacing:.11em; text-transform:uppercase; color:var(--dnv-ink-3); font-weight:500; }
.pcx-n, .pcx-cartao__valor, .pcx-etapa__valor, .pcx-transit-linha__valor, .pcx-transit-linha__n, .pcx-origem-linha__valor { font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1, "lnum" 1; }
.pcx-pan, .pcx-cartao, .pcx-etapa, .pcx-estado, .pcx-aviso { background:var(--dnv-surface); min-width:0; }
.pcx-pan { padding:18px 20px 16px; display:flex; flex-direction:column; gap:12px; }
.pcx-estado { margin:0; padding:28px 14px; text-align:center; color:var(--dnv-ink-3); font-size:var(--fonte-pequena); }
.pcx-cartoes, .pcx-etapas { display:grid; gap:1px; grid-template-columns:minmax(0, 1fr); min-width:0; background:var(--dnv-rule); }
.pcx-cartao { padding:22px 24px; }
.pcx-etapa { padding:16px 20px; }
.pcx-cartao__rotulo { white-space:nowrap; }
.pcx-cartao__valor, .pcx-etapa__valor { margin-top:8px; font-size:var(--fonte-heroi); line-height:40px; font-weight:500; letter-spacing:-.02em; color:var(--dnv-ink); }
.pcx-cartao__apoio, .pcx-etapa__apoio { margin-top:6px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); }
.pcx-bloco { min-width:0; }
.pcx-bloco__cabecalho { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 16px; }
.pcx-bloco__apoio { margin:0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); line-height:1.5; }
.pcx-bloco__nota { margin-top:0; }
.pcx-barra { display:flex; height:12px; margin-top:12px; background:var(--dnv-surface-3); overflow:hidden; }
.pcx-barra__trecho { display:block; height:100%; flex:0 0 0; }
.pcx-barra__trecho--china { background:var(--chart-azul); }
.pcx-barra__trecho--egito { background:var(--pcx-cor-egito); }
.pcx-barra__trecho--outras { background:var(--pcx-cor-outras); }
.pcx-barra__trecho + .pcx-barra__trecho { border-left:1px solid var(--dnv-surface); }
.pcx-origem-lista { list-style:none; margin:12px 0 0; padding:0; display:grid; gap:4px; }
.pcx-origem-linha { display:flex; align-items:center; gap:8px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); }
.pcx-origem-linha__valor { margin-left:auto; color:var(--dnv-ink); }
.pcx-ponto { display:inline-block; flex:none; width:8px; height:8px; }
.pcx-legenda { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:4px 16px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); }
.pcx-legenda li { display:flex; align-items:center; gap:8px; }
.pcx-aviso { grid-column:1 / -1; display:flex; flex-wrap:wrap; align-items:center; gap:12px; padding:16px 20px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); }
.pcx-esqueleto { height:24px; background:var(--dnv-surface-3); }
.pcx-transit-lista { list-style:none; margin:0; padding:0; display:grid; gap:8px; }
.pcx-transit-linha { display:grid; grid-template-columns:minmax(8rem, 16rem) minmax(0, 1fr) 4rem 5rem; align-items:center; gap:16px; font-size:var(--fonte-corpo); color:var(--dnv-ink); }
.pcx-transit-linha__trilho { display:block; height:12px; background:var(--dnv-surface-3); min-width:0; }
.pcx-transit-linha__barra { display:block; height:100%; }
.pcx-transit-linha__barra--china { background:var(--chart-azul); }
.pcx-transit-linha__barra--egito { background:var(--pcx-cor-egito); }
.pcx-transit-linha__barra--outras { background:var(--pcx-cor-outras); }
.pcx-transit-linha__valor { text-align:right; }
.pcx-transit-linha__n { color:var(--dnv-ink-3); }
.pcx-transit-nota { margin-top:4px; }
.pcx-previsto { color:var(--dnv-ink-3); font-style:italic; }
.pcx-col-texto { max-width:16rem; }
.pcx-ver-todos { margin:8px 0 0; font-size:var(--fonte-pequena); }
@media (max-width: 767.98px) {
  .pcx-transit-linha { grid-template-columns:minmax(0, 1fr) 4rem 5rem; }
  .pcx-transit-linha__trilho { grid-column:1 / -1; grid-row:2; }
}
@media (min-width: 768px) {
  .pcx-cartoes, .pcx-etapas { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .pcx-cartoes { grid-template-columns:repeat(4, minmax(0, 1fr)); }
  .pcx-etapas { grid-template-columns:repeat(4, minmax(0, 1fr)); }
}
/* Fatias 3-4 (#209): custo landed, FOB/t, câmbio, lead time, composição, série, metas e drill.
   Cores da composição e da série são locais (`--pcx-cor-*`): `--chart-mono-*` não carrega no app.
   Nada de marrom/âmbar; acima da meta = `--negative-text`. */
.page[data-pagina="painel_comex"] {
  --pcx-cor-mercadoria: var(--dnv-mark); --pcx-cor-frete: var(--chart-azul);
  --pcx-cor-imposto_importacao: color-mix(in srgb, var(--chart-azul) 80%, var(--dnv-surface));
  --pcx-cor-ipi: color-mix(in srgb, var(--chart-azul) 68%, var(--dnv-surface));
  --pcx-cor-pis: color-mix(in srgb, var(--chart-azul) 57%, var(--dnv-surface));
  --pcx-cor-cofins: color-mix(in srgb, var(--chart-azul) 47%, var(--dnv-surface));
  --pcx-cor-icms: color-mix(in srgb, var(--chart-azul) 38%, var(--dnv-surface));
  --pcx-cor-afrmm: color-mix(in srgb, var(--chart-azul) 30%, var(--dnv-surface));
  --pcx-cor-siscomex: color-mix(in srgb, var(--chart-azul) 22%, var(--dnv-surface));
  --pcx-cor-despesas: #0F766E; /* teal: despesas no Brasil destacam da rampa azul dos tributos */
}
.pcx-cartao__rotulo, .pcx-cartao__valor, .pcx-cartao__apoio { display:block; }
.pcx-cartao--drill { position:relative; }
.pcx-cartao--drill:hover { background:var(--dnv-surface-2); }
/* Botão esticado: o ::after cobre o cartão inteiro; os motivos (botões irmãos) ficam acima dele. */
.pcx-cartao__abrir { display:block; width:100%; padding:0; border:0; background:none; font:inherit; color:inherit; text-align:left; cursor:pointer; }
.pcx-cartao__abrir::after { content:""; position:absolute; inset:0; }
.pcx-cartao__abrir:focus-visible { outline:none; }
.pcx-cartao__abrir:focus-visible::after { outline:2px solid var(--dnv-mark); outline-offset:-2px; }
.pcx-cartao__motivo { position:relative; z-index:1; }
.pcx-cartao--acima .pcx-cartao__valor { color:var(--negative-text); }
/* Sem célula vazia no fim da grade (o fundo da grade é o filete): a última estica. */
@media (min-width: 768px) and (max-width: 1199.98px) { .pcx-cartoes > :last-child:nth-child(odd) { grid-column:span 2; } }
@media (min-width: 1200px) {
  .pcx-cartoes > :last-child:nth-child(4n+3) { grid-column:span 2; }
  .pcx-cartoes > :last-child:nth-child(4n+2) { grid-column:span 3; }
  .pcx-cartoes > :last-child:nth-child(4n+1) { grid-column:span 4; }
}
.pcx-comp--mercadoria { background:var(--pcx-cor-mercadoria); }
.pcx-comp--frete { background:var(--pcx-cor-frete); }
.pcx-comp--imposto_importacao { background:var(--pcx-cor-imposto_importacao); }
.pcx-comp--ipi { background:var(--pcx-cor-ipi); }
.pcx-comp--pis { background:var(--pcx-cor-pis); }
.pcx-comp--cofins { background:var(--pcx-cor-cofins); }
.pcx-comp--icms { background:var(--pcx-cor-icms); }
.pcx-comp--afrmm { background:var(--pcx-cor-afrmm); }
.pcx-comp--siscomex { background:var(--pcx-cor-siscomex); }
.pcx-comp--despesas_no_brasil { background:var(--pcx-cor-despesas); }
.pcx-comp--outro { background:var(--dnv-rule-3); }
.pcx-composicao { display:flex; flex-direction:column; gap:12px; }
.pcx-barra--composicao { width:100%; height:20px; margin-top:0; padding:0; border:0; border-radius:0; cursor:pointer; }
.pcx-barra--composicao:focus-visible { outline:2px solid var(--dnv-mark); outline-offset:2px; }
.pcx-barra__trecho.pcx-barra__trecho--zero { border-left:0; }
.pcx-comp-legenda { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill, minmax(19rem, 1fr)); gap:0 24px; }
.pcx-comp-legenda__item { display:flex; align-items:center; gap:8px; width:100%; padding:4px 0; border:0; background:none; font:inherit; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); text-align:left; cursor:pointer; }
.pcx-comp-legenda__item:hover { color:var(--dnv-ink); }
.pcx-comp-legenda__item:focus-visible { outline:2px solid var(--dnv-mark); outline-offset:1px; }
.pcx-comp-legenda__valor { margin-left:auto; color:var(--dnv-ink); white-space:nowrap; }
/* Fatia 5 (#209): comparação na 2ª linha do cartão; cartão-link do transit; R$/t e % na legenda da composição. */
.pcx-cartao__comparacao { display:block; margin-top:4px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); font-variant-numeric:tabular-nums; }
.pcx-comp-legenda__por-t, .pcx-comp-legenda__percentual { white-space:nowrap; color:var(--dnv-ink-3); }
.pcx-comp-legenda__percentual { min-width:3.5em; text-align:right; }
#pcx-serie-frete, #pcx-serie-porto { overflow-x:auto; }
.pcx-serie { list-style:none; margin:0; padding:0; display:grid; grid-auto-flow:column; grid-auto-columns:minmax(3.5rem, 1fr); gap:8px; }
.pcx-serie > li { display:flex; min-width:0; }
.pcx-serie__mes { display:flex; flex-direction:column; align-items:center; gap:2px; width:100%; min-width:0; padding:0 0 4px; border:0; border-radius:0; background:none; font:inherit; font-size:var(--fonte-pequena); color:inherit; cursor:pointer; }
.pcx-serie__mes:hover { background:var(--dnv-surface-2); }
.pcx-serie__mes:focus-visible { outline:2px solid var(--dnv-mark); outline-offset:1px; }
.pcx-serie__barras { display:flex; align-items:flex-end; justify-content:center; gap:3px; width:100%; height:140px; border-bottom:1px solid var(--dnv-rule-2); }
.pcx-serie__barra { display:block; width:min(18px, 40%); }
.pcx-serie__barra--frete { background:var(--pcx-cor-frete); }
.pcx-serie__rotulo { margin-top:4px; font-weight:500; color:var(--dnv-ink-2); }
.pcx-serie__valor { white-space:nowrap; }
/* Fatia 5 (#209): séries mensais. Barras (frete US$/ctr, porto) com marcador da meta; linhas (R$/t, FOB/t por
   fornecedor) em SVG com pontos-botão do drill. Cores locais: `--chart-mono-*` não carrega no app. */
.page[data-pagina="painel_comex"] {
  --pcx-cor-porto: var(--chart-azul);
  --pcx-cor-fornecedor-1: var(--dnv-mark);
  --pcx-cor-fornecedor-2: color-mix(in srgb, var(--chart-azul) 55%, var(--dnv-surface));
  --pcx-cor-fornecedor-3: #0F766E;
}
.pcx-serie__barras { position:relative; }
.pcx-serie__barra--porto { background:var(--pcx-cor-porto); }
.pcx-serie__meta { position:absolute; left:0; right:0; height:0; border-top:2px dashed var(--dnv-ink-2); pointer-events:none; }
.pcx-legenda__meta { display:inline-block; width:14px; height:0; border-top:2px dashed var(--dnv-ink-2); }
.pcx-serie__variacao { margin:0 0 8px; font-size:var(--fonte-pequena); color:var(--dnv-ink-2); }
.pcx-linhas__legenda { margin-bottom:8px; }
.pcx-linhas__area { position:relative; height:160px; margin:6px 6px 0; border-bottom:1px solid var(--dnv-rule-2); }
.pcx-linhas__desenho { position:absolute; inset:0; width:100%; height:100%; overflow:visible; }
.pcx-linhas__traco { fill:none; stroke:var(--pcx-linha); stroke-width:2; vector-effect:non-scaling-stroke; }
.pcx-linhas__ponto { position:absolute; width:10px; height:10px; margin:-5px 0 0 -5px; padding:0; border:2px solid var(--dnv-surface); border-radius:0; background:var(--pcx-linha); cursor:pointer; }
.pcx-linhas__ponto:focus-visible { outline:2px solid var(--dnv-mark); outline-offset:1px; }
.pcx-linhas__meses { list-style:none; margin:4px 6px 0; padding:0; display:grid; grid-auto-flow:column; grid-auto-columns:1fr; font-size:var(--fonte-pequena); font-weight:500; color:var(--dnv-ink-2); text-align:center; }
.pcx-linhas__legenda-ponto { background:var(--pcx-linha); }
.pcx-linhas--despesas { --pcx-linha:var(--pcx-cor-despesas); }
.pcx-linhas--despesas-e-impostos { --pcx-linha:var(--pcx-cor-mercadoria); }
.pcx-linhas--fornecedor-1 { --pcx-linha:var(--pcx-cor-fornecedor-1); }
.pcx-linhas--fornecedor-2 { --pcx-linha:var(--pcx-cor-fornecedor-2); }
.pcx-linhas--fornecedor-3 { --pcx-linha:var(--pcx-cor-fornecedor-3); }
.pcx-fornecedores-linhas { margin-bottom:16px; }
.pcx-painel { background:var(--dnv-surface); color:var(--dnv-ink); font-family:var(--dnv-sans); font-size:var(--fonte-corpo); border-left:1px solid var(--dnv-rule); }
.pcx-painel--drill { --bs-offcanvas-width:min(96vw, 110rem); }
.pcx-painel--metas { --bs-offcanvas-width:min(94vw, 34rem); }
.pcx-painel .offcanvas-header { align-items:flex-start; border-bottom:1px solid var(--dnv-rule); }
.pcx-painel__titulo { margin:0; font-size:var(--fonte-corpo); font-weight:500; letter-spacing:-.01em; }
.pcx-painel__sub { margin-top:2px; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); }
.pcx-drill__criterios { margin-bottom:12px; }
.pcx-metas__aviso { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 8px; padding:8px 12px; background:var(--dnv-surface-2); font-size:var(--fonte-corpo); }
.pcx-metas__indicador { padding:16px 0; border-bottom:1px solid var(--dnv-rule); }
.pcx-metas__vigente { margin:6px 0 0; font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-.02em; }
.pcx-metas__quem { margin:2px 0 0; font-size:var(--fonte-pequena); color:var(--dnv-ink-3); }
.pcx-metas__form { display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1fr) auto; align-items:end; gap:8px; margin-top:12px; }
.pcx-metas__campo { display:flex; flex-direction:column; gap:4px; min-width:0; }
.pcx-metas__erro { grid-column:1 / -1; margin:0; font-size:var(--fonte-pequena); color:var(--negative-text); }
.pcx-metas__titulo-historico { margin-top:16px; }
.pcx-metas__historico { list-style:none; margin:4px 0 0; padding:0; }
.pcx-metas__linha { display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; padding:6px 0; border-top:1px solid var(--dnv-surface-3); font-size:var(--fonte-corpo); }
.pcx-metas__linha--excluida { color:var(--dnv-ink-3); }
.pcx-metas__acoes { display:flex; align-items:center; gap:6px; margin-left:auto; }
.pcx-metas__pergunta { font-size:var(--fonte-pequena); color:var(--dnv-ink-2); }


/* ══ PREVISÃO DE CAIXA — veio do <style> do template (#476, onda 4) ══ */
@media(max-width:430px){.page[data-pagina="previsao_caixa"] #pc-hero > .card{grid-column:1 / -1}}

/* ══ COMEX KPI FINANCEIRO (/comex-kpi-financeiro/) — veio do <style> do template (#476, onda 4) ══ */
/* Comex KPI Financeiro — custo por container por processo (Armazenagem/ctnr + Frete/ctnr).
   Layout/spacing/type-scale portados 1:1 do preview validado; cores e fonte vêm SÓ do
   FCDS (custom.css já carregado pelo shell — --brand/--negative/--positive-text/
   --warning-text/--surf/--line/--ink-N/--sans). Tudo namespaced sob .kf/.ckf-* para não
   colidir com .card/.tile/.btn/.chip globais (§3 kpi spark tiles usa esses mesmos nomes).
   A tabela (mais abaixo) NÃO usa esse namespace: é o padrão DataTables (configDataTablePadrao,
   Task 8) sobre markup Bootstrap puro — nada bespoke ali. */
/* A regra `.kf{…}` que abria este bloco nunca valeu: o `--ink*/` do comentário acima fechava o
   comentário antes da hora e o resto virava o seletor dela (inválido). Saiu sem mudar a tela (#476). */
.kf, .kf *{box-sizing:border-box}
.kf .ckf-num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}

/* band (KPI) */
.kf .ckf-band{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--line);border-radius:var(--r);
  background:var(--surf);overflow:hidden;margin-bottom:12px}
.kf .ckf-tile{padding:11px 14px 10px;border-right:1px solid var(--line-2)}
.kf .ckf-tile:last-child{border-right:0}
.kf .ckf-tile .lbl{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.4px;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px;white-space:nowrap}
.kf .ckf-tile .v{font-size:var(--fonte-heroi);font-weight:500;line-height:40px;letter-spacing:.3px}
.kf .ckf-tile .v small{font-size:var(--fonte-corpo);color:var(--ink-3);font-weight:500;margin-right:1px}
.kf .ckf-tile .s{font-size:var(--fonte-pequena);color:var(--ink-4);font-weight:500;margin-top:5px}
.kf .ckf-tile--duo .duo{display:grid;grid-template-columns:auto 1fr;gap:2px 8px;align-items:baseline;margin-top:2px}
.kf .ckf-tile--duo .duo-k{font-size:var(--fonte-pequena);color:var(--ink-3);font-weight:500}
.kf .ckf-tile--duo .duo .v{font-size:var(--fonte-titulo);text-align:right}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Band de reconciliação de dois lados:
   rótulo de grupo acima de cada linha; Row 2 (órfãos) em 5 colunas com um divisor
   sutil entre o par Órfão-Senior (tiles 1–2) e o trio Órfão-Conexos (tiles 3–5);
   afordância de clique (cursor+hover) porque cada tile abre o drill do indicador
   (a metodologia fica um clique adiante, no chip "Como é calculado" do drill).
   Utilitário Bootstrap não cobre o rótulo de grupo, o divisor interno da grade nem o
   estado clicável do tile; light theme, tokens FCDS, sem hex cru, tinta neutra. */
.kf .ckf-band-group{margin-bottom:12px}
.kf .ckf-band-group .ckf-band{margin-bottom:0}
.kf .ckf-band-label{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.5px;text-transform:uppercase;color:var(--ink-3);margin:0 2px 5px}
.kf .ckf-band.orfaos{grid-template-columns:repeat(5,1fr)}
.kf .ckf-band.orfaos .ckf-tile:nth-child(2){border-right:2px solid var(--line)}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). O balde 4 rende 2 tiles (3 com a
   anomalia) e a seção de órfãos rende 4 (5 com a anomalia) — contagens variáveis.
   `grid-auto-flow:column` + `grid-auto-columns:1fr` dá N colunas iguais para N
   filhos, sem hardcodar a contagem, então nenhuma coluna fica vazia quando a
   anomalia não existe. `.row-cols-*` do Bootstrap exige a contagem no markup, que
   é justamente o que não sabemos aqui; `.d-flex` + `.flex-fill` daria larguras
   desiguais porque os tiles têm conteúdo de tamanhos diferentes. Light theme,
   tokens FCDS. */
.kf .ckf-band.ckf-band--auto{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:1fr}
.kf .ckf-tile[data-drill]{cursor:pointer}
.kf .ckf-tile[data-drill]:hover{background:var(--surf-2)}

/* grid 2col: gasto no tempo (chronológico) + régua de custo */
.kf .ckf-g2{display:grid;grid-template-columns:0.92fr 1.08fr;gap:12px;margin-bottom:12px}
.kf .ckf-card{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;min-width:0}
.kf .ckf-card-hd{display:flex;align-items:baseline;gap:9px;margin-bottom:12px}
.kf .ckf-card-hd h2{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.6px;text-transform:uppercase;color:var(--ink-3);margin:0}
.kf .ckf-card-hd .hint{font-size:var(--fonte-pequena);color:var(--ink-4);font-weight:500}
.kf .ckf-card-hd .sp{flex:1}
.kf .ckf-tg{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.kf .ckf-tg button{border:0;background:var(--surf);color:var(--ink-3);font-family:var(--sans);font-size:var(--fonte-pequena);font-weight:500;
  padding:4px 10px;cursor:pointer}
.kf .ckf-tg button.on{background:var(--surf-3);color:var(--ink)}

/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Legenda no TOPO do card "Gasto no Tempo"
   (acima da tabela unificada): três chips inline — Armazenagem (swatch sólido --brand),
   Frete (swatch hachurado --brand) e "Sem processo (órfão)" (swatch neutro --ink-3, só
   no modo Lançamento). Utilitário Bootstrap não cobre swatches de série com hachura;
   light theme, tokens FCDS, sem hex cru. */
.kf .ckf-chrono-lgd{display:flex;align-items:center;flex-wrap:wrap;gap:16px;font-size:var(--fonte-pequena);font-weight:500;color:var(--ink-2);margin-bottom:2px}
.kf .ckf-chrono-lgd > span{display:inline-flex;align-items:center;gap:5px}
.kf .ckf-chrono-lgd .gl{width:11px;height:11px;flex:0 0 auto}
.kf .ckf-chrono-lgd .tot{color:var(--ink-3);font-weight:500;font-size:var(--fonte-pequena)}

/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Tabela unificada do "Gasto no Tempo":
   ledger denso de auditoria com os meses nas colunas. Por bucket, uma LINHA-BARRA
   (célula = barra empilhada mapeado+órfão + rótulo do total) precede as linhas
   numéricas exatas. Utilitário Bootstrap (.table) é largo/espaçado demais para este
   bloco compacto dentro do card, e não desenha barras empilhadas em célula contra um
   eixo compartilhado; aqui é <table> nativa com tipografia/altura reduzidas. Light
   theme, tokens FCDS, sem hex cru; colunas numéricas à direita, rótulos à esquerda. */
.kf #chrono-subtabela{overflow-x:auto;max-width:100%}
.kf .ckf-subtable{width:100%;border-collapse:collapse;margin-top:12px;font-size:var(--fonte-pequena)}
.kf .ckf-subtable th,.kf .ckf-subtable td{padding:4px 8px;border-bottom:1px solid var(--line-2);white-space:nowrap}
.kf .ckf-subtable thead th{font-size:10px;font-weight:600;letter-spacing:.3px;text-transform:uppercase;
  color:var(--ink-3);border-bottom:1px solid var(--line);text-align:left}
.kf .ckf-subtable thead th.num{text-align:right}
.kf .ckf-subtable tbody th{font-weight:600;color:var(--ink-2);text-align:left}
.kf .ckf-subtable tbody td.num{text-align:right;color:var(--ink);font-weight:500}
.kf .ckf-subtable tbody tr:last-child th,.kf .ckf-subtable tbody tr:last-child td{border-bottom:0}
.kf .ckf-subtable tbody tr:hover{background:var(--surf-2)}
/* Linha Total (soma de exibição mapeado+órfão do bucket) — destaque leve. */
.kf .ckf-subtable tr.tot th,.kf .ckf-subtable tr.tot td{font-weight:600;color:var(--ink);border-top:1px solid var(--line)}
/* Layout fixo + 1ª coluna (rótulos) de 84px: cada coluna de mês cai alinhada. */
.kf .ckf-subtable{table-layout:fixed}
.kf .ckf-subtable th.corner,.kf .ckf-subtable tbody th{width:84px}
/* Linha-barra: separador de topo agrupa cada bucket (barra + números). A célula
   ancora a barra empilhada na base; a barra escala por geometria (altura = valor/
   máximo). Segmento mapeado (base) na matiz do bucket — sólido (Armazenagem) ou
   hachurado (Frete) — e segmento órfão (topo) em token neutro (--ink-3), fora da matiz
   porque é "sobra sem processo", não série comparável. A barra é puramente visual
   (sem rótulo numérico): os valores exatos estão nas linhas Mapeado/Órfão/Total logo
   abaixo. Identidade por FORMA (sólido vs hachura), não por cor extra. */
.kf .ckf-subtable tr.barrow{border-top:1px solid var(--line)}
.kf .ckf-subtable td.barcell{vertical-align:bottom;padding:2px 8px;cursor:pointer}
.kf .ckf-subtable td.barcell:hover{background:var(--surf-2)}
.kf .cellbar{position:relative;height:54px;display:flex;flex-direction:column;align-items:center;justify-content:flex-end}
.kf .cellbar .ckf-bar{width:100%;max-width:16px;border-radius:0;cursor:pointer}
.kf .cellbar .ckf-bar:first-of-type{border-radius:3px 3px 0 0}
.kf .barrow.port .ckf-bar.real{background:var(--brand)}
.kf .barrow.arm .ckf-bar.real{background:repeating-linear-gradient(45deg,var(--brand) 0 2px,transparent 2px 5px);border:1px solid var(--brand)}
.kf .cellbar .ckf-bar.orfao{background:var(--ink-3);border:0}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Selo "lote contábil" no mês de Frete
   em que todas as linhas foram lançadas num único dia (bulk billing do agente):
   sem ele a barra lê como custo econômico do mês. Não há utilitário Bootstrap
   para um selo inline com borda + tooltip nativo (title) deste tamanho; light
   theme, tokens FCDS existentes. */
.kf .ckf-lote{margin-left:6px;font-size:var(--fonte-pequena);font-weight:500;color:var(--ink-3);
  border:1px solid var(--line-2);border-radius:4px;padding:0 4px;cursor:help}

/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Curva "Custo por Container no Tempo":
   SVG inline com duas polylines (Armazenagem sólida --brand, Taxas de Frete tracejada
   --brand — identidade por FORMA, matiz única, como as barras do Gasto no Tempo). Não
   há utilitário Bootstrap para desenhar linhas/pontos escalados contra um eixo; a
   página já desenha suas próprias séries em DOM/CSS (drawChrono, régua) — mesmo idioma,
   sem lib de chart. `non-scaling-stroke` mantém a espessura ao escalar o viewBox; os
   pontos ficam redondos porque o SVG preserva o aspect ratio (sem preserveAspectRatio
   none). Light theme, tokens FCDS, sem hex cru. O strip numérico reusa .ckf-subtable. */
.kf #media-container-chart .ckf-mc-svg{width:100%;height:auto;display:block;max-height:220px}
.kf .ckf-mc-line{fill:none;stroke:var(--brand);stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
.kf .ckf-mc-line.fre{stroke-dasharray:6 4}
.kf .ckf-mc-dot{stroke:#fff;stroke-width:1.5;vector-effect:non-scaling-stroke}
.kf .ckf-mc-dot.arm{fill:var(--brand)}
.kf .ckf-mc-dot.fre{fill:#fff;stroke:var(--brand)}
.kf .ckf-mc-ref{stroke:var(--ink-4);stroke-width:1;stroke-dasharray:3 3;vector-effect:non-scaling-stroke;opacity:.7}
.kf .ckf-mc-reflbl{fill:var(--ink-4);font-size:var(--fonte-pequena);font-weight:500}
.kf #media-container-strip{overflow-x:auto;max-width:100%}

/* régua de custo */
.kf .ckf-rx{position:relative;height:18px;margin:0 0 4px 118px;border-bottom:1px solid var(--line)}
.kf .ckf-rx .tk{position:absolute;top:1px;font-size:var(--fonte-pequena);color:var(--ink-4);transform:translateX(-50%);font-weight:500}
.kf .ckf-rfloor{position:absolute;top:0;bottom:0;width:0;border-left:1px dashed var(--ink-4)}
.kf .ckf-rfloor span{position:absolute;top:-1px;left:3px;font-size:var(--fonte-pequena);color:var(--ink-4);font-weight:500;white-space:nowrap}
.kf .ckf-rscroll{max-height:340px;overflow-y:auto;overflow-x:hidden}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap) — a régua desenha, por processo, duas
   barras horizontais escaladas e posicionadas (largura = valor/máximo na escala do
   eixo) + rótulo ancorado no fim da barra. Utilitários Bootstrap não posicionam/
   escalam barras contra um eixo compartilhado; light theme, tokens FCDS, sem hex cru,
   reusa as cores de série existentes (--brand sólido = Armazenagem, hachura = Frete). */
.kf .ckf-rrow{display:flex;align-items:center;height:46px;cursor:pointer;border-bottom:1px solid var(--line-2)}
.kf .ckf-rrow:hover{background:var(--surf-2)}
.kf .ckf-rrow .rl{flex:0 0 118px;font-size:var(--fonte-pequena);color:var(--ink-2);font-weight:500;padding-right:8px;text-align:right;}
.kf .ckf-rrow .rt{position:relative;flex:1;height:100%;display:flex;flex-direction:column;justify-content:center;gap:2px;padding:5px 0}
.kf .ckf-rfloor-row{position:absolute;top:0;bottom:0;width:0;border-left:1px dashed var(--line-3)}
.kf .ckf-barrow{position:relative;height:9px}
.kf .ckf-hbar{position:absolute;left:0;top:0;height:100%;min-width:2px;border-radius:0 4px 4px 0}
.kf .ckf-hbar.p{background:var(--brand)}
.kf .ckf-hbar.a{background:repeating-linear-gradient(45deg,var(--brand) 0 2px,transparent 2px 5px);border:1px solid var(--brand)}
.kf .ckf-hbar-val{position:absolute;top:50%;transform:translateY(-50%);margin-left:6px;font-size:var(--fonte-pequena);font-weight:500;color:var(--ink-2);white-space:nowrap}
.kf .ckf-hbar-val.dentro{transform:translate(-100%,-50%);margin-left:0;margin-right:6px;color:#fff;text-shadow:0 0 2px rgba(0,0,0,.35)}
.kf .ckf-hbar-val small{font-size:var(--fonte-pequena);font-weight:500;opacity:.72}
.kf .ckf-rmeta{font-size:var(--fonte-pequena);color:var(--ink-4);font-weight:500;margin-top:1px}
.kf .ckf-rmeta .ckf-rdwell.crit{color:var(--negative);font-weight:500}
.kf .ckf-rlgd{display:flex;gap:16px;margin-top:9px;font-size:var(--fonte-pequena);color:var(--ink-2);font-weight:500;align-items:center}
.kf .ckf-rlgd .d{display:inline-block;width:16px;height:9px;border-radius:2px;margin-right:5px;vertical-align:middle}
.kf .ckf-rlgd .d.p{background:var(--brand)}
.kf .ckf-rlgd .d.a{background:repeating-linear-gradient(45deg,var(--brand) 0 2px,transparent 2px 5px);border:1px solid var(--brand)}
.kf .ckf-rlgd .d.x{background:var(--negative);border-radius:50%;width:9px}

/* tabela: conteúdo de célula bespoke (chip de fluxo, marcos, alerta de dwell). A grade/
   paginação/busca em si é 100% DataTables — sem CSS custom aqui. */
.kf .ckf-mut{color:var(--ink-4)}
.kf .ckf-flx-chip{display:inline-block;font-size:11px;font-weight:600;color:var(--ink-2);background:var(--surf-3);
  border:1px solid var(--line);border-radius:999px;padding:2px 9px;white-space:nowrap}
.kf .ckf-perm-datas{display:block;font-size:10.5px;color:var(--ink-4);font-weight:500;white-space:nowrap;margin-top:1px}
.kf .ckf-dw.hi{color:var(--warning-text);font-weight:600}
.kf .ckf-dw.crit{color:var(--negative);font-weight:700}
.kf .ckf-numv{font-weight:600;color:var(--ink)}
/* Saída para o Conexos: é um LINK, não um chip. Um único estilo para as quatro
   ocorrências (célula da tabela, cabeçalho do modal de auditoria e as listas de
   órfãos) — antes o cabeçalho e as listas usavam .ckf-cnxchip, uma pílula
   preenchida que, espremida no flex do cabeçalho, quebrava a linha e virava um
   círculo azul. `nowrap` é o que garante que ele nunca volte a quebrar. */
.kf .ckf-cnx{font-weight:700;font-size:12px;white-space:nowrap}

.kf .ckf-foot{color:var(--ink-4);font-size:var(--fonte-pequena);text-align:center;margin-top:8px}

/* modal de auditoria (drill do processo) */
.kf .ckf-ov{position:fixed;inset:0;background:rgba(25,28,34,.34);display:none;align-items:flex-start;justify-content:center;padding:36px 16px;z-index:1100} /* = var(--z-modal); inline não herda o token com garantia de ordem */
.kf .ckf-ov.on{display:flex}
.kf .ckf-modal{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);max-width:620px;width:100%;max-height:82vh;overflow:auto}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). O drill de despesa é o único modal com
   uma DataTable larga: ao ligar as colunas de diagnóstico (Observação, Fornecedor,
   Histórico…) as colunas da direita ficavam cortadas atrás do scroll-x num card de
   620px. Este modificador (aplicado pelo JS só quando o modal hospeda a tabela)
   alarga o card até min(1320px, 92vw) — a tabela (w-100) preenche essa largura e as
   colunas de diagnóstico cabem SEM scroll no desktop. O teto é o MÁXIMO
   alargamento: nunca se corta dado; quando o texto ainda não cabe, ele QUEBRA em
   mais linhas (regra #ckf-drill-tabela abaixo), nunca some. Em tela estreita o teto
   vira 92vw, sem estourar a viewport. (Tentado width:max-content p/ ajustar à
   contagem de colunas, mas o DataTables fixa a largura da tabela e o max-content
   colapsava p/ 620px — teto fixo é o que cresce de forma confiável.) Bootstrap só
   tem larguras fixas (.mw-100, .w-75), não cobre min(px,vw). Demais drills
   (.ckf-ml, metodologia) seguem em 620px. Light theme. */
.kf .ckf-modal--wide{max-width:min(1320px,92vw)}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Anti-supressão de dado no drill de
   despesa: PROIBIDO cortar campo. Toda célula quebra em quantas linhas precisar e
   mostra o texto INTEIRO (Histórico, Observação, Credor, Fornecedor podem ser
   longos) — melhor linha alta que dado escondido. Sem nowrap, sem ellipsis, sem
   overflow:hidden. overflow-wrap:anywhere garante que um token longo sem espaço
   também quebre em vez de estourar a largura. Bootstrap não tem utilitário para
   forçar isto por célula de DataTable; escopado a esta tabela. */
.kf #ckf-drill-tabela th,.kf #ckf-drill-tabela td{white-space:normal;overflow-wrap:anywhere;text-overflow:clip;max-width:none}
/* `wrap`: h3 + até quatro chips + link do Conexos + fechar não cabem na largura
   do modal. Sem ele o excesso era cortado na borda (o link saía pela metade e o
   × ficava inalcançável) — os chips agora descem para uma segunda linha. */
.kf .ckf-mh{display:flex;flex-wrap:wrap;align-items:center;gap:9px;padding:14px 18px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surf)}
.kf .ckf-mh h3{margin:0;font-size:var(--fonte-destaque);font-weight:500}
.kf .ckf-mh .x{margin-left:auto;cursor:pointer;color:var(--ink-3);font-size:var(--fonte-titulo);width:28px;height:28px;display:grid;place-items:center;border-radius:7px}
.kf .ckf-mh .x:hover{background:var(--surf-2)}
.kf .ckf-mg{padding:12px 18px}
/* HUMAN-REVIEW: drill list scrolls horizontally on narrow viewports (fixed-px grid cols); min-width keeps columns from collapsing, mirrors #chrono-subtabela. */
.kf .ckf-drill-scroll{overflow-x:auto}
.kf .ckf-drill-scroll .ckf-ml{min-width:340px}
.kf .ckf-mg h4{margin:0 0 8px;font-size:var(--fonte-rotulo);letter-spacing:.5px;text-transform:uppercase;color:var(--ink-2);display:flex;align-items:center;gap:7px}
.kf .ckf-mg h4 .d{width:9px;height:9px;border-radius:50%}
.kf .ckf-mg h4 .d.p{background:var(--brand)}
.kf .ckf-mg h4 .d.a{background:var(--surf);border:1.5px solid var(--brand)}
.kf .ckf-ml{display:grid;grid-template-columns:70px 1fr 92px;gap:9px;padding:6px 0;border-bottom:1px solid var(--line-2);font-size:var(--fonte-corpo);align-items:baseline}
.kf .ckf-ml .d{color:var(--ink-3);font-weight:500}
.kf .ckf-ml .o{color:var(--ink-2);white-space:normal;line-height:1.2}
.kf .ckf-ml .o .cr{display:block;font-size:var(--fonte-pequena);color:var(--ink-4);font-weight:500}
.kf .ckf-ml .vv{text-align:right;font-weight:500}
.kf .ckf-ms{display:flex;justify-content:flex-end;gap:12px;padding:8px 18px;font-size:var(--fonte-corpo);font-weight:500;background:var(--surf-2);border-top:1px solid var(--line)}
.kf .ckf-ms .c{color:var(--ink-3);font-weight:500}
.kf .ckf-mempty{color:var(--ink-4);font-size:var(--fonte-corpo)}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Marcador de "sem código" no drill dos
   baldes de despesa: a ausência do código extraído é o DEFEITO que depois vira
   órfão Senior, então tem de ser visível, nunca uma célula vazia. Utilitário
   Bootstrap não cobre um marcador semântico de falha dentro de célula; .text-danger
   existe mas não itálico, e queremos as duas coisas numa regra. Light theme;
   --danger não existe neste template, daí o fallback hex explícito. */
.kf .ckf-sem-codigo{color:var(--danger, #b42318);font-style:italic}
/* HUMAN-REVIEW: CSS novo (não-Bootstrap). Parágrafo de texto do modal "Como é
   calculado" (definições das três classes + identidades de reconciliação). O .table/
   utilitários Bootstrap não cobrem este bloco de prosa densa dentro do modal bespoke;
   light theme, tokens FCDS, sem hex cru, tinta neutra (b = ink, i = qualificador). */
.kf .ckf-mtext{font-size:var(--fonte-corpo);line-height:1.5;color:var(--ink-2);margin:0 0 8px}
.kf .ckf-mtext:last-child{margin-bottom:0}
.kf .ckf-mtext b{color:var(--ink);font-weight:500}
.kf .ckf-mtext i{font-style:normal;color:var(--ink-3);font-weight:500}

/* Tabela larga "Custo por Processo": rola dentro do próprio wrapper e nunca
   empurra a largura da página (escopo desta página). */
.page[data-pagina="comex_kpi_financeiro"] .tbl-wrapper.datatable{overflow-x:auto;max-width:100%}

/* HUMAN-REVIEW: restaura o padding lateral do card "Custo por Processo".
   O FCDS global (.page > section, custom.css:6285) zera padding-left/right
   com !important em toda <section> filha direta de .page — regra pensada para
   seções que ENVOLVEM cards, mas aqui a própria seção É o card, então o título e a
   tabela encostavam na borda. Correção escopada só a esta página (.kf), com
   especificidade e !important suficientes para vencer a regra global sem editar o
   FCDS. Utilitário Bootstrap não cobre: precisa bater um !important global. */
.kf.page > section.card{
  padding-left:var(--bi-space-md,1rem) !important;
  padding-right:var(--bi-space-md,1rem) !important;
}

/* Responsivo estrutural (registro product): 6→3→2 colunas na band, gráfico+régua
   empilham, cabeçalho de card quebra p/ o toggle não cortar, alvos de toque
   maiores no mobile. Sem tipografia fluida — densidade consistente por breakpoint. */
@media(max-width:820px){
  .kf .ckf-band:not(.orfaos){grid-template-columns:repeat(3,1fr)}
  .kf .ckf-band:not(.orfaos) .ckf-tile:nth-child(n){border-bottom:1px solid var(--line-2)}
  .kf .ckf-band:not(.orfaos) .ckf-tile:nth-child(3n){border-right:0}
  .kf .ckf-band:not(.orfaos) .ckf-tile:nth-last-child(-n+3){border-bottom:0}
  /* Row 2 (órfãos): 5→2 colunas; bordas por 2n e divisor interno suprimido no mobile.
     5 é ímpar, então a última linha tem 1 tile solto na col.1 — :last-child cobre a
     borda direita órfã que o :nth-child(2n) sozinho não pegaria (não depende de
     paridade da contagem de tiles). */
  .kf .ckf-band.orfaos{grid-template-columns:repeat(2,1fr)}
  .kf .ckf-band.orfaos .ckf-tile{border-right:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
  .kf .ckf-band.orfaos .ckf-tile:nth-child(2n){border-right:0}
  .kf .ckf-band.orfaos .ckf-tile:last-child{border-right:0}
  .kf .ckf-band.orfaos .ckf-tile:nth-last-child(-n+2){border-bottom:0}
  /* HUMAN-REVIEW: CSS novo (não-Bootstrap). Reseta o auto-flow por COLUNA da regra
     base .ckf-band--auto. Sem isto, entre 561px e 820px o flow por coluna cria uma
     coluna implícita por tile e espreme 4-5 tiles numa linha só, ignorando as
     contagens de coluna que este bloco acabou de definir. A contagem de colunas vem
     das regras acima (3 para o balde 4, 2 para os órfãos); aqui só o flow muda. */
  .kf .ckf-band.ckf-band--auto{grid-auto-flow:row}
  .kf .ckf-g2{grid-template-columns:1fr}
  .kf .ckf-rrow .rl,.kf .ckf-rx{margin-left:0} .kf .ckf-rrow .rl{flex-basis:90px}
  .kf .ckf-card-hd{flex-wrap:wrap;row-gap:8px}
  .kf .ckf-card-hd .ckf-tg{margin-left:auto}
}
@media(max-width:560px){
  .kf .ckf-band{grid-template-columns:repeat(2,1fr)}
  /* Em telas estreitas os tiles empilham em 2 colunas; a auto-flow por coluna
     espremeria 5 tiles numa linha só. */
  .kf .ckf-band.ckf-band--auto{grid-auto-flow:row;grid-template-columns:repeat(2,1fr)}
  .kf .ckf-tile:nth-child(n){border-right:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
  .kf .ckf-tile:nth-child(2n){border-right:0}
  /* .ckf-tile:last-child cobre a borda direita órfã quando a band tem
  contagem ímpar de tiles (ex.: órfãos com 5) e a última linha fica com 1 tile solto
  na col.1 — não depende de paridade, ao contrário de :nth-child(2n) isolado. */
  .kf .ckf-tile:last-child{border-right:0}
  .kf .ckf-tile:nth-last-child(-n+2){border-bottom:0}
  .kf .ckf-tile .v{font-size:22px}
  .kf .ckf-tile .lbl{white-space:normal}
  .kf .ckf-card-hd h2{flex-basis:100%}
  .kf .ckf-tg button{padding:8px 13px}
  .kf .ckf-rrow .rl{flex-basis:74px;font-size:11px}
  .kf .ckf-rscroll{padding-right:2px}
}

  /* HUMAN-REVIEW: CSS novo (não-Bootstrap). Faixa de balanço: as duas identidades de reconciliação, sempre visíveis.
     Bootstrap não tem um primitivo para "linha de identidade com veredito"; um
     .alert seria semanticamente errado (não é um alerta quando fecha) e a
     .badge não comporta a equação. Alternativas consideradas: .list-group
     (pesado demais, borda dupla) e uma <table> (semântica errada — não são
     dados tabulares, é uma asserção). ── */
  .kf .ckf-balanco{display:flex;flex-direction:column;gap:2px;margin-bottom:14px;
    padding:10px 14px;border:1px solid var(--line-2);border-radius:8px;background:#fff}
  .kf .ckf-balanco__linha{display:flex;align-items:center;gap:8px;
    font-size:var(--fonte-pequena);color:var(--ink-2);font-variant-numeric:tabular-nums}
  .kf .ckf-balanco__linha .eq{flex:1}
  .kf .ckf-balanco__linha .vd{font-weight:500;letter-spacing:.02em}
  .kf .ckf-balanco--ok .vd{color:var(--ok, #1a7f4b)}
  .kf .ckf-balanco--erro{border-color:var(--danger, #b42318);background:#fff5f5}
  .kf .ckf-balanco--erro .vd{color:var(--danger, #b42318)}

  /* HUMAN-REVIEW: CSS novo (não-Bootstrap). Três baldes de entrada, lado a lado. Simétricos em repouso (é isso que
     torna legível que são três ENTRADAS paralelas); o drill de cada um abre a
     tabela nativa do seu dado. .row/.col do Bootstrap dariam a grade, mas não
     o cartão com headline+sub+ação nem a paridade de altura — e a página já
     usa CSS Grid próprio (.ckf-g2). Mantemos o mesmo idioma. ── */
  .kf .ckf-baldes{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}
  .kf .ckf-balde{display:flex;flex-direction:column;gap:6px;padding:14px 16px;
    border:1px solid var(--line-2);border-radius:10px;background:#fff}
  .kf .ckf-balde__hd{display:flex;align-items:baseline;gap:8px}
  .kf .ckf-balde__lbl{font-size:var(--fonte-rotulo);font-weight:500;letter-spacing:.06em;
    text-transform:uppercase;color:var(--ink-3)}
  .kf .ckf-balde__v{font-size:var(--fonte-titulo);font-weight:500;color:var(--ink);
    font-variant-numeric:tabular-nums;line-height:1.2}
  .kf .ckf-balde__s{font-size:var(--fonte-pequena);color:var(--ink-2);font-variant-numeric:tabular-nums}
  .kf .ckf-balde__acao{margin-top:auto;align-self:flex-start;padding:0;border:0;
    background:none;font-size:var(--fonte-pequena);font-weight:500;color:var(--brand);cursor:pointer}
  .kf .ckf-balde__acao:hover{text-decoration:underline}

  /* HUMAN-REVIEW: CSS novo (não-Bootstrap). Tile de anomalia: invariante quebrada.
     Só renderiza quando existe. Duas declarações sobre o .ckf-tile bespoke já
     existente; nenhuma classe contextual do Bootstrap se aplica a ele. */
  .kf .ckf-tile--alerta{border-color:var(--danger, #b42318);background:#fff5f5}
  .kf .ckf-tile--alerta .lbl{color:var(--danger, #b42318)}

  @media (max-width:900px){
    .kf .ckf-baldes{grid-template-columns:1fr}
  }

/* ── Painel Financeiro (#208), aba Visão ───────────────────────────────────────
   Linguagem do Four Group Design System, a mesma da aba Caixa (fatia 1d, 29/09/2026):
   os tokens `--ds-*` e as regras `ds-*` (kpi, quadro, cartão, rótulo, selo, vazio, botão)
   vêm da seção CAIXA EM TEMPO REAL, com escopo nas duas abas. Aqui fica só o layout da
   Visão (`pfin-*`): cartões soltos com 12px entre eles, sobre o fundo branco do shell.
   A página rola na vertical (snapshot do dia); abaixo de 1280px as grades empilham.
   ========================================================================== */
.page[data-pagina="painel_financeiro"] { color:var(--ds-tinta); }

/* ── estrutura ────────────────────────────────────────────────────────────── */
.page[data-pagina="painel_financeiro"] .pfin-app { display:flex; flex-direction:column; gap:12px; }
.page[data-pagina="painel_financeiro"] .pfin-kpis,
.page[data-pagina="painel_financeiro"] .pfin-meio { display:grid; gap:12px; }
.page[data-pagina="painel_financeiro"] .pfin-kpis { grid-template-columns:repeat(5,minmax(0,1fr)); min-height:96px; }
.page[data-pagina="painel_financeiro"] .pfin-meio { grid-template-columns:repeat(3,minmax(0,1fr)); }
.page[data-pagina="painel_financeiro"] .ds-kpi { padding:14px 18px; }
.page[data-pagina="painel_financeiro"] .ds-kpi__legenda b { color:var(--ds-tinta-2); font-weight:500; }
.page[data-pagina="painel_financeiro"] .ds-kpi__rotulo .ds-badge { margin-left:6px; height:18px; padding:0 6px; font-size:var(--fonte-pequena); }
/* Vazio ou erro: só a mensagem fica (o `.state-error` do `mostrarErro` ou o `.pfin-vazio`). */
.page[data-pagina="painel_financeiro"] .pfin-app[data-estado] > :not(.pfin-vazio):not(.state-error) { display:none; }
.page[data-pagina="painel_financeiro"] .pfin-app[data-estado] { min-height:240px; }
/* Carregando: só o logo da casa, no meio da janela, sem os quadros vazios por trás (dono, 29/09/2026). */
.page[data-pagina="painel_financeiro"] .pfin-app[data-bi-loading] { min-height:calc(100dvh - 122px); }
.page[data-pagina="painel_financeiro"] .pfin-app[data-bi-loading] > :not([data-bi-skel]) { display:none; }

/* ── gráficos no ChartFrame (`ds-quadro`) ─────────────────────────────────── */
.page[data-pagina="painel_financeiro"] .ds-quadro__cabecalho .ds-rotulo { margin:0; }
.page[data-pagina="painel_financeiro"] .pfin-grafico { position:relative; min-width:0; }
.page[data-pagina="painel_financeiro"] .pfin-grafico--fluxo { height:300px; }
.page[data-pagina="painel_financeiro"] .pfin-grafico--meio { height:250px; }
.page[data-pagina="painel_financeiro"] .ds-quadro__nota { margin-top:auto; }
/* Legend do design system: amostra quadrada de 9px (traço de 12×2 para linha), rótulo em tinta secundária, valor opcional. */
.page[data-pagina="painel_financeiro"] .pfin-legenda { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:6px 16px; }
.page[data-pagina="painel_financeiro"] .pfin-legenda:empty { display:none; }
.page[data-pagina="painel_financeiro"] .pfin-legenda li { display:flex; align-items:center; gap:8px; font-size:var(--fonte-pequena); color:var(--ds-tinta-2); white-space:nowrap; }
.page[data-pagina="painel_financeiro"] .pfin-legenda b { font-weight:500; color:var(--ds-tinta); }
.page[data-pagina="painel_financeiro"] .pfin-legenda__amostra { width:9px; height:9px; flex:none; }
.page[data-pagina="painel_financeiro"] .pfin-legenda__amostra--linha { width:12px; height:2px; }
/* O EmptyState (`ds-vazio`) cobre a área do gráfico quando não há o que desenhar. */
.page[data-pagina="painel_financeiro"] .pfin-grafico__estado { position:absolute; inset:0; }
.page[data-pagina="painel_financeiro"] .pfin-grafico__estado[hidden] { display:none; }

/* ── ciclo de caixa ───────────────────────────────────────────────────────── */
.page[data-pagina="painel_financeiro"] .pfin-ciclo { display:flex; flex-direction:column; gap:12px; flex:1 1 auto; }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__n { display:flex; align-items:baseline; gap:12px; font-size:var(--fonte-pequena); }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__n .ds-kpi__valor { font-size:var(--fonte-heroi); }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__composicao { margin:0; font-size:var(--fonte-corpo); color:var(--ds-tinta-2); }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__composicao b { color:var(--ds-tinta); font-weight:500; }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__composicao span { color:var(--ds-tinta-3); }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__serie {
  list-style:none; margin:auto 0 0; padding:12px 0 0; border-top:1px solid var(--ds-filete);
  display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:4px; }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__serie li { display:flex; flex-direction:column; gap:2px; font-size:var(--fonte-corpo); }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__serie b { font-weight:500; }
.page[data-pagina="painel_financeiro"] .pfin-ciclo__serie span { font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }

/* ── endividamento ────────────────────────────────────────────────────────── */
.page[data-pagina="painel_financeiro"] .pfin-endividamento__corpo {
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.4fr); gap:40px; align-items:start; }
.page[data-pagina="painel_financeiro"] .pfin-divida-figuras { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
.page[data-pagina="painel_financeiro"] .pfin-figura__v { margin:6px 0 0; font-size:var(--fonte-titulo); font-weight:500; letter-spacing:-0.03em; white-space:nowrap; }
.page[data-pagina="painel_financeiro"] .pfin-divida-barra { display:flex; gap:2px; height:12px; margin-top:18px; }
.page[data-pagina="painel_financeiro"] .pfin-divida-barra__curto { flex-basis:0; background:var(--ds-grafico-3); }
.page[data-pagina="painel_financeiro"] .pfin-divida-barra__longo { flex-basis:0; background:var(--ds-grafico-1); }
.page[data-pagina="painel_financeiro"] .pfin-divida-legenda { display:flex; justify-content:space-between; gap:12px; margin-top:6px; font-size:var(--fonte-pequena); color:var(--ds-tinta-3); }
.page[data-pagina="painel_financeiro"] .pfin-divida-legenda b { color:var(--ds-tinta-2); font-weight:500; }
.page[data-pagina="painel_financeiro"] .pfin-tabela { width:100%; border-collapse:collapse; font-size:var(--fonte-corpo); }
.page[data-pagina="painel_financeiro"] .pfin-tabela th,
.page[data-pagina="painel_financeiro"] .pfin-tabela td { padding:7px 0; border-bottom:1px solid var(--ds-filete); }
.page[data-pagina="painel_financeiro"] .pfin-tabela td + td,
.page[data-pagina="painel_financeiro"] .pfin-tabela th + th { padding-left:16px; white-space:nowrap; }
.page[data-pagina="painel_financeiro"] .pfin-tabela tfoot th { font-weight:500; border-top:1px solid var(--ds-regra); border-bottom:0; }

/* ── vazio da tela inteira: frase centrada, sem moldura ───────────────────── */
.page[data-pagina="painel_financeiro"] .pfin-vazio { margin:0; padding:28px 14px; text-align:center; color:var(--ds-tinta-3); font-size:var(--fonte-pequena); }
.page[data-pagina="painel_financeiro"] .pfin-app[data-estado] .pfin-vazio { padding-top:96px; }

/* ── topbar: a mesma da aba Caixa (`.bnk-topbar`); o aviso de conferências tinge de perigo ── */
#topbar .bnk-topbar.pfin-aviso { color:var(--ds-negativo); cursor:help; }
#topbar .bnk-topbar.pfin-aviso[hidden] { display:none; }

/* Detalhe (#208, fatias 1b e 1d): tudo que tem `detalhe` no payload abre o painel lateral de
   drill da casa (biUtils.gridPainel). Mão, tinta de ação ao passar e anel de foco no teclado. */
.page[data-pagina="painel_financeiro"] [data-pfin-detalhe] { cursor:pointer; }
.page[data-pagina="painel_financeiro"] [data-pfin-detalhe]:hover { background:var(--ds-acao-tinta); }
.page[data-pagina="painel_financeiro"] [data-pfin-detalhe]:focus-visible { outline:2px solid var(--ds-acao); outline-offset:-2px; }
.fcds-modal .pfin-detalhe-estado { display:flex; flex-direction:column; align-items:flex-start; gap:12px; padding:24px 0; color:var(--gc-ink-3); }
.fcds-modal .pfin-detalhe-estado p { margin:0; }
/* O pagar tem 10 colunas: no painel lateral o texto longo (fornecedor, tipo) corta com
   reticências; o texto inteiro fica no `title` da célula. */
body:has(.page[data-pagina="painel_financeiro"]) #fcds-lateral .fcds-gm td:not(.fcds-gm__num):not(.fcds-gm__inteiro) { max-width:9rem; }
/* A escada de largura do painel (por nº de colunas) é curta para estas grades — rótulos longos em
   caixa alta, dívida com 4 colunas de texto: aqui ganha 4rem, com piso de 44rem e teto de 92vw. */
body:has(.page[data-pagina="painel_financeiro"]) { --pfin-lateral-w:min(92vw, max(44rem, calc(var(--fcds-lateral-w, 32.5rem) + 4rem))); }
body:has(.page[data-pagina="painel_financeiro"]) #fcds-lateral { width:var(--pfin-lateral-w); }
/* Onde o painel doca (acima de 106.75rem), a página cede a MESMA largura, senão ele cobre a borda direita da Visão. */
@media (min-width:106.76rem) {
  body[data-lateral]:has(.page[data-pagina="painel_financeiro"]) .main { margin-right:var(--pfin-lateral-w); }
}
/* Abas do Painel Financeiro (#208, fatia 1c): Visão | Caixa em tempo real. Tabs do design system em
   modo underline — marcador de 2px na cor de ação, nunca pílula. Vive nas duas abas; `flex:0 0 auto`
   porque o caixa é coluna flex na altura da janela. */
:is(.page[data-pagina="painel_financeiro"], .page[data-pagina="banking"]) .pfin-abas { display:flex; gap:24px; flex:0 0 auto; margin:0 0 12px; border-bottom:1px solid var(--ds-filete); }
:is(.page[data-pagina="painel_financeiro"], .page[data-pagina="banking"]) .pfin-abas__aba { padding:10px 0 8px; margin-bottom:-1px; border-bottom:2px solid transparent; color:var(--ds-tinta-2); font-size:var(--fonte-corpo); font-weight:500; text-decoration:none; }
:is(.page[data-pagina="painel_financeiro"], .page[data-pagina="banking"]) .pfin-abas__aba:hover { color:var(--ds-tinta); }
:is(.page[data-pagina="painel_financeiro"], .page[data-pagina="banking"]) .pfin-abas__aba[aria-current="page"] { color:var(--ds-tinta); border-bottom-color:var(--ds-acao); }
:is(.page[data-pagina="painel_financeiro"], .page[data-pagina="banking"]) .pfin-abas__aba:focus-visible { outline:2px solid var(--ds-acao); outline-offset:2px; }

@media (max-width:1279.98px) {
  .page[data-pagina="painel_financeiro"] .pfin-kpis { grid-template-columns:repeat(3,minmax(0,1fr)); }
  .page[data-pagina="painel_financeiro"] .pfin-meio,
  .page[data-pagina="painel_financeiro"] .pfin-endividamento__corpo { grid-template-columns:minmax(0,1fr); }
}
/* Fatia 5b (#209): todo número abre o drill. `:where` zera a especificidade do reset para que a classe
   de cada peça (linha de origem, linha do transit, etapa) mantenha o seu tamanho e cor. */
:where(.pcx-numero-drill) { padding:0; border:0; background:none; font:inherit; color:inherit; text-align:inherit; cursor:pointer; }
.pcx-numero-drill:hover { color:var(--ds-acao); }
.pcx-etapa__abrir:hover > *, .pcx-origem-linha:hover > *, .pcx-transit-linha:hover > * { color:var(--ds-acao); }
.pcx-numero-drill:focus-visible { outline:2px solid var(--dnv-mark); outline-offset:1px; }
button.pcx-origem-linha, button.pcx-transit-linha, .pcx-etapa__abrir { width:100%; text-align:left; }
.pcx-etapa__abrir { display:block; }
.pcx-etapa__abrir > .pcx-etapa__valor, .pcx-etapa__abrir > .pcx-etapa__apoio { display:block; }
.pcx-drill__contagem { font-weight:400; color:var(--dnv-ink-3); }
/* ── Painel Comex: trilho do topbar (46px); Origem, Período e Metas são os controles de fábrica no `-sm` (#454) ── */
#topbar:has(.pcx-trilho) {
  height:46px; padding:0 12px 0 16px;
  background:var(--dnv-surface); border-bottom:1px solid var(--dnv-rule);
  font-family:var(--dnv-sans); color:var(--dnv-ink); }
#topbar:has(.pcx-trilho) .pcx-trilho,
#topbar:has(.pcx-trilho) .pcx-trilho__item { display:flex; align-items:center; gap:.5rem; white-space:nowrap; }
#topbar:has(.pcx-trilho) .fcds-reportar { width:2rem; padding-inline:0; justify-content:center; }
#topbar:has(.pcx-trilho) .fcds-reportar span { display:none !important; }

/* === PEDIDOS E NOTAS FISCAIS (tela nova) · aba ATENDIMENTO (#130) ==============
   Escopo [data-pagina="separacao_faturamento"] (o mesmo da tela), classes .at-*. Fundo
   branco, sem moldura, tela na altura inteira. */
[data-pagina="crm-pedidos"] .pd-saida-marca{display:block;font-size:var(--fonte-corpo);color:#495057}
[data-pagina="crm-pedidos"] .pd-situacao-atendimento,
.pd-canvas[data-variante="nova"] .pd-situacao-atendimento{display:block;font-size:var(--fonte-corpo);margin-top:.25rem}
[data-pagina="crm-pedidos"] .pd-col-atendimento,
.pd-canvas[data-variante="nova"] .pd-col-atendimento{min-width:14rem}
[data-pagina="crm-pedidos"] .pd-ficha__nota,
.pd-canvas[data-variante="nova"] .pd-ficha__nota{display:block;font-size:var(--fonte-corpo);color:#495057}
[data-pagina="separacao_faturamento"] .at{display:flex;flex-direction:column;gap:.75rem;min-height:0;height:100%}
[data-pagina="separacao_faturamento"] .at-barra{display:flex;align-items:center;gap:1rem;flex-wrap:wrap}
[data-pagina="separacao_faturamento"] .at-controle{display:inline-flex;align-items:center;gap:.5rem}
[data-pagina="separacao_faturamento"] .at-chips{display:inline-flex;flex-wrap:wrap;gap:.25rem}
[data-pagina="separacao_faturamento"] .at-corpo{flex:1;min-height:0;display:flex;flex-direction:column}
[data-pagina="separacao_faturamento"] .at-grade{flex:1;min-height:0}
[data-pagina="separacao_faturamento"] .at-grade .grade-filtros-col{display:none}
[data-pagina="separacao_faturamento"] .at-grade th{white-space:pre-line;vertical-align:bottom}
[data-pagina="separacao_faturamento"] .at-col-saldo{text-align:right;font-variant-numeric:tabular-nums;min-width:9rem}
[data-pagina="separacao_faturamento"] .at-col-situacao{min-width:16rem}
/* Lista "Ver pedidos": CLIENTE, VENDEDOR e SITUAÇÃO quebram em vez de cortar numa linha,
   para a SITUAÇÃO (com [Resolver no pedido]) caber em 1280 sem rolar a grade. */
[data-pagina="separacao_faturamento"] #at-lista :is(.at-col-cliente,.at-col-vendedor,.at-col-situacao) .grade-celula{white-space:normal}
[data-pagina="separacao_faturamento"] #at-lista .at-col-cliente{max-width:16rem}
[data-pagina="separacao_faturamento"] #at-lista .at-col-vendedor{max-width:11rem}
[data-pagina="separacao_faturamento"] #at-lista .at-col-situacao{min-width:20rem;max-width:30rem}
[data-pagina="separacao_faturamento"] .at-situacao__linha{display:block}
[data-pagina="separacao_faturamento"] .at-falha{padding:2rem 0;color:#212529}
[data-pagina="separacao_faturamento"] .at-marca{display:block;font-size:var(--fonte-corpo);color:#495057}
[data-pagina="separacao_faturamento"] .at-situacao__acao{display:block;margin-top:.25rem}
[data-pagina="separacao_faturamento"] .at-painel{position:fixed;top:0;right:0;bottom:0;width:min(32rem,100vw);
  background:#fff;border-left:1px solid #dee2e6;z-index:1045;display:flex;flex-direction:column;
  box-shadow:-8px 0 24px rgba(0,0,0,.08)}
[data-pagina="separacao_faturamento"] .at-painel[hidden]{display:none}
[data-pagina="separacao_faturamento"] .at-painel__barra{display:flex;justify-content:space-between;align-items:baseline;
  gap:1rem;padding:1rem;border-bottom:1px solid #dee2e6}
/* min-width:0 + [Fechar] flex:none: em 390 px o título longo espremia o botão até cortar o texto (ensaio HML2 07/10). */
[data-pagina="separacao_faturamento"] .at-painel__titulo{font-size:var(--fonte-destaque);font-weight:500;letter-spacing:.04em;margin:0;min-width:0}
[data-pagina="separacao_faturamento"] #at-painel-fechar{flex:none}
[data-pagina="separacao_faturamento"] .at-painel__corpo{padding:1rem;overflow:auto;display:flex;flex-direction:column;gap:.75rem}
[data-pagina="separacao_faturamento"] .at-painel__corpo p{margin:0}
[data-pagina="separacao_faturamento"] .at-movimentos{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
[data-pagina="separacao_faturamento"] .at-tabela-importacao{width:100%;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"] .at-tabela-importacao td,[data-pagina="separacao_faturamento"] .at-tabela-importacao th{padding:.25rem .5rem .25rem 0}
@media (max-width:1023.98px){
  [data-pagina="separacao_faturamento"] .at-painel{width:100vw;border-left:0}
  [data-pagina="separacao_faturamento"] #at-painel-fechar,
  [data-pagina="separacao_faturamento"] .at-movimentos .fcds-valor,
  [data-pagina="separacao_faturamento"] .at-situacao__acao{display:inline-flex;align-items:center;min-height:44px;min-width:44px}
}
/* Toque (#130): abas, [Ordem de faturamento], Segmento/Subsegmento e os
   valores da SITUAÇÃO tinham 21–33 px de altura. Só no dedo; no mouse ficam como estão. */
@media (max-width:1023.98px),(pointer:coarse){
  [data-pagina="crm-pedidos"][data-tela="nova"] .pd-aba{display:inline-flex;align-items:center;min-height:44px}
}

/* Fase 2 (#130): ações do painel, recusa no lugar, aviso do rodapé (a confirmação é o modal da casa, D13). */
[data-pagina="separacao_faturamento"] .at-acoes{display:flex;flex-direction:column;gap:.5rem}
[data-pagina="separacao_faturamento"] .at-acao{margin:0;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
[data-pagina="separacao_faturamento"] .at-acao--indisponivel span{color:#495057}
[data-pagina="separacao_faturamento"] .at-recusa{border-left:2px solid var(--acc);
  padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
[data-pagina="separacao_faturamento"] .at-recusa{border-left-color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"] .at-recusa p{margin:0;flex-basis:100%}
[data-pagina="separacao_faturamento"] .at-opcoes{padding-left:1rem;display:flex;flex-direction:column;gap:.5rem}
[data-pagina="separacao_faturamento"] .at-situacao__acoes{display:flex;gap:.75rem;align-items:center;margin-top:.25rem;flex-wrap:wrap}
[data-pagina="separacao_faturamento"] .at-historico,[data-pagina="separacao_faturamento"] .at-atendidos{list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:.5rem}
[data-pagina="separacao_faturamento"] .at-painel__subtitulo{font-size:var(--fonte-corpo);font-weight:500;letter-spacing:.04em;margin:.5rem 0 0}
[data-pagina="separacao_faturamento"] .at-rodape{position:fixed;left:50%;bottom:1rem;transform:translateX(-50%);z-index:1050;
  background:#fff;color:#212529;border:1px solid #dee2e6;box-shadow:0 4px 16px rgba(0,0,0,.12);padding:.75rem 1rem;
  display:flex;gap:.75rem;align-items:center;max-width:calc(100vw - 2rem)}
[data-pagina="separacao_faturamento"] .at-rodape[hidden]{display:none}
/* Fase 3 (#130), redesenhada no #273 (dono 06/10): ORDEM DE FATURAMENTO do dia — cabeçalho com os totais,
   o estado numa linha e um cartão (canto 0) com um bloco por pedido: 1º · PEDIDO · CLIENTE · situação · R$,
   e os itens do dia alinhados em colunas (código+descrição | quantidade | situação). */
[data-pagina="separacao_faturamento"] .at-ordem{display:flex;flex-direction:column;gap:.75rem}
[data-pagina="separacao_faturamento"] .at-ordem__titulo{margin:0;font-size:var(--fonte-corpo);font-weight:500;letter-spacing:.04em}
[data-pagina="separacao_faturamento"] .at-ordem__nao-atende{color:var(--ds-perigo)}
/* #273 (dono): pedido/item fora do filtro da tela (outro material, produto ou cliente): etiqueta neutra, tokens do .at (nunca cor de alerta). */
[data-pagina="separacao_faturamento"] .at-ordem__outros{display:inline-block;padding:0 6px;background:var(--ds-filete);color:var(--ds-tinta-2);font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.04em;line-height:1.5}
[data-pagina="separacao_faturamento"] .at-ordem__estado{justify-content:space-between}
[data-pagina="separacao_faturamento"] .at-ordem__estado p{margin:0}
[data-pagina="separacao_faturamento"] .at-ordem__estado[hidden]{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem{min-width:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__erro{color:var(--ds-perigo);font-size:var(--fonte-corpo)}
/* #273 (dono 06/10): a ordem é uma GRADE alinhada, sem cartão nem caixa — as mesmas nove colunas
   no cabeçalho, na linha do pedido e na de cada item; filete de 1px entre pedidos; números à
   direita, tabulares. Abaixo de ~600 px de largura a grade vira bloco por pedido, com o rótulo
   de cada número (data-rotulo), sem rolagem lateral. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem{container-type:inline-size;--colunas-da-ordem:2.75rem 5.25rem minmax(6rem,1fr) 4.5rem 4.75rem 5.75rem 6.25rem 8.5rem minmax(9rem,13rem)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__grade{min-width:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__fila{display:grid;grid-template-columns:var(--colunas-da-ordem);column-gap:.5rem;align-items:baseline}
/* ENTREGAR EM e SEPARAR EM (Task 4) não cabem numa linha da coluna estreita: o cabeçalho quebra. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__colunas > span{white-space:normal}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__colunas{padding:0 0 .375rem;border-bottom:1px solid var(--ds-filete);font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.08em;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__lista{list-style:none;margin:0;padding:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__linha{padding:.375rem 0;background:#fff}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__linha + .at-ordem__linha{border-top:1px solid var(--ds-filete)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__cabeca{min-height:32px;align-items:center}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__ordinal{display:inline-flex;align-items:center;gap:.25rem;font-weight:500;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pedido{display:inline-flex;align-items:center;gap:.375rem;white-space:nowrap;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__cliente{min-width:0;overflow-wrap:anywhere}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__entrega,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__separacao{font-variant-numeric:tabular-nums;white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__quantidade,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__valor{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__colunas .at-ordem__quantidade,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__colunas .at-ordem__valor{text-align:right}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__situacao{min-width:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__faturado{color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__itens{list-style:none;margin:0;padding:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item{font-size:var(--fonte-corpo);padding:.125rem 0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item .at-ordem__produto{padding-left:1rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__situacao--atende{color:var(--ds-tinta-2)}
/* O pedido agrupador (dono, 06/10): "Outros itens deste pedido: 1 em 25/10" sob os itens, recuada como o
   produto (colunas 1 e 2 + vãos + 1rem). Cada link é alvo da altura da linha (32 px; 44 no toque). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pista{display:flex;flex-wrap:wrap;align-items:stretch;column-gap:.25rem;min-height:32px;margin:0;padding-left:10rem;font-size:var(--fonte-pequena);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pista > span{align-self:center}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pista .fcds-siglink{display:inline-flex;align-items:center}
@media (pointer:coarse){[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pista{min-height:44px}}
/* AÇÃO do item (#273, sem menu): a sugestão (botão) e "Trocar importação" (link) empilhados; o rótulo quebra,
   nunca corta. O link é alvo do próprio tamanho (32 px; 44 no toque). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao{display:flex;flex-direction:column;align-items:flex-start;gap:.125rem;min-width:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao .btn{white-space:normal;text-align:left}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao .fcds-siglink{display:inline-flex;align-items:center;min-height:32px;text-align:left}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao .at-recusa{width:100%;font-size:var(--fonte-pequena)}
/* Gesto local (frontend instantâneo): enquanto grava, a AÇÃO do item sai e a SITUAÇÃO diz "Salvando…". */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item--salvando .at-ordem__acao > button{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item--salvando + .at-ordem__opcoes{display:none}
/* As opções de "Trocar importação" abrem sob o item, recuadas como o produto, uma linha-alvo cada, sem caixa. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__opcoes ul{list-style:none;margin:0;padding:0 0 0 10rem;font-size:var(--fonte-corpo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__opcoes .at-recusa{margin-left:10rem;font-size:var(--fonte-pequena)}
@media (pointer:coarse){[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao .fcds-siglink{min-height:44px}}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__situacao--em_parte{color:var(--warning-text)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__situacao--nao_atende{color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__rodape{margin:0;font-size:var(--fonte-corpo);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__rodape:empty{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__rotulo{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* Revisão N6 + AÇÃO (#273): a grade pede ~908 px (37.75rem fixos + 9rem de AÇÃO + 6rem de cliente + 8 vãos de .5rem
   = 56.75rem); abaixo disso, bloco. */
@container (max-width:56.75rem){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__fila{display:flex;flex-wrap:wrap;gap:.125rem .75rem}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__colunas.at-ordem__fila{display:none}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__fila > span:empty{display:none}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__cliente,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item .at-ordem__produto{flex-basis:100%}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item .at-ordem__produto{padding-left:0}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__item{padding:.25rem 0 .25rem 1rem}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__pista{padding-left:1rem}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__acao{flex-basis:100%}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__opcoes ul{padding-left:1rem}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__opcoes .at-recusa{margin-left:1rem}
  /* Sem o cabeçalho, o nome da coluna aparece nas datas e na quantidade do item (o mesmo rótulo do leitor de tela). */
  [data-pagina="separacao_faturamento"][data-tela="programacao"] :is(.at-ordem__entrega,.at-ordem__separacao,.at-ordem__item .at-ordem__quantidade) .at-ordem__rotulo{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto;font-size:var(--fonte-rotulo);letter-spacing:.08em;color:var(--ds-tinta-2)}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__quantidade,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__valor{text-align:left}
}
/* #273: arrastar pela linha inteira (a alça é o sinal, o alvo do dedo e o foco do teclado ↑/↓); a linha-alvo ganha o fio azul do lado em que a origem vai entrar. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__linha[data-posicao]{cursor:grab}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__salvando{color:var(--ds-tinta-2);font-size:var(--fonte-pequena)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem--salvando .at-ordem__posicao-texto{opacity:.35}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__alca{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;cursor:grab;touch-action:none;user-select:none;color:#595A5C}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__alca:focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__linha--arrastando{background:var(--ds-selecionado-tinta)}
body.at-arrastando{cursor:grabbing;user-select:none}
/* Fantasma do arrasto (fábrica `ligarArrasto`, painel do dia e lista PROGRAMAÇÃO; dono 09/10/2026): o cartão segue
   o ponteiro; a linha mesma troca de lugar na pré-visualização, com as vizinhas deslizando (FLIP no JS). */
.at-arrasto__fantasma{position:fixed;left:0;top:0;z-index:1080;pointer-events:none;max-width:26rem;padding:.4rem .75rem;
  border:1px solid var(--ds-acao);border-radius:var(--bs-border-radius-sm);background:#fff;color:var(--ds-tinta);
  font-size:var(--fonte-corpo);font-weight:500;
  box-shadow:0 8px 24px rgba(22,22,22,.18);transform:translate(-9999px,-9999px);animation:at-fantasma-entra .12s ease-out}
@keyframes at-fantasma-entra{from{opacity:0;scale:.96}to{opacity:1;scale:1}}
.at-arrasto__marcador{position:fixed;left:0;top:0;width:0;height:0;z-index:1079;pointer-events:none;
  border-top:3px solid var(--ds-acao);opacity:0;transition:top .12s ease-out,left .12s ease-out,width .12s ease-out,opacity .12s}
.at-arrasto__marcador::before{content:'';position:absolute;left:-5px;top:-7px;width:11px;height:11px;border-radius:50%;background:var(--ds-acao)}
.at-arrasto__marcador--visivel{opacity:1}
/* Calendário (#130, spec 16ª 4.3–4.4): célula = um alvo; cor só em área, forma diz o estado; altura medida pelo JS. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-barra--navegacao{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-legenda{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin:.25rem 0;color:#212529;font-size:var(--fonte-corpo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-legenda__titulo{color:var(--ds-tinta-2);font-size:var(--fonte-pequena)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-quadradinho{display:inline-block;width:12px;height:12px;border-radius:0;vertical-align:middle;border:2px solid transparent;box-sizing:border-box}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-quadradinho--atende{background:var(--ds-sucesso);border-color:var(--ds-sucesso)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-quadradinho--em_parte{background:linear-gradient(135deg,var(--ds-atencao) 50%,#fff 50%);border-color:var(--ds-atencao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-quadradinho--nao_atende{background:linear-gradient(45deg,transparent 40%,#fff 40% 60%,transparent 60%),linear-gradient(-45deg,transparent 40%,#fff 40% 60%,transparent 60%),var(--ds-perigo);border-color:var(--ds-perigo)}
/* #273: o `*` do pedido sem dias de separação — botão que leva ao campo (44px só no toque); no MÊS e na legenda, só marca */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-asterisco{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;padding:0;border:0;background:none;color:var(--warning-text);font-weight:500;cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-asterisco--marca{min-width:0;min-height:0;cursor:inherit}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-asterisco:focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-mes{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));grid-template-rows:auto;grid-auto-rows:minmax(min-content,1fr);min-height:100%;border-top:1px solid #dee2e6;border-left:1px solid #dee2e6}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-mes__semana{display:contents}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-mes__sigla{font-size:var(--fonte-pequena);font-weight:500;padding:.25rem .5rem;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6;background:#fff}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-mes__celula{border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6;min-width:0;min-height:88px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;height:100%;min-height:44px;padding:.25rem .5rem;border:0;border-radius:0;background:#fff;color:#212529;text-align:left;font-size:var(--fonte-corpo);cursor:pointer;overflow:hidden}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia:hover{background:var(--ds-selecionado-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia:has(.at-dia__abrir:focus-visible){outline:2px solid var(--ds-acao);outline-offset:-2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia--passado{background:#f8f9fa}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia--fora{background:#f8f9fa;color:#495057}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia--fora .at-dia__numero{font-weight:400}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia__numero{font-weight:500}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia--hoje .at-dia__numero{background:var(--ds-acao);color:#fff;padding:0 .25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia__perigo{color:var(--ds-perigo);font-weight:500}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia__mais{font-size:var(--fonte-pequena);font-weight:500}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia__total,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-dia__chegada{display:block;max-width:100%;overflow-wrap:anywhere}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-corpo:has(>.at-mes){overflow:auto}
/* A origem da previsão lê no Conexos: o logo-loader do app precisa de altura para aparecer na linha. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] #at-origem-da-previsao[data-bi-loading]{min-height:2.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-pedido-do-dia{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;min-height:44px;padding:.25rem 0;border-bottom:1px solid #dee2e6}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-pedido-do-dia__item{display:block;flex-basis:100%;padding-left:1.25rem}
/* #273 rodada 11 + AÇÃO: a ordem em grade de 9 colunas precisa de mais largura que os cartões. De 1024 px até
   ~1100 px de tela o painel (85vw) ainda fica abaixo dos 908 px da grade, e ela vem em bloco; abaixo de 1024 px
   o painel ocupa a tela. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-painel.at-painel--largo{width:min(1120px,85vw)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-negativo{color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-lista-por-dia__dia{border-bottom:1px solid #dee2e6;padding:.25rem 0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-lista-por-dia__cabecalho{display:flex;flex-direction:column;align-items:flex-start;width:100%;min-height:44px;padding:.25rem .5rem;border:0;border-bottom:1px solid #dee2e6;border-radius:0;background:#fff;color:#212529;text-align:left;font-weight:500;cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-lista-por-dia__cabecalho:hover{background:var(--ds-selecionado-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-lista-por-dia__cabecalho:focus-visible{outline:2px solid var(--ds-acao);outline-offset:-2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-lista-por-dia__pedidos{list-style:none;margin:0;padding:.25rem .5rem}
/* #273 (dono 06/10, "não tem hierarquia visual"): o painel do pedido de cima para baixo —
   "‹ Dia" na linha do [Fechar], quem (cliente, representante em tinta 2), a faixa de situação
   na cor do estado, o número que falta entregar grande, três datas rótulo/valor, COMO ATENDER
   com UM botão cheio (a sugestão) e o resto em texto, e o histórico. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel__barra:has(.at-painel__voltar){flex-wrap:wrap;align-items:center;row-gap:.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel__voltar{margin-top:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel__voltar ~ .at-painel__titulo{order:2;flex-basis:100%}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__quem p{margin:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__cliente{font-size:var(--fonte-corpo);font-weight:500;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__representante{font-size:var(--fonte-corpo);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido{padding:.5rem .75rem;font-size:var(--fonte-corpo);font-weight:500;letter-spacing:.04em;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido .fcds-valor{letter-spacing:inherit}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido--encerrado{background:var(--surf-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido--atende{background:color-mix(in srgb,var(--ds-sucesso) 10%,#fff)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido--em_parte{background:color-mix(in srgb,var(--ds-atencao) 14%,#fff)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido--nao_atende{background:color-mix(in srgb,var(--ds-perigo) 8%,#fff);color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__quanto p{margin:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__produto{font-size:var(--fonte-corpo);color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__falta{font-size:var(--fonte-corpo);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__falta strong{font-size:var(--fonte-titulo);font-weight:500;line-height:1.2;color:var(--ds-tinta);font-variant-numeric:tabular-nums;margin-right:.25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__secundario{font-size:var(--fonte-pequena);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-datas{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;margin:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-datas dt{font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.08em;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-datas dd{margin:0;font-size:var(--fonte-corpo);color:var(--ds-tinta);font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__secao{border-top:1px solid var(--ds-filete);padding-top:.75rem;display:flex;flex-direction:column;gap:.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-pedido__secao .at-painel__subtitulo{margin:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao__chegada{margin:0;font-size:var(--fonte-corpo);color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao__atraso{color:var(--warning-text)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao__chegada .at-acao__atraso::before{content:'· ';color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acoes__rotulo{font-size:var(--fonte-pequena);font-weight:500;letter-spacing:.08em;color:var(--ds-tinta-2);margin:.5rem 0 0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acoes__importacoes{list-style:none;margin:0;padding:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-opcoes.at-acoes__importacoes{padding-left:1rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acoes__importacoes .at-acao{flex-wrap:nowrap;align-items:baseline;gap:.75rem;padding:.375rem 0;border-bottom:1px solid var(--ds-filete);font-size:var(--fonte-corpo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acoes__importacoes .at-acao > .fcds-siglink{margin-left:auto}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao__processo{font-weight:500;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao__perigo{color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-acao .fcds-siglink:disabled{color:var(--ds-tinta-2);text-decoration:none;cursor:default}
/* #273 rodada 5 (dono: "as bordas grossas conversam com o design system?"): bordas levam hierarquia em
   filete de 1px; seleção/hover é tinta clara (--selected-tint), não caixa azul; azul é ação e foco
   (só :focus-visible); overlay é sombra, sem moldura. Valores de design-system/tokens/{colors,elevation}.css. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at{--ds-selecionado-tinta:#F0EDE4;--ds-sombra-overlay:0 24px 64px rgba(22,22,22,.22)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel{border-left:1px solid var(--ds-filete);box-shadow:var(--ds-sombra-overlay)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel:focus,[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-painel:focus-visible{outline:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-recusa{border-left:0;background:color-mix(in srgb,var(--ds-perigo) 8%,#fff)}
/* #273 rodada 2: a nota de "Fora da ordem". */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-datas__nota{display:block;font-size:var(--fonte-pequena);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-estado-do-pedido .fcds-etiqueta{margin-left:.5rem}
/* #273 rodada 3: linha de lista que é UM alvo (OUTROS ITENS, OUTRAS IMPORTAÇÕES, opções de Trocar de
   importação, e as ações em texto empilhadas). O ::after do botão deixa de ser o quadrado de 44 px
   centrado (que, em linhas mais baixas que 44 px, cobria a vizinha e gravava na importação errada)
   e passa a cobrir exatamente a linha; a linha tem 32 px, 44 px no ponteiro grosso. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-linha-alvo{position:relative;min-height:32px;display:flex;align-items:center}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-linha-alvo > button{position:static}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-linha-alvo > button::after{content:'';position:absolute;inset:0;width:auto;height:auto;transform:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-linha-alvo > button:disabled::after{content:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens{list-style:none;margin:0;padding:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens__item{display:flex;align-self:stretch;justify-content:space-between;align-items:center;gap:.75rem;width:100%;padding:.25rem 0;border:0;border-bottom:1px solid var(--ds-filete);border-radius:0;background:none;font:inherit;font-size:var(--fonte-corpo);text-align:left;cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens__nome{color:var(--ds-acao);text-decoration:underline;text-underline-offset:3px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens__situacao{color:var(--ds-tinta-2);font-size:var(--fonte-pequena);text-align:right}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens__item:hover{background:var(--ds-acao-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-outros-itens__item:focus-visible{outline:2px solid var(--ds-acao);outline-offset:-2px}
@media (pointer:coarse){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at :is(.at-acao,.at-situacao__acoes,.at-recusa) .btn,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-linha-alvo{min-height:44px}
}
/* #273 (Task 4, I1): "Cadastrar dias" na célula SEPARAR EM das grades — a célula quebra a linha; 44 px só no toque. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at :is(.at-ordem__separacao,td):has(.at-cadastrar-dias){white-space:normal}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-ordem__separacao:has(.at-cadastrar-dias){align-self:start}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-cadastrar-dias{text-align:left}
@media (pointer:coarse){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-ordem__separacao:has(.at-cadastrar-dias){min-height:44px}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at td:has(.at-cadastrar-dias){height:44px}
}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-motivo--nao_atende{color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-motivo--em_parte{color:var(--warning-text)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-motivo--atende{color:var(--ds-tinta-2)}
/* A linha da LISTA abre a ordem do dia dela: o pedido fica destacado na ordem (tinta de seleção). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-ordem__linha--destaque{background:var(--ds-selecionado-tinta)}
/* #273 (dono 06/10): a célula do MÊS — o número do dia abre o dia e cobre a célula inteira (::after);
   por cima, a mini grade de TODOS os pedidos do dia, sempre 2 colunas de largura igual, cada pedido
   um alvo próprio (ícone + número + `*`); o total do dia em destaque. A linha da semana cresce
   para o dia mais cheio: nada cortado, nada rolando dentro da célula. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia{position:relative;container-type:inline-size}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__abrir{padding:0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__abrir::after{content:'';position:absolute;inset:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__abrir:focus-visible{outline:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedidos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:4px;width:100%;margin:0;padding:0;list-style:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedido{position:relative;z-index:1;display:flex;align-items:center;gap:4px;width:100%;min-height:24px;padding:0;border:0;background:none;color:var(--ds-tinta);font-size:var(--fonte-pequena);line-height:16px;font-variant-numeric:tabular-nums;text-align:left;cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedido:hover{text-decoration:underline}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedido:focus-visible{outline:2px solid var(--ds-acao);outline-offset:-1px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedido .at-asterisco--marca{margin-left:-2px}
@media (pointer:coarse){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedido{min-height:44px}
}
/* #273 rodada 9: 2 × ~56 px ("[ícone] 21515*") + o intervalo não cabem: 1 coluna, no mouse
   também (entre 1024 e 1150 px de janela o número era cortado). 24 px de alvo: WCAG 2.5.8. */
@container (max-width:115px){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__pedidos{grid-template-columns:minmax(0,1fr)}
}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at .at-dia__total{font-size:var(--fonte-corpo);font-weight:500;color:var(--ds-tinta)}
/* Onda D (#130, portão do calendário): o MÊS cabe na janela (sem rolagem interna), os alvos têm 44 px. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at{gap:.375rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-barra--controles{gap:8px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-controle{gap:.25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-chips{flex-wrap:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-legenda{margin:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-mes__celula{min-height:44px}
/* F2: o aviso do rodapé fica à esquerda, longe do painel, e o painel ganha folga para rolar por baixo dele. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-rodape{left:1rem;transform:none;max-width:min(36rem,calc(100vw - 2rem))}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at:has(.at-rodape:not([hidden])) .at-painel__corpo{padding-bottom:7rem}
@media (min-width:1024px){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at:has(.at-painel:not([hidden])) .at-rodape{max-width:calc(40vw - 1.5rem)}
}
/* Topo em 3 faixas (#273, dono 06/10: "o painel de ações no topo é bagunçado"): faixa do período
   (‹ Hoje › + o rótulo que é o seletor de dia; CALENDÁRIO | LISTA à direita), faixa dos filtros
   (ATRASADOS à direita) e um filete antes do conteúdo. 8px entre controles, 16px entre grupos. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-topo{display:flex;flex-direction:column;gap:8px;padding-bottom:8px;border-bottom:1px solid var(--ds-filete)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-faixa{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-faixa--filtros{gap:8px 16px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-faixa__direita{margin-left:auto;display:flex;align-items:center;gap:16px;flex-wrap:wrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-periodo{margin-left:8px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-periodo .fcds-seletor__chave{display:inline}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-periodo .fcds-seletor__valor{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-voltar{align-self:flex-start}
/* Estado da ordem, Histórico e [Confirmar] numa faixa só. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__estado{gap:8px 16px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__estado #at-ordem-estado{flex:1 1 auto}
/* 390: filtros recolhidos num botão; o primeiro dia aparece na primeira tela. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-filtros-botao{display:none}
@media (max-width:1023.98px){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-filtros-botao{display:inline-block;align-self:flex-start}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-barra--controles:not(.at-barra--aberta){display:none}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-legenda{gap:.25rem .5rem}
}
@media (max-width:1023.98px){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-painel.at-painel--largo{width:100vw}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at{height:auto}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-corpo{flex:none}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-faixa__direita{flex-basis:100%;margin-left:0}
}
/* #273 (dono 06/10, "botões grandes, desproporcionais"): no mouse a barra e os controles da ordem são
   os -sm de fábrica (31px). Os 44px de alvo ficam só no ponteiro grosso. */
@media (pointer:coarse){
  [data-pagina="separacao_faturamento"] .at-ordem__estado .btn,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at .colfilter-multi__trigger,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-barra--navegacao .btn,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-barra--navegacao .fcds-seletor__botao,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] #at-ordem-dia .fcds-seletor__botao,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-filtros-botao,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__alca,
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-asterisco:not(.at-asterisco--marca){min-height:44px;min-width:44px}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .at :is(.fcds-valor,.fcds-siglink){display:inline-flex;align-items:center;min-height:44px;min-width:44px}
}
/* O painel lateral nasce ABAIXO da barra do topo (mesma régua do `.offcanvas-end` do shell, `top:52px`),
   para o Reportar da barra ser o único. */
body.stm-shell [data-pagina="separacao_faturamento"][data-tela="programacao"] .at-painel{top:var(--topbar-h, 52px)}

/* ── Editar pedido e item no pedido aberto da tela nova (#217) ──────────────
   Só a tela nova carrega `pedido-edicao.js`, então estas regras (todas sob
   `data-tela="nova"`) não alcançam a antiga. Botão e campo são os -sm de
   fábrica; a confirmação é caixa reta, sem sombra. Sem marrom nem
   âmbar: o tom "incerto" é a tinta comum com fio à esquerda. */
.pd-canvas[data-variante="nova"] .pd-edicao__form {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-start;
}
.pd-canvas[data-variante="nova"] .pd-edicao__form .form-control,
.pd-canvas[data-variante="nova"] .pd-edicao__form .form-select { max-width: 24rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__form textarea.form-control {
  width: 100%; max-width: 36rem;
}
/* "Mudar a entrega de vários itens" (#273): uma caixa por item, empilhadas; a data, a nota e o erro abaixo. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos { margin-top: .75rem; align-items: center; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos fieldset {
  flex-basis: 100%; display: flex; flex-direction: column; gap: .25rem; margin: 0; font-size: .875rem;
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos legend {
  font-size: .75rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; margin-bottom: .25rem;
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos fieldset label { display: flex; gap: .5rem; align-items: center; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos .pd-edicao__nota,
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos .pd-edicao__erro {
  flex-basis: 100%; margin: 0; font-size: .8125rem;
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos .pd-edicao__erro { color: var(--pd-alerta); }
.pd-canvas[data-variante="nova"] .pd-edicao__itens-escolhidos .pd-edicao__erro:empty { display: none; }
.pd-canvas[data-variante="nova"] .pd-edicao__motivo {
  color: var(--bs-secondary-color, #495057); font-size: .8125rem;
}
/* O motivo do campo travado desce para a linha de baixo do valor (nunca colado nele). */
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__motivo {
  display: block; white-space: normal; min-width: 6rem;
}
/* A grade editável (como a F120GPD): o campo mora na célula, do tamanho do valor; a linha recusada leva o
   motivo logo abaixo; os cabeçalhos numéricos alinham à direita, com os valores, e nenhum quebra. */
.pd-canvas[data-variante="nova"] .pd-edicao__celula { display: inline-block; }
.pd-canvas[data-variante="nova"] .pd-edicao__celula[inputmode="decimal"] { width: 6.5rem; text-align: right; }
.pd-canvas[data-variante="nova"] .pd-edicao__celula[type="date"] { width: 9rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__com-unidade {
  display: inline-flex; align-items: center; gap: .25rem;
}
.pd-canvas[data-variante="nova"] .pd-edicao__linha-nova [name="produto"] { min-width: 14rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__linha-motivo td {
  white-space: normal; padding-top: 0; color: var(--pd-alerta); font-size: .8125rem;
}
/* A FAIXA de números (#307, A.2): quatro números numa faixa com fio em cima e embaixo, sem caixa; o líquido
   domina (20/600), os outros 13/500 (revisão do DS, 08/10). */
.pd-canvas[data-variante="nova"] .pd-faixa {
  display: flex; flex-wrap: wrap; gap: .5rem 2rem; padding: .75rem 0; margin: 0 0 .25rem;
  border-block: 1px solid var(--pd-fio);
}
.pd-canvas[data-variante="nova"] .pd-faixa__par { display: flex; flex-direction: column; gap: .125rem; }
.pd-canvas[data-variante="nova"] .pd-faixa__numero { font-size: .8125rem; font-weight: 500; font-variant-numeric: tabular-nums; line-height: 1.2; }
.pd-canvas[data-variante="nova"] .pd-faixa__par--liquido .pd-faixa__numero { font-size: 1.25rem; font-weight: 600; }
.pd-canvas[data-variante="nova"] .pd-faixa__rotulo { font-size: .75rem; color: var(--pedido-tinta-2); }
.pd-canvas[data-variante="nova"] .pd-doc-cel--acao { width: 2.5rem; text-align: center; }
/* O drill do atendimento é o CÓDIGO do item: pontilhado em repouso, sólido no hover (revisão do DS). */
.pd-canvas[data-variante="nova"] .pd-cel-codigo__drill { color: inherit; text-decoration: underline dotted; text-underline-offset: 2px; }
.pd-canvas[data-variante="nova"] .pd-cel-codigo__drill:hover { text-decoration-style: solid; color: var(--ds-acao); }
/* Condição, dias de separação e observações (#323): pares da ficha do dossiê (`#pd-ficha-edicao`); na edição
   viram campos que gravam ao sair. O motivo da capa travada vem uma vez, acima deles. */
.pd-canvas[data-variante="nova"] .pd-capa-campos__motivo { font-size: .8125rem; color: var(--pedido-tinta-2); }
.pd-canvas[data-variante="nova"] .pd-edicao__campo-erro { display: block; margin-top: .25rem; font-size: .8125rem; color: var(--warning-text); }
.pd-canvas[data-variante="nova"] .pd-edicao[hidden] { display: none; }
/* CANCELADOS em tinta-2 (não tinta-3: contraste), #323. */
.pd-canvas[data-variante="nova"] .pd-edicao__item--cancelado td,
.pd-canvas[data-variante="nova"] .pd-edicao__item--cancelado .pd-ficha__nota {
  color: var(--ds-tinta-2, #595A5C);
}
.pd-canvas[data-variante="nova"] .pd-canvas__motivo { font-size: .75rem; color: var(--pedido-tinta-2); }
.pd-canvas[data-variante="nova"] .pd-canvas__motivo:empty { display: none; }
.pd-canvas[data-variante="nova"] {
  --crm-ok: var(--positive-text);  --crm-ok-fundo: var(--positive-subtle);
  --crm-avi: var(--warning-text);  --crm-avi-fundo: var(--warning-subtle);
  --crm-mal: var(--negative-text); --crm-mal-fundo: var(--negative-subtle);
  --crm-acento: var(--ds-acao);    --crm-acento-fundo: var(--ds-acao-tinta, #e7eff7);
  --crm-tinta-2: var(--ds-tinta-2, #595A5C);
}
/* Situação = pílula tint + ponto (dono, 08/10): o texto é tinta, só o ponto leva a cor da situação. */
.pd-canvas[data-variante="nova"] .crm-pilula {
  border-radius: 999px; padding: .125rem .6rem .125rem .5rem; font-size: var(--fonte-pequena); font-weight: 500; color: var(--ds-tinta);
}
.pd-canvas[data-variante="nova"] .crm-pilula__ponto { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ds-tinta-3, #7C7D7F); }
.pd-canvas[data-variante="nova"] .crm-pilula--ok .crm-pilula__ponto { background: var(--crm-ok); }
.pd-canvas[data-variante="nova"] .crm-pilula--aviso .crm-pilula__ponto { background: var(--ds-atencao); }
.pd-canvas[data-variante="nova"] .crm-pilula--erro .crm-pilula__ponto { background: var(--ds-perigo); }
.pd-canvas[data-variante="nova"] .crm-pilula--acento .crm-pilula__ponto { background: var(--ds-acao); }
/* A camada Separar e a trilha (U7). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-camada[hidden] { display: none; }
/* #354: a superfície mede `100dvh - 52px` (a janela inteira menos a topbar), mas aqui a trilha vem em cima dela — o
   rodapé passava 32 px do fim da janela e o `.main` (overflow:hidden) cortava a linha "Encerrar o saldo" e a última
   linha das listas. Na camada, quem dá a altura é o flex: a trilha leva a dela e a superfície fica com o resto. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-camada:not([hidden]) {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-camada > .wsurface { flex: 1 1 auto; min-height: 0; height: auto; }
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-trilha {
  display: flex; align-items: center; gap: .5rem; margin: 0 0 .75rem; font-size: var(--fonte-corpo); color: var(--ds-tinta-2, #595A5C);
}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-trilha__elo {
  background: none; border: 0; padding: 0; font: inherit; color: var(--ds-acao); text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-trilha__atual { color: var(--ds-tinta); font-weight: 500; }
/* #307 (Tasks 2.3/2.3b/2.3c; spec visual no plano docs/superpowers/plans/2026-10-08-atendimento-e-separacao-unificados.md,
   Apêndices C e D): a lista PROGRAMAÇÃO na grade da casa, com a casca, a densidade e a tipografia de Pedidos e Notas
   Fiscais (dono, 09/10/2026). Tabela FLUIDA — `table-layout: fixed`, largura por coluna no <th> pela classe, CLIENTE
   (17%) e ITEM (o resto) elásticas, nunca rola na horizontal (1512 px úteis em 1600). Linha de 36 px; 44 na cabeça do
   bloco, que leva a emissão sob o número. Hierarquia: pedido (600) › código do item (500, pontilhado, o único drill) ›
   o resto (400, 14 px). ESTÁGIO ponto + texto como Pedidos; DISPONIBILIDADE é a única pílula da linha, com o tint da
   cor do estado. Cabeçalho de grupo de 32 px com o resumo na mesma linha. Só tokens do DS; nada de âmbar. */
/* Larguras DINÂMICAS (dono, 09/10/2026, #323): `table-layout:auto` como Pedidos e NF. As colunas estreitas
   (datas, quantidade, estágio, botão) declaram a largura e o conteúdo nunca passa dela; ITEM toma o que o
   código + descrição pedem (teto de 20rem, ANTES do cliente); CLIENTE fica com a sobra (`width:100%` +
   `max-width:0`, nunca abaixo de 8rem), com a reticência na própria célula e o `.grade-celula` inline — um
   bloco interno medindo a si mesmo dentro de célula com teto saía em branco no Chrome. Zero rolagem
   horizontal: as colunas esparsas nascem ocultas (dono, 09/10/2026). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela{table-layout:auto;width:100%}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-ordem{width:76px;max-width:5rem;padding-right:.25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-pedido{width:96px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-cliente{width:11rem;min-width:9rem;max-width:12rem;overflow:hidden;white-space:normal}   /* `max-width:0` zerava a célula e o nome sumia (09/10) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela td.pg-col-cliente .grade-celula{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;line-height:1.15;overflow-wrap:anywhere}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-item{width:13rem;min-width:12rem;max-width:13rem;white-space:normal}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela td.pg-col-item .grade-celula{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;line-height:1.15;overflow-wrap:anywhere}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-entrega{max-width:8.5rem}
/* As colunas que herdaram a linha-filha (dono, 09/10/2026): teto de largura, senão uma frase longa ou uma dúzia de
   ações num item só esticam a coluna para milhares de px e esmagam CLIENTE (medido: 5.382 px em OUTRAS AÇÕES). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-processos{max-width:12rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-outros-dias{max-width:12rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-outras-acoes{max-width:11rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela td.pg-col-outras-acoes .grade-celula{white-space:normal;line-height:1.3}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-estagio{width:140px;max-width:8.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-entrega{width:96px;padding-right:.25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-separar{width:112px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-quantidade{width:96px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-disponibilidade{width:172px;max-width:12rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-acao{width:96px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela td.pg-col-acao:not(.pg-col-acao--vazia){padding-left:.6rem}   /* respiro do fio preto do hover (1ª coluna) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-acao--vazia,[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela td.pg-col-acao--vazia{width:0;padding:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-acao-link{display:block;margin:0;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap;color:var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-acao-link:disabled{color:var(--ds-tinta-3);text-decoration:none;cursor:default}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .at-ordem__motivo{display:block;font-size:var(--fonte-pequena);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-segmento{width:112px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-subsegmento{width:144px;max-width:8rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-representante{width:160px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-valor{width:104px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-financeiro{width:96px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-observacao{width:18%}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-quantidade,[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-valor{text-align:right}
/* densidade de Pedidos: 14 px, linha de 36 px (6 + 23 + 6 + fio; a pílula de 22 px é a célula mais alta); 44 na cabeça do bloco */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela tbody td{padding:6px .75rem 6px 0;vertical-align:top;font-size:14px;line-height:1.5}
/* SEM hover de linha (dono, 09/10/2026: "já falei para remover o hover effect"): a linha e o bloco mesclado leem
   como uma coisa só, sem fundo mudando sob o ponteiro. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela tbody tr.grade-linha:hover,
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela tbody tr.grade-linha:hover > td{background:transparent;box-shadow:none}
/* Coluna congelada sem diferença nenhuma (dono, 09/10/2026: "um padrão só"): mesmo branco da linha, sem o fio na
   borda do painel congelado. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols > tbody > tr > td[class*="stick--"],[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols > tbody > tr:hover > td[class*="stick--"]{background:#fff}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols td.stick--edge::after,[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols th.stick--edge::after{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela .grade-celula{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* hierarquia: pedido › código do item › resto; a emissão (data e hora, sempre) é a 2ª linha da cabeça do bloco */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-pedido{margin-top:0;font-size:15px;font-weight:600;line-height:21px;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-emissao{display:block;margin-top:-2px;font-size:12px;line-height:12px;color:var(--ds-tinta-2);font-variant-numeric:tabular-nums}   /* --ds-tinta-2: 7:1; a tinta-3 dava 4,0:1 (M13) */
/* Bloco do pedido lê como célula mesclada (dono, 09/10): sem fio entre as linhas do bloco e sem repetir as ações. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela tbody tr.grade-linha:has(+ tr.pg-linha--continua) td{border-bottom:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua .pg-acao-link{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua .pg-pedido{visibility:hidden;pointer-events:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua td.pg-col-cliente{text-overflow:clip}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua .pg-emissao{display:none}
/* O motivo do bloqueio sob "Bloqueado" (dono, 09/10/2026, #323): a mesma 2ª linha da emissão, só na cabeça do bloco. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] :is(.pg-estagio-motivo,.pg-sublinha){display:block;margin-top:-2px;font-size:12px;line-height:12px;color:var(--ds-tinta-2);font-weight:400;white-space:normal;overflow-wrap:anywhere}   /* quebra em vez de cortar (dono, 09/10) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua :is(.pg-estagio-motivo,.pg-sublinha:not(.pg-sublinha--dias)){display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-separacao{margin-left:.25rem;border-bottom:0;vertical-align:middle}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--continua :is(.pg-ordem,.pg-col-cliente,.pg-col-estagio) .grade-celula{visibility:hidden}   /* ordem, cliente e estágio são do PEDIDO: só na cabeça do bloco (dono, 09/10) */
/* O código do item não é mais drill (a linha-filha saiu, dono 09/10/2026): só peso, sem fio. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-item-codigo{font-weight:500;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-item-descricao{margin-left:.35em;font-weight:400}
/* estágio: a anatomia e as cores da coluna ESTÁGIO de Pedidos (.pd-estagio-marca + .pd-e-<estagio>, tokens --pedido-*) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-estagio .grade-celula{font-size:13px}
/* datas, atraso UMA vez (SEPARAR EM); sem dias de separação é "—" com o motivo no title */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-entrega .grade-celula,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-separar .grade-celula{font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-sem-dias-celula{color:var(--ds-tinta-3);cursor:help}
/* ENTREGAR EM editável (Task 4.1, A7): em repouso só o texto; ao passar/focar, fio inferior na cor da ação e o
   lápis Lucide de 14 px. O campo de data substitui o texto na célula, 22 px para a linha ficar em 36. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entrega{background:none;border:0;border-bottom:1px solid transparent;padding:0;font:inherit;color:var(--ds-tinta);cursor:pointer;display:inline-flex;align-items:center;gap:.25rem;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entrega__lapis{width:14px;height:14px;color:var(--ds-acao);visibility:hidden}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:hover .pg-entrega,[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:focus-within .pg-entrega{border-bottom-color:var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:hover .pg-entrega__lapis,[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:focus-within .pg-entrega__lapis,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entrega:focus-visible .pg-entrega__lapis{visibility:visible}
/* O botão do histórico (entrega e separação, #388): ícone da casa ao lado da data, à vista no hover como o lápis;
   abre a linha-filha da grade (drill nativo, sem balão). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico{display:inline-flex;align-items:center;margin-left:.25rem;padding:0;border:0;background:none;color:var(--ds-acao);cursor:pointer;vertical-align:middle;visibility:hidden}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico__icone{width:14px;height:14px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:hover .pg-historico,[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:focus-within .pg-historico,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico[aria-expanded="true"]{visibility:visible}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico:focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe{padding:.25rem 0;font-size:var(--fonte-pequena);line-height:1.2;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe__titulo{margin:0 0 .25rem;font-weight:500;font-size:var(--fonte-rotulo);letter-spacing:.04em;text-transform:uppercase;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe__lista{margin:0;padding:0;list-style:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe__linha{display:grid;grid-template-columns:8.5rem 10rem minmax(0,1fr) auto;gap:.75rem;padding:.25rem 0;border-top:1px solid var(--ds-filete)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe__quando{font-variant-numeric:tabular-nums;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-historico-detalhe__origem{color:var(--ds-tinta-2);white-space:nowrap}
/* Histórico do estágio (#388 fatia 6): linha-filha da grade, "data hora · o quê · quem"; o tom pinta só o ponto. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico{font-size:12px;line-height:1.35;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__titulo{margin:0 0 .25rem;font-weight:600;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__lista{margin:0;padding:0;list-style:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__item{display:grid;grid-template-columns:8.5rem minmax(0,1fr) 10rem;gap:.75rem;align-items:baseline;padding:.2rem 0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__quando{font-variant-numeric:tabular-nums;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__o-que::before{content:"";display:inline-block;width:6px;height:6px;margin-right:.45rem;border-radius:50%;background:var(--ds-tinta-2);vertical-align:middle}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__item--perigo .pg-estagio-historico__o-que::before{background:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__item--sucesso .pg-estagio-historico__o-que::before{background:var(--ds-sucesso)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__quem{color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-estagio-historico__vazio{margin:0;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entrega__campo{width:8rem;position:relative;z-index:2}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-entrega .grade-celula{overflow:visible}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr[aria-busy="true"] .pg-entrega{color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-atrasado{color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-atrasado small{display:inline-block;margin-left:.35em;font-size:var(--fonte-pequena);color:inherit}
/* quantidade: número forte, unidade fraca */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-quantidade .grade-celula{font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-unidade{margin-left:.25em;font-size:var(--fonte-pequena);color:var(--ds-tinta-2)}
/* ordem: só a alça (22px de toque), o ordinal curto e as setas em hover/focus */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ordem{white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-sem-ordem td.pg-ordem .grade-celula{visibility:hidden}   /* ordenada por outra coluna: sem ordinal (M8) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-varrendo{margin-left:.75rem;font-size:var(--fonte-corpo);color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] td.pg-ordem .grade-celula{display:flex;align-items:center;height:22px;line-height:1;overflow:visible}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-alca,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-seta{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:0;background:none;color:var(--ds-tinta-3);vertical-align:middle}
/* As setas não ocupam lugar (dono, 09/10): escondidas até receberem foco pelo teclado. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ordem__setas{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ordem__setas:focus-within{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-alca{cursor:grab}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-alca:active{cursor:grabbing}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-alca:hover,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-seta:hover{color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ordem__ordinal{margin-left:.15rem;font-size:var(--fonte-pequena);font-weight:500;line-height:1;font-variant-numeric:tabular-nums;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ordem__setas{visibility:hidden;display:inline-flex;margin-left:.15rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:hover .pg-ordem__setas,[data-pagina="separacao_faturamento"][data-tela="programacao"] tr:focus-within .pg-ordem__setas{visibility:visible}
/* cabeçalho de grupo (Apêndice D, seção 4): SÓ o dia — uma linha de 28 px, 12 px 700 caixa alta tinta-2, fio superior
   de 1 px; ATRASADOS em perigo com fio de 2 px. Sem resumo (dono, 09/10). A grade é contínua, sem respiro entre dias. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr.grade-grupo td{padding:0;border-top:0;border-bottom:0;background:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo{display:flex;align-items:center;gap:.4rem;height:28px;padding:0 0 0 .6rem;border-top:1px solid var(--ds-filete-2);background:none;font-size:12px;line-height:1;letter-spacing:.04em;text-transform:uppercase;color:var(--ds-tinta-2);white-space:nowrap;overflow:hidden}
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr.grade-grupo:first-child .pg-grupo{border-top:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo__titulo{font-weight:700;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo__alternar{display:inline-flex;align-items:center;gap:.25rem;margin:0 0 0 -.25rem;padding:0 .25rem;border:0;background:none;font:inherit;letter-spacing:inherit;text-transform:inherit;cursor:pointer;color:inherit}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo__seta{width:14px;height:14px;color:var(--ds-tinta-2);transition:transform .12s}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo__alternar[aria-expanded="true"] .pg-grupo__seta{transform:rotate(90deg)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo__alternar:focus-visible{outline:2px solid var(--ds-acao);outline-offset:1px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela tbody tr.pg-linha--recolhida{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo.pg-grupo--perigo{border-top-width:2px;border-top-color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-grupo--perigo .pg-grupo__titulo{color:var(--ds-perigo)}
/* pílula de estado (memória situacao-ponto-e-texto-nao-etiqueta; referência .rt-selo): 22 px, 12 px 500, fundo tint
   DA COR do estado, ponto dentro; uma linha, motivo no title; a ÚNICA pílula colorida da linha. Nunca âmbar/bege. */
/* DISPONIBILIDADE como bloco de estado (dono, 09/10/2026, "liberdade criativa"): fio vertical na cor do tom, o
   estado em 12px/600 na 1ª linha, o detalhe (processo · chegada, ou a falta) em 12px na 2ª, ambos truncando com
   "…" dentro da coluna. Mesma linguagem da coluna ESTÁGIO (estado + motivo), nada de pílula. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade{display:block;max-width:100%;padding:1px 0 1px 8px;border-left:3px solid var(--ds-tinta-3);font-size:12px;line-height:14px;color:var(--ds-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade__texto{display:block;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade__detalhe{display:block;color:var(--ds-tinta-2);font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-sucesso{border-color:var(--ds-sucesso)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-acao{border-color:var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-atencao{border-color:#FF7B00}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-atencao .pg-disponibilidade__texto{color:#FA4B00}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-perigo{border-color:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade--tom-perigo .pg-disponibilidade__texto{color:var(--ds-perigo)}
/* "Escolher processo": o <select> nativo vestido de link de ação, na linha do detalhe, com a seta da casa. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-disponibilidade__acao{display:block;margin-top:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher{position:relative;display:inline-flex;align-items:center;max-width:100%;vertical-align:top}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher[hidden]{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher-processo{appearance:none;-webkit-appearance:none;height:14px;max-width:100%;margin:0;padding:0 14px 0 0;border:0;border-radius:0;background:none;font:inherit;font-size:var(--fonte-pequena);font-weight:500;line-height:16px;color:var(--ds-acao);cursor:pointer}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher-processo:hover{color:var(--ds-acao-hover);text-decoration:underline}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher-processo:focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher-processo:disabled{color:var(--ds-tinta-3);cursor:default}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-escolher__seta{position:absolute;right:0;top:1px;width:12px;height:12px;color:var(--ds-acao);pointer-events:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-col-disponibilidade .grade-celula{white-space:normal;line-height:22px}
/* O <select> "Escolher processo" ao lado da pílula Sem cobertura (dono, 09/10/2026): campo nativo, baixo como a pílula. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ponto{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:.25rem;vertical-align:middle}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-ponto--perigo{background:var(--ds-perigo)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-bloqueado{font-size:var(--fonte-corpo);color:var(--ds-tinta);white-space:nowrap}
/* arrasto: o bloco esmaece e ganha o tint de ação; os outros dias esmaecem (só o mesmo dia aceita); o alvo ganha o fio */
[data-pagina="separacao_faturamento"][data-tela="programacao"] tr.grade-linha td,[data-pagina="separacao_faturamento"][data-tela="programacao"] tr.grade-grupo td{transition:opacity .15s ease-out}
/* O lugar de origem vira um VÃO neutro (dono, 09/10/2026: o tint azul "ficou horrível"): fundo cinza do painel, fio
   tracejado em cima e embaixo e o conteúdo quase apagado; quem mostra o pedido é o fantasma que segue o ponteiro. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--arrastando td{background:var(--ds-fundo);box-shadow:inset 0 1px 0 var(--ds-filete-2),inset 0 -1px 0 var(--ds-filete-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--arrastando td > *{opacity:.25}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--fora td{opacity:.3}
/* A linha inteira arrasta (dono, 09/10): a mão aberta em toda linha ordenável; fechada enquanto arrasta. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] tbody tr.grade-linha[data-posicao]{cursor:grab}
body.at-arrastando [data-pagina="separacao_faturamento"][data-tela="programacao"] tbody tr.grade-linha{cursor:grabbing}
/* Toasts (dono, 09/10/2026): o aviso de um gesto e o da leitura moram no pé da tela, com temporizador. GLOBAL desde o
   #388 (biUtils.toast): nasceu na programação e subiu porque toda escrita precisa de resposta visível, em qualquer tela. BRANCO (o
   Toast preto do DS foi reprovado: "odiei o toast preto"): fundo branco, texto tinta, filete cinza, sombra, e a barra
   de 3px à esquerda é a única cor (neutro cinza, atenção laranja, perigo vermelho); a ação em azul, como os links. */
.bi-toasts{position:fixed;left:50%;bottom:1.25rem;z-index:1090;display:flex;flex-direction:column;gap:.5rem;align-items:center;transform:translateX(-50%);pointer-events:none}
.bi-toast{pointer-events:auto;display:flex;align-items:center;gap:.75rem;min-width:20rem;max-width:40rem;padding:.6rem .75rem .6rem 1rem;background:#fff;color:var(--ds-tinta);border:1px solid var(--ds-filete-2);border-left:3px solid var(--ds-tinta-3);border-radius:var(--bs-border-radius-sm);box-shadow:0 8px 24px rgba(22,22,22,.16);animation:bi-toast-entra .16s ease-out}
.bi-toast--atencao{border-left-color:var(--ds-atencao)}
.bi-toast--perigo{border-left-color:var(--ds-perigo)}
.bi-toast__texto{flex:1 1 auto}
.bi-toast__acao{flex:0 0 auto;padding:0;border:0;background:none;color:var(--ds-acao);font:inherit;font-weight:500;text-decoration:underline;text-underline-offset:2px;cursor:pointer}
.bi-toast__acao:hover{color:var(--ds-acao-hover)}
.bi-toast__fechar{flex:0 0 auto;width:28px;height:28px;margin:-.25rem -.25rem -.25rem 0;padding:0;border:0;background:none;color:var(--ds-tinta-3);font-size:18px;line-height:1;cursor:pointer;border-radius:var(--bs-border-radius-sm)}
.bi-toast__fechar:hover{color:var(--ds-tinta)}
:is(.bi-toast__acao,.bi-toast__fechar):focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
.bi-toast--carregando{border-left-color:var(--ds-acao)}
.bi-toast__giro{flex:0 0 auto;width:14px;height:14px;border:2px solid var(--ds-filete-2);border-top-color:var(--ds-acao);border-radius:50%;animation:bi-toast-gira .8s linear infinite}
@keyframes bi-toast-gira{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.bi-toast__giro{animation-duration:2.4s}}
@keyframes bi-toast-entra{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
/* Bloco do pedido como célula MESCLADA de verdade (dono, 09/10/2026): o que é do pedido (ações, ordem, número, cliente,
   estágio) fica centrado na altura do bloco (`--pg-bloco`, medida no JS a cada desenho). A célula congelada já é o
   bloco de referência (sticky); as outras ganham `position:relative`. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--cabeca :is(td.pg-col-acao,td.pg-ordem,td.pg-col-pedido,td.pg-col-cliente,td.pg-col-estagio){overflow:visible}
/* A cabeça sobe um degrau na escada z das colunas congeladas (5/4/3): o conteúdo centrado atravessa as linhas de
   continuação por cima do fundo branco delas, que segue cobrindo as colunas roladas. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols > tbody > tr.pg-linha--cabeca > .stick--1{z-index:8}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols > tbody > tr.pg-linha--cabeca > .stick--2{z-index:7}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .stickcols > tbody > tr.pg-linha--cabeca > .stick--3{z-index:6}
/* O conteúdo desce metade da sobra do bloco (`100%` no transform é a própria altura): fica no meio do bloco sem
   sair do fluxo, e a largura da célula (inclusive a de CLIENTE, com `max-width:0`) segue a da tabela. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-linha--cabeca :is(td.pg-col-acao,td.pg-ordem,td.pg-col-pedido,td.pg-col-cliente,td.pg-col-estagio) > .grade-celula{transform:translateY(calc((var(--pg-bloco) - 100%) / 2));position:relative;z-index:1}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-guardados[hidden]{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade .datatable-toolbar__left .grade-chips{padding:0}
/* Até 1366 px (área útil de 1192 em 1280) as colunas de texto fixo cedem: ESTÁGIO 120, DISPONIBILIDADE 140 (o
   Amarrar quebra sob a pílula) e o teto do ITEM cai para 11rem, para sobrar CLIENTE legível. */
@media (max-width:1366px){
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade .grade-chip{padding:0 .5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela :is(th,td).pg-col-item{max-width:11rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-estagio{width:120px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .grade-tabela th.pg-col-disponibilidade{width:140px}
}
/* Entre a barra e a grade: o aviso ÚNICO dos pedidos sem dias de separação e os indicadores (seção 5) */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entre{display:flex;flex-direction:column;gap:.5rem;margin:.5rem 0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entre:empty,[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-entre:not(:has(> :not([hidden]))){display:none}
/* Indicadores (dono, 09/10/2026): botões de recorte — numeral e rótulo em caixa alta; ligado = fio e tint de ação.
   Uma faixa baixa, numeral ao lado do rótulo (#408: em 1366×768 os cartões altos tomavam metade da tela). */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicadores{display:flex;flex-wrap:nowrap;gap:.5rem;position:relative}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicadores[hidden]{display:none}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador{display:flex;flex:1 1 0;flex-direction:row;align-items:center;gap:.5rem;min-width:0;min-height:2.25rem;padding:.25rem .625rem;border:1px solid var(--ds-filete-2);border-radius:var(--bs-border-radius-sm);background:#fff;color:var(--ds-tinta);font:inherit;text-align:left;cursor:pointer;transition:border-color .12s,background .12s}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador:hover{border-color:var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador:focus-visible{outline:2px solid var(--ds-acao);outline-offset:2px}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador[aria-pressed="true"]{border-color:var(--ds-acao);background:var(--ds-acao-tinta)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador__valor{flex:none;font-size:18px;font-weight:600;line-height:1;font-variant-numeric:tabular-nums}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador[aria-pressed="true"] .pg-indicador__valor{color:var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pg-indicador__rotulo{font-size:10.5px;font-weight:500;line-height:1.15;letter-spacing:.03em;text-transform:uppercase;color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] [data-vista-painel][hidden] { display: none; }
/* A tela usa a janela inteira (dono): a vista ativa estica até o rodapé e o `#at` (calendário do mês, com
   `grid-auto-rows: minmax(min-content, 1fr)`) cresce com ela — sem faixa branca abaixo da legenda. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] [data-vista-painel]:not([hidden]){display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] [data-vista-painel] > .at{flex:1 1 auto;min-height:0}
/* A vista IMPORTAÇÕES (#388, fatia 5): dois panes lado a lado (memória drill-em-panes), cada um rola sozinho e
   ocupa a altura toda; abaixo de 1024 px empilham. A linha do processo aberto leva o fio de ação à esquerda. */
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-panes{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr);gap:1.5rem;flex:1 1 auto;min-height:0}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-pane{min-height:0;overflow:auto}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-pane--processo{border-left:1px solid var(--ds-filete);padding-left:1.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-processo__titulo{margin-bottom:.5rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-processo__vazio{color:var(--ds-tinta-2)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-pane--processo .at-painel__titulo + *{margin-top:.25rem}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-pane--processo .at-atendidos > li{padding:.375rem 0;border-bottom:1px solid var(--ds-filete)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-linha--escolhida > td:first-child{box-shadow:inset 3px 0 0 var(--ds-acao)}
[data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-aviso{margin:0 0 .5rem;color:#FA4B00;font-size:var(--fonte-corpo)}
@media (max-width: 1023.98px){
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-panes{grid-template-columns:minmax(0,1fr)}
  [data-pagina="separacao_faturamento"][data-tela="programacao"] .pi-pane--processo{border-left:0;padding-left:0;border-top:1px solid var(--ds-filete);padding-top:1rem}
}
/* Na Programação (#307) a escolha CALENDÁRIO|AGENDA é a vista: os botões do painel somem. */

/* === Gaveta do pedido redesenhada (#323, 09/10/2026) ==========================================================
   Plano: docs/superpowers/plans/2026-10-09-gaveta-do-pedido-redesenho-323.md. Cabeça enxuta (PEDIDO N — CLIENTE,
   pílula, ✕); a FAIXA de quatro números na largura toda; painel LATERAL à esquerda (22rem; 25rem de 1440px) com o
   bloco de ações fixo ao rolar, a ficha em duas colunas, a jornada e a linha do tempo; à direita os itens em UMA
   tabela com grupos (título e cabeçalhos grudados) e os FATURADOS por NF. Quem rola é a gaveta (.offcanvas-body);
   nenhuma caixa de rolagem própria. Só tokens do DS; tema claro. */
.pd-canvas[data-variante="nova"] .pd-canvas__cabecalho { align-items: center; gap: .75rem; flex-wrap: nowrap; }
.pd-canvas[data-variante="nova"] .pd-canvas__titulo {
  font-size: 1.125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; line-height: 1.25; margin: 0; flex: 0 1 auto;
}
.pd-canvas[data-variante="nova"] #pd-canvas-situacao:empty { display: none; }
.pd-canvas[data-variante="nova"] .pd-canvas__acoes-topo[hidden] { display: none; }
.pd-canvas[data-variante="nova"] .pd-canvas__cabecalho .btn-close { margin-left: auto; }
/* As duas colunas: painel lateral de 22rem (25rem de 1440px), itens com o resto. */
.pd-canvas[data-variante="nova"] .pd-dossie { grid-template-columns: 1fr; gap: 1.5rem; }
@media (min-width: 62rem) { .pd-canvas[data-variante="nova"] .pd-dossie { grid-template-columns: 22rem minmax(0, 1fr); } }
@media (min-width: 90rem) { .pd-canvas[data-variante="nova"] .pd-dossie { grid-template-columns: 25rem minmax(0, 1fr); } }
/* A FAIXA mora em #pd-dossie-resumo: sem a caixa da gaveta antiga (o fio em cima e embaixo é da .pd-faixa); os
   rótulos são eyebrows. Sem moldura também na ficha, na linha do tempo e no bloco da NF (cartão 0, fio só). */
.pd-canvas[data-variante="nova"] .pd-dossie-resumo { background: transparent; border: 0; border-radius: 0; padding: 0; margin-bottom: 1rem; }
.pd-canvas[data-variante="nova"] .pd-faixa__rotulo { font-size: .6875rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ds-tinta-2); }
.pd-canvas[data-variante="nova"] #pd-capa,
.pd-canvas[data-variante="nova"] #pd-historico { background: transparent; border: 0; border-radius: 0; padding: 0; }
.pd-canvas[data-variante="nova"] #pd-historico { padding-top: 1rem; border-top: 1px solid var(--ds-filete-2); }
.pd-canvas[data-variante="nova"] .pd-nota { background: transparent; border: 0; border-radius: 0; padding: .75rem 0 0; margin-bottom: 1rem; border-top: 1px solid var(--ds-filete-2); }
/* O bloco de ações: rola com o painel (#547); três andares separados por filete. */
.pd-canvas[data-variante="nova"] #pd-acoes { padding-bottom: .75rem; margin-bottom: 1rem; border-bottom: 1px solid var(--ds-filete-2); }
.pd-canvas[data-variante="nova"] #pd-acoes:empty { display: none; }
.pd-canvas[data-variante="nova"] .pd-acoes__passo,
.pd-canvas[data-variante="nova"] .pd-acoes__programacao,
.pd-canvas[data-variante="nova"] .pd-acoes__situacao { display: flex; flex-direction: column; gap: .5rem; }
.pd-canvas[data-variante="nova"] .pd-acoes__programacao:empty,
.pd-canvas[data-variante="nova"] .pd-acoes__situacao:empty,
.pd-canvas[data-variante="nova"] .pd-acoes__destrutivas:empty { display: none; }
/* O "Ver na Programação" escondido (sem link, ou na própria Programação) não deixa o vão do andar (#403). */
.pd-canvas[data-variante="nova"] .pd-acoes__programacao:not(:has(> :not([hidden]))) { display: none; }
.pd-canvas[data-variante="nova"] #pd-acoes .btn:not(.btn-link) { display: flex; width: 100%; justify-content: center; }
.pd-canvas[data-variante="nova"] #pd-acoes .pd-canvas__motivo { margin-top: -.25rem; }
/* Documentos: siglinks numa linha, com o ponto entre os visíveis (o ponto é atômico, não leva o sublinhado). */
.pd-canvas[data-variante="nova"] .pd-acoes__documentos {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; margin-top: .75rem; padding-top: .75rem;
  border-top: 1px solid var(--ds-filete-2); font-size: .8125rem; line-height: 1.4;
}
.pd-canvas[data-variante="nova"] .pd-acoes__documentos[hidden],
.pd-canvas[data-variante="nova"] .pd-acoes__documentos:not(:has(> :not([hidden]))) { display: none; }
/* Na NF não há próximo passo (#457): os documentos abrem o bloco, sem filete por cima. */
.pd-canvas[data-variante="nova"] .pd-acoes__passo[hidden] + .pd-acoes__documentos { margin-top: 0; padding-top: 0; border-top: 0; }
.pd-canvas[data-variante="nova"] .pd-acoes__documentos .pd-doc {
  display: inline; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: none;
  color: var(--ds-acao); font-size: .8125rem; font-weight: 600; text-decoration: underline; text-underline-offset: 2px;
  white-space: normal; cursor: pointer;
}
.pd-canvas[data-variante="nova"] .pd-acoes__documentos .pd-doc:hover { color: var(--ds-acao-hover); border: 0; background: none; }
.pd-canvas[data-variante="nova"] .pd-acoes__documentos > .pd-doc:not([hidden]) ~ .pd-doc:not([hidden])::before {
  content: '·'; display: inline-block; margin-right: .5rem; color: var(--ds-tinta-2); font-weight: 400;
}
.pd-canvas[data-variante="nova"] .pd-acoes__destrutivas { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; margin-top: .75rem; padding-top: .75rem; border-top: 1px solid var(--ds-filete-2); }
/* A ficha: dl em duas colunas; eyebrow 11/600 caixa alta tinta-2; valor 13; observações na largura inteira.
   `#pd-ficha-edicao` (os pares do painel de edição) entra no mesmo grid por `display: contents`. */
.pd-canvas[data-variante="nova"] .pd-ficha { grid-template-columns: 1fr 1fr; gap: .75rem 1rem; margin: 0; }
.pd-canvas[data-variante="nova"] #pd-ficha-edicao { display: contents; }
.pd-canvas[data-variante="nova"] .pd-ficha__rotulo { font-size: .6875rem; letter-spacing: .04em; color: var(--ds-tinta-2); }
.pd-canvas[data-variante="nova"] .pd-ficha__valor { font-size: .8125rem; color: var(--ds-tinta); overflow-wrap: anywhere; }
.pd-canvas[data-variante="nova"] .pd-ficha__par--inteiro { grid-column: 1 / -1; }
.pd-canvas[data-variante="nova"] #pd-edicao-dias { width: 6rem; }
/* A tabela de itens: UMA, em grupos. O título do grupo (fundo --ds-fundo, eyebrow + totais 13px) e os cabeçalhos
   de coluna (eyebrow 11/600) grudam no topo da gaveta ao rolar; linhas de 36px no mínimo. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens { table-layout: auto; font-size: .8125rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens tr.pd-grupo td {
  position: sticky; top: 0; z-index: 2; background: var(--ds-fundo); padding: .5rem .75rem .5rem .5rem; line-height: 1.3;
  border-bottom: 1px solid var(--ds-filete-2); font-size: .8125rem; color: var(--ds-tinta); white-space: normal;
}
.pd-canvas[data-variante="nova"] .pd-grupo__resumo { font-weight: 600; letter-spacing: .02em; }
.pd-canvas[data-variante="nova"] .pd-grupo__nota { float: right; margin-left: 1rem; color: var(--ds-tinta-2); font-weight: 400; }
.pd-canvas[data-variante="nova"] .pd-grupo__nota .fcds-siglink { margin-top: 0; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens th {
  position: sticky; top: 2.3rem; z-index: 1; background: #fff; text-align: left; white-space: nowrap;
  font-size: .6875rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ds-tinta-2);
  padding: .4rem .75rem .4rem 0; border-bottom: 1px solid var(--ds-filete-2);
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens th.pd-doc-cel--valor { text-align: right; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens tbody td {
  padding: .5rem .75rem .5rem 0; height: 36px; border-bottom: 1px solid var(--ds-filete-2); vertical-align: top;
  white-space: nowrap; line-height: 1.3;
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens td.pd-doc-cel--valor { text-align: right; font-variant-numeric: tabular-nums; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens tbody tr:last-child td { border-bottom: 0; }
.pd-canvas[data-variante="nova"] .pd-cel-sequencia { width: 1%; color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens td.pd-cel-item,
.pd-canvas[data-variante="nova"] .pd-edicao__itens td.pd-cel-disponibilidade { white-space: normal; }
.pd-canvas[data-variante="nova"] .pd-cel-item { width: 99%; min-width: 11rem; max-width: 22rem; }
.pd-canvas[data-variante="nova"] .pd-item__codigo { display: block; font-size: .875rem; font-weight: 500; }
.pd-canvas[data-variante="nova"] .pd-item__descricao {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: .75rem; font-weight: 400; color: var(--ds-tinta-2);
}
.pd-canvas[data-variante="nova"] .pd-edicao__unidade { font-size: .75rem; color: var(--ds-tinta-2); }
.pd-canvas[data-variante="nova"] .pd-edicao__atraso { display: block; font-size: .75rem; color: var(--ds-perigo); }
.pd-canvas[data-variante="nova"] tr[data-atrasado] .pd-cel-saida,
.pd-canvas[data-variante="nova"] tr[data-atrasado] .pd-cel-saida + td { color: var(--ds-perigo); }
.pd-canvas[data-variante="nova"] .pd-cel-disponibilidade { min-width: 7.5rem; }
/* DISPONIBILIDADE como a .pg-disponibilidade da lista da Programação: bloco de duas linhas com fio de 3px. */
.pd-canvas[data-variante="nova"] .pd-disp { display: block; max-width: 100%; padding: 1px 0 1px 8px; border-left: 3px solid var(--ds-filete-2); font-size: 12px; line-height: 14px; color: var(--ds-tinta); }
.pd-canvas[data-variante="nova"] .pd-disp__texto { display: block; font-weight: 600; }
.pd-canvas[data-variante="nova"] .pd-disp__detalhe { display: block; color: var(--ds-tinta-2); font-weight: 400; }
.pd-canvas[data-variante="nova"] .pd-disp--tom-sucesso { border-color: var(--ds-sucesso); }
.pd-canvas[data-variante="nova"] .pd-disp--tom-acao { border-color: var(--ds-acao); }
.pd-canvas[data-variante="nova"] .pd-disp--tom-atencao { border-color: #FF7B00; }
.pd-canvas[data-variante="nova"] .pd-disp--tom-atencao .pd-disp__texto { color: #FA4B00; }
.pd-canvas[data-variante="nova"] .pd-disp--tom-perigo { border-color: var(--ds-perigo); }
.pd-canvas[data-variante="nova"] .pd-disp--tom-perigo .pd-disp__texto { color: var(--ds-perigo); }
/* A EDIÇÃO (#323, fatia 3). Os campos da grade (form-control-sm) existem sempre nas células liberadas e parecem
   texto fora do foco: borda transparente, filete no hover, o foco de fábrica; número à direita como na leitura. A
   célula travada leva o cadeado com a frase curta; a regra inteira no title. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula { padding-inline: .375rem; font-variant-numeric: tabular-nums; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula:not(:focus) { border-color: transparent; background: transparent; }
/* Largura do valor, não do formulário: a tabela cabe na coluna sem rolagem própria (1366 com o painel de 22rem). */
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula[inputmode="decimal"] { width: 4.5rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula[name="quantidade"] { width: 4rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula[type="date"] { width: 6.75rem; padding-right: .125rem; }
/* O calendário nativo do campo de data: pequeno e apagado, para a data ler como texto. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula::-webkit-calendar-picker-indicator {
  width: 12px; height: 12px; margin: 0 0 0 2px; padding: 0; opacity: .45; cursor: pointer;
}
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula:is(:hover, :focus)::-webkit-calendar-picker-indicator { opacity: 1; }
/* O preço com o "R$" fixo à frente (todo dinheiro com R$); o número continua à direita. */
.pd-canvas[data-variante="nova"] .pd-edicao__com-moeda { display: inline-flex; align-items: center; justify-content: flex-end; gap: .125rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__moeda { font-size: .8125rem; color: var(--ds-tinta-2); }
/* SEPARAR EM começa depois de um vão a mais: na leitura e na edição o "—" não cola no VALOR, alinhado à direita. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens :is(th, td).pd-cel-saida { padding-left: .5rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens td.pd-doc-cel--acao { width: 1%; padding-inline: 6px; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__celula:hover:not(:focus) { border-color: var(--ds-filete-2); }
.pd-canvas[data-variante="nova"] .pd-edicao__itens tbody td:has(.pd-edicao__celula) { padding-top: .125rem; padding-bottom: .125rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__itens .pd-edicao__com-unidade { justify-content: flex-end; }
.pd-canvas[data-variante="nova"] .pd-edicao__trava {
  display: flex; align-items: center; justify-content: inherit; gap: .25rem; margin-top: .125rem;
  font-size: .75rem; color: var(--ds-tinta-2); white-space: nowrap; cursor: help;
}
.pd-canvas[data-variante="nova"] td.pd-doc-cel--valor .pd-edicao__trava { justify-content: flex-end; }
.pd-canvas[data-variante="nova"] td.pd-doc-cel--acao .pd-edicao__trava { justify-content: center; height: 32px; margin: 0; }
.pd-canvas[data-variante="nova"] .pd-edicao__trava svg { flex: 0 0 auto; }
/* A linha nova: campos com moldura (é digitação, não texto); o "+ Adicionar item" fecha o grupo. */
.pd-canvas[data-variante="nova"] .pd-edicao__itens tr.pd-edicao__adicionar td { height: auto; padding: .5rem 0; }
.pd-canvas[data-variante="nova"] .pd-edicao__adicionar .fcds-siglink { margin-top: 0; }
.pd-canvas[data-variante="nova"] #pd-capa-previsao { max-width: 10rem; }
/* O status da gravação no topo da coluna dos itens: branco, filete, fio de 3px no tom (como o toast da lista;
   nunca preto). */
.pd-canvas[data-variante="nova"] .pd-edicao__aviso {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem; margin: 0 0 .75rem;
  padding: .6rem .75rem .6rem 1rem; background: #fff; border: 1px solid var(--ds-filete-2);
  border-left: 3px solid var(--ds-tinta-3); border-radius: 2px; font-size: 13px; line-height: 1.4; color: var(--ds-tinta);
}
.pd-canvas[data-variante="nova"] .pd-edicao__aviso[hidden] { display: none; }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso-texto { flex: 1 1 16rem; }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso--ok { border-left-color: var(--ds-sucesso); }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso--espera { border-left-color: var(--ds-acao); }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso--incerto,
.pd-canvas[data-variante="nova"] .pd-edicao__aviso--sem_resposta { border-left-color: #FF7B00; }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso--erro { border-left-color: var(--ds-perigo); }
.pd-canvas[data-variante="nova"] .pd-edicao__aviso .fcds-siglink { margin-top: 0; }
/* Decisão 10: quem rola é a gaveta — nem a grade da NF nem a linha do tempo têm caixa de rolagem própria. */
.pd-canvas[data-variante="nova"] .pd-rolagem { max-height: none; overflow: visible; padding-right: 0; }
/* As grades da NF (itens e títulos) com a tipografia da tabela de itens do painel: corpo 13px, cabeçalho
   eyebrow 11/600 caixa alta tinta-2, linha de 36px com filete, ITEM em duas linhas, dinheiro à direita. */
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade { width: 100%; table-layout: auto; font-size: .8125rem; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade thead th {
  font-size: .6875rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ds-tinta-2);
  padding: .4rem .75rem .4rem 0; border-bottom: 1px solid var(--ds-filete-2); white-space: nowrap; text-align: left;
}
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade tbody td {
  font-size: .8125rem; padding: .5rem .75rem .5rem 0; height: 36px; line-height: 1.3; color: var(--ds-tinta);
  border-bottom: 1px solid var(--ds-filete-2); vertical-align: top; white-space: nowrap;
}
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade tbody tr:last-child td { border-bottom: 0; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade :is(th, td).pd-doc-cel--valor { text-align: right; font-variant-numeric: tabular-nums; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade :is(th, td):first-child { width: 99%; white-space: normal; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade td.pd-cel-item { min-width: 11rem; max-width: 22rem; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-docs-grade .pd-doc { font-size: .8125rem; }
.pd-canvas[data-variante="nova"] .pd-nota .pd-nota__itens + .pd-docs-grade { margin-top: 1rem; }
.pd-canvas[data-variante="nova"] .pd-nota__capa .pd-doc { font-size: .8125rem; }
/* FATURADOS por NF: o título do grupo como os outros (eyebrow), os blocos do dossiê embaixo. */
.pd-canvas[data-variante="nova"] .pd-notas__titulo { margin: 1.5rem 0 .5rem; }
.pd-canvas[data-variante="nova"] .pd-edicao + #pd-notas .pd-notas__titulo { margin-top: 1.5rem; }

/* Confirmação em modal (biUtils.confirmar, D11 do #273) — GLOBAL, justificado: é o componente compartilhado da
   confirmação do app; o modal vai para o <body>, fora de qualquer `.page`, então os valores do design system
   (design-system/tokens: superfície #fff, filete #EAEAEA, tinta #161616, botão 2px) vão literais. */
.modal.bi-confirmar { z-index: var(--z-modal); }
.bi-confirmar .modal-content {
  background: #fff; border: 1px solid #EAEAEA; border-radius: 0; box-shadow: 0 24px 64px rgba(22, 22, 22, .22);
}
.bi-confirmar .modal-header { border-bottom: 0; padding: 1rem 1.25rem .25rem; }
.bi-confirmar .modal-title { color: #161616; }
.bi-confirmar .modal-body { padding: .25rem 1.25rem 1rem; color: #161616; }
.bi-confirmar .modal-body p { margin: 0 0 .5rem; white-space: pre-line; }
.bi-confirmar .bi-confirmar__detalhe { color: #595A5C; }
.bi-confirmar .bi-confirmar__escolha { display: flex; flex-direction: column; gap: .25rem; margin: .5rem 0; color: #595A5C; }
.bi-confirmar .bi-confirmar__resultado { color: #FA4B00; font-weight: 500; }
.bi-confirmar .modal-footer { border-top: 1px solid #EAEAEA; padding: .75rem 1.25rem; gap: .5rem; }

/* === RASTREIO DE CONTAINERS (#247) — Painel de rastreio do Four Cloud (/comex/rastreio/) ===
   Na casca do app (core/base_fcds.html), no Four Group Design System: valores copiados de
   design-system/tokens/*.css com o token de origem. Branco, filete 1px, raio 0 no bloco,
   2px no controle, ação azul, Neue Haas Display. Faixa de atenção laranja, nunca marrom.
   Dashboard: na tela larga cabe na janela (fontes e resultados à esquerda, containers à
   direita, cada bloco rola por dentro); abaixo de 1200px empilha. */
[data-pagina="rastreio"] {
  --rt-fonte:'Neue Haas Display','Helvetica Neue',Helvetica,Arial,sans-serif;
  --rt-tinta:#161616;          /* --text-primary */
  --rt-tinta-2:#595A5C;        /* --text-secondary */
  --rt-tinta-3:#8C8D8F;        /* --fg-gray-400 */
  --rt-filete:#EAEAEA;         /* --border-subtle */
  --rt-filete-campo:#CFCFCF;
  --rt-fundo:#FFFFFF;          /* --surface-card */
  --rt-fundo-2:#F6F6F4;        /* --surface-sunken */
  --rt-ok:#14743C;             /* --status-success */
  --rt-ok-tinta:#E6F2EA;
  --rt-atencao:#FF7B00;        /* --figure-attention (fundo, texto preto) */
  --rt-atencao-texto:#FA4B00;  /* texto de atenção */
  --rt-atencao-tinta:#FFF1E3;
  --rt-perigo:#B42727;         /* --status-danger */
  --rt-perigo-tinta:#F8E7E7;
  --rt-margem:32px;
  margin:0; background:var(--rt-fundo); color:var(--rt-tinta);
  font-family:var(--rt-fonte); font-size:14px; line-height:1.5; font-variant-numeric:tabular-nums;
}
body[data-pagina="rastreio"] :is(button, input, select) { font:inherit; color:inherit; }  /* só a página avulsa: no Four Cloud valem o Bootstrap e a grade (#458) */
[data-pagina="rastreio"] :focus-visible { outline:2px solid var(--ds-acao); outline-offset:2px; }
[data-pagina="rastreio"] [hidden] { display:none !important; }  /* a faixa e os blocos têm display próprio */

/* Topo */
[data-pagina="rastreio"] .rt-topo { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:12px 24px;
  padding:14px var(--rt-margem); border-bottom:1px solid var(--rt-filete); }
[data-pagina="rastreio"] .rt-sobretitulo { display:block; font-size:11px; font-weight:500; letter-spacing:.18em;
  text-transform:uppercase; color:var(--rt-tinta-2); }

/* Controles */
[data-pagina="rastreio"] .rt-link { padding:0; border:0; background:none; color:var(--ds-acao); cursor:pointer; text-decoration:underline; text-underline-offset:3px; }
[data-pagina="rastreio"] .rt-link:disabled { color:var(--rt-tinta-3); text-decoration:none; cursor:not-allowed; }
[data-pagina="rastreio"] .rt-marcar { display:inline-flex; align-items:center; gap:6px; color:var(--rt-tinta-2); white-space:nowrap; }
[data-pagina="rastreio"] .rt-marcar input { accent-color:var(--ds-acao); width:16px; height:16px; margin:0; }

/* Estado: ponto + rótulo */
[data-pagina="rastreio"] .rt-estado { display:inline-flex; align-items:center; gap:8px; min-height:34px; padding:0 12px;
  border:1px solid var(--rt-filete); font-weight:500; white-space:nowrap; }
[data-pagina="rastreio"] i[data-situacao],
[data-pagina="rastreio"] .rt-estado i { display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--rt-tinta-3); flex:none; }
[data-pagina="rastreio"] [data-situacao="ok"] > i,
[data-pagina="rastreio"] i[data-situacao="ok"] { background:var(--rt-ok); }
[data-pagina="rastreio"] [data-situacao="alerta"] > i,
[data-pagina="rastreio"] i[data-situacao="alerta"] { background:var(--rt-atencao); }
[data-pagina="rastreio"] [data-situacao="falha"] > i,
[data-pagina="rastreio"] i[data-situacao="falha"] { background:var(--rt-perigo); }
[data-pagina="rastreio"] .rt-estado[data-situacao="falha"] { border-color:var(--rt-perigo); color:var(--rt-perigo); }

/* Corpo */
[data-pagina="rastreio"] .rt-aviso-acao { margin:0 0 12px; padding:8px 14px; background:var(--ds-acao-tinta); }
[data-pagina="rastreio"] .rt-faixa { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 24px;
  margin:0 0 12px; padding:8px 8px 8px 14px; background:var(--rt-atencao-tinta); border:1px solid var(--rt-atencao); }
[data-pagina="rastreio"] .rt-faixa strong { font-weight:500; }
[data-pagina="rastreio"] .rt-faixa--motivos[data-situacao="falha"] { background:var(--rt-perigo-tinta); border-color:var(--rt-perigo); }
[data-pagina="rastreio"] .rt-motivos { margin:4px 0 0; padding-left:18px; }
[data-pagina="rastreio"] .rt-motivos li + li { margin-top:4px; }

/* Rodada em andamento */
[data-pagina="rastreio"] .rt-andamento { margin:0 0 12px; padding:10px 14px 0; border:1px solid var(--ds-acao); background:var(--ds-acao-tinta); }
[data-pagina="rastreio"] .rt-andamento__texto { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 16px; }
[data-pagina="rastreio"] .rt-andamento__texto strong { font-weight:500; }
[data-pagina="rastreio"] .rt-andamento__texto span { color:var(--rt-tinta-2); }
[data-pagina="rastreio"] .rt-andamento__barra { height:4px; margin:10px -14px 0; background:rgba(18,104,171,.15); }
[data-pagina="rastreio"] .rt-andamento__barra span { display:block; height:100%; width:0; background:var(--ds-acao);
  transition:width 400ms cubic-bezier(.2,0,.2,1); }

/* Indicadores: uma faixa baixa */
[data-pagina="rastreio"] .rt-indicadores { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); border-top:1px solid var(--rt-tinta);
  border-bottom:1px solid var(--rt-filete); margin-bottom:16px; }
[data-pagina="rastreio"] .rt-indicador { padding:12px 20px 12px 0; }
[data-pagina="rastreio"] .rt-indicador + .rt-indicador { padding-left:20px; border-left:1px solid var(--rt-filete); }
[data-pagina="rastreio"] .rt-indicador__valor { margin:6px 0 0; font-size:34px; font-weight:500; letter-spacing:-.03em; line-height:1; }
[data-pagina="rastreio"] .rt-indicador__valor small { font-size:16px; letter-spacing:0; color:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-infra { list-style:none; margin:8px 0 0; padding:0; display:grid; gap:4px; }
[data-pagina="rastreio"] .rt-infra li { display:flex; align-items:center; gap:8px; white-space:nowrap; }
[data-pagina="rastreio"] .rt-infra span { margin-left:auto; color:var(--rt-tinta-2); }

/* Grade do dashboard */
/* duas colunas: o resumo das fontes, estreito, e a lista de processos no resto; as consultas abrem na gaveta */
[data-pagina="rastreio"] .rt-grade { display:grid; gap:16px; grid-template-columns:250px minmax(0, 1fr);
  grid-template-areas:"fontes containers"; grid-template-rows:minmax(0, 1fr); }
[data-pagina="rastreio"] .rt-bloco--fontes { grid-area:fontes; }
[data-pagina="rastreio"] .rt-bloco--containers { grid-area:containers; }
[data-pagina="rastreio"] .rt-bloco { display:flex; flex-direction:column; min-height:0; border:1px solid var(--rt-filete); }
[data-pagina="rastreio"] .rt-bloco__cabeca { display:flex; flex-wrap:wrap; align-items:center; gap:8px 16px; padding:10px 14px;
  border-bottom:1px solid var(--rt-filete); }
[data-pagina="rastreio"] .rt-bloco__titulo { margin:0; font-size:16px; font-weight:500; }
[data-pagina="rastreio"] .rt-bloco__nota { color:var(--rt-tinta-3); font-size:12px; }
[data-pagina="rastreio"] .rt-bloco__corpo { flex:1 1 auto; min-height:0; overflow:auto; }
[data-pagina="rastreio"] .rt-filtros { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-left:auto; }
[data-pagina="rastreio"] .rt-paginacao { display:flex; align-items:center; gap:12px; padding:8px 14px; border-top:1px solid var(--rt-filete);
  color:var(--rt-tinta-2); font-size:12px; }
[data-pagina="rastreio"] .rt-paginacao span { margin-right:auto; }

/* Fontes: uma linha por fonte */
[data-pagina="rastreio"] .rt-fontes { list-style:none; margin:0; padding:4px 0; display:grid; grid-template-columns:minmax(0, 1fr); overflow:auto; }
[data-pagina="rastreio"] .rt-fonte { display:grid; grid-template-columns:auto minmax(0, 1fr) auto auto; align-items:center; gap:2px 10px;
  padding:7px 14px; cursor:default; }
[data-pagina="rastreio"] .rt-fonte__nome { font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
[data-pagina="rastreio"] .rt-fonte__nome small { margin-left:6px; font-weight:400; font-size:11px; color:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-fonte__lidos { font-size:16px; font-weight:500; }
[data-pagina="rastreio"] .rt-fonte__lidos small { font-size:12px; font-weight:400; color:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-fonte__tempo { min-width:44px; text-align:right; font-size:12px; color:var(--rt-tinta-2); }
[data-pagina="rastreio"] .rt-fonte__nota { grid-column:2 / -1; font-size:12px; color:var(--rt-tinta-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
[data-pagina="rastreio"] .rt-fonte[data-situacao="alerta"] .rt-fonte__nota { color:var(--rt-atencao-texto); }
[data-pagina="rastreio"] .rt-fonte[data-situacao="falha"] .rt-fonte__nota { color:var(--rt-perigo); }

/* Tabelas */
[data-pagina="rastreio"] .rt-clicavel { cursor:pointer; }
[data-pagina="rastreio"] .rt-num { text-align:right !important; white-space:nowrap; }
[data-pagina="rastreio"] .rt-processo { font-weight:500; white-space:nowrap; }
[data-pagina="rastreio"] .rt-numero { letter-spacing:.03em; white-space:nowrap; }
[data-pagina="rastreio"] .rt-secundario { color:var(--rt-tinta-2); white-space:nowrap; }
[data-pagina="rastreio"] .rt-eta { white-space:nowrap; }
[data-pagina="rastreio"] .rt-eta strong { font-weight:500; }
[data-pagina="rastreio"] .rt-eta small { color:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-atualizado { color:var(--rt-tinta-2); white-space:nowrap; }
[data-pagina="rastreio"] .rt-detalhe { display:block; font-size:11px; color:var(--rt-tinta-3); letter-spacing:.02em; }
[data-pagina="rastreio"] .rt-numero { position:relative; }
[data-pagina="rastreio"] .rt-falhas { margin-left:8px; font-size:12px; color:var(--rt-atencao-texto); }
[data-pagina="rastreio"] .rt-vazio { margin:0; padding:24px 0; text-align:center; color:var(--rt-tinta-2); }

/* Selos de situação: pílula de fundo claro com o ponto da cor dentro e texto escuro em caixa normal.
   Delimitada (o dono gosta do contorno do badge do Bootstrap), mas sem a anatomia do botão: botão do
   design system é reto (raio 2px) e cheio; pílula é a forma que o DS reserva à etiqueta (08/10/2026). */
[data-pagina="rastreio"] .rt-selo,
[data-pagina="rastreio"] .rt-marca { display:inline-flex; align-items:center; gap:6px; height:22px; padding:0 10px 0 8px;
  border-radius:999px; font-size:12px; font-weight:500; line-height:1; white-space:nowrap; vertical-align:middle;
  background:#F1F1EF; color:var(--rt-tinta); box-shadow:inset 0 0 0 1px rgba(22,22,22,.06); }
[data-pagina="rastreio"] .rt-selo::before { content:''; flex:none; width:7px; height:7px; border-radius:50%; background:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-selo[data-situacao="em_transito"] { background:var(--ds-acao-tinta); }
[data-pagina="rastreio"] .rt-selo[data-situacao="em_transito"]::before { background:var(--ds-acao); }
[data-pagina="rastreio"] .rt-selo[data-situacao="chegou"] { background:var(--rt-ok-tinta); }
[data-pagina="rastreio"] .rt-selo[data-situacao="chegou"]::before { background:var(--rt-ok); }
[data-pagina="rastreio"] .rt-selo[data-situacao="sem_leitura"] { background:var(--rt-atencao-tinta); }
[data-pagina="rastreio"] .rt-selo[data-situacao="sem_leitura"]::before { background:var(--rt-atencao); }
[data-pagina="rastreio"] .rt-selo[data-situacao="erro"] { background:var(--rt-perigo-tinta); }
[data-pagina="rastreio"] .rt-selo[data-situacao="erro"]::before { background:var(--rt-perigo); }
/* rótulo ao lado do texto: pílula menor, só contorno, sem ponto */
[data-pagina="rastreio"] .rt-marca { height:18px; margin-left:8px; padding:0 8px; font-size:11px; font-weight:400;
  background:transparent; color:var(--rt-tinta-2); box-shadow:inset 0 0 0 1px #D6D6D3; }

/* Gaveta de consultas do processo (offcanvas à direita, não bloqueia a lista) */
[data-pagina="rastreio"] .rt-destaque { padding:14px 16px; border:1px solid var(--ds-acao); background:var(--ds-acao-tinta); }
[data-pagina="rastreio"] .rt-destaque__cabeca { display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; margin-bottom:10px; }
[data-pagina="rastreio"] .rt-destaque__cabeca .rt-sobretitulo { flex-basis:100%; }
[data-pagina="rastreio"] .rt-destaque__cabeca strong { font-weight:500; font-size:15px; }
[data-pagina="rastreio"] .rt-destaque__explicacao { margin:0 0 8px; color:var(--rt-tinta-2); }
[data-pagina="rastreio"] .rt-destaque .rt-leitura__campos { margin:0 0 10px; }
[data-pagina="rastreio"] .rt-consultas { list-style:none; margin:0; padding:0; }
[data-pagina="rastreio"] .rt-consultas li { display:grid; grid-template-columns:96px minmax(0, 1fr) auto 48px; align-items:center; gap:10px;
  padding:7px 4px; border-bottom:1px solid var(--rt-filete); font-size:13px; }
[data-pagina="rastreio"] .rt-consultas li:hover { background:var(--rt-fundo-2); }
[data-pagina="rastreio"] .rt-consultas__fonte { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
[data-pagina="rastreio"] .rt-consultas .rt-selo { max-width:190px; }
[data-pagina="rastreio"] .rt-consultas .rt-selo span { overflow:hidden; text-overflow:ellipsis; }

/* Janelas: navegador e resposta bruta */
[data-pagina="rastreio"] .rt-containers { display:flex; flex-wrap:wrap; gap:6px; }
[data-pagina="rastreio"] .rt-containers .rt-marca { margin-left:0; letter-spacing:.03em; }
[data-pagina="rastreio"] .rt-containers .rt-marca[data-lido="true"] { color:var(--rt-tinta); box-shadow:inset 0 0 0 1px var(--ds-acao); }
[data-pagina="rastreio"] .rt-leitura { padding:16px; max-height:calc(85vh - 110px); overflow:auto; }
[data-pagina="rastreio"] .rt-leitura__campos { display:grid; grid-template-columns:max-content minmax(0, 1fr); gap:8px 24px; margin:14px 0 0; }
[data-pagina="rastreio"] .rt-leitura__campos dt { color:var(--rt-tinta-2); }
[data-pagina="rastreio"] .rt-leitura__campos dd { margin:0; font-weight:500; overflow-wrap:anywhere; }
[data-pagina="rastreio"] .rt-leitura__titulo { margin:20px 0 8px; font-size:14px; font-weight:500; }
[data-pagina="rastreio"] .rt-leitura > .rt-leitura__titulo:first-child { margin-top:0; }
[data-pagina="rastreio"] #processo .rt-leitura__campos { grid-template-columns:140px minmax(0, 1fr); }  /* as três seções alinhadas */
[data-pagina="rastreio"] .rt-linha-do-tempo { list-style:none; margin:0; padding:0 0 0 14px; border-left:1px solid var(--rt-filete); }
[data-pagina="rastreio"] .rt-linha-do-tempo li { position:relative; display:grid; grid-template-columns:150px minmax(0, 1fr); gap:12px; padding:6px 0; }
[data-pagina="rastreio"] .rt-linha-do-tempo li::before { content:''; position:absolute; left:-19px; top:12px; width:9px; height:9px; border-radius:50%;
  background:var(--rt-fundo); border:1px solid var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-linha-do-tempo li[data-real="true"]::before { background:var(--ds-acao); border-color:var(--ds-acao); }
[data-pagina="rastreio"] .rt-linha-do-tempo li[data-real="false"] { color:var(--rt-tinta-2); }
[data-pagina="rastreio"] .rt-linha-do-tempo__data { white-space:nowrap; }
[data-pagina="rastreio"] .rt-linha-do-tempo__data small,
[data-pagina="rastreio"] .rt-linha-do-tempo__evento small { display:block; font-size:12px; color:var(--rt-tinta-3); }
[data-pagina="rastreio"] .rt-linha-do-tempo__evento strong { font-weight:500; }

/* Tela larga: o painel cabe na janela e cada bloco rola por dentro */
@media (min-width: 1200px) and (max-width: 1365px) {
  /* telas de 1280: fontes mais estreitas para a lista de processos caber sem rolagem lateral */
  [data-pagina="rastreio"] .rt-grade { grid-template-columns:195px minmax(0, 1fr); }
  [data-pagina="rastreio"] .rt-fonte { padding:7px 10px; gap:2px 6px; }
  [data-pagina="rastreio"] .rt-fonte__nome small,
  [data-pagina="rastreio"] .rt-fonte__tempo { display:none; }
  [data-pagina="rastreio"] .rt-fonte { grid-template-columns:auto minmax(0, 1fr) auto; }
}
@media (min-width: 1200px) and (min-height: 640px) {
  body[data-pagina="rastreio"] { display:flex; flex-direction:column; height:100vh; overflow:hidden; }
  [data-pagina="rastreio"] .rt-grade { flex:1 1 auto; min-height:0; }
}
@media (max-width: 1199px), (max-height: 639px) {
  [data-pagina="rastreio"] .rt-grade { grid-template-columns:minmax(0, 1fr); grid-template-areas:"fontes" "containers"; grid-template-rows:auto auto; }
  [data-pagina="rastreio"] .rt-bloco__corpo { max-height:60vh; }
}
@media (max-width: 700px) {
  [data-pagina="rastreio"] { --rt-margem:16px; }
  [data-pagina="rastreio"] .rt-indicadores { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  [data-pagina="rastreio"] .rt-indicador:nth-child(3) { padding-left:0; border-left:0; }
  [data-pagina="rastreio"] .rt-indicador:nth-child(n + 3) { border-top:1px solid var(--rt-filete); }
  [data-pagina="rastreio"] .rt-fontes { grid-template-columns:minmax(0, 1fr); }
  [data-pagina="rastreio"] .rt-fonte:nth-child(odd) { border-right:0; }
  [data-pagina="rastreio"] .rt-filtros { margin-left:0; width:100%; }
}
/* No Four Cloud (#458): a mesma tela dentro do app (`.page`, altura cheia). O cabeçalho mora na barra do app
   e o drill vira panes lado a lado (lista | processo ou fonte | consulta), cada um rolando por dentro; abaixo de
   1200px os panes viram pilha: só o mais fundo aparece, com "Voltar". */
.rt-topo-acoes[data-pagina="rastreio"] { display:inline-flex; align-items:center; gap:10px; background:transparent; }
.rt-topo-acoes[data-pagina="rastreio"] .rt-estado { min-height:31px; }
.rt-topo-acoes[data-pagina="rastreio"] :is(.input-group, .btn) { flex-wrap:nowrap; white-space:nowrap; }
.page[data-pagina="rastreio"] { --rt-pane:clamp(380px, 30vw, 560px); padding-top:16px; }
.page[data-pagina="rastreio"] .rt-panes { flex:1 1 auto; min-height:0; display:grid; gap:16px; grid-template-columns:minmax(0, 1fr); }
.page[data-pagina="rastreio"] .rt-panes[data-niveis="2"] { grid-template-columns:minmax(0, 1fr) var(--rt-pane); }
.page[data-pagina="rastreio"] .rt-panes[data-niveis="3"] { --rt-pane:clamp(340px, 26vw, 520px); grid-template-columns:minmax(0, 1fr) var(--rt-pane) var(--rt-pane); }
/* com três níveis a lista estreita: as fontes sobem para cima dos processos, cada bloco rolando por dentro */
.page[data-pagina="rastreio"] .rt-panes[data-niveis="3"] .rt-grade { grid-template-columns:minmax(0, 1fr); grid-template-areas:"fontes" "containers";
  grid-template-rows:minmax(0, 2fr) minmax(0, 3fr); }
.page[data-pagina="rastreio"] .rt-pane { min-height:0; min-width:0; }
.page[data-pagina="rastreio"] .rt-pane__cabeca { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 14px;
  border-bottom:1px solid var(--rt-filete); }
.page[data-pagina="rastreio"] .rt-pane__titulo { display:block; margin-top:2px; font-size:16px; font-weight:500; }
.page[data-pagina="rastreio"] .rt-pane__corpo { flex:1 1 auto; min-height:0; overflow:auto; padding:14px; }
.page[data-pagina="rastreio"] .rt-pane .rt-leitura__campos { grid-template-columns:130px minmax(0, 1fr); }
.page[data-pagina="rastreio"] .rt-filtros-da-fonte { display:flex; gap:16px; margin-bottom:8px; }
.page[data-pagina="rastreio"] .rt-fonte__lidos[data-hoje] { cursor:pointer; }
.page[data-pagina="rastreio"] .rt-pane .rt-paginacao { margin:8px -14px -14px; }
.page[data-pagina="rastreio"] .rt-pane .rt-abas { display:flex; gap:20px; padding:0 14px; border-bottom:1px solid var(--rt-filete); }
.page[data-pagina="rastreio"] .rt-pane .rt-abas button { padding:10px 0; margin-bottom:-1px; border:0; border-bottom:2px solid transparent;
  background:none; font-weight:500; color:var(--rt-tinta-3); cursor:pointer; }
.page[data-pagina="rastreio"] .rt-pane .rt-abas [aria-selected="true"] { color:var(--rt-tinta); border-bottom-color:var(--ds-acao); }
.page[data-pagina="rastreio"] .rt-pane pre { margin:0; font-size:12px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; background:var(--rt-fundo-2); }
.page[data-pagina="rastreio"] :is(.rt-fonte, .rt-consultas li).rt-selecionada { background:var(--ds-acao-tinta); }
.page[data-pagina="rastreio"] .rt-fonte:hover { background:var(--rt-fundo-2); }
.page[data-pagina="rastreio"] .rt-fonte__nota { cursor:pointer; }
.page[data-pagina="rastreio"] .rt-so-estreito { display:none; }
.page[data-pagina="rastreio"] .rt-faixas { list-style:none; margin:0; padding:0; }
@media (max-width: 1199px) {
  .page[data-pagina="rastreio"] { overflow:auto; }
  .page[data-pagina="rastreio"] .rt-panes { flex:0 0 auto; grid-template-columns:minmax(0, 1fr) !important; }
  .page[data-pagina="rastreio"] .rt-panes:not([data-niveis="1"]) .rt-pane--lista,
  .page[data-pagina="rastreio"] .rt-panes[data-niveis="3"] #pane-detalhe { display:none; }
  .page[data-pagina="rastreio"] .rt-pane:not(.rt-pane--lista) { height:80vh; }
  .page[data-pagina="rastreio"] .rt-so-largo { display:none; }
  .page[data-pagina="rastreio"] .rt-so-estreito { display:inline; }
}
/* ── Início: home só com o feed (#286 / #737) ─────────────────────────────────
   Pele do Four Group Design System na home. Só USA os tokens globais --ds-*
   (bloco :root ~1361). Uma coluna central de 720 px: saudação em uma linha,
   composer e posts separados por fio, sem caixa. O composer é uma linha;
   `is-aberto` (feed.js, no foco) mostra Foto/Publicar e cresce o campo — não é
   :focus-within porque o mousedown em "Foto" tira o foco do textarea antes do
   click chegar. */
[data-pagina="inicio"]{font-family:var(--ds-fonte);color:var(--ds-tinta);background:#fff;padding:24px}
[data-pagina="inicio"] .home-feed{max-width:720px;margin:0 auto;font-size:var(--fonte-corpo)}
@media (max-width:991.98px){
  [data-pagina="inicio"]{padding:16px}
}
[data-pagina="inicio"] .home-saudacao{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:24px}
[data-pagina="inicio"] .home-saudacao__rotulo{font-size:var(--fonte-rotulo);letter-spacing:.18em;text-transform:uppercase;font-weight:500;color:var(--ds-tinta-2);white-space:nowrap}
[data-pagina="inicio"] .home-saudacao__nome{font-size:var(--fonte-heroi);font-weight:500;letter-spacing:-.03em}
[data-pagina="inicio"] .home-saudacao__data{margin-left:auto;color:var(--ds-tinta-2);font-size:var(--fonte-corpo)}
[data-pagina="inicio"] .home-feed .feed-publicar.is-aberto textarea{min-height:96px}
[data-pagina="inicio"] .home-feed .feed-publicar__acoes{display:none;margin-top:8px}
[data-pagina="inicio"] .home-feed .feed-publicar.is-aberto .feed-publicar__acoes{display:flex}
[data-pagina="inicio"] .home-feed .feed-item__texto{margin:8px 0}
[data-pagina="inicio"] .home-feed .feed-avatar{width:24px;height:24px;font-size:var(--fonte-pequena)}
[data-pagina="inicio"] .home-feed .feed-fotos--1 .feed-fotos__item img{max-height:420px;aspect-ratio:auto;height:auto}
[data-pagina="inicio"] .feed-publicar{padding:0 0 12px;margin-bottom:4px;border-bottom:1px solid var(--ds-filete)}
[data-pagina="inicio"] .feed-publicar.is-arrastando textarea{border-style:dashed;border-color:var(--ds-acao)}
[data-pagina="inicio"] .feed-publicar__acoes{display:flex;align-items:center;gap:12px;margin-top:12px}
[data-pagina="inicio"] .feed-publicar__acoes .btn-primary{margin-left:auto}
[data-pagina="inicio"] .feed-publicar__contador{color:var(--ds-tinta-3);font-size:var(--fonte-corpo)}
[data-pagina="inicio"] .feed-publicar__erro{color:var(--ds-negativo);margin:8px 0 0}
[data-pagina="inicio"] .feed-publicar__miniaturas{display:flex;gap:8px;margin-top:12px}
[data-pagina="inicio"] .feed-publicar__miniatura{position:relative;width:72px;height:72px}
[data-pagina="inicio"] .feed-publicar__miniatura img{width:100%;height:100%;object-fit:cover}
[data-pagina="inicio"] .feed-publicar__miniatura button{position:absolute;top:2px;right:2px;border:0;background:#fff;width:20px;height:20px;line-height:1}
[data-pagina="inicio"] .feed-item{padding:16px 0;border-bottom:1px solid var(--ds-filete);background:#fff}
[data-pagina="inicio"] .feed-item.is-destaque{border-left:2px solid var(--ds-acao);padding-left:12px}
[data-pagina="inicio"] .feed-item__topo{display:flex;align-items:center;gap:12px}
[data-pagina="inicio"] .feed-item__quem{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;flex:1}
[data-pagina="inicio"] .feed-item__quando,
[data-pagina="inicio"] .feed-item__editado{color:var(--ds-tinta-3);font-size:var(--fonte-corpo)}
[data-pagina="inicio"] .feed-item__moderado{font-size:var(--fonte-pequena);color:var(--ds-negativo)}
[data-pagina="inicio"] .feed-item__texto{white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0;line-height:1.5;max-width:66ch}
[data-pagina="inicio"] .feed-item__removido{color:var(--ds-tinta-3);font-style:italic;margin:12px 0}
[data-pagina="inicio"] .feed-mencao{color:var(--ds-acao);font-weight:500}
[data-pagina="inicio"] .feed-avatar{flex:none;width:32px;height:32px;border-radius:50%;background:var(--ds-acao-tinta);color:var(--ds-acao);
  display:inline-flex;align-items:center;justify-content:center;font-size:var(--fonte-pequena);font-weight:500}
[data-pagina="inicio"] .feed-fotos{display:grid;gap:4px;margin:12px 0}
[data-pagina="inicio"] .feed-fotos--2,
[data-pagina="inicio"] .feed-fotos--3,
[data-pagina="inicio"] .feed-fotos--4{grid-template-columns:1fr 1fr}
[data-pagina="inicio"] .feed-fotos__item{border:0;padding:0;background:none;cursor:zoom-in}
[data-pagina="inicio"] .feed-fotos__item img{display:block;width:100%;height:auto;max-height:520px;object-fit:cover}
[data-pagina="inicio"] .feed-fotos--2 img,
[data-pagina="inicio"] .feed-fotos--3 img,
[data-pagina="inicio"] .feed-fotos--4 img{aspect-ratio:1;height:100%}
[data-pagina="inicio"] .feed-item__rodape{display:flex;gap:16px;padding-top:8px;border-top:1px solid var(--ds-filete)}
[data-pagina="inicio"] .feed-acao{border:0;background:none;display:inline-flex;gap:6px;align-items:center;color:var(--ds-tinta-2);padding:4px 0}
[data-pagina="inicio"] .feed-acao.is-ativo{color:var(--ds-negativo)}
[data-pagina="inicio"] .feed-comentarios{margin-top:8px}
[data-pagina="inicio"] .feed-comentarios__todos{border:0;background:none;color:var(--ds-acao);padding:4px 0}
[data-pagina="inicio"] .feed-comentario{display:flex;gap:8px;padding:8px 0}
[data-pagina="inicio"] .feed-comentario__corpo{flex:1}
[data-pagina="inicio"] .feed-comentario .feed-item__texto{margin:2px 0}
[data-pagina="inicio"] .feed-comentario.is-enviando{opacity:.6}
[data-pagina="inicio"] .feed-comentario .feed-item__texto:empty{display:none}
[data-pagina="inicio"] .feed-comentario__imagem{display:block;border:0;padding:0;background:none;cursor:zoom-in;margin:4px 0}
[data-pagina="inicio"] .feed-comentario__imagem img{display:block;max-width:100%;max-height:240px;width:auto;height:auto}
[data-pagina="inicio"] .feed-comentar__linha{display:flex;align-items:center;gap:8px}
[data-pagina="inicio"] .feed-comentar__anexar{flex:none;cursor:pointer;color:var(--ds-tinta-2);padding:4px}
[data-pagina="inicio"] .feed-comentar__anexar:hover{color:var(--ds-acao)}
[data-pagina="inicio"] .feed-comentar{position:relative;margin-top:8px}
[data-pagina="inicio"] .feed-menu{position:relative}
[data-pagina="inicio"] .feed-menu__gatilho{list-style:none;cursor:pointer;padding:4px 8px;color:var(--ds-tinta-2)}
[data-pagina="inicio"] .feed-menu__gatilho::-webkit-details-marker{display:none}
[data-pagina="inicio"] .feed-menu__lista{position:absolute;right:0;z-index:5;background:#fff;border:1px solid var(--ds-filete);
  box-shadow:var(--ds-sombra-balao);min-width:180px}
[data-pagina="inicio"] .feed-menu__lista button{display:block;width:100%;text-align:left;border:0;background:none;padding:8px 12px}
[data-pagina="inicio"] .feed-menu__lista button:hover{background:var(--ds-acao-tinta)}
[data-pagina="inicio"] .feed-mencoes{position:absolute;z-index:6;list-style:none;margin:0;padding:0;background:#fff;
  border:1px solid var(--ds-filete);box-shadow:var(--ds-sombra-balao);min-width:240px}
[data-pagina="inicio"] .feed-mencoes button{display:block;width:100%;text-align:left;border:0;background:none;padding:8px 12px}
[data-pagina="inicio"] .feed-mencoes button:hover{background:var(--ds-acao-tinta)}
[data-pagina="inicio"] .feed-vazio{text-align:center;padding:40px 16px;color:var(--ds-tinta-2)}
[data-pagina="inicio"] .feed-vazio__titulo{font-weight:500;color:var(--ds-tinta)}
[data-pagina="inicio"] .feed-fim{height:1px}
.feed-aviso{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ds-tinta);color:#fff;
  padding:12px 16px;display:flex;gap:16px;align-items:center;z-index:1080;font-family:var(--ds-fonte)}
.feed-aviso button{border:0;background:none;color:#fff;text-decoration:underline}
.feed-ampliada{border:0;padding:0;max-width:92vw;max-height:92vh;background:transparent}
.feed-ampliada::backdrop{background:rgba(22,22,22,.85)}
.feed-ampliada img{max-width:92vw;max-height:92vh;display:block}
.feed-versoes{border:1px solid var(--ds-filete);font-family:var(--ds-fonte);padding:24px;max-width:560px;width:92vw}
.feed-versoes__item{border-bottom:1px solid var(--ds-filete);padding:8px 0}
.feed-versoes__item p{white-space:pre-wrap;margin:4px 0 0}

/* === PLANILHA DA CASA (static/js/planilha.js, #376) ==========================
   Componente compartilhado de edição no lugar, à moda do Excel (primeira tela:
   Metas). A célula é TEXTO, sem caixa: o hover diz que ali se digita, a célula
   ativa ganha o anel de foco. Leitura (ANO, TOTAL) não reage ao mouse. A
   primeira coluna e o cabeçalho ficam presos para o ano inteiro rolar sob eles. */
.planilha-rolagem { overflow: auto; height: 100%; }
.planilha { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%;
            font-size: var(--fonte-corpo); font-variant-numeric: tabular-nums; color: var(--ink); }
.planilha th, .planilha td { padding: .3rem .45rem; border-bottom: 1px solid var(--line-2);
                             white-space: nowrap; background: var(--surf); }
.planilha thead th { position: sticky; top: 0; z-index: 2; text-align: right; color: var(--ink-2);
                     font-weight: 500; border-bottom: 1px solid var(--line-3); }
.planilha .planilha-rotulo { position: sticky; left: 0; z-index: 1; text-align: left;
                             font-weight: normal; min-width: 13rem; max-width: 13.5rem; white-space: normal;
                             border-right: 1px solid var(--line); }
.planilha thead .planilha-rotulo { z-index: 3; }
.planilha td { text-align: right; min-width: 5.5rem; }
.planilha td[data-editavel] { cursor: cell; }
.planilha td[data-editavel]:hover { background: var(--surf-2); }
.planilha-celula--ativa { outline: 2px solid var(--bs-primary); outline-offset: -2px; }
/* Intervalo (#398): o tom de "selecionado" da app (`--acc-soft`, o mesmo da
   linha selecionada e da pílula ativa). Vence o fundo do rótulo e do cabeçalho
   fixos; o arrastar não pinta texto. */
.planilha .planilha-celula--intervalo, .planilha td[data-editavel].planilha-celula--intervalo:hover { background: var(--acc-soft); }
.planilha { user-select: none; }
/* Editando (#393): o editor FLUTUA sobre a célula, como no Excel — absoluto,
   ancorado nela, no mínimo da largura dela, crescendo com o texto por cima das
   vizinhas (à direita; `--esquerda` na beira da folha). O conteúdo da célula
   fica invisível e segura coluna e linha: a tabela não se mexe. */
.planilha-celula--editando { position: relative; z-index: 1; }
.planilha-celula--editando > :not(.planilha-editor-caixa) { visibility: hidden; }
.planilha-celula--editando { color: transparent; }
.planilha-editor-caixa { position: absolute; top: 0; bottom: 0; left: 0; min-width: 100%; max-width: 22rem;
                         display: flex; align-items: center; gap: .2em; padding: 0 .45rem;
                         background: var(--surf); color: var(--ink);
                         outline: 2px solid var(--bs-primary); outline-offset: -2px; }
.planilha-editor-caixa--esquerda { left: auto; right: 0; }
.planilha-editor { flex: 1 1 auto; width: auto; min-width: 0; border: 0; padding: 0; margin: 0;
                   text-align: right; font: inherit; line-height: inherit; background: transparent;
                   color: var(--ink); outline: none; }
.planilha-unidade { flex: none; font-size: var(--fonte-pequena); color: var(--ink-3); }
/* Estado da gravação NA célula (#440): salvando = anel girando no canto (o
   número digitado fica à vista); salvo = ✓ que some; erro = filete + ↻. */
.planilha-celula--salvando, .planilha-celula--salvo, .planilha-celula--erro { position: relative; }
.planilha-celula--salvando { color: var(--ink-3); }
.planilha-celula--salvando::after { content: ''; position: absolute; top: 3px; left: 3px; width: 9px; height: 9px;
    border: 1.5px solid var(--line-3); border-top-color: var(--bs-primary); border-radius: 50%;
    animation: planilha-girar .7s linear infinite; }
.planilha-celula--salvo::after { content: '✓'; position: absolute; top: 1px; left: 3px; font-size: .7rem;
    line-height: 1; color: var(--positive-text); animation: planilha-sumir 1.5s ease-in forwards; }
.planilha-celula--erro { box-shadow: inset 0 -2px 0 var(--negative-text); }
.planilha-tentar { position: absolute; top: 50%; left: 1px; transform: translateY(-50%); border: 0; background: none;
    padding: 0 .2rem; font-size: var(--fonte-corpo); line-height: 1; color: var(--negative-text); cursor: pointer; }
.planilha-tentar:hover { color: var(--ink); }
.planilha-tentar:focus-visible { outline: none; box-shadow: var(--ring); }
@keyframes planilha-girar { to { transform: rotate(360deg); } }
@keyframes planilha-sumir { 0%, 60% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .planilha-celula--salvando::after { animation: none; }
    .planilha-celula--salvo::after { animation: none; }
}

/* ══ ESTOQUE E PRODUTOS — Por produto e Ficha (#220) ═══════════════════════════════════════════
   Spec docs/superpowers/specs/2026-10-14-estoque-e-produtos-design.md §5.2–5.4 e §10.
   Painéis lista · ficha · mês, cada um rola por dentro; a página não rola (memória tela-usa-janela-inteira;
   a altura vem do gancho `content--altura-cheia`). A ficha é sempre tela cheia, sem a lista (#461); o mês
   abre ao lado dela a partir de 1200px e, abaixo, sozinho, com Voltar. `data-profundidade` (1 = lista;
   2 = ficha; 3 = ficha + mês) é escrito por estoque-produtos.js. Coluna nunca some para caber: código e
   descrição congelados na grade. */
.ep { gap:8px; }
.page:is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) { color:var(--ds-tinta); }
[data-pagina="estoque_produtos"].page { padding:0 24px; }
/* Lista A (#220 v4): o título e as etiquetas à esquerda, Período, Filtros ▾, Copiar ▾ e Colunas à direita, numa
   linha (a barra é a da casa, #454); as vistas como abas sublinhadas logo abaixo (`.ep-vistas-vaga`). */
.ep-titulo { margin:0 8px 0 0; font-size:var(--fonte-titulo); line-height:28px; font-weight:500; letter-spacing:-.01em; color:var(--ds-tinta); white-space:nowrap; }
.ep-vistas { display:flex; gap:24px; margin-top:8px; line-height:20px; border-bottom:1px solid var(--ds-filete); overflow-x:auto; }
.ep-vista { height:40px; display:flex; align-items:center; gap:6px; margin-bottom:-1px; padding:0; border:0;
  border-bottom:2px solid transparent; background:none; font-size:var(--fonte-corpo); color:var(--ds-tinta-2); white-space:nowrap; cursor:pointer; }
.ep-vista__conta { font-weight:500; color:var(--ds-tinta-3); }
.ep-vista:hover { color:var(--ds-tinta); }
.ep-vista--ativa { color:var(--ds-tinta); font-weight:500; border-bottom-color:var(--ds-acao); }
.ep-vista--ativa .ep-vista__conta { color:var(--ds-acao); }
.ep-vista--vazia, .ep-vista--vazia .ep-vista__conta { color:var(--ds-tinta-3); }
[data-pagina="estoque_produtos"] .ep-filtros__menu { width:18rem; padding:.75rem; }
[data-pagina="estoque_produtos"] .ep-filtros__menu .form-select { margin-bottom:.5rem; }
[data-pagina="estoque_produtos"] .ep-etiquetas { display:flex; align-items:center; gap:.5rem; }
[data-pagina="estoque_produtos"] .ep-etiquetas:empty { display:none; }
[data-pagina="estoque_produtos"] .ep-etiqueta { display:inline-flex; align-items:center; gap:.375rem; font-weight:500; }
[data-pagina="estoque_produtos"] .ep-etiqueta .btn-close { width:.5em; height:.5em; padding:0; background-size:.5em; }
.ep-dica { margin-left:6px; font-size:var(--fonte-pequena); vertical-align:-1px; color:var(--ds-tinta-3); }
/* No cabeçalho de 11px, o glifo da fonte de ícones assenta 2px abaixo do SVG da maquete. */
[data-pagina="estoque_produtos"] .ep-grade thead .ep-dica { vertical-align:1px; }
[data-pagina="estoque_produtos"] .ep-grade .grade .grade-tabela :is(th, td) .ep-mudo { color:var(--ds-tinta-3); font-weight:400; }
/* `.grade` no seletor: sem ele a cor perde para a do `tbody td` acima (mesmas classes, um elemento a mais). */
[data-pagina="estoque_produtos"] .ep-grade .grade .grade-tabela :is(td.ep-col-livre, thead tr:first-child th.ep-col-livre) { color:var(--ds-tinta); font-weight:500; }
[data-pagina="estoque_produtos"] .ep-grade .grade .grade-tabela td.ep-col-codigo { color:var(--ds-tinta-3); }
[data-pagina="estoque_produtos"] .ep-grade .grade .grade-tabela td.ep-col-descricao { color:var(--ds-tinta); }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela td.ep-col-descricao .ep-selo { margin-left:8px; }
/* As larguras da maquete A: as colunas padrão têm a sua; a Descrição fica com o resto (sem teto além do da janela).
   Código e descrição congelados (`congelarColunas: 2`); coluna ligada no Colunas rola de lado, nunca some. */
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-codigo { width:100px; min-width:100px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-subsegmento { width:150px; min-width:150px; max-width:150px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela :is(.ep-col-livre, .ep-col-estoque) { width:112px; min-width:112px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-bloqueio { width:96px; min-width:96px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-valor { width:116px; min-width:116px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-chegar { width:88px; min-width:88px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-proxima { width:116px; min-width:116px; }
[data-pagina="estoque_produtos"] .ep-grade .grade-tabela .ep-col-descricao { max-width:max(10rem, calc(100vw - 1090px)); }
.ep .ep-col-descricao { max-width:24rem; }
/* Total por unidade: quebra entre unidades, nunca dentro de uma ("7.801 CX" fica inteiro). */
.ep .ep-por-unidade { display:block; width:max-content; max-width:13rem; margin-left:auto; white-space:normal; }
.ep .ep-por-unidade > span { white-space:nowrap; }
/* No celular a casa sangra a tabela até a borda (`.content .tbl-wrapper`, margem −16px); dentro do painel, que
   corta o que vaza, isso comia 16px de cada lado (código e busca cortados). */
.ep .ep-painel .tbl-wrapper { margin-left:0; margin-right:0; }
/* Gráfico de 12 meses do produto na aba Histórico (#462): até 160px, recolhível (a 1366 a tabela mensal precisa da altura). */
.ep-grafico { flex:0 0 auto; }
.ep-grafico > summary { font-size:var(--fonte-corpo); font-weight:500; padding:4px 0; cursor:pointer; color:var(--ds-tinta); }
[data-pagina="estoque_produtos"] .ep-grafico .evm-faixa__area { height:160px; }
/* PANES DA CASA (fc-paineis, #220 → #472): o drill em panes lado a lado, cada um com rolagem própria e a
   janela sem rolagem de página (dono, 13/10 e 19/10/2026). A tela diz a profundidade (`data-profundidade`)
   e quais panes cabem em cada uma; o pane ao lado (`--lado`) leva o filete. Usado por Estoque e Produtos e
   por Certificados e laudos. */
.fc-paineis { flex:1 1 auto; min-height:0; display:grid; gap:12px; grid-template-columns:minmax(0,1fr); }
.fc-painel { min-width:0; min-height:0; display:flex; flex-direction:column; overflow:hidden; background:#fff; }
.fc-painel[hidden] { display:none !important; }
.fc-painel--lado { border-left:1px solid var(--bs-border-color); padding-left:12px; }
.fc-painel .datatable { --bi-dt-scroll-max:none; }
.ep-grade, .ep-ficha-host, .ep-aba, .ep-aba__grade, .ep-mes__corpo { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.ep-nota { flex:none; margin:.25rem 0 0; font-size:var(--fonte-corpo); color:var(--ink-2); }
.ep-nota[hidden] { display:none; }
.ep-aba[hidden], .ep-aba__grade[hidden] { display:none; }
.fc-painel .grade, .fc-painel .dataTables_wrapper, .fc-painel .tbl-wrapper { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.fc-painel .datatable-scroll { flex:1 1 auto; min-height:0; overflow:auto; }
.ep-voltar { align-self:flex-start; }
/* A ficha tira a lista da tela (#461); o mês fica sozinho até caber ao lado da ficha. */
.ep-paineis[data-profundidade="2"] .ep-painel--lista,
.ep-paineis[data-profundidade="3"] .ep-painel--lista,
.ep-paineis[data-profundidade="3"] .ep-painel--ficha { display:none; }
@media (min-width:1200px) {
  .ep-paineis[data-profundidade="3"] { grid-template-columns:minmax(0,7fr) minmax(0,5fr); }
  .ep-paineis[data-profundidade="3"] .ep-painel--ficha { display:flex; }
  .ep-paineis[data-profundidade="3"] .ep-voltar[data-voltar="ficha"] { display:none; }
}
.ep-linha--aberta > td { background:var(--ds-acao-tinta); }
.ep-pareto { flex:0 0 auto; border-bottom:1px solid var(--bs-border-color); margin-bottom:8px; max-height:45%; overflow:auto; }
.ep-pareto > summary { font-size:var(--fonte-corpo); font-weight:500; padding:4px 0; cursor:pointer; }
.ep-falha { color:var(--negative-text); margin:8px 0; font-size:var(--fonte-corpo); }
.ep-vazio { color:var(--ink-3); margin:8px 0; font-size:var(--fonte-corpo); }
/* Fonte fora do ar (avisoDeFontes): neutro, filete à esquerda; nada de âmbar. */
.ep-aviso { flex:0 0 auto; margin:0 0 8px; padding:4px 10px; border-left:3px solid #8A8F98; background:#F8F9FA; color:var(--ink-2); font-size:var(--fonte-corpo); }
/* A ficha da direção C (#220 v4): topo ("‹ Lista" · ‹ › · Copiar link), título e o retrato em 5 blocos, com o
   Detalhe no pé. A aba aberta toma o lugar dos blocos e a linha das abas sobe para o topo. */
.ep-ficha { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; font-size:var(--fonte-corpo); line-height:20px; }
.ep-ficha__cabeca { flex:0 0 auto; display:flex; flex-direction:column; }
.ep-ficha__topo { display:flex; align-items:center; gap:8px; padding-top:12px; font-size:var(--fonte-corpo); color:var(--ds-tinta-3); }
.ep-ficha__vao { flex:1 1 auto; }
.ep-ficha__titulo { display:flex; align-items:center; gap:8px; padding:8px 8px 0; min-width:0; }
.ep-ficha__titulo h2 { margin:0; font-size:var(--fonte-titulo); line-height:28px; font-weight:500; letter-spacing:-.01em; color:var(--ds-tinta);
 }
.ep-ficha__titulo h2 .ep-codigo { color:var(--ds-tinta-3); font-weight:400; margin-right:4px; }
.ep-icone { width:16px; height:16px; vertical-align:-3px; }
.ep-outra-unidade { cursor:pointer; color:var(--warning-text); }
.ep-retrato { overflow:auto; display:block; }
.ep-blocos { display:grid; grid-template-columns:repeat(auto-fit, minmax(16rem, 1fr)); gap:32px 56px; padding:28px 8px 8px; }
.ep-blocos--duas { padding-top:24px; }
.ep-bloco { min-width:0; }
.ep-bloco__titulo { margin:0 0 12px; font-size:var(--fonte-rotulo); line-height:16px; font-weight:500; letter-spacing:.06em; text-transform:uppercase; color:var(--ds-tinta-3); }
.ep-linha { display:flex; justify-content:space-between; align-items:baseline; gap:16px; height:32px; padding-top:6px;
  border-bottom:1px solid var(--ds-filete); font-size:var(--fonte-corpo); line-height:20px; color:var(--ds-tinta-2); }
.ep-linha__rotulo { min-width:0; }
.ep-linha__rotulo b { font-weight:500; color:var(--ds-tinta); }
.ep-linha__rotulo .ep-codigo { color:var(--ds-tinta-3); margin-right:8px; }
.ep-linha__valor { color:var(--ds-tinta); font-weight:500; white-space:nowrap; border:0; background:none; padding:0; font:inherit; font-weight:500; }
.ep-linha__valor.ep-mudo { color:var(--ds-tinta-3); font-weight:400; }
.ep-linha__data { margin-left:12px; color:var(--ds-tinta-3); font-weight:400; }
button.ep-linha__valor { cursor:pointer; }
/* #567: o lote do "Onde está" abre Movimentos filtrado nele; a linha inteira é o alvo. */
.ep-linha--lote { cursor:pointer; }
.ep-linha--lote:hover .ep-linha__rotulo { color:var(--ds-acao); }
.ep-heroi { display:flex; justify-content:space-between; align-items:baseline; padding-bottom:4px; border-bottom:1px solid var(--ds-filete);
  font-size:var(--fonte-corpo); color:var(--ds-tinta); }
.ep-heroi .ep-linha__rotulo { color:var(--ds-tinta-2); }
.ep-heroi__valor { font-size:var(--fonte-heroi); line-height:40px; font-weight:500; letter-spacing:-.02em; color:var(--ds-tinta); }
.ep-heroi small { font-size:var(--fonte-corpo); font-weight:500; letter-spacing:0; margin-left:4px; color:var(--ds-tinta-3); }
/* #714: o herói é cartão de KPI — "Ver a conta" no pé, o herói inteiro clicável; a dica do rótulo fica por cima. */
.ep-heroi { position:relative; flex-wrap:wrap; }
.ep-heroi__pe { flex-basis:100%; text-align:right; font-size:var(--fonte-pequena); }
.ep-heroi .conta-calc-vaga { position:static; }
.ep-heroi .ep-dica { position:relative; z-index:2; }
.ep-mais { display:block; margin-top:8px; padding:0; border:0; background:none; font-size:var(--fonte-corpo); color:var(--ds-acao); cursor:pointer; }
/* Conta auditável (#220 v4; compartilhada desde o #508 — ficha do produto e Análise de Produção, `biUtils.contaHtml`): o número abre o dropdown do Bootstrap com as parcelas e o "=" do servidor.
   #681 (dono, 28/10/2026): é conteúdo clicável, então tem a cara do link de fábrica do Bootstrap — azul e sublinhado,
   o azul escuro no mouse, o anel de foco do navegador. É um <button> (abre sem navegar) com o botão zerado. */
.conta-calc { cursor:pointer; border:0; background:none; padding:0; font:inherit; color:var(--bs-link-color); text-decoration:underline; }
.conta-calc:hover { color:var(--bs-link-hover-color); }
/* A vaga do dropdown é a referência do Popper: inline, o `dropdown-menu-end` não acha a ponta direita do número. */
.conta-calc-vaga { display:inline-block; }
.conta-aberta { width:340px; padding:12px 16px; border:1px solid var(--bs-border-color); border-radius:6px; font-size:var(--fonte-corpo); line-height:20px; text-align:left;
  font-weight:400; color:var(--ds-tinta); box-shadow:0 8px 24px rgba(22,22,22,.10), 0 1px 2px rgba(22,22,22,.06); letter-spacing:0;
  max-height:min(70vh, 640px); overflow-y:auto; }
.conta-aberta__titulo { font-size:var(--fonte-pequena); color:var(--ds-tinta-3); margin-bottom:6px; }
.conta-aberta__linha { display:grid; grid-template-columns:14px 1fr auto; gap:8px; align-items:baseline; padding:3px 0; color:var(--ds-tinta-2); }
.conta-aberta__operador { color:var(--ds-tinta-3); text-align:center; }
.conta-aberta__rotulo { min-width:0; overflow-wrap:anywhere; }
.conta-aberta__valor { color:var(--ds-tinta); font-weight:500; white-space:nowrap; }
.conta-aberta__total { border-top:1px solid var(--ds-filete-2); margin-top:4px; padding-top:6px; }
.conta-aberta__total .conta-aberta__valor { font-size:var(--fonte-destaque); }
.conta-aberta__ir { display:block; width:100%; margin-top:8px; padding:0; border:0; background:none; font:inherit; text-align:left; color:var(--ds-acao); cursor:pointer; }
/* Os modais de Preço médio e Custo médio (modal-xl do Bootstrap): a conta em grade no topo e a tabela das notas. */
.ep-modal { font-size:var(--fonte-corpo); line-height:20px; }
.ep-modal .modal-title { font-size:var(--fonte-destaque); font-weight:500; }
/* As células na entrelinha normal, como na maquete (13px → linha de 25px). */
.ep-modal__tabela :is(tr, th, td) { line-height:normal; }
.ep-modal .modal-title .ep-codigo { color:var(--ds-tinta-3); font-weight:400; margin-right:4px; }
.ep-modal-conta { display:grid; grid-template-columns:auto 1fr auto auto auto auto; gap:4px 16px; align-items:baseline; font-size:var(--fonte-corpo);
  margin-bottom:16px; }
.ep-modal-conta__rotulo { color:var(--ds-tinta-2); }
.ep-modal-conta__numero { text-align:right; font-weight:500; color:var(--ds-tinta); }
.ep-modal-conta__operador { color:var(--ds-tinta-3); text-align:center; }
.ep-modal-conta__fim { border-top:1px solid var(--ds-filete-2); padding-top:6px; }
.ep-modal-conta__alvo { background:var(--ds-acao-tinta); border-radius:4px; padding:0 6px; }
.ep-modal__tabela { font-size:var(--fonte-corpo); margin:0; }
.ep-modal__tabela th { position:sticky; top:0; background:#fff; font-size:var(--fonte-rotulo); font-weight:500; letter-spacing:.05em; text-transform:uppercase;
  color:var(--ds-tinta-3); white-space:nowrap; border-bottom:1px solid var(--ds-filete-2); }
.ep-modal__tabela td { color:var(--ds-tinta-2); white-space:nowrap; }
.ep-modal__tabela .ep-modal__n { text-align:right; }
.ep-modal__tabela td.ep-modal__forte, .ep-modal__tabela tr.ep-modal__compra td { color:var(--ds-tinta); }
.ep-modal__tabela td.ep-modal__forte { font-weight:500; }
.ep-modal__cliente { max-width:320px; }
.ep-modal .modal-footer { justify-content:flex-end; }
.ep-ficha__recorte { margin:0; font-size:var(--fonte-pequena); color:var(--ink-3); }
.ep-ficha__corpo { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
/* Abas da ficha (#462): o desenho da `.pd-aba` do Pedidos e NF (preso a crm-pedidos), com o azul da ação.
   Copiar e Colunas da aba aberta na ponta da mesma linha. */
.ep-abas-linha { flex:0 0 auto; display:flex; align-items:center; gap:.5rem; padding:16px 8px 0; }
:is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) .pd-abas {
  display:flex; gap:1.25rem; padding:.25rem 0 .5rem; min-width:0; overflow-x:auto; }
:is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) .pd-aba {
  background:none; border:0; border-bottom:2px solid transparent;
  padding:.25rem .1rem; color:var(--ink-2); font-size:var(--fonte-corpo); cursor:pointer; white-space:nowrap; }
:is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) .pd-aba:hover { color:var(--ds-tinta); }
:is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) .pd-aba--ativa {
  color:var(--ds-tinta); font-weight:500; border-bottom-color:var(--ds-acao); }
@media (max-width:1023.98px),(pointer:coarse){
  :is([data-pagina="estoque_produtos"], [data-pagina="estoque_mensal"]) .pd-aba { display:inline-flex; align-items:center; min-height:44px; }
}
.ep-abas__ferramentas { margin-left:auto; display:flex; align-items:center; }
.ep-abas__ferramentas > [hidden] { display:none; }
.ep-abas__ferramentas .dt-buttons { display:flex; gap:.5rem; }
/* Com um depósito só, o cabeçalho do grupo vem vazio (repetia a cabeça): a linha não se desenha. */
.ep-aba tr.grade-grupo:has(> td:empty) { display:none; }
.ep-aba__barra { flex:0 0 auto; display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:6px 0; font-size:var(--fonte-corpo); }
.ep-subtitulo { font-size:var(--fonte-corpo); font-weight:500; margin:8px 0 4px; color:var(--ds-tinta); }
.ep-origem { border:0; background:none; padding:0; color:var(--ds-acao); text-decoration:underline; font:inherit; }
.ep-mes__cabeca { flex:0 0 auto; display:flex; flex-direction:column; }
.ep-mes__linha { font-size:var(--fonte-corpo); margin:4px 0 8px; }
.ep-gaveta { width:min(720px, 100vw); }
/* Selo de situação: pílula tint + ponto (memória situacao-ponto-e-texto-nao-etiqueta). */
.ep-selo { display:inline-flex; align-items:center; gap:6px; height:22px; padding:0 10px 0 8px; border-radius:999px; font-size:var(--fonte-pequena); font-weight:500; line-height:1; white-space:nowrap; vertical-align:middle; background:#F1F1EF; color:var(--ds-tinta); box-shadow:inset 0 0 0 1px rgba(22,22,22,.06); }
.ep-selo::before { content:''; flex:none; width:7px; height:7px; border-radius:50%; background:#8A8F98; }
.ep-selo[data-situacao="falta"] { background:#FFF1E5; }
.ep-selo[data-situacao="falta"]::before { background:#FF7B00; }
/* Faixa da margem (#220, F5): mesma pílula; média = laranja de atenção, nunca âmbar. */
.ep-selo[data-faixa="baixa"] { background:color-mix(in srgb, var(--ds-perigo) 12%, #fff); }
.ep-selo[data-faixa="baixa"]::before { background:var(--ds-perigo); }
.ep-selo[data-faixa="media"] { background:#FFF1E5; }
.ep-selo[data-faixa="media"]::before { background:#FF7B00; }
.ep-selo[data-faixa="saudavel"] { background:color-mix(in srgb, var(--ds-sucesso) 12%, #fff); }
.ep-selo[data-faixa="saudavel"]::before { background:var(--ds-sucesso); }

/* ══ Estoque › Visão mensal (/estoque/mensal/, #220, spec §5.1) ═══════════════
   Escopo de página: tudo sob .evm. Os chips são os da casa (`.grade .grade-chip`, como as vistas da Por produto);
   fora de uma .grade os tokens --grade-* não existem, então o resto usa --ds-* e --ink. A altura vem de
   `content--altura-cheia` (a página é uma coluna): barra e gráfico ocupam o que precisam, os painéis ficam com a sobra. */
.evm-barra { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: 0 0 .5rem; }
.evm-barra__direita { display: flex; align-items: center; gap: .75rem; margin-left: auto; }
.evm-deposito { width: auto; min-width: 12rem; }
.evm-a-chegar-motivo { color: var(--ink-2); }
.evm-nota-fundo { margin: .25rem 0 0; color: var(--ink-2); }
.evm-nota-fundo:empty { display: none; }
.evm-barra .evm-chips.grade-chips { display: flex; flex-direction: row; flex: 0 0 auto; flex-wrap: wrap; max-width: 100%; padding: 0; }
/* Quem rola é o conteúdo (o gráfico sobe) e os painéis têm a altura dele (`grade-na-altura-da-janela`, #498): sem
   isso, a 1366×768 a barra, o gráfico e a linha do mês comiam a janela e a grade ficava sem linha visível. */
.evm-conteudo { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }
.evm-grafico { flex: 0 0 auto; }
.evm-grafico__area { position: relative; height: clamp(160px, 28vh, 260px); }
.evm-atrasados { margin: .25rem 0 0; color: var(--warning-text); font-size: var(--fonte-corpo); }
.evm-atrasados:empty { display: none; }
.evm-mes:empty { display: none; }
.evm-linha-do-mes { flex: 0 0 auto; margin: .25rem 0 .5rem; font-variant-numeric: tabular-nums; color: var(--ink); }
.evm-paineis { display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr); }
.evm-paineis--com-ficha { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.evm-painel { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: auto; background: #fff; }
.evm-painel[hidden] { display: none !important; }
.evm-painel--grade > #evm-grade { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.evm-painel__barra { display: flex; align-items: center; padding-bottom: .25rem; }
.evm-voltar { display: none; }
.evm-marca { font-size: var(--fonte-pequena); color: var(--ink-2); }
.evm-linha-marcada > td { background: var(--surf-2); }
/* O menu de trânsito é o dropdown do Bootstrap (como `.conta-aberta`): só a largura da tabela e o respiro. */
.evm-transito__menu { min-width: 26rem; max-width: 32rem; padding: .5rem .75rem; }
.evm-transito__topo { display: flex; align-items: center; justify-content: space-between; font-weight: 500; padding-bottom: .25rem; }
.evm-transito__tabela { width: 100%; font-size: var(--fonte-corpo); margin-bottom: .5rem; }
.evm-transito__tabela th { font-weight: 500; color: var(--ink-2); padding: .2rem .5rem; }
.evm-transito__tabela td { padding: .2rem .5rem; }
.evm-transito__atrasado td { background: color-mix(in srgb, var(--ds-atencao) 8%, #fff); }
.evm-transito__selo { color: var(--warning-text); font-weight: 500; }
.evm-transito__vazio { margin: 0; color: var(--ink-2); }
/* Faixa do gráfico do produto sobre a lista Por produto (spec §5.2), montada por estoqueMensal.montarGrafico. */
.evm-faixa__topo { display: flex; align-items: baseline; gap: .75rem; font-size: var(--fonte-pequena); letter-spacing: .04em; color: var(--ink-2); }
.evm-faixa__titulo { font-weight: 500; color: var(--ink); }
.evm-faixa__mes { font-variant-numeric: tabular-nums; }
.evm-faixa__area { position: relative; height: 96px; margin-bottom: .5rem; }
/* Tela estreita: um painel por vez, com Voltar (spec §10). */
@media (max-width: 991.98px) {
  .evm-paineis--com-ficha { grid-template-columns: minmax(0, 1fr); }
  .evm-paineis--com-ficha .evm-painel--grade { display: none; }
  .evm-paineis--com-ficha .evm-voltar { display: inline-block; }
}

/* ── Portal dos representantes (#471) ─────────────────────────────────────
   representantes/templates/representantes/base.html: fundo branco, cabeçalho
   com a marca, o escritório, as três entradas e Sair. Botões e campos são os
   do Bootstrap (#454). */
[data-pagina^="rep-"] { margin: 0; min-height: 100vh; background: #fff; color: var(--ink); font-family: var(--sans); }
[data-pagina^="rep-"] .rep-cabecalho { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.5rem; padding: .75rem 1.5rem; border-bottom: 1px solid var(--line); }
[data-pagina^="rep-"] .rep-marca { display: block; line-height: 0; }
[data-pagina^="rep-"] .rep-marca img { height: 20px; width: auto; }
/* O logo da entrada, o mesmo do login interno (logo-inv.png, o escuro para fundo claro). */
[data-pagina^="rep-"] .rep-logo { display: block; max-width: 100%; height: auto; margin: 0 auto 1.5rem; }
[data-pagina^="rep-"] .rep-escritorio { color: var(--ink-2); }
[data-pagina^="rep-"] .rep-menu { display: flex; gap: 1.25rem; margin-left: auto; }
[data-pagina^="rep-"] .rep-menu a { color: var(--ink); text-decoration: none; }
[data-pagina^="rep-"] .rep-menu a:hover { color: var(--bs-primary); }
[data-pagina^="rep-"] .rep-sair .btn { padding: 0; }
[data-pagina^="rep-"] .rep-conteudo { padding: 1.5rem; }
/* O Funil e o Negócio do CRM no portal (#471 §10) ocupam a janela: quem rola são as colunas,
   como no interno (`content--altura-cheia`), sem a topbar de 52px da casca interna. */
[data-pagina="rep-funil"], [data-pagina="rep-negocio"] { height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
[data-pagina="rep-funil"] .rep-conteudo, [data-pagina="rep-negocio"] .rep-conteudo { flex: 1 1 auto; min-height: 0; padding: 0; }
[data-pagina^="rep-"] .rep-titulo { font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; }
[data-pagina^="rep-"] .rep-cartao { max-width: 24rem; margin: 3rem auto; }
[data-pagina^="rep-"] .rep-outro-codigo { display: flex; justify-content: space-between; margin-top: 1rem; }
[data-pagina^="rep-"] .rep-outro-codigo .btn { padding-left: 0; padding-right: 0; }
[data-pagina^="rep-"] .rep-topo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: 1rem; }
[data-pagina^="rep-"] .rep-topo .rep-titulo { margin-bottom: 0; }
[data-pagina^="rep-"] .rep-formulario { max-width: 40rem; }
/* A grade do portal mora num bloco comum, sem a casca de altura cheia do app: enquanto carrega
   ela mede 0 e o logo-loader some. A reserva do modo "board" volta só durante a carga. */
[data-pagina^="rep-"] .grade .tbl-wrapper[data-bi-loading] { min-height: 30rem; }

/* ── Comex › Certificados e laudos: detalhe do lote (#472) ──
   A gaveta larga o bastante para a página do certificado; as caixas sobre os números
   são posicionadas pelo JS em % da imagem (a fração que o motor gravou). */
[data-pagina="certificados_e_laudos"] .cl-gaveta { width:min(960px, 100vw); }
[data-pagina="certificados_e_laudos"] .cl-pagina { position:relative; display:inline-block; max-width:100%; border:1px solid var(--bs-border-color); background:var(--bs-body-bg); }
[data-pagina="certificados_e_laudos"] .cl-pagina img { display:block; max-width:100%; height:auto; }
[data-pagina="certificados_e_laudos"] .cl-caixa { position:absolute; padding:0; border:2px solid var(--bs-primary); background:rgba(var(--bs-primary-rgb), .08); border-radius:2px; cursor:pointer; }
[data-pagina="certificados_e_laudos"] .cl-caixa[data-fere="true"] { border-color:var(--bs-danger); background:rgba(var(--bs-danger-rgb), .1); }
[data-pagina="certificados_e_laudos"] .cl-caixa.is-ativa { outline:3px solid var(--bs-warning); outline-offset:1px; }
[data-pagina="certificados_e_laudos"] .cl-recorte img { max-width:100%; height:auto; border:1px solid var(--bs-border-color); background:var(--bs-body-bg); }
[data-pagina="certificados_e_laudos"] .cl-valores-gravados { max-height:20rem; overflow:auto; font-size:var(--fonte-pequena); background:var(--bs-light); padding:.5rem; }
/* A evidência do original (entrega 2): o recorte é a linha inteira da tabela (~2.500 × 100 px a 300 dpi). Reduzido à
   largura do modal fica ilegível; vai na altura de leitura, com rolagem lateral, e a marca sobre o número. Sem o
   escopo da página: o modal da confirmação mora no <body>. */
.cl-faixa-evidencia { overflow-x:auto; border:1px solid var(--bs-border-color); background:var(--bs-body-bg); }
.cl-faixa-evidencia__trilho { position:relative; display:inline-block; vertical-align:top; }
.cl-faixa-evidencia img { display:block; height:3.5rem; width:auto; max-width:none; }
.cl-faixa-evidencia__marca { position:absolute; top:0; bottom:0; border:2px solid var(--bs-danger); border-radius:2px; pointer-events:none; }
/* A lista (#472, maquete 3 aprovada pelo dono em 19/10/2026): a grade montada no #cl-grade ocupa a altura que
   sobra, como a irmã Pedidos e Notas Fiscais; o fabricante longo quebra em linhas (nada cortado), o lote não;
   a situação é ponto + palavra (o ponto laranja vivo no parado, nunca marrom). */
[data-pagina="certificados_e_laudos"] #cl-grade,
[data-pagina="certificados_e_laudos"] #cl-grade > .grade { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
[data-pagina="certificados_e_laudos"] .cel-col-fabricante,
[data-pagina="certificados_e_laudos"] .cel-col-fabricante .grade-celula { white-space:normal; }
[data-pagina="certificados_e_laudos"] .cel-acoes { display:flex; gap:.25rem; }
[data-pagina="certificados_e_laudos"] .cel-situacao { white-space:nowrap; }
[data-pagina="certificados_e_laudos"] .cel-situacao::before { content:""; display:inline-block; width:.5rem; height:.5rem; border-radius:50%; margin-right:.45rem; background:var(--bs-secondary-color); }
[data-pagina="certificados_e_laudos"] .cel-s-gerado::before { background:var(--bs-success); }
[data-pagina="certificados_e_laudos"] .cel-s-na_fila::before { background:var(--bs-primary); }
[data-pagina="certificados_e_laudos"] .cel-s-parado_para_conferencia::before { background:#FF7B00; }
[data-pagina="certificados_e_laudos"] .cel-s-falhou::before { background:var(--bs-danger); }
[data-pagina="certificados_e_laudos"] .cel-s-sem_certificado::before { background:transparent; box-shadow:inset 0 0 0 1.25px var(--bs-secondary-color); }
/* Por processo em panes (maquete 5, dono 19/10/2026): a barra da lista (período, busca, chips) sobe para cima
   dos panes, na largura inteira; os processos à esquerda e o processo aberto ao lado (fc-paineis), cada um
   com a sua rolagem. */
[data-pagina="certificados_e_laudos"] .cel-barra .datatable-toolbar { margin:4px 0 8px; display:flex; flex-wrap:wrap;
  justify-content:space-between; align-items:center; gap:6px 8px; }
[data-pagina="certificados_e_laudos"] .cel-barra .datatable-toolbar > div { display:flex; align-items:center; gap:8px; }
[data-pagina="certificados_e_laudos"] .cel-paineis[data-profundidade="2"] { grid-template-columns:minmax(0,5fr) minmax(0,7fr); }
[data-pagina="certificados_e_laudos"] .cel-paineis .cl-grade,
[data-pagina="certificados_e_laudos"] .cel-processo__lotes { flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca { flex:0 0 auto; margin:2px 0 8px; }
[data-pagina="certificados_e_laudos"] .cel-processo__topo { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca h2 { font-size:var(--fonte-destaque); font-weight:500; margin:0 0 2px; }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca dl { display:flex; flex-wrap:wrap; gap:4px 20px; margin:0; font-size:var(--fonte-corpo); }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca dl > div { white-space:nowrap; }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca dt { font-weight:400; color:#6c757d; }
[data-pagina="certificados_e_laudos"] .cel-processo__cabeca dd { margin:0; color:#212529; }
[data-pagina="certificados_e_laudos"] .cel-processo__acoes { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:.25rem; }
[data-pagina="certificados_e_laudos"] .cel-paineis tr.cel-processo-aberto > td { background:var(--bs-primary-bg-subtle); font-weight:500; }
/* O andamento do processo em três etapas numeradas (#546): certificado, packing list, laudos. */
[data-pagina="certificados_e_laudos"] .cel-etapas { list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:8px; }
[data-pagina="certificados_e_laudos"] .cel-etapa { display:flex; align-items:flex-start; gap:10px; padding-top:8px; border-top:1px solid var(--bs-border-color); }
[data-pagina="certificados_e_laudos"] .cel-etapa__numero { flex:0 0 auto; width:1.5rem; height:1.5rem; border-radius:50%; display:inline-flex;
  align-items:center; justify-content:center; background:#e7f1ff; color:var(--bs-primary); font-weight:500; }
[data-pagina="certificados_e_laudos"] .cel-etapa__corpo { flex:1 1 auto; min-width:0; }
[data-pagina="certificados_e_laudos"] .cel-etapa__corpo h3 { font-size:var(--fonte-corpo); font-weight:500; margin:2px 0 0; }
[data-pagina="certificados_e_laudos"] .cel-etapa__estado { color:#495057; }
[data-pagina="certificados_e_laudos"] .cel-etapa__barra { height:.375rem; margin-top:4px; max-width:320px; }
[data-pagina="certificados_e_laudos"] .cel-etapa__motivos { margin:2px 0 0; padding-left:1rem; }
[data-pagina="certificados_e_laudos"] .cel-etapa__acoes { flex:0 0 auto; display:flex; flex-wrap:wrap; justify-content:flex-end; gap:.25rem; }

/* ── #471 · Representantes externos (tela interna) ─────────────────────────── */
[data-pagina="representantes-externos"] .rx-contagens { color: #495057; margin-bottom: .5rem; }
[data-pagina="representantes-externos"] .rx-secao { margin-bottom: 1.25rem; }
[data-pagina="representantes-externos"] .rx-gerente { display: flex; justify-content: space-between; align-items: center; padding: .25rem 0; border-bottom: 1px solid #dee2e6; }
[data-pagina="representantes-externos"] .rx-sugestao { margin-bottom: .75rem; }
[data-pagina="representantes-externos"] .rx-confirma { padding: .5rem 0; }

/* ── Novidades da tela (#529): modal da casca e auditoria /novidades/ ── */
.novidade + .novidade { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--bs-border-color); }
.novidade__texto { white-space: pre-line; }
.novidade__print { width: 240px; max-width: 100%; }

/* ── #558 · Matriz de acesso: nome da tela na vertical no cabeçalho ──────── */
/* Na horizontal cada tela ocupava 94–342px e cabiam 3 por vez em 1366. Na vertical
   (de baixo para cima) a coluna fica na largura do filtro e o nome quebra em linhas,
   sem corte. A grade fixa o rótulo em 34px e gruda os filtros em `top:34px`; aqui os
   dois sobem juntos para 9rem, só nesta tela (grade.js e .grade intocados). */
[data-pagina="matriz_acesso"] .grade-tabela thead tr:first-child th.mz-col-tela {
  writing-mode: sideways-lr; white-space: normal; height: 9rem; vertical-align: bottom; text-align: left;
}
[data-pagina="matriz_acesso"] .grade-tabela thead tr.grade-filtros-col th { top: 9rem; }
[data-pagina="matriz_acesso"] .grade .grade-tabela :is(th, td).mz-col-tela { padding-left: 4px; padding-right: 4px; }

/* Produção de Bobinas — lançamento da fábrica (#639): quadro oculto que recebe a folha da etiqueta e imprime. */
.producao-bobinas-fabrica__folha { display: none; }
@media print {
  body:has(> .producao-bobinas-fabrica__folha) { margin: 0; padding: 0; background: #fff; }
  body:has(> .producao-bobinas-fabrica__folha) > :not(.producao-bobinas-fabrica__folha) { display: none !important; }
  .producao-bobinas-fabrica__folha { display: block; }
}
/* Linha do tempo das etapas: círculo numerado, setas entre elas; texto sempre escuro (sem cinza). */
.producao-bobinas-fabrica__etapa { display: flex; align-items: center; gap: .5rem; font-weight: 500; }
.producao-bobinas-fabrica__numero { display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border: 2px solid currentColor; border-radius: 50%; }
.producao-bobinas-fabrica__etapa[data-situacao="atual"] { color: var(--bs-primary); }
.producao-bobinas-fabrica__etapa[data-situacao="atual"] .producao-bobinas-fabrica__numero { background: var(--bs-primary); border-color: var(--bs-primary); color: #fff; }
.producao-bobinas-fabrica__etapa[data-situacao="feita"] { color: var(--bs-success); }
.producao-bobinas-fabrica__etapa[data-situacao="feita"] .producao-bobinas-fabrica__numero { background: var(--bs-success); border-color: var(--bs-success); color: #fff; }

/* ── Pílula de situação (componente compartilhado) ────────────────────────
   Tint + ponto (memória situacao-ponto-e-texto-nao-etiqueta; referência .rt-selo). Nasceu em Compras
   (`.compras-situacao`) e é usada também pelo Processar DDA (#638):
     <span class="situacao-pilula" data-tom="neutro|acao|ok|erro|atencao">Rótulo</span>
   As tintas viraram tokens (os valores de Compras, sem mudança). */
:root {
  --situacao-tinta-neutro: #F1F1EF;
  --situacao-tinta-ok: #E8F3EC;
  --situacao-tinta-erro: #F8E9E9;
  --situacao-tinta-atencao: #FFF1E6;
}
.situacao-pilula {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 10px 0 8px;
  border-radius: 999px; font-size: var(--fonte-pequena); font-weight: 500; line-height: 1; white-space: nowrap;
  vertical-align: middle; background: var(--situacao-tinta-neutro); color: var(--ds-tinta);
  box-shadow: inset 0 0 0 1px rgba(22, 22, 22, .06); }
.situacao-pilula::before {
  content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ds-tinta-3); }
.situacao-pilula[data-tom="acao"] { background: var(--ds-acao-tinta); }
.situacao-pilula[data-tom="acao"]::before { background: var(--ds-acao); }
.situacao-pilula[data-tom="ok"] { background: var(--situacao-tinta-ok); }
.situacao-pilula[data-tom="ok"]::before { background: var(--ds-sucesso); }
.situacao-pilula[data-tom="erro"] { background: var(--situacao-tinta-erro); }
.situacao-pilula[data-tom="erro"]::before { background: var(--ds-perigo); }
.situacao-pilula[data-tom="atencao"] { background: var(--situacao-tinta-atencao); }
.situacao-pilula[data-tom="atencao"]::before { background: var(--ds-atencao); }

/* ── #638 · Processar DDA ──────────────────────────────────────────────────── */
/* A mesa de trabalho: filas · a lista da fila (grade da casa) · o boleto aberto, e o rodapé com o único
   primário. A página não rola: cada coluna rola por dentro. Abaixo de 1366px o boleto abre por cima da
   lista, com o X para fechar. Hierarquia: a fila em que se está (a aba azul que encosta na lista) e o
   boleto aberto (a capa com a mesma tinta da linha atual e a decisão como bloco principal); o resto é
   rótulo cinza. Movimento curto (≤ 220ms, ease-out), desligado em prefers-reduced-motion. */
[data-pagina="processar_dda"] { --pdda-curva: cubic-bezier(.25, 1, .5, 1); }
[data-pagina="processar_dda"] .pdda-cabeca { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  flex: 0 0 auto; padding: .75rem 0; }
[data-pagina="processar_dda"] .pdda-cabeca__titulo,
[data-pagina="processar_dda"] .pdda-rotulo {
  margin: 0; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .pdda-ferramentas { display: inline-flex; align-items: center; gap: .25rem; }
[data-pagina="processar_dda"] .pdda-ferramentas [hidden],
[data-pagina="processar_dda"] .pdda-acao[hidden],
[data-pagina="processar_dda"] [hidden].btn { display: none; }

[data-pagina="processar_dda"] .pdda-mesa {
  flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 184px minmax(0, 1fr) minmax(360px, 26rem);
  border-top: 1px solid var(--line); }

/* As filas: três grupos de intenção (trabalho · revisão · feito) e o Histórico, separados por um filete. A
   fila atual tem a mesma forma do mouse (margem à direita e cantos), só que na tinta de ação (#706). */
[data-pagina="processar_dda"] .pdda-filas {
  min-height: 0; overflow-y: auto; padding: .75rem 0; box-shadow: inset -1px 0 0 var(--line); }
[data-pagina="processar_dda"] .pdda-filas__lista { list-style: none; margin: .5rem 0 0; padding: 0; }
[data-pagina="processar_dda"] .pdda-filas__quebra { height: 1px; margin: .375rem 1.25rem .375rem .5rem; background: var(--line); }
[data-pagina="processar_dda"] .pdda-fila {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem; width: calc(100% - .75rem);
  padding: .4rem .5rem; border: 0; background: none; color: var(--ds-tinta); text-align: left; border-radius: var(--r-sm);
  transition: background-color 160ms var(--pdda-curva); }
[data-pagina="processar_dda"] .pdda-fila:hover { background: var(--ds-fundo); color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-fila[aria-current="page"] { background: var(--ds-acao-tinta); font-weight: 500; }
[data-pagina="processar_dda"] .pdda-fila__conta {
  display: inline-block; min-width: 2.25rem; padding: 0 .25rem; border-radius: var(--r-sm); text-align: right;
  color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-fila[aria-current="page"] .pdda-fila__conta { color: var(--ds-tinta); }
/* A contagem que o servidor mudou dá um tique: sobe 2px e acende na tinta de ação. */
[data-pagina="processar_dda"] .pdda-fila__conta--mudou { animation: pdda-tique 220ms var(--pdda-curva); }
@keyframes pdda-tique {
  from { transform: translateY(-2px); background: var(--ds-acao-tinta); color: var(--ds-acao); }
  to { transform: none; }
}
[data-pagina="processar_dda"] .pdda-filas__total {
  display: flex; flex-direction: column; margin: .75rem .75rem 0 0; padding: .75rem .5rem 0; border-top: 1px solid var(--line);
  color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* A lista da fila: o título (o que é) e o propósito (o que fazer), na barra da grade. */
[data-pagina="processar_dda"] .pdda-lista { min-width: 0; min-height: 0; display: flex; flex-direction: column; padding: .5rem .75rem 0; }
[data-pagina="processar_dda"] .pdda-lista__cabeca { display: inline-flex; align-items: baseline; gap: .5rem; margin-right: .5rem; white-space: nowrap; }
[data-pagina="processar_dda"] .pdda-lista__titulo {
  margin: 0; font-size: var(--fonte-corpo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-lista__proposito { color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .pdda-col-data { width: 5.5rem; font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-col-valor { width: 6.5rem; }
[data-pagina="processar_dda"] .pdda-col-beneficiario { min-width: 16rem; }
[data-pagina="processar_dda"] .pdda-col-titulo { width: 6.5rem; }
[data-pagina="processar_dda"] .pdda-col-aviso { min-width: 11rem; color: var(--ink-2); }
/* A linha atual tem a mesma tinta da capa do boleto e o contorno azul da borda do painel: as duas leem
   como uma coisa só. A linha citada no painel (o concorrente sob o mouse) acende só na tinta. */
[data-pagina="processar_dda"] tr.grade-linha > td {
  transition: background-color 160ms var(--pdda-curva), box-shadow 160ms var(--pdda-curva); }
/* Mesma força do banho de mouse da grade compartilhada (`.grade .grade-tabela tbody tr:hover > td`) e depois
   dele: a linha atual e a citada seguem azuis sob o mouse. */
[data-pagina="processar_dda"] .grade .grade-tabela tbody tr.pdda-linha--atual > td {
  background: var(--ds-acao-tinta); box-shadow: inset 0 1px 0 var(--ds-acao), inset 0 -1px 0 var(--ds-acao); }
[data-pagina="processar_dda"] .grade .grade-tabela tbody tr.pdda-linha--ligada > td { background: var(--ds-acao-tinta); }
/* #711: o vencimento do título do Sênior que difere do boleto, no texto de atenção. */
[data-pagina="processar_dda"] .pdda-vencimento-difere { color: var(--warning-text); font-weight: 500; }
/* #710: o cabeçalho do grupo do Decidir (a disputa de um título, a combinação de um fornecedor): uma linha
   discreta com fio em cima, como o dia da Programação. A linha sem grupo não ganha cabeçalho. */
[data-pagina="processar_dda"] .grade .grade-tabela tbody tr.grade-grupo > td {
  height: auto; padding: 0; border-bottom: 0; background: none; }
[data-pagina="processar_dda"] .grade .grade-tabela tbody tr.grade-grupo:has(> td:empty) { display: none; }
[data-pagina="processar_dda"] .pdda-grupo {
  padding: .5rem .5rem .25rem; border-top: 1px solid var(--line-3); font-size: var(--fonte-rotulo); font-weight: 500;
  letter-spacing: .02em; color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .grade .grade-tabela tbody tr.grade-grupo:first-child .pdda-grupo { border-top: 0; }
/* A linha decidida sai de Decidir antes de a lista se redesenhar. */
[data-pagina="processar_dda"] tr.pdda-linha--saindo { animation: pdda-sai 180ms var(--pdda-curva) forwards; }
@keyframes pdda-sai { to { opacity: 0; transform: translateX(.5rem); } }
/* A caixa de marcar só existe onde se grava: na fila Prontos. */
[data-pagina="processar_dda"]:not([data-fila="prontos"]) .grade-col-selecao { display: none; }

/* O histórico (#712) ocupa a lista e o painel; a ação de gravar não existe nele. */
[data-pagina="processar_dda"] .pdda-historico {
  grid-column: 2 / -1; min-width: 0; min-height: 0; display: none; flex-direction: column; padding: .5rem .75rem 0; }
[data-pagina="processar_dda"] .pdda-historico > div:not([hidden]) { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; }
[data-pagina="processar_dda"][data-fila="historico"] .pdda-historico { display: flex; }
[data-pagina="processar_dda"][data-fila="historico"] :is(.pdda-lista, .pdda-boleto) { display: none; }
[data-pagina="processar_dda"] .pdda-col-quando { width: 8.5rem; font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-col-acao { min-width: 18rem; }
[data-pagina="processar_dda"] .pdda-resultado[data-tom="neutro"] { font-weight: 400; color: var(--ink-2); }
/* #718: a operação aberta divide o histórico com o painel (o mesmo do boleto), como a lista e o boleto. */
[data-pagina="processar_dda"][data-fila="historico"][data-operacao] .pdda-historico { grid-column: 2; }
[data-pagina="processar_dda"][data-fila="historico"][data-operacao] .pdda-boleto { display: flex; }
[data-pagina="processar_dda"] .pdda-col-situacao { min-width: 8rem; }
[data-pagina="processar_dda"] .pdda-col-codigo { white-space: nowrap; }
[data-pagina="processar_dda"] .pdda-dados--par { grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; padding: 0; }
[data-pagina="processar_dda"] .pdda-dados--par > div:last-child { grid-column: 1 / -1; }   /* o código de barras, inteiro */
/* A chamada ao Sênior: recolhida; o texto cru (já mascarado no servidor) quebra a linha em vez de rolar de lado. */
[data-pagina="processar_dda"] .pdda-chamada { margin-top: 1rem; }
[data-pagina="processar_dda"] .pdda-chamada > summary { cursor: pointer; font-weight: 500; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-chamada .pdda-rotulo { margin: .75rem 0 .25rem; }
[data-pagina="processar_dda"] .pdda-chamada__texto {
  max-height: 24rem; margin: 0; padding: .5rem .75rem; overflow-y: auto; white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: var(--bs-font-monospace); font-size: var(--fonte-pequena); color: var(--ds-tinta);
  background: var(--ds-superficie); border: 1px solid var(--line); border-radius: var(--r-sm); }

/* O boleto aberto: a pane acionável, com a anatomia da gaveta do pedido (capa · faixa · o bloco que age ·
   a ficha · o rodapé com as ações) sobre o chão cinza, cada região uma superfície branca. A borda do
   painel fica azul enquanto há boleto aberto, como o contorno da linha atual. */
[data-pagina="processar_dda"] .pdda-boleto {
  display: flex; flex-direction: column; min-height: 0; overflow-y: auto; padding: .75rem 1rem 0;
  border-left: 1px solid var(--line); background: var(--ds-fundo); transition: border-color 160ms var(--pdda-curva); }
[data-pagina="processar_dda"] .pdda-boleto[data-vazio="false"] { border-left-color: var(--ds-acao); }
[data-pagina="processar_dda"] .pdda-boleto__cabeca { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
[data-pagina="processar_dda"] .pdda-boleto__fechar { display: none; }
/* O corpo cresce até o pé do painel: o rodapé das ações fica sempre embaixo, como na gaveta do pedido. */
[data-pagina="processar_dda"] .pdda-boleto__corpo { display: flex; flex: 1 0 auto; flex-direction: column; padding-bottom: .75rem; }
[data-pagina="processar_dda"] .pdda-boleto__corpo--entra { animation: pdda-entra 200ms var(--pdda-curva); }
@keyframes pdda-entra { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

[data-pagina="processar_dda"] .pdda-capa {
  padding: .75rem .875rem; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--ds-acao-tinta); }
[data-pagina="processar_dda"] .pdda-capa__nome { margin: 0 0 .25rem; font-size: var(--fonte-destaque); font-weight: 500; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-capa__linha { display: flex; align-items: center; flex-wrap: wrap; gap: .25rem .75rem; }
[data-pagina="processar_dda"] .pdda-capa__valor {
  font-size: var(--fonte-titulo); font-weight: 500; line-height: 1.2; color: var(--ds-tinta); font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-capa__meta { margin: .25rem 0 0; color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }

/* A faixa: o motivo e os avisos. Fraude e recusa na tinta de perigo; sem tom, texto solto no chão. */
[data-pagina="processar_dda"] .pdda-faixa { margin-top: .5rem; padding: 0 .125rem; }
[data-pagina="processar_dda"] .pdda-faixa:not([data-tom="neutro"]) { padding: .5rem .75rem; border-radius: var(--r-sm); }
[data-pagina="processar_dda"] .pdda-faixa[data-tom="erro"] { background: var(--situacao-tinta-erro); }
[data-pagina="processar_dda"] .pdda-faixa[data-tom="ok"] { background: var(--situacao-tinta-ok); }
[data-pagina="processar_dda"] .pdda-faixa[data-tom="atencao"] { background: var(--situacao-tinta-atencao); }
[data-pagina="processar_dda"] .pdda-faixa p { margin: 0; }
[data-pagina="processar_dda"] .pdda-faixa p + .pdda-avisos { margin-top: .25rem; }
[data-pagina="processar_dda"] .pdda-motivo-fraude { color: var(--ds-perigo); font-weight: 500; }
[data-pagina="processar_dda"] .pdda-avisos { margin: 0; padding-left: 1rem; color: var(--warning-text); }

/* O bloco que age: título no peso do corpo (o maior do painel depois da capa), as opções como cartões. */
[data-pagina="processar_dda"] .pdda-decisao { margin-top: 1rem; }
[data-pagina="processar_dda"] .pdda-decisao__titulo {
  margin: 0 0 .5rem; font-size: var(--fonte-corpo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-decisao > .pdda-nota { margin-bottom: .5rem; }
[data-pagina="processar_dda"] .pdda-decisao > .btn { margin-top: .25rem; }
/* #721: a escolha do vencimento: a pergunta inteira, um botão por data; ao lado, a sugestão ou o motivo do bloqueio. */
[data-pagina="processar_dda"] .pdda-decisao + .pdda-decisao { margin-top: 1.25rem; }
[data-pagina="processar_dda"] .pdda-decisao__pergunta { margin: 0 0 .5rem; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-escolha { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .75rem; }
[data-pagina="processar_dda"] .pdda-escolha + .pdda-escolha { margin-top: .5rem; }
[data-pagina="processar_dda"] .pdda-escolha__dica { color: var(--ds-sucesso); font-weight: 500; }
[data-pagina="processar_dda"] .pdda-escolha__bloqueio { flex-basis: 100%; color: var(--warning-text); }
/* #721: a escolha do vencimento em lote, numa linha sobre a lista do Decidir; ao clicar, a mesma linha vira a
   confirmação (as contagens vêm da prévia do servidor), com o Cancelar no foco. */
[data-pagina="processar_dda"] .pdda-lote:not([hidden]) { display: flex; flex: 0 0 auto; align-items: center; min-height: 2.25rem; }
[data-pagina="processar_dda"] :is(.pdda-lote__acoes, .pdda-lote__confirmacao):not([hidden]) {
  display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .75rem; }
[data-pagina="processar_dda"] .pdda-lote__acoes > .btn { padding-left: 0; }
[data-pagina="processar_dda"] .pdda-lote__confirmacao:not([hidden]) {
  flex: 1 1 auto; padding: .25rem .75rem; border-radius: var(--r-sm); background: var(--ds-acao-tinta); }
[data-pagina="processar_dda"] .pdda-lote__pergunta { font-weight: 500; color: var(--ds-tinta); }
[data-pagina="processar_dda"] .pdda-lote__fora { flex: 1 1 auto; color: var(--warning-text); }
[data-pagina="processar_dda"] .pdda-cartao {
  padding: .625rem .75rem; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--ds-superficie);
  transition: border-color 160ms var(--pdda-curva); }
[data-pagina="processar_dda"] .pdda-cartao + .pdda-cartao { margin-top: .5rem; }
[data-pagina="processar_dda"] .pdda-cartao .pdda-rotulo { margin-bottom: .375rem; }
[data-pagina="processar_dda"] .pdda-cartao p { margin: 0; }
[data-pagina="processar_dda"] .pdda-cartao--escolha { cursor: pointer; }
[data-pagina="processar_dda"] .pdda-cartao--escolha > .btn { margin-top: .5rem; }
[data-pagina="processar_dda"] :is(.pdda-cartao--escolha, .pdda-concorrente):is(:hover, :focus-within) { border-color: var(--ds-acao); }

/* Os títulos do Sênior pendurados num trilho que desce até a soma: no cartão sob o mouse o trilho fica
   azul, e a soma lê como "estes títulos dão o valor do boleto". */
[data-pagina="processar_dda"] .pdda-titulo {
  display: grid; grid-template-columns: minmax(0, 1fr) 5.5rem 6.5rem; gap: .5rem; padding: .2rem 0;
  font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-titulo__numero { font-weight: 500; overflow-wrap: anywhere; }
[data-pagina="processar_dda"] .pdda-titulo--cabeca {
  padding: 0 0 .125rem calc(1rem + 1px); font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .pdda-decisao > .pdda-titulo--cabeca { padding: 0 calc(.75rem + 1px) .125rem calc(1.75rem + 2px); }
[data-pagina="processar_dda"] .pdda-ligacao {
  list-style: none; margin: 0 0 0 .25rem; padding: 0 0 0 .75rem; border-left: 1px solid var(--ink-4);
  transition: border-color 160ms var(--pdda-curva); }
[data-pagina="processar_dda"] .pdda-ligacao .pdda-titulo { position: relative; }
[data-pagina="processar_dda"] .pdda-ligacao .pdda-titulo::before {
  content: ""; position: absolute; top: 50%; left: -.75rem; width: .5rem; border-top: 1px solid var(--ink-4);
  transition: border-color 160ms var(--pdda-curva); }
[data-pagina="processar_dda"] .pdda-cartao--escolha:is(:hover, :focus-within) .pdda-ligacao,
[data-pagina="processar_dda"] .pdda-cartao--escolha:is(:hover, :focus-within) .pdda-titulo::before { border-color: var(--ds-acao); }
[data-pagina="processar_dda"] .pdda-soma {
  display: flex; justify-content: space-between; gap: 1rem; margin-top: .375rem; padding-top: .375rem;
  border-top: 1px solid var(--line); color: var(--ds-tinta-2); font-variant-numeric: tabular-nums; }
[data-pagina="processar_dda"] .pdda-soma + .pdda-soma { margin-top: 0; padding-top: .125rem; border-top: 0; }
[data-pagina="processar_dda"] .pdda-cartao--escolha:is(:hover, :focus-within) .pdda-soma { color: var(--ds-tinta); }

/* A disputa (#710): o título do Sênior em cima, um cartão por boleto do banco embaixo. O rótulo pequeno em
   versal diz a origem de cada cartão; o mouse num boleto acende a linha dele na lista. */
[data-pagina="processar_dda"] .pdda-concorrentes { list-style: none; margin: .5rem 0; padding: 0; }
[data-pagina="processar_dda"] .pdda-concorrentes > .pdda-cartao + .pdda-cartao { margin-top: .5rem; }
[data-pagina="processar_dda"] .pdda-origem {
  margin: 0 0 .25rem; font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .pdda-cartao__linha { margin: 0; font-weight: 500; overflow-wrap: anywhere; }
[data-pagina="processar_dda"] .pdda-cartao--titulo { background: var(--ds-fundo); }
[data-pagina="processar_dda"] .pdda-cartao--atual { border-color: var(--ds-acao); }
[data-pagina="processar_dda"] .pdda-cartao--boleto > .btn { margin-top: .5rem; }
[data-pagina="processar_dda"] .pdda-confere { margin: .25rem 0 0; color: var(--warning-text); }
[data-pagina="processar_dda"] .pdda-confere[data-confere="true"] { color: var(--ds-sucesso); }
[data-pagina="processar_dda"] .pdda-dado-numerico { display: block; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* Antes → depois: o que há hoje no Sênior, a seta, o que vai ficar. */
[data-pagina="processar_dda"] .pdda-transformacao { margin-top: 1rem; }
[data-pagina="processar_dda"] .pdda-seta { position: relative; width: 1px; height: 1.25rem; margin: 0 auto .375rem; background: var(--line-3); }
[data-pagina="processar_dda"] .pdda-seta::after {
  content: ""; position: absolute; left: -.3rem; bottom: -.375rem;
  border: .3rem solid transparent; border-top: .375rem solid var(--line-3); border-bottom: 0; }
[data-pagina="processar_dda"] .pdda-transformacao .pdda-seta + .pdda-cartao { margin-top: 0; }
[data-pagina="processar_dda"] .pdda-destino { background: var(--situacao-tinta-ok); }

/* A ficha: dado de conferência, quieto (rótulo cinza em cima, valor embaixo), como a ficha do pedido. */
[data-pagina="processar_dda"] .pdda-dados { display: grid; gap: .5rem; margin: 1rem 0; padding: 0 .125rem; }
[data-pagina="processar_dda"] .pdda-dados dt {
  font-size: var(--fonte-rotulo); font-weight: 500; letter-spacing: .04em; color: var(--ds-tinta-2); }
[data-pagina="processar_dda"] .pdda-dados dd { margin: 0; color: var(--ink-2); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
[data-pagina="processar_dda"] .pdda-codigo { font-family: var(--bs-font-monospace); word-spacing: .25em; }

/* O rodapé do painel: as ações do boleto, presas embaixo enquanto o painel rola. */
[data-pagina="processar_dda"] .pdda-rodape {
  position: sticky; bottom: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin: auto -1rem -.75rem; padding: .5rem 1rem; border-top: 1px solid var(--line); background: var(--ds-superficie); }

@media (max-width: 1599.98px) {
  [data-pagina="processar_dda"] .pdda-mesa { grid-template-columns: 184px minmax(0, 1fr) minmax(300px, 22rem); }
  [data-pagina="processar_dda"] .pdda-col-beneficiario { min-width: 10rem; }
  [data-pagina="processar_dda"] .pdda-col-aviso { min-width: 12rem; }
  /* Sem folga para o propósito: a barra da grade quebraria em duas linhas. O título da fila fica. */
  [data-pagina="processar_dda"] .pdda-lista__proposito { display: none; }
}
@media (max-width: 1365.98px) {
  [data-pagina="processar_dda"] .pdda-mesa { grid-template-columns: 184px minmax(0, 1fr); }
  [data-pagina="processar_dda"] .pdda-boleto {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 1040; width: min(26rem, 96vw); padding: 1rem 1rem 0;
    box-shadow: var(--ds-sombra-balao); animation: pdda-desliza 220ms var(--pdda-curva); }
  [data-pagina="processar_dda"] .pdda-boleto[data-vazio="true"] { display: none; }
  [data-pagina="processar_dda"] .pdda-boleto__fechar { display: inline-block; }
}
@keyframes pdda-desliza { from { opacity: 0; transform: translateX(1.5rem); } to { opacity: 1; transform: none; } }

[data-pagina="processar_dda"] .pdda-acao {
  display: flex; align-items: center; justify-content: flex-end; gap: .75rem; flex: 0 0 auto;
  padding: .5rem 0; border-top: 1px solid var(--line); }
[data-pagina="processar_dda"] .pdda-acao__selecao { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Resultado da última gravação (vem do servidor), na linha e no painel. */
[data-pagina="processar_dda"] .pdda-resultado { font-weight: 500; }
[data-pagina="processar_dda"] .pdda-resultado[data-tom="ok"] { color: var(--ds-sucesso); }
[data-pagina="processar_dda"] .pdda-resultado[data-tom="erro"] { color: var(--ds-perigo); }
[data-pagina="processar_dda"] .pdda-resultado[data-tom="atencao"] { color: var(--warning-text); }

[data-pagina="processar_dda"] .pdda-nota { margin: 0; color: var(--ink-2); font-size: var(--fonte-corpo); }
[data-pagina="processar_dda"] .pdda-nota--aviso { margin: 0 0 .5rem; color: var(--warning-text); }
[data-pagina="processar_dda"] .pdda-nota--erro {
  margin: .5rem 0; padding: .5rem .75rem; border: 1px solid var(--ds-perigo); border-radius: var(--r-sm);
  color: var(--ds-perigo); background: var(--ds-superficie); }
[data-pagina="processar_dda"] .pdda-nota[hidden] { display: none; }

/* A prévia da gravação, boleto a boleto (com aviso primeiro): rola dentro do painel. */
[data-pagina="processar_dda"] .pdda-previa {
  list-style: none; margin: 0; padding: 0; min-height: 0; overflow-y: auto; font-size: var(--fonte-corpo);
  border-top: 1px solid var(--line); }
[data-pagina="processar_dda"] .pdda-previa__item { padding: .5rem 0; border-bottom: 1px solid var(--line); }
[data-pagina="processar_dda"] .pdda-previa__cabeca { display: flex; justify-content: space-between; gap: 1rem; font-weight: 500; }
[data-pagina="processar_dda"] .pdda-previa__valor { font-variant-numeric: tabular-nums; white-space: nowrap; }
[data-pagina="processar_dda"] .pdda-previa__aviso { color: var(--warning-text); }

/* Sem movimento para quem pediu: tudo acima vira troca instantânea. */
@media (prefers-reduced-motion: reduce) {
  [data-pagina="processar_dda"] *,
  [data-pagina="processar_dda"] *::before { animation: none !important; transition: none !important; }
}

/* ── Etapas e linha do tempo (componentes globais, #728) ─────────────────────────────────────────────────────────────
   `.fcds-etapas`: o andamento de um processo em etapas fixas (ex.: a compra: Criada → Aprovada → … → Recebida). Cada
   `<li class="fcds-etapa" data-estado="feita|atual|pendente|erro">` com `__ponto`, `__rotulo` e `__detalhe`. Feita em
   verde, atual em azul com anel, pendente em cinza, erro em vermelho; no celular vira lista vertical.
   `.fcds-linha-do-tempo`: o histórico de eventos com data, em lista vertical com ponto (`.fcds-quando` na data).
   Telas com passo a passo próprio (`.inad-stepper`, `.process-timeline`) migram para cá quando forem mexidas. */
.fcds-etapas { list-style: none; margin: 0 0 1.25rem; padding: 0; display: grid; grid-auto-columns: minmax(0, 1fr); grid-auto-flow: column; }
.fcds-etapa { position: relative; padding-top: 1.75rem; text-align: center; font-size: var(--fonte-pequena); display: flex; flex-direction: column; gap: .125rem; }
.fcds-etapa::before { content: ""; position: absolute; top: .55rem; left: -50%; width: 100%; height: 3px; background: var(--bs-border-color); }
.fcds-etapa:first-child::before { display: none; }
.fcds-etapa:is([data-estado="feita"], [data-estado="atual"], [data-estado="erro"])::before { background: var(--bs-success); }
.fcds-etapa__ponto { position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 1.3rem; height: 1.3rem; border-radius: 50%; background: #fff; border: 3px solid var(--bs-border-color); z-index: 1; }
.fcds-etapa[data-estado="feita"] .fcds-etapa__ponto { background: var(--bs-success); border-color: var(--bs-success); }
.fcds-etapa[data-estado="atual"] .fcds-etapa__ponto { border-color: var(--bs-primary); box-shadow: 0 0 0 4px rgba(var(--bs-primary-rgb), .2); }
.fcds-etapa[data-estado="erro"] .fcds-etapa__ponto { background: var(--bs-danger); border-color: var(--bs-danger); }
.fcds-etapa__rotulo { font-weight: 500; color: var(--ink); }
.fcds-etapa[data-estado="atual"] .fcds-etapa__rotulo { color: var(--bs-primary); }
.fcds-etapa[data-estado="erro"] .fcds-etapa__rotulo { color: var(--bs-danger); }
.fcds-etapa[data-estado="pendente"] .fcds-etapa__rotulo { color: var(--ink-2); }
.fcds-etapa__detalhe { color: var(--ink-2); }
@media (max-width: 767.98px) {
  .fcds-etapas { grid-auto-flow: row; gap: .5rem; }
  .fcds-etapa { padding: 0 0 0 1.9rem; text-align: left; }
  .fcds-etapa::before { display: none; }
  .fcds-etapa__ponto { left: .65rem; }
}
.fcds-linha-do-tempo { list-style: none; margin: 0; padding: 0 0 0 .9rem; border-left: 2px solid var(--bs-border-color); font-size: var(--fonte-corpo); }
.fcds-linha-do-tempo li { position: relative; padding: 0 0 .6rem .6rem; }
.fcds-linha-do-tempo li::before { content: ""; position: absolute; left: -1.3rem; top: .4rem; width: .65rem; height: .65rem; border-radius: 50%; background: var(--bs-success); }
.fcds-linha-do-tempo .fcds-quando { display: block; color: var(--ink-2); font-size: var(--fonte-pequena); }

/* Rodapé fixo das ações que concluem um formulário (#745, regra do CLAUDE.md): faixa branca com filete, colada no
   fim da área (a página em coluna, ou o corpo que rola do painel lateral), com o vermelho à esquerda do verde. */
.fcds-rodape-acoes {
  position: sticky; bottom: 0; z-index: 2; flex: 0 0 auto;
  display: flex; justify-content: flex-end; gap: .5rem;
  margin-inline: calc(-1 * var(--content-pad-x)); padding: .75rem var(--content-pad-x);
  background: #fff; border-top: 1px solid var(--bs-border-color);
}
.offcanvas-body .fcds-rodape-acoes {
  margin-inline: calc(-1 * var(--bs-offcanvas-padding-x)); padding-inline: var(--bs-offcanvas-padding-x);
}
/* Formulário que é o corpo todo do painel (Nova solicitação): ocupa a altura e empurra o rodapé para o fim. */
.offcanvas-body:has(> .compras-formulario > .fcds-rodape-acoes) { padding-bottom: 0; }
.offcanvas-body > .compras-formulario:has(> .fcds-rodape-acoes) { min-height: 100%; margin-bottom: 0; display: flex; flex-direction: column; }
.offcanvas-body > .compras-formulario > .fcds-rodape-acoes { margin-top: auto; }
/* Nova e Editar ordem de compra (#745): a página ocupa a janela; o formulário rola acima do rodapé. */
.compras-ordem__corpo { flex: 1 1 auto; min-height: 0; overflow: auto; padding-block: .75rem; }

/* Permissões de compras (#747): a grade ocupa a janela; a área da tabela rola e o cabeçalho e o Salvar ficam à vista. */
[data-tela="permissoes"] > * { flex: 0 0 auto; }
[data-tela="permissoes"] > #pm-tela { flex: 1 1 auto; min-height: 0; overflow: auto; }
[data-tela="permissoes"] #pm-tabela thead th { position: sticky; top: 0; z-index: 1; background: #fff; box-shadow: inset 0 -1px 0 var(--bs-border-color); }
