/* AUTO-GENERATED by scripts/build_shell_bundles.py — do not edit. Edit the source files listed below and re-run the script. */
/* shell css sources (56): */

/* >>> css/v2/tokens.css >>> */
/* v2 — vocabulário. A ÚNICA folha do sistema novo que declara valor literal.
 *
 * Todas as outras só leem daqui. Se um componente precisar de uma cor que não
 * está neste arquivo, o token está faltando — não é para escrever o hex lá.
 * Foi a ausência dessa regra que produziu as seis camadas do sistema antigo.
 *
 * ## Superfícies
 *
 * A escada é fechada e tem três degraus, do fundo para a frente:
 *
 *     --surface-page  →  --surface-rail  →  --surface-field
 *
 * `--surface-page` é o fundo da tela; `--surface-rail` é a faixa de controles
 * (o que o sistema antigo chamava de sub-header); `--surface-field` é o campo
 * em si. Um componente escolhe UM degrau. Não existe degrau intermediário e
 * não se mistura cor com cor — no tema escuro o accent é dourado e qualquer
 * `color-mix` dele com o azul-marinho cai em oliva (medido: `#2d302c`).
 *
 * ## Temas
 *
 * O claro vive em `:root` e é o padrão de quem nunca escolheu tema. O escuro
 * REDEFINE apenas os tokens que mudam. Nenhum componente consulta o tema: se
 * uma regra precisa de `html[data-theme="dark"]`, é sinal de que falta token.
 */

:root {
  /* ---- superfícies ---------------------------------------------------- */
  /* O `page` é mais fundo que o valor claro original porque o degrau para o rail
     media 1.055 — praticamente nada — e a alternância de superfície, que é o
     que separa uma camada da outra em todo o sistema, sumia no tema claro.
     Agora mede 1.29.

     O `rail` voltou ao valor original por decisão do dono: a versão mais funda
     que eu tinha posto igualava o degrau rail→field ao do escuro,
     mas puxava o azul para o cinza. Em troca, rail→field fica em 1.106 no
     claro contra 1.27 no escuro — o campo se separa menos da caixa aqui. */
  --surface-page: #d4dde9;
  /* Clareado de #e3eaf2 para #f0f4f9 em 2026-08-20, a pedido do dono
     (NOVO-20260820-220939-23c3de47a4cc): com o fundo da página agora branco, o
     degrau `rail` era a única faixa tingida entre dois brancos, e o cartão da
     lista lia como pesado demais.

     O valor não foi escolhido no olho. `audit_paleta --max 0` reprova qualquer
     cor a menos de 2,5 de deltaE2000 de outra, e a faixa entre o tingido antigo
     e o branco tem 6,27 no total. Ela estava LOTADA: duas cores quase-brancas
     (as antigas f7fbff e f0f6ff) ocupavam o meio dela, e nenhum valor mais
     claro que o tingido passava no gate — varri a faixa inteira e os 149
     valores legais tinham todos a luminância do tingido, mudando só o matiz.
     Aposentar as duas (ver a nota em `base/tokens.css`) foi o que abriu o
     espaço para este valor: 2,73 do tingido antigo e 4,07 do branco.

     Os hex das cores aposentadas NÃO aparecem escritos aqui de propósito: o
     auditor lê o arquivo inteiro, comentário incluído, e uma cor citada em
     prosa volta a ocupar vaga na faixa como se estivesse em uso.

     Custa separação para dentro e ganha para fora: rail→field cai de 1.213 para
     1.104 e page→rail sobe de 1.130 para 1.241. */
  --surface-rail: #f0f4f9;
  --surface-field: #ffffff;
  /* PAPEL e TINTA do documento exibido, não da interface. Os dois valem igual nos dois
     temas, e é essa a razão de existirem: a folha de um PDF é branca e o carimbo é
     preto na impressão, então escurecê-los no tema escuro mostraria ao operador algo
     diferente do que vai sair. Por isso não são redefinidos no bloco escuro. */
  --paper: #ffffff;
  --paper-ink: #000000;
  --surface-brand: #155b9a;
  /* Fundo da linha escolhida numa lista de opções. É a cor que o desenho antigo
     usava para "selecionado" — no tema escuro, o azul-marinho profundo do
     `--surface-brand`; no claro, o accent diluído, que era o que a folha
     compartilhada já fazia. Precisa ser um token porque não é um degrau da
     escada de superfícies: é significado, e some se virar `rail` ou `field`. */
  /* 17%, e não os mesmos 16% do escuro: o que precisa bater entre os temas é o
     CONTRASTE contra o fundo do menu, não a porcentagem. Com 10% dava 1.18
     contra os 1.35 do escuro, e a linha escolhida praticamente sumia no claro
     enquanto saltava no escuro. Agora os dois medem 1.34. */
  --surface-selected: color-mix(in srgb, var(--accent) 17%, var(--surface-rail));

  /* O fundo da linha do MOTORISTA (2026-08-21, a pedido do dono: "uma clareada
     no azul, como se fosse uma base branca azulada").

     Token próprio, e não o `--surface-selected` que ele usava: aquele é
     "item ESCOLHIDO numa lista" — menu do select, picker, listbox — e está
     calibrado para 1.34 de contraste contra o fundo do menu, nos dois temas.
     A linha do motorista não é escolha de ninguém, é MARCA DE PAPEL, e clarear
     o token compartilhado teria apagado a linha selecionada de oito outros
     lugares para resolver a cor de um.

     Base BRANCA (`--surface-field`) e não o degrau tingido: é o que dá o
     branco-azulado pedido.

     A PORCENTAGEM foi calibrada com a cor na tela, e 18% é o meio do caminho.
     A primeira tentativa usou 12%, que mede 1.11 contra o cartão: o dono viu e
     disse que a linha tinha ficado com cara de fundo do painel — clarear até o
     branco-azulado aproxima a linha do cartão, que também é quase branco, e
     passa do ponto. Os 18% medem 1.238, contra os 1.329 de antes: clareia de
     verdade e continua uma faixa, não um vazio.

     Para referência de quem for mexer: a cor ANTIGA equivale a accent 22% sobre
     branco. A escala inteira, contra o cartão, é 12%→1.11, 16%→1.19, 18%→1.24,
     22%→1.33.

     Quem carrega o sinal de "este é o motorista" segue sendo a barra de 3px em
     accent na borda esquerda, que não mudou em nenhuma das versões. */
  --surface-driver: color-mix(in srgb, var(--accent) 18%, var(--surface-field));
  /* Sombra da camada que flutua sobre a página (menu do select, lista do
     picker). Vira token porque as duas precisam ser a MESMA, e cada folha
     escrevendo o seu valor foi como elas divergiram. */
  --shadow-menu: 0 12px 28px rgb(7 26 51 / 0.16);

  /* Os dois degraus que existem SOBRE a faixa de marca — a barra lateral e o
     `c-v2.header`. A escada `page → rail → field` não serve ali: ela é feita
     para o fundo da página, e um `--surface-rail` sobre o azul-marinho vira uma
     mancha clara no meio da faixa.
     
     São tokens por tema, e não um `color-mix` fixo na folha, porque a MESMA
     porcentagem de branco dá contrastes diferentes sobre os dois azuis de
     marca: 10% mede 1.257 sobre o claro (#155b9a) e 1.342 sobre o escuro
     (#062847). O que precisa bater entre os temas é o contraste, não a
     porcentagem — é a mesma decisão, e a mesma conta, do `--surface-selected`
     logo acima. Medido com `scripts/` fora do repo, WCAG relative luminance. */
  /* 8% → 1.201 (o claro) · 6% → 1.185 (o escuro). */
  --surface-on-brand: color-mix(in srgb, var(--text-on-brand) 8%, transparent);
  /* 13% → 1.347 (o claro) · 10% → 1.342 (o escuro) — o mesmo 1.34 que o
     `--surface-selected` das listas persegue. */
  --surface-selected-on-brand: color-mix(in srgb, var(--text-on-brand) 13%, transparent);

  /* Sobre a faixa de marca o accent NÃO serve para texto nem para anel de foco
     no tema claro: `#004a90` sobre `#155b9a` mede 1.26:1 — azul escuro sobre
     azul médio. No escuro o mesmo papel cabe ao dourado, que mede 7.75:1. Por
     isso os três tokens abaixo trocam de valor com o tema em vez de existirem
     como um `color-mix` fixo na folha.

     Medidos com luminância relativa da WCAG contra `--surface-brand`. */
  /* 7.01:1 no claro (branco) · 7.75:1 no escuro (dourado). */
  --accent-on-brand: var(--text-on-brand);
  /* Anel de foco: 7.01:1 no claro · 6.49:1 no escuro. O piso para indicador de
     foco é 3:1; o accent do claro dava 1.26 e sumia. */
  --focus-ring-on-brand: var(--text-on-brand);
  /* Rótulo apagado sobre a faixa. 76%, e não os 62% do primeiro corte: aquilo
     media 3.75:1 no claro, abaixo dos 4.5:1 que texto de 12px exige. Agora
     4.80:1 no claro e 9.16:1 no escuro. */
  --text-muted-on-brand: color-mix(in srgb, var(--text-on-brand) 76%, transparent);

  /* Vermelho de TEXTO, separado do `--danger` de superfície.
     `--danger` é o mesmo nos dois temas por decisão do dono, e como fundo de
     botão isso funciona — o texto sobre ele é branco. Como COR DE TEXTO ele
     mede 2.99:1 sobre a caixa escura, abaixo do piso. Este token é o `--danger`
     no claro e o vermelho claro do tema escuro (6.09:1) no escuro. */
  --text-danger: var(--danger);

  /* ---- texto ---------------------------------------------------------- */
  --text-strong: #223348;
  --text-muted: #52657a;
  --text-on-brand: #ffffff;
  --text-on-accent: #ffffff;

  /* ---- traço e realce -------------------------------------------------- */
  --line: rgb(11 58 102 / 0.16);
  --line-on-brand: rgb(255 255 255 / 0.22);
  /* Saturação no máximo e um pouco mais de luz que o valor original
     (#0b3a66, 81% sat / 22% luz): naquele ponto o azul lia como fosco. */
  --accent: #004a90;
  --focus-ring: #155b9a;

  /* Perigo. Um tom sólido, não gradiente: o botão legado usava
     `linear-gradient(135deg, #c0392b, ...)`, que só existia para dar volume e
     não sobrevive a fundo variável.

     NÃO é redefinido no tema escuro — é o mesmo vermelho nos dois, por decisão
     do dono. O trade-off, medido sobre a caixa escura (#223348): texto branco
     em 5.44 (bom) e destaque contra a caixa em 2.36, abaixo do ideal de 3.0.
     Um vermelho mais claro resolveria o destaque mas exigiria texto escuro. */
  --danger: #c0392b;
  --text-on-danger: #ffffff;

  /* ---- estados (selos) --------------------------------------------------
   *
   * FIXAS nos dois temas, de propósito: "concluído" é verde no claro e no
   * escuro. Estado é significado, não decoração — se a cor mudasse com o tema,
   * o usuário teria de reaprender o código de cores ao trocar de tema.
   *
   * Por isso NÃO aparecem no bloco `[data-theme="dark"]` abaixo. */
  --status-done: #1e8e4f;
  --status-progress: #d8a21b;
  --status-late: #c0392b;
  --status-info: #2b6cb0;

  /* ---- cor por FUNÇÃO da ação (2026-08-20) -------------------------------
   *
   * Regra do dono: o botão que faz a MESMA COISA tem a MESMA COR em toda tela
   * do sistema. A cor é do que a ação faz, não do ícone que ela usa nem da tela
   * em que aparece — quem varre um menu deve reconhecer "baixar PDF" pela cor,
   * antes de ler o rótulo.
   *
   * Como a família de estado logo acima, e pelo mesmo motivo, estas cores NÃO
   * mudam com o tema: função é significado, não decoração, e trocar de tema não
   * pode obrigar a reaprender o código de cores.
   *
   * O que havia antes não era uma escolha, era o acúmulo: medido no navegador,
   * QUATRO das sete funções saíam douradas — `preview` e `edit` nem existiam no
   * CSS e caíam no accent —, e baixar DOCX tinha exatamente a mesma cor de
   * cancelar. A mesma função também mudava de cor conforme a tela: "Baixar PDF"
   * aparecia com `icon_tone="late"` em cinco lugares e `icon_tone="pdf"` em
   * quatro.
   *
   * Quatro reaproveitam a família de estado, onde ela já dizia a coisa certa;
   * duas são novas, escolhidas por varredura sob duas restrições ao mesmo tempo
   * — pelo menos 3,0 de deltaE2000 de QUALQUER cor já existente (o gate
   * `audit_paleta --max 0`) e contraste legível sobre as duas superfícies de
   * menu. As duas novas ficam em ~3,58 nos dois temas, mais equilibradas que a
   * família de estado, que oscila entre 5,44 e 2,31 conforme o tema. */
  --action-view:   #1e94a9;                 /* visualizar / abrir no navegador */
  --action-pdf:    var(--status-late);      /* baixar PDF */
  --action-docx:   var(--status-info);      /* baixar DOCX */
  --action-attach: var(--status-done);      /* anexar, e o construtivo: reativar */
  --action-cancel: var(--status-progress);  /* cancelar */
  --action-amend:  #9a76cb;                 /* retificar e complementar */
  --action-delete: var(--status-late);      /* excluir */
  /* Editar e copiar mensagem seguem o accent. O WhatsApp usa um token de canal:
     é identificação da integração, não estado nem ação genérica. */
  --action-edit:   var(--accent);
  --action-neutral: var(--accent);
  --channel-whatsapp: var(--status-done);


  /* ---- forma ----------------------------------------------------------- */
  --radius-field: 8px;
  --radius-rail: 14px;
  --radius-brand: 18px;
  --radius-pill: 999px;

  /* ---- ritmo ----------------------------------------------------------- */
  --gap-tight: 8px;
  --gap: 12px;
  --gap-loose: 20px;
  --pad-field: 0 12px;
  /* 12px, igual ao painel e ao registro: o recuo é o mesmo em toda a escada, e
     só o RAIO diminui para dentro. Era 16px 20px, o que dava ao header e ao
     rail um respiro maior que o do conteúdo — a página lia como se a moldura
     importasse mais que o dado. */
  --pad-rail: 12px;
  --control-height: 44px;
  /* A altura miúda, para controles que vivem DENTRO de outro — o gatilho do
     calendário dentro do campo, os botões dentro do painel. Duas alturas, não
     três: a antiga escala legada tinha `sm` e `xs` sem nada por trás, e o que
     justifica esta é a hierarquia, não o gosto. */
  --control-height-sm: 28px;

  /* ---- tipografia ------------------------------------------------------ */
  /* MESMO valor de `base/tokens.css:215`, e de proposito.
   *
   * Não é duplicação por descuido: são dois vocabulários convivendo, e o v2
   * precisa ser completo o bastante para vestir uma tela sozinho — foi
   * justamente o que o login exigiu ao sair da camada legada. Enquanto os dois
   * arquivos existirem, os valores TÊM de ser idênticos, senão a fonte muda
   * conforme a folha que a página carrega. Quando `base/tokens.css` for
   * apagado, esta passa a ser a única definição e o comentário sai junto. */
  --font-sans: "Inter Variable", Inter, "Segoe UI", system-ui, sans-serif;
  /* O degrau abaixo do eyebrow (2026-08-19). Nasceu para o rótulo do stepper,
     que é NAVEGAÇÃO — nome de etapa lido de relance, não texto de leitura — e
     que em 12px ainda competia com o conteúdo do painel. É o piso da escala:
     abaixo de 11px o texto deixa de ser legível em tela comum, e um quinto
     degrau seria escolher tamanho por gosto, não por hierarquia. */
  --text-size-micro: 11px;
  --text-size-eyebrow: 12px;
  --text-size-base: 14px;
  --text-size-title: 24px;
  --weight-normal: 500;
  /* 900, e não 700 (2026-08-16): o traço da Bahnschrift é mais fino que o da
     Inter no mesmo número, e a 700 as peças fortes ficavam sem presença. O peso
     foi escolhido no provador do UI Lab, com a interface inteira na fonte nova —
     não numa amostra isolada. `--fact-weight` acompanha, para o valor grande do
     cartão não ficar mais leve que o título. */
  --weight-strong: 900;
  --fact-weight: 900;

  /* ---- movimento ------------------------------------------------------- */
  --ease: 150ms ease;
}

:is(html[data-theme="dark"]) {
  --surface-page: #0d1725;
  --surface-rail: #111e2f;
  --surface-field: #223348;
  --surface-brand: #062847;
  /* O accent diluído — o tom amarelado que o desenho antigo dava à linha
     escolhida. É a exceção deliberada à regra de não misturar accent com
     superfície no tema escuro: aqui a mistura É o sinal, e o dono a escolheu
     com a cor na tela. */
  --surface-selected: color-mix(in srgb, var(--accent) 16%, var(--surface-field));
  /* O escuro NÃO foi clareado: o pedido era sobre o azul, e no escuro esta
     linha não tem azul nenhum — é o dourado misturado ao azul-marinho, que dá
     o oliva registrado como exceção deliberada logo acima. Fica como estava até
     haver decisão sobre ele. */
  --surface-driver: var(--surface-selected);
  --shadow-menu: 0 12px 28px rgb(2 10 18 / 0.28);
  --surface-on-brand: color-mix(in srgb, var(--text-on-brand) 6%, transparent);
  --surface-selected-on-brand: color-mix(in srgb, var(--text-on-brand) 10%, transparent);
  --accent-on-brand: var(--accent);
  --focus-ring-on-brand: var(--focus-ring);
  --text-danger: #ef7d77;

  --text-strong: #ffffff;
  --text-muted: #afc0d3;
  --text-on-brand: #ffffff;
  /* O accent escuro é dourado: texto sobre ele é ESCURO, não branco. */
  --text-on-accent: #062847;

  --line: rgb(175 192 211 / 0.2);
  --line-on-brand: rgb(255 255 255 / 0.1);
  /* Saturação no máximo (era 78%): o dourado lia como mostarda. */
  --accent: #f3ae00;
  --focus-ring: #d8a21b;


}
/* <<< css/v2/tokens.css <<< */

/* >>> css/v2/base.css >>> */
/* v2 — primitivas.
 *
 * Depende de `v2/tokens.css`.
 *
 * NÃO é um reset. Nada aqui atinge seletor de elemento (`body`, `button`,
 * `input`) nem classe legada: enquanto uma tela não migrar, esta folha não
 * pode mudar um pixel dela. Toda regra é opt-in, ancorada numa classe que só o
 * sistema novo emite.
 *
 * O que mora aqui são as primitivas que mais de um componente compartilha.
 * Regra de admissão: entra quando o SEGUNDO componente precisar. Enquanto for
 * um só, fica na folha dele.
 */

/* ---- foco -----------------------------------------------------------------
 *
 * Um anel só para todo o sistema. `:focus-visible` e não `:focus`: quem clica
 * com o mouse não vê anel, quem navega por teclado vê.
 */
:is(html[data-theme]) .focus-ring:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* `.visually-hidden` NÃO entra aqui, embora pertença a esta camada: ela já
   existe em `base/utilities.css:9`, com outra implementação (`clip: rect()` e
   margem negativa, contra `clip-path`). Redefinir criaria duas fontes para a
   mesma classe — e como esta folha carrega depois, mudaria o comportamento das
   telas ainda não migradas. Volta para cá quando `base/utilities.css` for
   apagado, na etapa final. */


/* ---- andaime da galeria do UI Lab ---------------------------------------
 *
 * Não são componentes: existem só para a vitrine respirar e sairiam junto com
 * ela. Ficam aqui, e não numa folha de página, porque a galeria é o lugar onde
 * o sistema v2 se prova.
 */
:is(html[data-theme]) .v2-lab {
  display: grid;
  gap: var(--gap);
}

:is(html[data-theme]) .v2-lab__group {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  margin: var(--gap-loose) 0 0;
  text-transform: uppercase;
}

:is(html[data-theme]) .v2-lab__row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

:is(html[data-theme]) .v2-lab__sub {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  font-weight: var(--weight-normal);
  margin: var(--gap) 0 0;
}
/* <<< css/v2/base.css <<< */

/* >>> css/v2/shell.css >>> */
/* Casca do aplicativo — a grade que segura barra lateral e conteúdo.
 *
 * Veio de `layout/layout.css` (a grade) e da metade não-lateral de
 * `layout/app-shell.css` (o salto de acessibilidade e a barra móvel) em
 * 2026-08-20, quando a pasta `layout/` foi extinta. As classes são as mesmas —
 * quem as emite é `templates/base.html`, e renomeá-las trocaria a casca de
 * TODAS as telas de uma vez, sem ganho nenhum.
 *
 * O que mudou foi o endereço e a raiz: agora tudo mora sob `html[data-theme]`,
 * como todo o resto do v2. Par da barra lateral em `v2/sidebar.css`.
 */

:is(html[data-theme]) .app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  min-height: 100vh;
}

:is(html[data-theme]) .app-main {
  box-sizing: border-box;
  min-width: 0;
  /* O recuo é FLUIDO, e veio de `theme-shared-components.css` (2026-08-20).
     `layout/layout.css` declarava 32px/24px/16px/12px em quatro faixas e
     NENHUM valia: a regra do tema tinha um seletor a mais e vencia em todas
     elas. O que a tela sempre mostrou é este clamp. */
  padding: clamp(20px, 2.6vw, 40px);
  width: 100%;
}

:is(html[data-theme]) .content-wrap {
  margin: 0;
  max-width: var(--page-max-width);
  padding: 0;
  width: 100%;
}

/* A sobrancelha de página. Continua aqui, e não em `v2/header.css`, porque
   `js/core/app.js` a escreve em avisos montados fora do cabeçalho. */
:is(html[data-theme]) .eyebrow {
  color: var(--color-accent);
  display: block;
  font-size: 12px;
  font-weight: 700;
  margin-bottom: var(--space-1);
  text-transform: uppercase;
}

/* O salto para o conteúdo: fora da tela até receber foco. */
:is(html[data-theme]) .skip-link {
  border-radius: var(--radius-control);
  left: 16px;
  padding: 10px 14px;
  position: fixed;
  top: 12px;
  transform: translateY(-160%);
  transition: transform 120ms ease;
  z-index: calc(var(--z-modal, 1000) + 10);
}

:is(html[data-theme]) .skip-link:focus {
  transform: translateY(0);
}

/* Barra móvel e fundo escurecido só existem abaixo de 840px. */
:is(html[data-theme]) .app-mobile-bar,
:is(html[data-theme]) .sidebar-drawer-close,
:is(html[data-theme]) .sidebar-scrim {
  display: none;
}

/* O raio fica FORA da consulta de mídia, como estava em
   `theme-shared-components.css`: os dois botões existem no DOM em qualquer
   largura — escondidos acima de 840px —, e o raio é do botão, não da faixa. */
:is(html[data-theme]) .app-mobile-bar__toggle,
:is(html[data-theme]) .sidebar-drawer-close {
  border-radius: 10px;
}

@media (max-width: 840px) {
  :is(html[data-theme]) .app-shell {
    display: block;
  }

  :is(html[data-theme]) .app-mobile-bar {
    align-items: center;
    display: flex;
    height: 64px;
    justify-content: space-between;
    padding: 0 16px;
    position: sticky;
    top: 0;
    z-index: calc(var(--z-sidebar, 20) - 1);
  }

  :is(html[data-theme]) .app-mobile-bar__brand {
    align-items: center;
    display: inline-flex;
    font-weight: 750;
    gap: 10px;
    text-decoration: none;
  }

  :is(html[data-theme]) .app-mobile-bar__toggle,
  :is(html[data-theme]) .sidebar-drawer-close {
    align-items: center;
    cursor: pointer;
    display: inline-flex;
    height: 40px;
    justify-content: center;
    width: 40px;
  }

  :is(html[data-theme]) .app-mobile-bar__toggle {
    flex-direction: column;
    gap: 4px;
  }

  :is(html[data-theme]) .app-mobile-bar__toggle > span {
    height: 2px;
    width: 18px;
  }
}

/* No celular o clamp daria 20px; 14px é o que o tema impunha, e é o que a tela
   mostra desde então. */
@media (max-width: 600px) {
  :is(html[data-theme]) .app-main {
    padding: 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .skip-link {
    transition: none;
  }
}

/* ---- pintura do tema escuro -----------------------------------------------
 *
 * Veio de `components/theme-dark-components.css` em 2026-08-20, com o seletor
 * intacto. A barra móvel e o salto de acessibilidade só têm pintura NO ESCURO:
 * no claro eles herdam a superfície da página, e mudar isso aqui seria
 * redesenhar duas peças de casca no meio de uma mudança de endereço.
 */

:is(html[data-theme="dark"]) .skip-link {
  background: var(--color-surface-strong);
  border: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-md);
  color: var(--color-heading);
}

:is(html[data-theme="dark"]) .app-mobile-bar {
  background: var(--sidebar-surface);
  border-bottom: 1px solid var(--sidebar-border);
  box-shadow: var(--shadow-sm);
}

:is(html[data-theme="dark"]) .app-mobile-bar__brand {
  color: var(--sidebar-brand-fg);
}

:is(html[data-theme="dark"]) :is(.app-mobile-bar__toggle, .sidebar-drawer-close) {
  background: var(--color-primary-soft);
  border: 1px solid var(--color-border);
  color: var(--color-heading);
}

:is(html[data-theme="dark"]) .app-mobile-bar__toggle:hover,
:is(html[data-theme="dark"]) .sidebar-drawer-close:hover {
  background: var(--color-primary);
  border-color: var(--color-primary-bright);
}

:is(html[data-theme="dark"]) .app-mobile-bar__toggle > span {
  background: currentColor;
}
/* <<< css/v2/shell.css <<< */

/* >>> css/v2/document-loading.css >>> */
/* Aviso de download em curso — a caixa que aparece no canto inferior enquanto
 * o documento é gerado, e vira erro quando a geração falha.
 *
 * Veio de `feedback/document-download-loading.css` em 2026-08-20, com as regras
 * intactas: a marcação é de `templates/base.html` e o estado é aceso por
 * `js/components/document-download.js` — a peça já era do sistema, faltava-lhe
 * o endereço.
 *
 * Não é um `alert`: aquele ocupa uma faixa no fluxo da página e some com a
 * navegação; este flutua sobre a tela porque o download continua enquanto se lê
 * outra coisa.
 */

:is(html[data-theme]) .document-loading {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 10050;
  width: min(360px, calc(100vw - 32px));
  pointer-events: none;
}

:is(html[data-theme]) .document-loading[hidden] {
  display: none;
}

:is(html[data-theme]) .document-loading__panel {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--theme-border-card);
  border-radius: 18px;
  background: var(--theme-surface-card);
  color: var(--color-text);
  box-shadow: var(--theme-shadow-block);
  text-align: left;
}

:is(html[data-theme]) .document-loading__spinner {
  grid-row: 1 / span 2;
  width: 30px;
  height: 30px;
  border: 3px solid color-mix(in srgb, var(--color-primary) 24%, transparent);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: cv-document-loading-spin 0.72s linear infinite;
}

:is(html[data-theme]) .document-loading__title {
  margin: 0;
  color: var(--color-heading);
  font-size: 0.92rem;
  font-weight: 800;
}

:is(html[data-theme]) .document-loading__detail {
  margin: -8px 0 0;
  color: var(--color-text-muted);
  font-size: 0.875rem;
  line-height: 1.45;
}

:is(html[data-theme]) .document-loading.is-error .document-loading__spinner {
  border-color: var(--color-danger);
  animation: none;
}

:is(html[data-theme]) .document-loading.is-error .document-loading__spinner::after {
  content: "!";
  display: grid;
  height: 100%;
  place-items: center;
  color: var(--color-danger);
  font-weight: 900;
}

:is(html[data-theme]) [data-document-download-active] {
  cursor: wait;
  pointer-events: none;
}

@media (max-width: 600px) {
  :is(html[data-theme]) .document-loading {
    right: 16px;
    bottom: 16px;
    left: 16px;
    width: auto;
  }
}

@keyframes cv-document-loading-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .document-loading__spinner {
    animation-duration: 1.8s;
  }
}

/* ---- a espera EMBUTIDA -----------------------------------------------------
 *
 * A mesma espera, na tela inteira: a prévia do plano de trabalho abre num
 * `<iframe>`, e enquanto o servidor gera o arquivo é esta página que ocupa o
 * quadro. Veio de `pages/document-generation-embedded.css` em 2026-08-20 — o
 * assunto é o mesmo do aviso flutuante acima (documento em preparação), e
 * manter dois desenhos para ele era manter duas folhas.
 *
 * Aqui o painel é CENTRADO e não flutua: não há página por trás para continuar
 * lendo — a espera é a tela.
 */

:is(html[data-theme]) .document-loading--embedded {
  background: var(--surface-rail);
  color: var(--text-strong);
  display: grid;
  margin: 0;
  min-height: 100vh;
  padding: clamp(1.5rem, 6vw, 4rem);
  place-items: center;
  pointer-events: auto;
  position: static;
  width: auto;
}

:is(html[data-theme]) .document-loading--embedded .document-loading__panel {
  align-items: center;
  background: var(--surface-field);
  border: 0;
  border-radius: var(--radius-rail);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  padding: clamp(1.75rem, 5vw, 3rem);
  text-align: center;
  width: min(100%, 31rem);
}

:is(html[data-theme]) .document-loading__mark {
  align-items: center;
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  color: var(--accent);
  display: grid;
  height: 3.5rem;
  margin-bottom: var(--gap);
  place-items: center;
  width: 3.5rem;
}

:is(html[data-theme]) .document-loading__mark svg {
  height: 1.65rem;
  width: 1.65rem;
}

:is(html[data-theme]) .document-loading--embedded .document-loading__spinner {
  grid-row: auto;
  margin-bottom: var(--gap-tight);
}

:is(html[data-theme]) .document-loading__eyebrow {
  color: var(--accent);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  margin: 0 0 var(--gap-tight);
  text-transform: uppercase;
}

:is(html[data-theme]) .document-loading--embedded .document-loading__title {
  font-size: clamp(1.25rem, 4vw, 1.65rem);
  margin: 0;
}

:is(html[data-theme]) .document-loading--embedded .document-loading__detail {
  margin: var(--gap-tight) 0 0;
  max-width: 27rem;
}
/* <<< css/v2/document-loading.css <<< */

/* >>> css/v2/button.css >>> */
/* Button — o controle de ação. Par de `templates/cotton/ui/buttons/button.html`.
 *
 * Depende de `v2/tokens.css`. Não escreve cor literal.
 *
 * ## Por que 3 variantes e não 18
 *
 * O botão legado (`actions/buttons.css`, 1141 linhas) tinha 18 variantes.
 * Medido no repositório, **8 estavam mortas** — zero uso em template e em JS:
 * `soft-danger`, `neutral`, `icon`, `pill`, `tool`, `docx`, `back`, `lg`.
 *
 * `ghost` saiu por decisão do dono: os 3 usos que tinha eram todos do navegador
 * de pastas do Drive, e viraram `secondary`.
 *
 * Das que restam, `preview` (2 usos), `pdf` (2) e `back-list` (1) não são
 * variantes de botão: são aparências de uma tela específica que viraram
 * variante global. Elas continuam no CSS legado até as telas delas migrarem,
 * quando viram composição na própria tela — não entram aqui.
 *
 * ## Forma única
 *
 * O legado tinha três raios (12px no primary, 8px no secondary, 10px no sm) e
 * dois pesos de fonte (720 e 600) para o mesmo controle — medido no navegador.
 * Aqui é um raio só, o mesmo do campo (`--radius-field`), porque botão e campo
 * dividem a mesma barra e precisam ler como a mesma família.
 *
 * O `translateY(-1px)` do hover legado saiu: mexer a geometria no hover faz a
 * linha inteira de botões tremer quando o mouse passa.
 */

:is(html[data-theme]) .button {
  align-items: center;
  background: var(--surface-field);
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: var(--text-size-base);
  font-weight: var(--weight-normal);
  gap: var(--gap-tight);
  justify-content: center;
  line-height: 1;
  min-height: var(--control-height);
  padding: var(--pad-field);
  text-decoration: none;
  transition: background var(--ease), border-color var(--ease), color var(--ease);
  user-select: none;
  white-space: nowrap;
}

:is(html[data-theme]) .button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Desabilitado vale para `<button disabled>` e para `<a aria-disabled>`, que
   não aceita o atributo `disabled`. */
:is(html[data-theme]) .button:disabled,
:is(html[data-theme]) .button[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
}

/* ---- variantes ---------------------------------------------------------- */

/* A ação principal é o accent do tema: azul-marinho no claro, dourado no
   escuro. É a decisão que também desatou o nó do contraste — nenhum azul com
   texto branco satisfazia, ao mesmo tempo, o mínimo de leitura (4.5) e o
   destaque contra a caixa (3.0) no tema escuro. */
:is(html[data-theme]) .button--primary {
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: var(--weight-strong);
}

/* O secondary INTERCALA a superfície: fica no degrau oposto ao da camada que o
   contém, e é esse contraste — não uma borda — que lhe dá contorno. Quem
   define o degrau é o contêiner, via `--surface-contrast`. */
:is(html[data-theme]) .button--secondary {
  background: var(--surface-contrast, var(--surface-rail));
  border-color: transparent;
  color: var(--text-strong);
}

:is(html[data-theme]) .button--danger {
  background: var(--danger);
  color: var(--text-on-danger);
  font-weight: var(--weight-strong);
}

/* ---- hover --------------------------------------------------------------
 *
 * Um degrau de superfície, nunca mistura de matiz: no tema escuro o accent é
 * dourado, e `color-mix` dele com o azul-marinho do fundo cai em oliva
 * (medido: `#2d302c`). Foi um erro cometido duas vezes no sistema antigo. */

/* Mesmo hover do "Limpar" do calendário (`fields/date-picker.css:234`, na
   versão de `ui/date-picker.css`): a superfície recebe 14% do accent e o texto
   assume o accent.

   Decisão do dono, tomada com o número na mesa: no tema escuro o accent é
   dourado e a mistura com o azul-marinho dá `#3b4342`, um pardo. Fica
   registrado aqui para quem reabrir o arquivo não "consertar" achando que é
   descuido. */
:is(html[data-theme]) .button--secondary:hover:not(:disabled):not([aria-disabled="true"]) {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-contrast, var(--surface-rail)));
  color: var(--accent);
}

/* ACENDE, não apaga: sobreposição branca sobre a cor cheia. A sobreposição
   preserva o matiz do accent — clarear com `color-mix` para o branco
   dessaturaria o dourado do tema escuro. */
:is(html[data-theme]) .button--primary:hover:not(:disabled):not([aria-disabled="true"]) {
  box-shadow: inset 0 0 0 999px rgb(255 255 255 / 0.16);
}

/* O danger continua escurecendo: no vermelho, clarear lê como "menos grave" —
   o oposto do que o botão comunica. */
:is(html[data-theme]) .button--danger:hover:not(:disabled):not([aria-disabled="true"]) {
  box-shadow: inset 0 0 0 999px rgb(0 0 0 / 0.12);
}


/* Só o ícone, em caixa quadrada da altura do controle. Existe para as ações que
   se repetem numa lista, onde o rótulo seria a mesma palavra em toda linha; o
   nome vive no `aria-label`, que passa a ser obrigatório. Vale com qualquer
   variante — é forma, não ênfase. */
:is(html[data-theme]) .button--icon {
  padding: 0;
  width: var(--control-height);
}

/* ---- miúdo --------------------------------------------------------------- */

:is(html[data-theme]) .button--sm {
  font-size: var(--text-size-eyebrow);
  min-height: var(--control-height-sm);
  padding: 0 10px;
}

:is(html[data-theme]) .button--sm.button--icon {
  width: var(--control-height-sm);
}

:is(html[data-theme]) .button--sm .button__icon svg {
  height: 14px;
  width: 14px;
}

/* Duas alturas: 44px, a padrão, e 28px para o botão que vive DENTRO de outro
   controle — o painel do calendário, por exemplo, onde quatro botões de 44px
   ocupam mais do que o mês inteiro que eles navegam.

   O legado tinha três (`sm`, `xs` e a base) sem nada por trás: valores fixos
   escolhidos um a um. A diferença aqui é que a segunda altura tem critério —
   está aninhada dentro de outro controle — e sai do mesmo token que todo o
   resto lê.

   ---- ícone ---------------------------------------------------------------
 *
 * Dimensão fixa para o ícone não esticar quando o rótulo quebra. */

:is(html[data-theme]) .button__icon {
  align-items: center;
  display: inline-flex;
  flex: none;
  justify-content: center;
}

:is(html[data-theme]) .button__icon svg {
  height: 16px;
  width: 16px;
}
/* <<< css/v2/button.css <<< */

/* >>> css/v2/input.css >>> */
/* Input — campo de texto e busca. Depende de `v2/tokens.css`.
 *
 * Um campo é a mesma coisa em qualquer contexto: barra de filtros, formulário
 * ou wizard. O sistema antigo tinha TRÊS superfícies diferentes para isto na
 * mesma tela (medido em `/roteiros/novo/` com três tons intermediários) — é
 * exatamente o que esta folha existe para não deixar acontecer de novo.
 */

:is(html[data-theme]) .input {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
  position: relative;
}

:is(html[data-theme]) .input__control {
  /* A superfície do campo é `--surface-field` — o token leva o nome dele. Quem
     muda é o CONTÊINER, que fica um degrau abaixo (`--surface-rail`). Cheguei a
     fazer o contrário, com o bloco em `field` e o campo intercalando para
     `rail`; ficava invertido, com o campo mais escuro que a caixa. */
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  font: inherit;
  font-size: var(--text-size-base);
  min-height: var(--control-height);
  min-width: 0;
  padding: var(--pad-field);
  width: 100%;
}

:is(html[data-theme]) .input__control::placeholder {
  color: var(--text-muted);
}

/* O foco ACENDE A BORDA. O campo já reserva `1px solid transparent`, então
   colorir esse fio não desloca nada — e ocupa o lugar da borda que o campo não
   usa em repouso. Sem anel, sem sombra: a sombra fica reservada ao erro.
 *
 * O `!important` é a ÚNICA forma de dispensar o anel: `base/base.css:128` o
 * impõe a todo controle com `!important`, como garantia global de
 * acessibilidade. A garantia não cai — a borda acesa cumpre a mesma função.
 * Quando o CSS legado sair, este `!important` sai junto. */
:is(html[data-theme]) .input__control:focus-visible {
  border-color: var(--focus-ring);
  outline: none !important;
}

/* Ícone dentro do campo: sai do fluxo e o texto ganha recuo para não passar
   por baixo dele. */
:is(html[data-theme]) .input--with-icon .input__control {
  padding-left: 38px;
}

:is(html[data-theme]) .input__icon {
  align-items: center;
  color: var(--text-muted);
  display: inline-flex;
  left: 12px;
  pointer-events: none;
  position: absolute;
}

:is(html[data-theme]) .input__icon svg {
  height: 16px;
  width: 16px;
}

:is(html[data-theme]) .input__control:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* A área de texto cresce na vertical e por isso não usa `--control-height`; o
   padding vira simétrico, senão o texto cola no topo.
 *
 * NÃO neutralizar a altura inline aqui. Cheguei a pôr `height: auto !important`
 * para ter "uma fonte só" — e isso matou o redimensionamento manual, porque o
 * arrasto do canto também escreve altura inline, igual ao auto-ajuste do JS. O
 * CSS não distingue os dois.
 *
 * O `min-height` já garante o piso: altura inline menor que ele não tem efeito.
 * O que o usuário aumenta, fica. */
:is(html[data-theme]) .input__control--textarea {
  min-height: 96px;
  padding: 10px 12px;
  resize: vertical;
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

/* ---- só leitura -------------------------------------------------------------
 *
 * Campo `readonly` tem a MESMA aparência do campo comum — a diferença é só não
 * aceitar digitação (decisão do dono, 2026-08-17). As folhas legadas
 * (`base/base.css`, `fields/forms.css`) pintam `input[readonly]` com fundo,
 * contorno e texto próprios, e como esta folha não declarava nada, quem mandava
 * era a regra antiga: medido `#243541` com traço claro e texto acinzentado,
 * contra `#223348` sem traço e texto branco do campo comum. Lado a lado — a
 * distância do mapa ao lado da hora do trecho — pareciam dois componentes.
 *
 * O cursor continua o de texto e o campo segue selecionável: o valor é para ser
 * lido e copiado. Quem informa que não se digita ali é o `aria-readonly`, que o
 * leitor de tela anuncia. */
:is(html[data-theme]) .input__control[readonly],
:is(html[data-theme]) .cv-field__control[readonly] {
  background: var(--surface-contrast, var(--surface-field));
  border-color: transparent;
  color: var(--text-strong);
  opacity: 1;
}

/* ---- o widget do Django dentro de um campo do v2 ---------------------------
 *
 * Os formulários do sistema mandam as classes do widget desde o Python
 * (`core/forms/widgets.py`): `form-control`, `form-select`, `cv-field__control`.
 * São as mesmas classes das telas legadas, então elas não podem ser trocadas por
 * `input__control` sem repintar o que ainda não migrou.
 *
 * A saída é vesti-las AQUI, e só dentro de um `.field` do v2: o catálogo
 * renderiza `{{ field }}` como o Django o entrega, e o campo veste a roupa da
 * tela. Sem isto o cadastro rápido saía com o input branco do navegador no meio
 * de uma tela escura.
 */
:is(html[data-theme]) .field > .form-control,
:is(html[data-theme]) .field > .form-select,
:is(html[data-theme]) .field > .cv-field__control {
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  font: inherit;
  font-size: var(--text-size-base);
  min-height: var(--control-height);
  padding: var(--pad-field);
  width: 100%;
}

:is(html[data-theme]) .field > .form-control:focus-visible,
:is(html[data-theme]) .field > .form-select:focus-visible,
:is(html[data-theme]) .field > .cv-field__control:focus-visible {
  border-color: var(--focus-ring);
  /* O legado aplica anel e sombra com `!important` a todo widget Django. No
     field V2 o foco é a própria borda reservada, igual ao `input__control`. */
  box-shadow: none !important;
  outline: none !important;
}

/* A estrela de "definir como padrão" é um formulário de um botão só; sem isto o
   `<form>` quebra a linha das ações. */
:is(html[data-theme]) .catalog-row__default-form {
  display: contents;
}
/* <<< css/v2/input.css <<< */

/* >>> css/v2/field.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/field.css` em 2026-08-20 — mesma história do picker: são as
 * declarações do componente do v2, que nasceram numa pasta com nome do sistema
 * antigo. O `cv-field*` e o `form-select` são emitidos pelo PRÓPRIO
 * `v2/form_field.html` e `v2/date_picker.html`.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ==========================================================================
   Campo de texto — a regra base que nunca existiu
   ==========================================================================

   `.cv-field__control` é a classe de campo com maior alcance do sistema: 11
   templates, 30 rotas. E até este arquivo ela **não tinha nenhuma regra base**.

   Ela existia só em 64 regras de sobrescrita espalhadas por 14 arquivos, com 70
   `!important`. O que pintava o campo de fato era o seletor de elemento nu
   `input, select, textarea` em `base.css:59`.

   Não é que os campos divergiram ao longo do tempo. É que **nunca existiu um
   campo** — existia o elemento cru do navegador e um monte de correção por
   cima. Daí saíram, medidos: 27 cadeias distintas de `background`, 13 valores
   de `border-radius`, 7 alturas com 5 nomes de token diferentes todos valendo
   44px, e 6 formas de declarar a mesma linha de 1px.

   ## Por que os valores aqui são exatamente os de `base.css`

   Este arquivo **não muda aparência nenhuma**, de propósito. Ele copia o que o
   seletor de elemento já entrega e passa a entregar pela classe.

   A tentação era escrever aqui os valores "certos" e corrigir tudo de uma vez.
   Isso misturaria duas coisas num PR só — dar um lar à classe, e mudar o
   visual — e qualquer diferença que aparecesse na medição seria impossível de
   atribuir a uma das duas. Com a base neutra, cada sobrescrita pode ser
   removida depois e medida sozinha: some ou não some.

   ## O que muda, então

   O lugar. A partir daqui existe **um** ponto onde a aparência de um campo é
   decidida, e as 64 sobrescritas passam a ser dívida visível em vez de
   arquitetura. A ordem do trabalho seguinte é: remover as redundantes (as que
   já declaram o que esta regra entrega), depois converter as divergentes.

   O `uppercase` NÃO mora aqui: o dono escolheu máscara, que muda o valor
   digitado, e não `text-transform`, que só muda a aparência. Está em
   `core/forms/widgets.py` (`NOVO-53`).

   ## Por que `:where()` e não a classe nua

   `.cv-field__control` tem especificidade 0,1,0 — mais que o seletor de
   elemento (0,0,1) que hoje pinta o campo. Escrita assim, a regra base passava
   a VENCER estilos de contexto legítimos escritos com seletor de elemento, e a
   medição pegou: 55 elementos mudaram, com raio indo de 12px para 14px e borda
   de 0 para 1px em campos que eram deliberadamente sem borda.

   `:where()` zera a especificidade. A regra vira o que uma base deve ser: vale
   onde ninguém disse nada, e perde para qualquer coisa que diga. É o que
   permite que ela seja neutra hoje e o alvo da padronização amanhã.
   ========================================================================== */

:where(.cv-field__control) {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  min-height: var(--control-height-md);
  padding: 0 var(--space-3);
}

/* A única variação que o dono admitiu: textarea aceita as duas caixas e cresce.
   Os valores são os mesmos de `base.css:71`. */
:where(.cv-field__control--textarea) {
  min-height: var(--text-area-height-md);
  padding-bottom: var(--space-3);
  padding-top: var(--space-3);
  resize: vertical;
}




/* ═══════════════════════════════════════════════════════════════════════════
 * VINDAS DAS FOLHAS DE TEMA E DO CASCO ANTIGO, em 2026-08-20.
 *
 * Descreviam este componente DE FORA dele — em `theme-shared-components.css`,
 * `theme-dark-components.css`, `layout/page-shell.css`, `fields/forms.css` ou
 * `lists/list-header.css`. Enquanto ficaram lá, o componente do v2 dependia de
 * folhas do sistema antigo para ter forma, e toda tela migrada carregava
 * aquelas folhas por causa dele.
 *
 * Vieram com o texto INTACTO — `!important` e escopo de wizard inclusive —, e
 * ANTES da divisa: elas chegavam pelo bundle do shell, que é anterior ao
 * `ui.bundle.css`, e por isso perdiam para o delta do v2. Anexá-las no fim
 * inverteria a disputa sem mudar um valor sequer. Medido antes e depois em 20
 * telas: nenhuma diferença.
 * ═══════════════════════════════════════════════════════════════════════════ */

.quick-create-panel .field-grid {
  flex: 1;
}

@media (max-width: 600px) {
.field-grid--cols-2,
  .field-grid--cols-3,
  .field-grid--cols-4 {
    grid-template-columns: minmax(0, 1fr);
  }
}

#quick-add-modelo-motivo .inline-create__fields > .field-grid {
  margin: 0;
}

#quick-add-atividade .inline-create__fields > .field-grid {
  margin: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`: as asserções de
 * aparência do v2 descrevem ESTA metade. Medir o arquivo inteiro faria o teste
 * ler a regra base que o delta sobrescreve — foi o que aconteceu na fusão de
 * 2026-08-20, com sete asserções apontando para a declaração antiga da mesma
 * classe, três telas acima.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Field — rótulo, controle, ajuda e erro. Depende de `v2/tokens.css`.
 *
 * COLISÃO: `.field` já existe no legado (33 usos). Enquanto ele viver, estas
 * regras só valem dentro de `.form-block--v2`, para não repintar tela não
 * migrada. O escopo cai junto com o legado.
 */

:is(html[data-theme]) .field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

:is(html[data-theme]) .field__label {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  /* Declarado, e não omitido: `fields/forms.css` dava `0.01em` a todo `label`
     dentro de `.field`, e era a ÚNICA declaração daquela folha que ainda
     alcançava uma tela do v2 (medido no editor de roteiro em 2026-08-20).
     Espaçamento de letra no v2 é coisa de sobrancelha, não de rótulo — 0,14px
     num texto de 14px não se vê, e a herança atravessava o sistema inteiro. */
  letter-spacing: normal;
}

:is(html[data-theme]) .field__help {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

:is(html[data-theme]) .field__error {
  color: var(--text-danger);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

/* O campo inválido muda de traço, nunca de forma: mudar geometria no erro faz
   o formulário inteiro pular quando a validação roda. */
:is(html[data-theme]) .field--invalid .input__control {
  border-color: var(--danger);
}

/* O erro é o ÚNICO caso com sombra. Nos demais o foco só acende a borda; aqui
   a borda já está vermelha em repouso, então precisa de outro sinal para o foco
   não passar despercebido. */
:is(html[data-theme]) .field--invalid .input__control:focus-visible {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 40%, transparent);
  outline: none !important;
}

/* ---- campo com ação -------------------------------------------------------
 *
 * Uma ação secundária ao lado do controle — "gerenciar modelos" ao lado do
 * select que os escolhe. Ela fica OCULTA e aparece quando o ponteiro entra no
 * campo; o controle encolhe para abrir espaço, em vez de a ação flutuar por
 * cima dele.
 *
 * `:focus-within` junto com `:hover` NÃO é zelo: uma ação que só existe sob o
 * cursor desaparece para quem navega por teclado e para quem usa toque. Com o
 * foco dentro do campo ela aparece igual, e o Tab alcança o botão.
 */
:is(html[data-theme]) .field-with-action {
  align-items: center;
  display: flex;
  gap: 0;
  min-width: 0;
}

:is(html[data-theme]) .field-with-action > :first-child {
  flex: 1 1 auto;
  min-width: 0;
}

/* Some pela LARGURA, e não por `display`: assim o controle ao lado cresce e
   encolhe com transição, em vez de saltar. */
:is(html[data-theme]) .field-with-action__action {
  flex: 0 0 auto;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  transition: opacity var(--ease), width var(--ease), margin-left var(--ease);
  width: 0;
}

:is(html[data-theme]) .field-with-action:hover .field-with-action__action,
:is(html[data-theme]) .field-with-action:focus-within .field-with-action__action {
  margin-left: var(--gap-tight);
  opacity: 1;
  pointer-events: auto;
  width: var(--control-height);
}

/* O botão nunca encolhe junto com a caixa que o esconde — ele só some de vista.
 *
 * No ACCENT, e não na cor neutra dos outros botões de ícone: ele aparece só
 * quando o ponteiro entra no campo, e nesse instante precisa se anunciar. Um
 * botão que surge apagado ao lado do controle parece parte dele. */
:is(html[data-theme]) .field-with-action__action > .icon-button {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--accent);
  flex: none;
  height: var(--control-height);
  width: var(--control-height);
}

:is(html[data-theme]) .field-with-action__action > .icon-button:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}

/* ══════════════════════════════════════════════════════════════════════════
 * A GRADE DE CAMPOS — veio de `layout/page-shell.css` em 2026-08-20.
 *
 * `field-grid`, `field-grid--cols-N` e `field-size-N` são emitidos por 40
 * templates do v2 (todo quick-add, todo formulário de catálogo), e as regras
 * moravam na folha do casco antigo. Enquanto ficaram lá, toda tela do v2
 * dependia de uma folha do sistema que este refactor existe para apagar — e as
 * páginas de catálogo, que carregam um perfil enxuto, chegavam a perder os
 * modificadores de coluna no caminho.
 *
 * SEM o prefixo `:is(html[data-theme])` do resto do v2, de propósito: telas não
 * migradas ajustam a grade com seletores de duas classes
 * (`.main-form-panel .field-grid`, `.roteiro-trecho-card__route-row.field-grid--cols-2`).
 * Acrescentar o prefixo subiria a especificidade destas regras acima das
 * daquelas e mudaria a grade em telas que ninguém pediu para mexer. O prefixo
 * entra quando o último desses seletores morrer.
 * ══════════════════════════════════════════════════════════════════════════ */

:root {
  --field-grid-gap: var(--space-4);
}

.field-grid {
  align-items:           start;
  display:               grid;
  gap:                   var(--field-grid-gap);
  width:                 100%;
}

.field-grid > .field,
.field-grid > .app-form-field,
.field-grid--cols-3 > .field,
.field-grid--cols-3 > .app-form-field {
  min-width: 0;
  width:     100%;
}

/* 2 colunas: pares de campos — nome + sigla, data + hora */
.field-grid--cols-2 {
  display: grid;
  gap: var(--field-grid-gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: 100%;
}

/* 3 colunas: trios de campos — nome + CPF + telefone */
.field-grid--cols-3 {
  display:               grid;
  gap:                   var(--field-grid-gap);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  width:                 100%;
}

/* 4 colunas: alias explícito do `.field-grid` padrão */
.field-grid--cols-4 {
  display:               grid;
  gap:                   var(--field-grid-gap);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  width:                 100%;
}

/* Quatro tamanhos, em colunas da grade. O tamanho segue o TIPO do dado:
   pequeno para UF e CEP, médio para telefone e cargo, linha inteira para
   textarea. `--3` não tem regra própria: ele é o vão entre `--2` e a linha
   inteira, e só existe nas consultas de mídia abaixo. */
.field-size-1 { grid-column: span 1; }

.field-size-2 { grid-column: span 2; }

.field-size-4 { grid-column: 1 / -1; }

/* Tablet: a grade cai para duas colunas, e os tamanhos a acompanham. */
@media (max-width: 840px) {
  .field-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .field-grid--cols-2,
  .field-grid--cols-3,
  .field-grid--cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .field-size-1 { grid-column: span 1; }
  .field-size-2 { grid-column: span 2; }

  .field-size-4 { grid-column: 1 / -1; }
}

/* Celular: uma coluna, e nenhum campo atravessa nada. */
@media (max-width: 600px) {
  .field-grid {
    grid-template-columns: 1fr;
  }

  .field-size-1,
  .field-size-2,
  .field-size-3,
  .field-size-4 {
    grid-column: 1;
  }
}
/* <<< css/v2/field.css <<< */

/* >>> css/v2/form-block.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/form-sections.css` em 2026-08-20 — mesma história do
 * picker e do calendário: são as declarações do componente do v2, escritas numa
 * pasta com nome do sistema antigo porque foi lá que nasceram. O arquivo v2
 * carregava só o DELTA.
 *
 * O que ficou para trás na folha antiga foi o `segment-toggle`, e ele foi
 * APAGADO em vez de mudar de endereço: o alternador do sistema é o
 * `c-v2.toggle` desde 2026-08-16, e as últimas duas telas que emitiam a classe
 * antiga (motorista do ofício, fonte do roteiro) migraram no mesmo dia.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ========================================================================
   Canonical form composition

   These classes describe reusable layout contracts. Page modules may add
   data-* hooks for business behaviour, but should not duplicate this visual
   structure with module-prefixed selectors.
   ======================================================================== */

.form-card > .form-section-body {
  display: grid;
  gap: 10px;
}

.form-block {
  align-items: start;
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
  min-width: 0;
  /* NOVO-58 (E8): existia só no tema escuro, em
     `theme-dark-components.css`. O claro é o desenho ANTERIOR ao redesenho, e é
     o que o sistema mostra para quem nunca escolheu tema.

     Não é ajuste cosmético: medido no navegador, o padding só-escuro encolhia a
     caixa de conteúdo em 28px, os filhos iam de 434px para 406px, o texto
     quebrava diferente e a página ganhava 48,55px — propagando por 14 níveis. É
     essa cadeia que desestabilizava a régua de tema (`NOVO-84`).

     O `NOVO-89` formalizou o valor medido como passo intermediário da escala:
     arredondar para 16px mudaria os dois temas e quebraria a paridade visual. */
  padding: var(--space-3-5);
}

.form-block__header {
  align-items: baseline;
  display: flex;
  gap: var(--space-3);
  justify-content: space-between;
  min-width: 0;
}

.form-block__copy {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.form-block:not(.form-block--split):not(.form-block--resource) >
  .form-block__header .form-block__copy {
  align-items: baseline;
  display: flex;
  gap: var(--space-3);
  justify-content: space-between;
  width: 100%;
}

.form-block__title,
.form-block__description {
  margin: 0;
}

.form-block__body {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.form-block__actions {
  align-items: center;
  display: flex;
  flex-shrink: 0;
  gap: var(--space-2);
}

.form-block--split {
  align-items: end;
  grid-template-columns: minmax(160px, 0.7fr) minmax(0, 2fr);
}

.form-block--split > .form-block__header {
  align-self: center;
  display: grid;
  gap: 3px;
  justify-content: start;
}

.form-block--split > .form-block__body {
  align-self: end;
}

.form-stack {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

/* O bloco Destinos já traz margin-top no ofício; dentro do schedule o gap cobre. */
.travel-schedule .route-destinos-block.route-destinos-block--split {
  margin-top: 0;
}

.composite-field__control > .form-control {
  min-width: 0;
}

@media (max-width: 900px) {
  .form-block--split {
    align-items: stretch;
    grid-template-columns: minmax(0, 1fr);
  }

  .form-block--split > .form-block__header {
    align-items: baseline;
    display: flex;
    justify-content: space-between;
  }
}

@media (max-width: 640px) {
  .form-block:not(.form-block--split):not(.form-block--resource) >
    .form-block__header .form-block__copy {
    align-items: flex-start;
    flex-direction: column;
  }

  .form-block__header,
  .form-block--split > .form-block__header {
    align-items: flex-start;
    flex-direction: column;
  }

  .form-block__actions {
    width: 100%;
  }
}



/* ═══════════════════════════════════════════════════════════════════════════
 * VINDAS DAS FOLHAS DE TEMA E DO CASCO ANTIGO, em 2026-08-20.
 *
 * Descreviam este componente DE FORA dele — em `theme-shared-components.css`,
 * `theme-dark-components.css`, `layout/page-shell.css`, `fields/forms.css` ou
 * `lists/list-header.css`. Enquanto ficaram lá, o componente do v2 dependia de
 * folhas do sistema antigo para ter forma, e toda tela migrada carregava
 * aquelas folhas por causa dele.
 *
 * Vieram com o texto INTACTO — `!important` e escopo de wizard inclusive —, e
 * ANTES da divisa: elas chegavam pelo bundle do shell, que é anterior ao
 * `ui.bundle.css`, e por isso perdiam para o delta do v2. Anexá-las no fim
 * inverteria a disputa sem mudar um valor sequer. Medido antes e depois em 20
 * telas: nenhuma diferença.
 * ═══════════════════════════════════════════════════════════════════════════ */

:is(html[data-theme])
  .form-block {
  border-radius: 14px;
}

:is(html[data-theme])
  .form-block {
  background: var(--color-surface-soft);
  border: 0;
  grid-template-columns: minmax(0, 1fr);
  margin: 0;
  /* NOVO-58 (E8): composição e superfície pertencem ao componente; apenas a
     paleta vem dos tokens de cada tema. */
}

:is(html[data-theme])
  .form-block__header {
  align-items: baseline;
  display: flex;
  gap: 14px;
  justify-content: space-between;
}

:is(html[data-theme])
  .form-block__title {
  color: var(--color-heading);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-black);
  letter-spacing: 0;
  text-transform: none;
}

:is(html[data-theme])
  .form-block__description {
  color: var(--color-muted);
  font-size: var(--font-size-2xs);
  line-height: 1.4;
  text-align: right;
}

:is(html[data-theme])
  .form-block--split {
  align-items: end;
  grid-template-columns: minmax(160px, 0.7fr) minmax(0, 2fr);
}

:is(html[data-theme])
  .form-block--split > .form-block__header {
  align-self: center;
  display: grid;
  gap: 3px;
  justify-content: start;
}

:is(html[data-theme])
  .form-block--split .form-block__description {
  text-align: left;
}

:is(html[data-theme])
  .form-block--split > .form-block__body {
  align-self: end;
}

@media (max-width: 900px) {
:is(html[data-theme])
    .form-block--split {
    align-items: stretch;
    grid-template-columns: minmax(0, 1fr);
  }

:is(html[data-theme])
    .form-block--split > .form-block__header {
    align-items: baseline;
    display: flex;
    justify-content: space-between;
  }

:is(html[data-theme])
    .form-block--split .form-block__description {
    text-align: right;
  }
}

@media (max-width: 640px) {
:is(html[data-theme])
    .form-block--split > .form-block__header {
    align-items: start;
    display: grid;
  }

:is(html[data-theme])
    .form-block--split .form-block__description {
    text-align: left;
  }
}

@media (max-width: 640px) {
:is(html[data-theme])
    .form-block__header {
    align-items: flex-start;
    flex-direction: column;
  }

:is(html[data-theme])
    .form-block__description {
    text-align: left;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Form block — cabeçalho (título, descrição, ações) e corpo.
 *
 * COLISÃO: `.form-block` já existe no legado (16 usos). Usa `--v2` até a
 * migração atômica descrita no plano; o modificador cai quando o legado sair.
 */

:is(html[data-theme]) .form-block--v2 {
  --surface-contrast: var(--surface-field);
  background: var(--surface, var(--surface-rail));
  border-radius: var(--radius-field);
  box-sizing: border-box;
  display: grid;
  gap: var(--gap);
  min-width: 0;
  padding: var(--gap);
}

/* `center`, e não `baseline`: com a ação alinhada pela primeira linha do texto,
   ela ficava colada no título e a descrição sobrava embaixo dela — a ação
   parecia pertencer ao título, e não ao bloco inteiro. Centrada, ela se alinha
   ao conjunto título + descrição. */
:is(html[data-theme]) .form-block--v2 > .form-block__header {
  align-items: center;
  display: flex;
  gap: var(--gap);
  justify-content: space-between;
  min-width: 0;
}

:is(html[data-theme]) .form-block--v2 .form-block__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .form-block--v2 .form-block__description {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
  /* À ESQUERDA, debaixo do título. `theme-shared-components.css` alinha toda
     `.form-block__description` à direita — regra do sistema antigo, em que a
     descrição era uma legenda no canto do cabeçalho. Os wizards já a
     desfaziam um por um; aqui ela é desfeita para o componente inteiro, que é
     de quem a descrição é. Sem isto, a frase do bloco aparecia encostada na
     margem direita em toda tela do v2 fora dos wizards (medido no cartão do
     Drive, 2026-08-20). */
  text-align: left;
}

:is(html[data-theme]) .form-block--v2 > .form-block__body {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* A grade pertence ao bloco v2 e precisa viajar no `ui.bundle.css`. Algumas
   páginas de catálogo carregam um perfil enxuto que conhece `.field-grid`, mas
   não seus modificadores de coluna; sem esta regra `--cols-2` virava uma grade
   de uma coluna justamente no desktop. */
:is(html[data-theme]) .form-block--v2 .field-grid--cols-2,
:is(html[data-theme]) .form-block--v2 .field-grid--cols-3,
:is(html[data-theme]) .form-block--v2 .field-grid--cols-4 {
  display: grid;
  gap: var(--gap);
  min-width: 0;
  width: 100%;
}

:is(html[data-theme]) .form-block--v2 .field-grid--cols-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

:is(html[data-theme]) .form-block--v2 .field-grid--cols-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

:is(html[data-theme]) .form-block--v2 .field-grid--cols-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* A identificação do ofício tem três campos no custeio comum e ganha o quarto
   somente quando "Outra instituição" revela seu complemento. As trilhas devem
   acompanhar a quantidade visível, sem deixar uma coluna vazia no primeiro
   estado. */
:is(html[data-theme]) .form-block--v2 .oficio-identity-grid:has(> .oficio-custeio-instituicao[hidden]) {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Programa ocupa a largura disponível enquanto o complemento não participa do
   formulário. Ao escolher "Outro", o JS revela o segundo filho e a grade volta
   automaticamente às duas colunas iguais declaradas por `--cols-2`. */
:is(html[data-theme]) .form-block--v2 .programa-solicitante-grid:has(
  > [data-pt-programa-outros-field][hidden]
) {
  grid-template-columns: minmax(0, 1fr);
}

:is(html[data-theme]) .form-block--v2 .field-grid--cols-4[hidden] {
  display: none;
}

:is(html[data-theme]) .form-block--v2 .field-grid__span-2 {
  grid-column: span 2;
  min-width: 0;
}

:is(html[data-theme]) .form-block--v2 .field-grid__span-3 {
  grid-column: span 3;
  min-width: 0;
}

:is(html[data-theme]) .form-block--v2 .field-grid__span-all {
  grid-column: 1 / -1;
  min-width: 0;
}

/* Corpo com TODOS os filhos ocultos não reserva trilha na grade. O bloco é
   `display: grid` com `gap` e `padding` do mesmo tamanho: com o corpo vazio, os
   dois se somavam e o bloco fechava com o dobro do respiro embaixo do cabeçalho
   — é o que se via no bate-volta desligado.

   `:has(> *)` primeiro para não pegar corpo de texto puro; depois "nenhum filho
   visível". `:empty` não serviria: o Cotton deixa espaço em branco entre as
   tags, e um corpo com espaços não é `:empty`. */
:is(html[data-theme]) .form-block--v2 > .form-block__body:has(> *):not(:has(> :not([hidden]))) {
  display: none;
}

/* ---- split: cabeçalho à esquerda, corpo à direita -------------------------
 *
 * Para o bloco de UM controle só, onde empilhar título e campo desperdiça uma
 * linha inteira para dizer duas palavras. A primeira coluna tem piso de 148px
 * para o rótulo não quebrar em duas linhas, e teto em fração para o campo — que
 * é o que se preenche — ficar com a maior parte da largura.
 *
 * `.form-block--split` existe no legado, mas lá toda regra exige um ancestral
 * `[data-travel-document-wizard-*]`; fora dos wizards ela não alcança nada.
 * Aqui o par com `.form-block--v2` mantém as duas separadas até o legado sair.
 */
/* A coluna do cabeçalho tem largura FIXA, e não `max-content`.
 *
 * Com `max-content` cada bloco media a sua própria descrição: "Ida e volta no
 * mesmo calendário." dava 188px e "Na ordem da visita." dava 162px, então dois
 * blocos split empilhados começavam os campos em x diferentes (475 e 450) e as
 * colunas não se alinhavam entre si. Alinhar blocos é o motivo de existir um
 * sistema de grade — deixar cada um se medir sozinho o desfaz.
 *
 * A descrição quebra dentro dessa coluna fixa. Assim textos longos aumentam
 * somente a altura do cabeçalho e nunca invadem o campo seguinte; a origem da
 * coluna de campos continua idêntica entre todos os blocos. */
:is(html[data-theme]) .form-block--v2.form-block--split {
  --split-label: 200px;

  align-items: center;
  grid-template-columns: var(--split-label) minmax(0, 1fr);
}

/* Empilha título e descrição: na coluna estreita eles não cabem lado a lado,
   que é o arranjo do cabeçalho normal. */
:is(html[data-theme]) .form-block--v2.form-block--split > .form-block__header {
  display: grid;
  gap: 2px;
}

/* Texto livre precisa respeitar a trilha de 200px. `overflow-wrap` também cobre
   nomes ou identificadores sem espaços, sem deslocar a coluna dos campos. */
:is(html[data-theme]) .form-block--v2.form-block--split .form-block__description {
  min-width: 0;
  overflow-wrap: anywhere;
  white-space: normal;
}

@media (max-width: 720px) {
  :is(html[data-theme]) .form-block--v2.form-block--split {
    grid-template-columns: minmax(0, 1fr);
  }

  :is(html[data-theme]) .form-block--v2 .field-grid--cols-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  :is(html[data-theme]) .form-block--v2 .field-grid--cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  :is(html[data-theme]) .form-block--v2 .field-grid--cols-2,
  :is(html[data-theme]) .form-block--v2 .field-grid--cols-3,
  :is(html[data-theme]) .form-block--v2 .field-grid--cols-4 {
    grid-template-columns: minmax(0, 1fr);
  }

  :is(html[data-theme]) .form-block--v2 .field-grid__span-2 {
    grid-column: auto;
  }
}
/* <<< css/v2/form-block.css <<< */

/* >>> css/v2/header.css >>> */
/* Header — a faixa de identidade: eyebrow, título e ações à direita.
 *
 * Único componente que usa `--surface-brand`.
 */

:is(html[data-theme]) .header {
  align-items: center;
  background: var(--surface-brand);
  border-radius: var(--radius-brand) var(--radius-brand) 0 0;
  box-sizing: border-box;
  display: flex;
  /* O que vai à direita pode ser largo — quatro abas com contador, por exemplo.
     Sem a quebra, ele espremia o título até este se partir em três linhas
     debaixo dele. Quebrar em duas linhas é o que preserva os dois. */
  flex-wrap: wrap;
  gap: var(--gap-loose);
  justify-content: space-between;
  /* A MESMA altura da faixa logo abaixo: as duas são bandas da mesma peça, e
     uma mais baixa que a outra fazia a junção parecer um degrau em vez de uma
     divisão. A conta é a do rail — um controle de altura cheia mais o recuo. */
  min-height: calc(var(--control-height) + var(--pad-rail) * 2);
  min-width: 0;
  padding: var(--pad-rail);
}

:is(html[data-theme]) .header__copy {
  display: grid;
  /* Cresce e encolhe com a sobra; `min-width: 0` é o que permite ao título
     truncar em vez de forçar a linha a ficar mais larga que o contêiner. */
  flex: 1 1 16rem;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .header__eyebrow {
  color: var(--accent);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:is(html[data-theme]) .header__title {
  color: var(--text-on-brand);
  font-size: var(--text-size-title);
  font-weight: var(--weight-strong);
  line-height: 1.2;
  margin: 0;
}

:is(html[data-theme]) .header__description {
  color: var(--text-on-brand);
  font-size: var(--text-size-body);
  line-height: 1.45;
  margin: 0;
  opacity: 0.78;
}

:is(html[data-theme]) .header__aside {
  align-items: center;
  display: flex;
  flex: none;
  gap: var(--gap-tight);
}

/* A ação pertence à faixa: em repouso não abre uma segunda superfície dentro
   do header. A borda dá o limite; o preenchimento só muda quando há intenção
   (hover/foco). A regra vale para qualquer variante colocada neste slot. */
:is(html[data-theme]) .header__aside .button {
  background: var(--surface-brand);
  border-color: color-mix(in srgb, var(--text-on-brand) 38%, transparent);
  color: var(--text-on-brand);
}

:is(html[data-theme]) .header__aside .button:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--surface-selected-on-brand);
  border-color: color-mix(in srgb, var(--text-on-brand) 58%, transparent);
  color: var(--text-on-brand);
}

:is(html[data-theme]) .header__aside .button:focus-visible {
  outline-color: var(--focus-ring-on-brand);
}
/* <<< css/v2/header.css <<< */

/* >>> css/v2/rail.css >>> */
/* Rail — a faixa de controles abaixo do header (busca, filtros, ações).
 *
 * Chamava-se "sub-header" no sistema antigo. O nome novo diz o PAPEL e não o
 * lugar: a mesma faixa serve lista, wizard e detalhe.
 */

:is(html[data-theme]) .rail {
  --surface-contrast: var(--surface-field);
  background: var(--surface, var(--surface-rail));
  border-radius: var(--radius-rail);
  box-sizing: border-box;
  /* Mesma conta do header: as duas bandas fecham na mesma altura quando cada
     uma tem uma linha de conteúdo. */
  min-height: calc(var(--control-height) + var(--pad-rail) * 2);
  padding: var(--pad-rail);
}

:is(html[data-theme]) .rail__controls {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  min-width: 0;
}

/* A busca ocupa a sobra; os demais controles ficam no tamanho natural. */
:is(html[data-theme]) .rail__controls > .input {
  flex: 1 1 220px;
  min-width: 0;
}

/* Busca do SERVIDOR: os campos vão dentro de um `<form method="get">`, e sem
   esta regra o formulário viraria um bloco só na fila de controles, empilhando
   campo e botão. Ele se comporta como a própria fila, e o campo continua
   comendo a sobra. */
:is(html[data-theme]) .rail__form {
  align-items: center;
  display: flex;
  flex: 1 1 320px;
  /* UMA LINHA, sempre (2026-08-20). Era `wrap`, e com cinco controles a faixa
     de Ofícios abria em duas linhas: a segunda ficava com a ordenação e os dois
     períodos soltos sob um vão grande, e a faixa dobrava de altura empurrando a
     lista para baixo. A faixa é uma banda de uma linha por desenho — o que não
     couber ENCOLHE, e é para isso que cada controle abaixo tem `min-width`
     próprio em vez do vão fixo de antes. */
  flex-wrap: nowrap;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .rail__form > .input {
  flex: 1 1 220px;
  min-width: 0;
}

/* Filtros select no rail conservam largura suficiente para o rótulo, mas cedem
   espaço à busca. O piso caiu de 240px para 180px junto com o `nowrap`: com o
   piso antigo, dois selects mais os dois períodos não cabiam na linha e o
   `nowrap` viraria transbordo em vez de encolhimento. */
:is(html[data-theme]) .rail__form > .select {
  flex: 0 1 260px;
  min-width: 180px;
}

/* Ordenação é o controle mais estreito da faixa: o rótulo dela é curto
   ("Número: maior") e ela não precisa da largura de um filtro de situação, que
   carrega rótulo mais a contagem. Vem DEPOIS da regra acima de propósito — os
   dois seletores empatam em especificidade e quem decide é a ordem. */
:is(html[data-theme]) .rail__form > .select--compact {
  flex: 0 1 190px;
  min-width: 150px;
}

/* O rail é o contêiner que segura as seções da página (os `form-block`), então
   tem raio inteiro por padrão. Só quando encosta no header ele perde os cantos
   de cima, para os dois lerem como uma peça só — e perde a borda de cima junto:
   header e faixa são uma peça, e um traço entre eles a divide em duas. */
:is(html[data-theme]) .header + .rail {
  border-radius: 0 0 var(--radius-rail) var(--radius-rail);
}

/* A borda vem de `v2/surface.css`, que é a ÚLTIMA do bundle e empata em
   especificidade com a regra acima — no empate decide a ordem, e ela vence. Por
   isso o `.form-page`/`.list-page` no seletor: uma classe a mais é o que devolve
   a disputa. */
:is(html[data-theme]) :is(.form-page, .list-page) > .header + .rail {
  border-top: 0;
}

/* Empilha o conteúdo: uma barra de controles e/ou as seções da página. */
:is(html[data-theme]) .rail {
  display: grid;
  gap: var(--gap);
}

/* ---- descrição na faixa ---------------------------------------------------
 *
 * Uma linha apagada dizendo o que é o documento e o que se faz na tela, com a
 * volta para a lista no canto direito — o mesmo canto em que fica a ação
 * primária de toda tela do sistema.
 */
:is(html[data-theme]) .rail__description {
  color: var(--text-muted);
  flex: 1 1 auto;
  font-size: var(--text-size-base);
  margin: 0;
  min-width: 0;
  /* A descrição QUEBRA em telas estreitas em vez de truncar: um resumo de dados
     cortado ainda informa o que sobrou, mas uma frase cortada pela metade não
     diz nada. */
  max-width: 68ch;
}

/* O botão é empurrado para a direita pela sobra da linha, e não por uma ordem
   fixa: assim ele continua à direita mesmo quando o resumo não existe — que é o
   caso do termo ainda não salvo. */
:is(html[data-theme]) .rail__controls > .button:last-child {
  margin-left: auto;
}
/* <<< css/v2/rail.css <<< */

/* >>> css/v2/select.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/select.css` em 2026-08-20 — mesma história do picker: são as
 * declarações do componente do v2, que nasceram numa pasta com nome do sistema
 * antigo. O `cv-field*` e o `form-select` são emitidos pelo PRÓPRIO
 * `v2/form_field.html` e `v2/date_picker.html`.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ==========================================================================
   select.css
   Sistema global de select / multiselect
   Central de Viagens 3.0

   Componentes:
     .cv-select-wrapper      — wrapper de <select> nativo com seta customizada

   Tokens sao definidos aqui em :root e sobrescritos por tema.
   Nenhum hex de cor nas regras de componente — apenas tokens.
   ========================================================================== */

/* =========================================================
   01. Design Tokens — :root
   ========================================================= */

:root {
  /* Sizing */

  /* Colors — adapts to theme via tokens */
  --select-border:         var(--color-border-strong);
  --select-border-focus:   var(--color-primary);
  --select-focus-ring:     0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);

  /* Disabled */

  /* Error / Success */

}

/* =========================================================
   02. Theme overrides — Dark
   ========================================================= */

html[data-theme="dark"] {
  --select-border:         var(--theme-border-card);
}

/* =========================================================
   03. Theme overrides — Light
   ========================================================= */

html[data-theme="light"] {
  --select-border:         var(--color-border-strong);
}

/* =========================================================
   05. Global native select styling
   Todo <select> dentro de .main-form-panel e .list-panel
   recebe automaticamente o estilo do design system sem
   necessidade de alterar templates existentes.
   ========================================================= */

/* Native select em .main-form-panel: ver forms.css (gradiente --field-bg).
   List-panel mantém estilo legado abaixo. */

.list-panel select:not([class]),
.list-panel .form-select {
  appearance: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2352657a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")
    no-repeat right var(--space-3) center / 16px 16px,
    var(--color-card);
  border: 1px solid var(--select-border);
  border-radius: var(--radius-control);
  box-shadow: var(--shadow-xs);
  box-sizing: border-box;
  color: var(--color-text);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--font-size-sm);
  height: var(--control-height-md);
  padding: 0 calc(var(--space-6) + var(--space-2)) 0 var(--space-3);
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast);
  width: 100%;
}

.list-panel select:not([class]):focus,
.list-panel select:not([class]):focus-visible {
  outline: none;
}

/* ==========================================================================
   UI Lab clone — Custom Select Premium / Inline Action
   Fonte 1:1: static/css/dev/ui-lab-fields.css + templates/dev/ui_lab/selects_filters.html
   ========================================================================== */

:root {
  --field-padding-y: 0;
  --field-bg-hover: var(--theme-surface-card);
  --field-shadow-focus: 0 0 0 var(--space-1) var(--input-focus-ring), var(--shadow-xs);
  --field-error-bg: var(--color-danger-soft);
  --field-error-shadow: 0 0 0 var(--space-1) var(--color-danger-border-soft), var(--shadow-xs);
  /* NOVO-51: lia `var(--cv-field-border)`, que este mesmo bloco definia como
     `var(--theme-input-border)`. Aponta direto para a fonte, e nao para
     `--color-input-border`: no fallback sem JS os dois divergem, e a E7 nao
     mexe nessa camada (fica para a E8). */
  --select-border: var(--theme-input-border);
  --select-border-focus: var(--input-border-focus);
  --select-focus-shadow: var(--field-shadow-focus);
  --chip-bg: var(--color-primary-soft);
  --chip-border: var(--color-info-border-strong);
  --chip-color: var(--color-primary-strong);
  --option-selected-bg: var(--color-primary-soft);
  --cs-trigger-shadow: var(--shadow-sm);
  --cs-chevron-color: var(--theme-text-muted);
  --cs-menu-bg: var(--theme-surface-card);
  --cs-menu-border: var(--theme-border-card);
  --cs-menu-radius: var(--radius-control);
  --cs-option-selected-color: var(--color-primary);
  --cs-z-index: 200;
}

html[data-theme="dark"] {
  --field-bg-hover: var(--theme-surface-card-soft);
  --field-error-bg: var(--color-input-bg);
  --chip-bg: var(--color-info-bg);
  --chip-border: var(--color-info-border);
  --chip-color: var(--color-info-text);
  --option-selected-bg: var(--color-info-bg);
  --cs-trigger-shadow: none;
  --cs-option-selected-color: var(--color-info-text);
}

.cv-field {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.app-form-field .cv-field__label,
.cv-field__label {
  color: var(--color-label-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
}

.field-with-action {
  align-items: center;
  display: flex;
  gap: var(--space-2);
  min-width: 0;
}


.field-with-action .field-action {
  align-self: center;
  flex: 0 0 auto;
  height: var(--control-height-md);
  max-height: var(--control-height-md);
  min-height: var(--control-height-md);
}


/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/custom-select.css` em 2026-08-20.
 *
 * Esta parte NÃO é legado: são as declarações do próprio componente do v2, que
 * moravam numa pasta com nome do sistema antigo porque foi lá que nasceram. O
 * arquivo v2 carregava só o DELTA — e por isso apagar a pasta antiga teria
 * apagado o componente.
 *
 * A ordem foi preservada: base primeiro, delta depois, exatamente como os dois
 * bundles as entregavam.
 * ══════════════════════════════════════════════════════════════════════════ */

/* Custom select enhanced by static/js/components/picker-select.js. */

.custom-select {
  max-width: 100%;
  min-width: 0;
  position: relative;
  width: 100%;
}

.custom-select__native {
  clip: rect(0 0 0 0);
  height: 1px;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  position: absolute;
  width: 1px;
}

.custom-select__trigger {
  align-items: center;
  background:
    linear-gradient(var(--color-card), var(--color-card)) padding-box,
    linear-gradient(var(--select-border), var(--select-border)) border-box;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  box-shadow: var(--cs-trigger-shadow);
  box-sizing: border-box;
  color: var(--color-input-text);
  cursor: pointer;
  display: flex;
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  gap: var(--space-2);
  height: var(--control-height-md);
  max-width: 100%;
  min-height: var(--control-height-md);
  min-width: 0;
  padding: 0 var(--space-3);
  text-align: left;
  transition: background 150ms ease, box-shadow 150ms ease;
  width: 100%;
}

.custom-select__trigger:focus,
.custom-select__trigger:focus-visible {
  outline: none;
}

.custom-select--open:not(.custom-select--menu-portal) .custom-select__trigger {
  background:
    linear-gradient(var(--field-bg-hover), var(--field-bg-hover)) padding-box,
    linear-gradient(var(--select-border), var(--select-border)) border-box;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: none;
}

.custom-select__value {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.custom-select__value--placeholder {
  color: var(--color-input-placeholder);
}

.custom-select__chevron {
  align-items: center;
  color: var(--cs-chevron-color);
  display: flex;
  flex-shrink: 0;
  transition: color 150ms ease;
}

.custom-select__chevron svg {
  display: block;
  transition: transform 200ms ease;
}

.custom-select--open .custom-select__chevron {
  color: var(--cs-chevron-color);
}

.custom-select--open .custom-select__chevron svg {
  transform: rotate(180deg);
}

html[data-theme="dark"] .custom-select--v2 {
  --cs-chevron-color: var(--color-accent);
}

html[data-theme="dark"] .custom-select--v2 .custom-select__chevron,
html[data-theme="dark"] .custom-select--v2 .custom-select__chevron svg {
  color: var(--color-accent);
  stroke: currentColor;
}

@keyframes cv-cs-menu-enter {
  from { opacity: 0; transform: translateY(-4px) scaleY(0.97); }
  to   { opacity: 1; transform: translateY(0) scaleY(1); }
}

.custom-select__menu {
  --cs-menu-bg: var(--theme-surface-card);
  --cs-menu-border: var(--theme-border-card);
  --cs-menu-radius: var(--radius-control);
  animation: cv-cs-menu-enter 160ms ease both;
  background: var(--cs-menu-bg);
  border: 1px solid var(--select-border);
  border-top: none;
  border-radius: 0 0 var(--cs-menu-radius) var(--cs-menu-radius);
  box-shadow: var(--shadow-md);
  box-sizing: border-box;
  left: 0;
  list-style: none;
  margin: 0;
  max-height: 248px;
  min-width: 100%;
  overflow: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0;
  position: absolute;
  scrollbar-width: thin;
  top: 100%;
  transform-origin: top;
  width: 100%;
  z-index: var(--cs-z-index);
}

.custom-select__menu.floating-dropdown--active {
  background: var(--cs-menu-bg);
  border-radius: var(--cs-menu-radius);
  border-top: 1px solid var(--select-border);
  overflow: hidden;
  /* Portal no body: acima do modal, mesmo contrato do search-picker. */
  z-index: calc(var(--z-modal, 100) + 20);
}

.custom-select__menu::-webkit-scrollbar { width: 4px; }
.custom-select__menu::-webkit-scrollbar-track { background: transparent; }
.custom-select__menu::-webkit-scrollbar-thumb {
  background: var(--cs-menu-border);
  border-radius: 4px;
}

.custom-select__option {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-size: var(--font-size-sm);
  gap: var(--space-2);
  min-height: var(--control-height-sm);
  padding: var(--space-2) var(--space-3);
  transition: background 80ms ease;
  user-select: none;
}

.custom-select__option:first-child {
  border-top-left-radius: calc(var(--cs-menu-radius) - var(--space-1));
  border-top-right-radius: calc(var(--cs-menu-radius) - var(--space-1));
}

.custom-select__option:last-child {
  border-bottom-left-radius: calc(var(--cs-menu-radius) - var(--space-1));
  border-bottom-right-radius: calc(var(--cs-menu-radius) - var(--space-1));
}

.custom-select__option:hover:not(.custom-select__option--disabled) {
  background: var(--theme-list-row-hover);
}

.custom-select__option--focused {
  background: var(--theme-list-row-hover);
}

.custom-select__option--selected {
  background: var(--option-selected-bg);
  color: var(--cs-option-selected-color);
  font-weight: var(--font-weight-semibold);
}

.custom-select__option--selected:hover:not(.custom-select__option--disabled),
.custom-select__option--selected.custom-select__option--focused {
  background: var(--option-selected-bg);
  filter: brightness(0.97);
}

.custom-select__option--disabled {
  color: var(--color-input-placeholder);
  cursor: not-allowed;
  opacity: 0.55;
}

.custom-select__option-check {
  align-items: center;
  color: var(--color-primary);
  display: flex;
  flex-shrink: 0;
  opacity: 0;
  width: 16px;
}

.custom-select__option--selected .custom-select__option-check {
  opacity: 1;
}

.custom-select__option-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.custom-select--disabled .custom-select__trigger,
.custom-select__trigger:disabled {
  background:
    linear-gradient(var(--color-input-disabled-bg), var(--color-input-disabled-bg)) padding-box,
    linear-gradient(var(--select-border), var(--select-border)) border-box;
  color: var(--color-input-disabled-text);
  cursor: not-allowed;
  opacity: 0.7;
}

.custom-select--disabled .custom-select__chevron {
  opacity: 0.45;
}

.custom-select--error .custom-select__trigger {
  background:
    linear-gradient(var(--field-error-bg), var(--field-error-bg)) padding-box,
    linear-gradient(var(--color-danger-border-strong), var(--color-danger-border-strong)) border-box;
}

.custom-select--error.custom-select--open .custom-select__trigger {
  box-shadow: var(--field-error-shadow);
}

.custom-select--error .custom-select__chevron {
  color: var(--color-danger);
}

@media (max-width: 600px) {
  .custom-select__menu {
    max-height: 200px;
  }
}



/* ───────────────────────────────────────────────────────────────────────────
 * VINDAS DE `components/theme-shared-components.css`, em 2026-08-20.
 *
 * A folha inteira já era isto: o gatilho do select v2 descrito de fora dele.
 * Das 30 regras que ela tinha, a medição (33 telas, 23.034 elementos) mostrou
 * que só estas oito ainda pintavam algo — sem elas o gatilho recuperava a
 * sombra e o valor deixava de ser `flex`/centro em 32 casos.
 *
 * Entram ANTES da divisa `=== DELTA v2 ===` de propósito. Elas chegavam pelo
 * pacote do shell, que é anterior ao `ui.bundle.css`, e por isso PERDIAM para o
 * delta do v2; anexadas depois da divisa, inverteriam a disputa sem que uma
 * linha de valor mudasse. Foi assim que o menu do select voltou ao desenho
 * antigo na migração das folhas de lista.
 * ─────────────────────────────────────────────────────────────────────────── */


/* O gatilho do select v2 — e mais nada.
 *
 * A folha era a metade "vale nos dois temas" do redesenho: 30 regras sobre
 * ficha, rodapé de formulário, cartão de registro, faixa, linha de pessoa,
 * perna de itinerário e painel de coleção, todas descrevendo componentes DE
 * FORA deles.
 *
 * Em 2026-08-20 mediu-se o que elas ainda ganhavam (33 telas, 23.034 elementos,
 * com e sem a folha): 22 não mudavam um pixel. As 8 do select v2 mudavam —
 * o gatilho ganhava sombra de volta e o valor dentro dele deixava de ser
 * `flex`/centro em 32 casos —, e são as que ficaram.
 *
 * O nome do arquivo já não descreve o conteúdo: isto é `v2/select.css` fora de
 * lugar. A fusão é o passo seguinte, e não é mecânica — esta folha é a ÚLTIMA
 * do pacote do shell, e `v2/select.css` vem depois dele, no `ui.bundle.css`.
 * Mover as regras para lá as faria vencer disputas que hoje perdem. É a mesma
 * armadilha que inverteu o menu do select e o cabeçalho do bloco de formulário
 * na migração das folhas de lista; ali a saída foi inserir ANTES da divisa
 * `=== DELTA v2 ===`, e é isso que precisa ser medido aqui também.
 */
:is(html[data-theme])
  .custom-select__trigger--v2 {
  border-radius: 10px;
}

:is(html[data-theme])
  .custom-select__trigger--v2 {
  align-items: stretch;
  background: var(--color-input-bg);
  border: 1px solid var(--color-input-border);
  box-shadow: none;
  color: var(--color-text);
  gap: 0;
  min-height: var(--control-height-md);
  overflow: hidden;
  padding: 0;
  transition: border-color 120ms ease;
}

:is(html[data-theme])
  .custom-select__trigger--v2:focus,
:is(html[data-theme])
  .custom-select__trigger--v2:focus-visible {
  outline: none;
}

:is(html[data-theme])
  .custom-select__trigger--v2 .custom-select__value {
  align-items: center;
  display: flex;
  min-width: 0;
  padding: 0 14px;
}

/* Chevron v2: usa o accent da paleta em TODOS os estados. */
:is(html[data-theme])
  .custom-select--v2 {
  --cs-chevron-color: var(--color-accent);
}

:is(html[data-theme])
  .custom-select__trigger--v2 .custom-select__chevron,
:is(html[data-theme])
  .custom-select__trigger--v2:hover .custom-select__chevron,
:is(html[data-theme])
  .custom-select__trigger--v2:focus .custom-select__chevron,
:is(html[data-theme])
  .custom-select__trigger--v2:focus-visible .custom-select__chevron,
:is(html[data-theme])
  .custom-select__trigger--v2[aria-expanded="true"] .custom-select__chevron,
:is(html[data-theme])
  .custom-select--v2.custom-select--open .custom-select__chevron,
:is(html[data-theme])
  .custom-select--v2.custom-select--disabled .custom-select__chevron,
:is(html[data-theme])
  .list-header__rail .custom-select__trigger--v2 .custom-select__chevron {
  align-items: center;
  align-self: stretch;
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface-muted));
  color: var(--color-accent);
  display: inline-flex;
  justify-content: center;
  transform: none;
  transition: none;
  width: 44px;
}

:is(html[data-theme])
  .custom-select--v2.custom-select--open .custom-select__chevron svg,
:is(html[data-theme])
  .custom-select__trigger--v2[aria-expanded="true"] .custom-select__chevron svg {
  transform: rotate(180deg);
}

:is(html[data-theme])
  .custom-select--v2.custom-select--disabled .custom-select__trigger--v2,
:is(html[data-theme])
  .custom-select__trigger--v2:disabled {
  background: var(--color-surface-muted);
  border-color: var(--color-border-soft);
  box-shadow: none;
  opacity: 0.64;
}

:is(html[data-theme])
  .custom-select--v2.custom-select--error .custom-select__trigger--v2 {
  background: var(--color-input-bg);
  border-color: var(--color-danger);
  box-shadow: none;
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`: as asserções de
 * aparência do v2 descrevem ESTA metade. Medir o arquivo inteiro faria o teste
 * ler a regra base que o delta sobrescreve — foi o que aconteceu na fusão de
 * 2026-08-20, com sete asserções apontando para a declaração antiga da mesma
 * classe, três telas acima.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Select — gatilho e menu. Depende de `v2/tokens.css`.
 *
 * O gatilho e o menu são criados em tempo de execução por
 * `js/components/picker-select.js`. As classes `custom-select__*` pertencem ao
 * JS e NÃO são renomeadas aqui: renomear sem tocar o JS quebra em silêncio —
 * a página não dá erro, o componente só não inicializa.
 */

:is(html[data-theme]) .select {
  min-width: 0;
  position: relative;
}

/* O select nativo continua no DOM como fonte do valor enviado pelo formulário,
   mas o controle visível é o gatilho criado pelo renderer v2. */
:is(html[data-theme]) .select > .custom-select__native {
  display: none !important;
}

:is(html[data-theme]) .select .custom-select__trigger {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  display: flex;
  font: inherit;
  font-size: var(--text-size-base);
  gap: var(--gap-tight);
  justify-content: space-between;
  min-height: var(--control-height);
  padding: var(--pad-field);
  width: 100%;
}

:is(html[data-theme]) .select .custom-select__trigger:focus-visible {
  border-color: var(--focus-ring);
  outline: none !important;
}

/* A seta mora DENTRO do campo, sem caixa própria. O desenho legado a fazia um
   bloco de altura inteira com fundo separado (`align-items: stretch` no gatilho
   e `padding: 0`), o que dava ao select um aspecto de duas peças coladas — não
   de um campo comum. */
:is(html[data-theme]) .select .custom-select__trigger {
  align-items: center;
  overflow: visible;
  padding: var(--pad-field);
}

/* O rótulo não tem recuo próprio: o afastamento do texto é o padding do campo,
   igual ao do input. O desenho legado somava mais 14px aqui, e o texto do
   select ficava mais adentro que o de qualquer outro controle. */
:is(html[data-theme]) .select .custom-select__value {
  padding: 0;
}

/* Sem realce ao passar o mouse: o select é um campo, e campo não muda de cor
   sob o cursor — só sob o foco, quando acende a borda. */
:is(html[data-theme]) .select .custom-select__trigger:hover {
  background: var(--surface-contrast, var(--surface-field));
  border-color: transparent;
}

:is(html[data-theme]) .select .custom-select__chevron {
  align-items: center;
  background: none;
  border: 0;
  color: var(--text-muted);
  display: inline-flex;
  flex: none;
  /* Tamanho explícito: com `auto` o span colapsava para 0px e o
     `transform-origin` ia para o canto (0 0) — a seta girava descrevendo um
     arco em vez de rodar no lugar. */
  /* `align-self: center` precisa estar AQUI, no repouso, e não só nos estados:
     o legado põe `stretch`, e sem esta linha a seta ficava esticada no topo e
     só se centralizava ao passar o mouse — quando a regra de estado assumia. */
  align-self: center;
  color: var(--accent);
  height: 16px;
  justify-content: center;
  padding: 0;
  width: 16px;
}

/* Gira no PRÓPRIO eixo: `transform-origin: center` explícito, senão o
   navegador usa a caixa inteira do span e a seta descreve um arco em vez de
   girar no lugar. */
:is(html[data-theme]) .select .custom-select__chevron svg {
  /* `fill` e `stroke-width` precisam ser declarados AQUI: o SVG traz
     `fill="none"` e `stroke-width="2"` como atributos, e atributo de
     apresentação perde para qualquer regra CSS. Alguma folha legada preenchia
     o traçado de preto e afinava o traço para 1px — a seta virava um fiapo
     escuro, invisível sobre o campo. */
  color: var(--accent);
  display: block;
  fill: none;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  transform-origin: center;
  transition: transform 160ms ease;
  width: 16px;
}

:is(html[data-theme]) .select .custom-select__chevron svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

:is(html[data-theme]) .select.custom-select--open .custom-select__chevron svg {
  transform: rotate(180deg);
}


/* ---- os estados da seta ---------------------------------------------------
 *
 * `theme-shared-components.css:2696` devolve à seta o bloco de 44px com fundo
 * de accent em CADA estado — hover, foco, aberto. A variante `:hover` daquela
 * lista pesa 401 contra os 301 da regra de repouso daqui, e era por isso que o
 * desenho antigo reaparecia justamente sob o cursor.
 *
 * Esta regra cobre os mesmos estados com peso maior. Ela some quando o CSS
 * legado sair; é dívida da convivência, não desenho.
 */
:is(html[data-theme]) .select
  .custom-select__trigger:is(:hover, :focus, :focus-visible, [aria-expanded="true"])
  .custom-select__chevron,
:is(html[data-theme]) .select.custom-select--open .custom-select__chevron,
:is(html[data-theme]) .select.custom-select--disabled .custom-select__chevron {
  align-self: center;
  background: none;
  color: var(--accent);
  width: 16px;
}

/* A lista de opções não é descrita aqui: ela é o modelo global e vive em
   `v2/listbox.css`, compartilhada com o dropdown do picker. Descrevê-la em
   cada folha foi como as duas divergiram em quinze propriedades. */
/* <<< css/v2/select.css <<< */

/* >>> css/v2/listbox.css >>> */
/* Listbox — a lista de opções que cai de um campo. O MODELO GLOBAL.
 *
 * Duas listas existem no sistema e são a mesma coisa para quem usa: o menu do
 * select (`custom-select__menu--v2`, criado por `picker-select.js`) e o
 * dropdown do picker (`search-picker__dropdown--v2`, criado por `picker.js`).
 * Os nomes das classes são dos dois motores JS e não se renomeiam aqui.
 *
 * ## Por que uma folha só
 *
 * Enquanto cada componente descrevia a sua lista na própria folha, elas
 * divergiram em quinze propriedades ao mesmo tempo — raio, recuo, altura do
 * item, peso e cor do rótulo, sombra, fita da escolhida, animação de entrada,
 * barra de rolagem — e a mesma escolha aparecia de dois jeitos na mesma tela.
 * Nenhuma divergência foi decidida: todas nasceram de uma folha declarar o que
 * a outra não declarava, deixando o legado preencher a lacuna.
 *
 * Aqui os dois seletores andam SEMPRE juntos, em todas as regras. Mexer numa
 * lista sem mexer na outra deixou de ser possível por construção, e não por
 * disciplina — `core/tests/test_listbox_unico.py` reprova quem tentar.
 *
 * As folhas dos componentes ficam com o que é só delas: o gatilho e a seta no
 * `select.css`, o campo de busca e as peças que o picker cria a mais no
 * `picker.css`.
 */

/* ---- a caixa --------------------------------------------------------------
 *
 * Ela é movida para o `body` ao abrir, então NÃO herda nada do campo: sem
 * ancestral comum, `--surface-contrast` não chega até aqui. Por isso as cores
 * vêm dos tokens diretamente.
 *
 * A altura da opção é declarada, não deduzida do conteúdo: é ela que define
 * quantos itens cabem, e o teto é um múltiplo exato dela. Sem isso o corte
 * cairia no meio de uma linha.
 *
 * A segunda e a quarta linha de seletor empatam com as regras legadas, que
 * qualificam a lista aberta com `.floating-dropdown--active` e por isso venciam
 * por uma classe. No empate decide a ordem, e o `ui.bundle.css` entra depois do
 * bundle legado.
 */


/* ═══════════════════════════════════════════════════════════════════════════
 * VINDAS DAS FOLHAS DE TEMA E DO CASCO ANTIGO, em 2026-08-20.
 *
 * Descreviam este componente DE FORA dele — em `theme-shared-components.css`,
 * `theme-dark-components.css`, `layout/page-shell.css`, `fields/forms.css` ou
 * `lists/list-header.css`. Enquanto ficaram lá, o componente do v2 dependia de
 * folhas do sistema antigo para ter forma, e toda tela migrada carregava
 * aquelas folhas por causa dele.
 *
 * Vieram com o texto INTACTO — `!important` e escopo de wizard inclusive —, e
 * ANTES da divisa: elas chegavam pelo bundle do shell, que é anterior ao
 * `ui.bundle.css`, e por isso perdiam para o delta do v2. Anexá-las no fim
 * inverteria a disputa sem mudar um valor sequer. Medido antes e depois em 20
 * telas: nenhuma diferença.
 * ═══════════════════════════════════════════════════════════════════════════ */

:is(html[data-theme])
  :is(.search-picker__option:first-child, .search-picker__option:last-child) {
  border-radius: 10px;
}

:is(html[data-theme])
  .search-picker__option-marker {
  display: none;
}

:is(html[data-theme])
  .search-picker__option-content {
  align-content: center;
  gap: 3px;
}

@media (max-width: 600px) {
:is(html[data-theme])
    .search-picker__option {
    grid-template-columns: 36px minmax(0, 1fr);
    min-height: 56px;
    padding: 8px;
  }

:is(html[data-theme])
    .search-picker__option-visual {
    height: 36px;
    width: 36px;
  }

:is(html[data-theme])
    .search-picker__option-status {
    display: none;
  }
}

:is(html[data-theme])
  .custom-select__menu--v2 {
  --cs-menu-bg: var(--color-input-bg);
  animation: none;
  background: var(--color-input-bg);
  border: 1px solid var(--color-border-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-custom-select-menu);
  max-height: 260px;
  padding: 6px;
  scrollbar-color: var(--color-border-strong) transparent;
  scrollbar-width: thin;
  top: calc(100% + 6px);
}

:is(html[data-theme])
  .custom-select__menu--v2.floating-dropdown--active {
  background: var(--surface-field);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-color: var(--color-border-strong) transparent;
  scrollbar-width: thin;
  translate: 0 6px;
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar {
  width: 14px;
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-track,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-track-piece {
  background: transparent;
  border: none;
  box-shadow: none;
  margin-block: 8px;
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-thumb {
  background-clip: padding-box;
  background-color: var(--color-border-strong);
  border: 4px solid transparent;
  border-radius: var(--radius-pill);
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-thumb:hover {
  background-color: color-mix(in srgb, var(--color-muted) 55%, transparent);
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button:single-button,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button:start:decrement,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button:end:increment,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button:vertical:start:decrement,
:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-button:vertical:end:increment {
  background: transparent;
  border: none;
  display: none;
  height: 0;
  width: 0;
}

:is(html[data-theme])
  .custom-select__menu--v2::-webkit-scrollbar-corner {
  background: transparent;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option {
  border-radius: 8px;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option {
  color: var(--color-muted-strong);
  gap: 10px;
  margin: 2px 0;
  min-height: 40px;
  padding: 0 10px 0 12px;
  transition: background-color 100ms ease, color 100ms ease;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option:hover:not(.custom-select__option--disabled),
:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option--focused {
  background: var(--color-surface-soft);
  color: var(--color-heading);
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option--selected {
  background: color-mix(in srgb, var(--color-accent) 10%, var(--color-surface-soft));
  box-shadow: inset 3px 0 0 var(--color-accent);
  color: var(--color-heading);
  font-weight: var(--font-weight-bold);
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option--selected:hover:not(.custom-select__option--disabled),
:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option--selected.custom-select__option--focused {
  background: color-mix(in srgb, var(--color-accent) 16%, var(--color-surface-soft));
  box-shadow: inset 3px 0 0 var(--color-accent);
  color: var(--color-heading);
  filter: none;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option-check {
  border-radius: 7px;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option-check {
  align-items: center;
  background: var(--color-accent);
  color: var(--color-on-accent);
  height: 26px;
  justify-content: center;
  margin-left: auto;
  order: 2;
  width: 26px;
}

:is(html[data-theme])
  .custom-select__menu--v2 .custom-select__option-label {
  order: 1;
}

@media (max-width: 600px) {
:is(html[data-theme])
    .custom-select__menu--v2 {
    max-height: 220px;
  }
}

html[data-theme="dark"] :is(.custom-select__menu, .search-picker__dropdown, .date-picker__popover) {
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-elevated);
}

html[data-theme="dark"] :is(.custom-select__option:hover, .custom-select__option--focused, .search-picker__option:hover, .search-picker__option--active) {
  background: var(--color-surface-soft);
}

html[data-theme="dark"] :is(.custom-select__option--selected, .search-picker__option--selected) {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-hover);
  color: var(--color-white);
}

html[data-theme="dark"] :is(.custom-select__option--selected:hover, .custom-select__option--selected.custom-select__option--focused, .search-picker__option--selected:hover) {
  background: color-mix(in srgb, var(--color-primary-hover) 35%, var(--color-primary-dark));
  border-color: var(--color-primary-hover);
  color: var(--color-white);
}

:is(html[data-theme="dark"])

:is(html[data-theme="dark"])

:is(html[data-theme="dark"])
  .search-picker__dropdown {
  background: var(--color-surface-strong);
  border: 1px solid var(--color-border-strong);
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(2, 9, 16, 0.48);
  padding: 6px;
}

:is(html[data-theme="dark"])
  .search-picker__dropdown.floating-dropdown--active {
  background: var(--color-surface-strong);
  border-color: var(--color-border-strong);
  border-radius: 14px;
  overflow: hidden;
  padding: 6px;
  z-index: calc(var(--z-modal, 100) + 20);
}

:is(html[data-theme="dark"])
  .search-picker__option {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: 10px;
  box-shadow: none;
  column-gap: 12px;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  min-height: 62px;
  padding: 9px 11px;
  text-align: left;
  transform: none;
}

:is(html[data-theme="dark"])
  .search-picker__option:hover,
:is(html[data-theme="dark"])
  .search-picker__option--active {
  background: color-mix(in srgb, var(--color-surface-elevated) 72%, var(--color-input-bg) 28%);
  border: 0;
  box-shadow: none;
  transform: none;
}

:is(html[data-theme="dark"])
  .search-picker__option--selected,
:is(html[data-theme="dark"])
  .search-picker__option--selected:hover,
:is(html[data-theme="dark"])
  .search-picker__option--selected.search-picker__option--active {
  background: color-mix(in srgb, var(--color-accent) 12%, var(--color-input-bg));
  border: 0;
  box-shadow: inset 3px 0 0 var(--color-accent);
}

:is(html[data-theme="dark"])
  .search-picker__option-visual {
  align-items: center;
  align-self: center;
  background: var(--color-input-bg);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  color: var(--color-accent-text);
  display: inline-grid;
  font-size: 0.7rem;
  font-weight: var(--font-weight-black);
  height: 40px;
  justify-content: center;
  letter-spacing: 0.02em;
  width: 40px;
}

:is(html[data-theme="dark"])
  .search-picker__option--vehicle .search-picker__option-visual {
  border-radius: 9px;
  color: var(--color-muted-strong);
}

:is(html[data-theme="dark"])
  .search-picker__option--selected .search-picker__option-visual {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}

:is(html[data-theme="dark"])
  .search-picker__option-main {
  color: var(--color-heading);
  font-size: 0.86rem;
  font-weight: var(--font-weight-black);
  line-height: 1.25;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

:is(html[data-theme="dark"])
  .search-picker__option-meta {
  color: var(--color-muted-strong);
  display: -webkit-box;
  font-size: 0.74rem;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

:is(html[data-theme="dark"])
  .search-picker__option-status {
  align-items: center;
  color: var(--color-muted);
  display: inline-flex;
  font-size: 0.68rem;
  font-weight: var(--font-weight-bold);
  justify-content: flex-end;
  min-width: 70px;
  white-space: nowrap;
}

:is(html[data-theme="dark"])
  .search-picker__option--selected .search-picker__option-status {
  color: var(--color-accent-text);
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho da lista de opções.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`. Acima dela entram as
 * regras que vieram das folhas do sistema antigo (2026-08-20); ficam ANTES de
 * propósito, para continuarem perdendo para o v2 exatamente como perdiam quando
 * moravam no shell. Ordem é metade da cascata: mover uma regra para depois é
 * mudá-la de valor sem tocar no valor.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

:is(html[data-theme]) .custom-select__menu--v2,
:is(html[data-theme]) .custom-select__menu--v2.floating-dropdown--active,
:is(html[data-theme]) .search-picker__dropdown--v2,
:is(html[data-theme]) .search-picker__dropdown--v2.floating-dropdown--active {
  --listbox-option-height: 40px;
  --listbox-option-gap: 8px;
  --listbox-padding: 6px;
  --listbox-border: 1px;

  /* Sem animação de entrada: uma das duas listas surgindo com deslize e a outra
     aparecendo direto era diferença visível entre elas. */
  animation: none;
  /* A caixa fica na cor do PAINEL e o realce na do campo — invertido em relação
     à primeira versão. Aberta sobre um formulário, a lista na cor do campo
     virava mais uma faixa igual às que já estão na tela; na cor do painel ela
     lê como uma camada que veio por cima, e o item sob o cursor é que sobe. */
  background: var(--surface-rail);
  border: var(--listbox-border) solid var(--line);
  border-radius: var(--radius-field);
  box-shadow: var(--shadow-menu);
  box-sizing: border-box;
  display: grid;
  /* Cinco itens INTEIROS, os quatro vãos entre eles e mais um vão de respiro
     abaixo do quinto — que é o que denuncia a existência do sexto.

     A BORDA entra na conta: com `box-sizing: border-box` o `max-height` a
     inclui, e omiti-la encurtava a área útil em 2px — o respiro caía de 8 para
     6 e o corte subia. */
  max-height: calc(
    var(--listbox-option-height) * 5 + var(--listbox-option-gap) * 4 +
      var(--listbox-padding) * 2 + var(--listbox-border) * 2
  );
  /* Descola do campo: o módulo de posicionamento cola a caixa com folga zero. */
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--listbox-padding);
  row-gap: var(--listbox-option-gap);
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}

/* O picker tem um invólucro a mais entre a caixa e as opções; o select não.
 * Ele SÓ distribui os itens — teto, rolagem e recuo são da caixa nos dois.
 *
 * As três anulações não são zelo: a folha legada dá a este invólucro
 * `max-height` e `overflow` próprios e, no tema claro, ainda um `padding`. Com
 * a caixa também rolando, apareciam duas barras de rolagem e recuo dobrado. */
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__list {
  display: grid;
  max-height: none;
  overflow: visible;
  padding: 0;
  row-gap: var(--listbox-option-gap);
}

/* ---- o item ---------------------------------------------------------------
 *
 * `min-width: 0` porque item de grade não encolhe abaixo do próprio
 * `min-content`: com ícone, vão, rótulo e recuo somando 162px numa faixa de
 * 140, ele transbordava e o `overflow` da caixa cortava. Assim o rótulo trunca.
 *
 * `margin: 0` porque a folha legada põe margem no item, que SOMARIA ao
 * `row-gap` e tornaria indeterminada a conta do teto acima. Uma origem só.
 *
 * `min-height` além de `height` porque o legado impõe `min-height: 62px` ao
 * item do picker, e `min-height` vence `height`.
 */
:is(html[data-theme]) .custom-select__menu--v2 .custom-select__option,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option {
  align-items: center;
  background: none;
  border: 0;
  border-radius: 6px;
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  display: flex;
  font: inherit;
  font-size: var(--text-size-base);
  gap: var(--gap-tight);
  height: var(--listbox-option-height);
  margin: 0;
  min-height: var(--listbox-option-height);
  min-width: 0;
  padding: 0 8px 0 12px;
  text-align: left;
  transition: background-color 0.1s ease, color 0.1s ease;
  user-select: none;
  width: 100%;
}

/* Realce: um degrau na escada de superfícies, nunca mistura de matiz.
 *
 * O `:not(--selected)` é o que torna isso possível. Antes de a escolhida ganhar
 * cor própria, as duas usavam `--surface-rail` e ficavam idênticas assim que o
 * mouse passava em outra linha; a exclusão diz explicitamente que o realce não
 * alcança a escolhida, em vez de depender da ordem das regras. */
:is(html[data-theme]) .custom-select__menu--v2
  .custom-select__option:hover:not(.custom-select__option--selected),
:is(html[data-theme]) .custom-select__menu--v2
  .custom-select__option--focused:not(.custom-select__option--selected),
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option:hover:not(.search-picker__option--selected),
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option--active:not(.search-picker__option--selected) {
  background: var(--surface-field);
  color: var(--text-strong);
}

/* ---- a opção escolhida ----------------------------------------------------
 *
 * Cor própria (`--surface-selected`), mantida em qualquer combinação: sozinha,
 * sob o mouse ou com o foco do teclado. Não é um degrau da escada de propósito
 * — "escolhida" é significado, não profundidade; como degrau, ela empatava com
 * o realce e desaparecia.
 *
 * As formas repetem exatamente as que as folhas legadas usam
 * (`--selected`, `--selected:hover:not(--disabled)`, `--selected.--focused`).
 * Sem repeti-las, aquelas regras venciam por terem uma classe a mais e a
 * escolhida voltava a mudar de cor conforme o mouse.
 */
:is(html[data-theme]) .custom-select__menu--v2 .custom-select__option--selected,
:is(html[data-theme]) .custom-select__menu--v2
  .custom-select__option--selected:hover:not(.custom-select__option--disabled),
:is(html[data-theme]) .custom-select__menu--v2
  .custom-select__option--selected.custom-select__option--focused,
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option--selected,
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option[aria-selected="true"] {
  background: var(--surface-selected);
  /* A fita lateral que marca a escolhida, com o accent do tema. Vinha de uma
     regra legada que alcançava uma lista e não a outra. */
  box-shadow: inset 3px 0 0 0 var(--accent);
  color: var(--accent);
  font-weight: var(--weight-strong);
}

/* ---- o rótulo -------------------------------------------------------------
 *
 * `inherit` nos três: cor, peso e corpo vêm do item. A folha legada pintava o
 * rótulo do picker de branco, com peso 900 e 13.76px, e era isso que mantinha
 * as duas listas diferentes mesmo com a caixa e o item já idênticos — a linha
 * escolhida saía dourada num e branca no outro.
 *
 * O rótulo trunca em vez de empurrar o item para fora da caixa.
 */
:is(html[data-theme]) .custom-select__menu--v2 .custom-select__option-label,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-content,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-main {
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- o "v" da escolhida ---------------------------------------------------
 *
 * O select o traz num span próprio; no picker o `picker.js` o põe no span que
 * antes repetia "Selecionado" em toda linha. Os dois ficam à direita, em
 * accent, com o mesmo traço.
 */
:is(html[data-theme]) .custom-select__menu--v2 .custom-select__option-check,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-status {
  align-items: center;
  background: none;
  color: var(--accent);
  display: inline-flex;
  flex: none;
  margin-left: auto;
}

:is(html[data-theme]) .custom-select__menu--v2 .custom-select__option-check svg,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-status svg {
  display: block;
  fill: none;
  height: 14px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.5;
  width: 14px;
}

/* O picker cria duas peças por opção que o select não tem: um marcador vazio e
   um ponto decorativo. A lista padrão mostra o rótulo e o "v", nada mais. */
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-marker,
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-visual {
  display: none;
}

/* ---- variação de DUAS LINHAS ----------------------------------------------
 *
 * Servidor e viatura não cabem em uma linha: "AAA-1234 - DUSTER" sozinho não
 * distingue três Dusters idênticas, e é o combustível, a caracterização e a
 * unidade que decidem qual é qual. O mesmo vale para o servidor, onde cargo e
 * unidade desempatam homônimos.
 *
 * A variação NÃO é do select: só o `picker.js` produz a segunda linha
 * (`search-picker__option-meta`). Exigir simetria aqui seria exigir markup que
 * não existe do outro lado — é a mesma exceção já aberta para o invólucro e as
 * peças decorativas em `test_listbox_unico`.
 *
 * O gatilho é a PRESENÇA da segunda linha, não o nome da apresentação:
 * `picker.js` monta `--meta` sempre que o item traz um segundo texto, inclusive
 * fora de "people"/"vehicle". Ligar a regra ao nome deixaria de fora casos que
 * já são de duas linhas hoje.
 */
:is(html[data-theme]) .search-picker__dropdown--v2:has(.search-picker__option-meta),
:is(html[data-theme]) .search-picker__dropdown--v2.floating-dropdown--active:has(.search-picker__option-meta) {
  /* A altura do item é o que fecha a conta do teto de cinco. Trocá-la aqui, e
     não no item, mantém corte e rolagem coerentes com a lista de uma linha.

     52px, e não 56: as duas linhas somam 35px e o recuo vertical fecha em 51.
     Com 56 sobravam 21px de vão morto e o texto boiava dentro da faixa — de
     longe a lista parecia uma fileira de barras vazias com letra no meio. */
  --listbox-option-height: 52px;
}

/* O vão entre a âncora e o texto acompanha o vertical. Com 8px na horizontal e
   uma faixa de 52 na vertical, o item ficava apertado de um lado e frouxo do
   outro — e é essa discordância que se lê como desalinho. */
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option:has(.search-picker__option-meta) {
  gap: var(--gap);
  padding-left: 8px;
}

/* A primeira linha LIDERA. Nas duas listas de uma linha o rótulo herda o peso
   do item, para as duas serem idênticas; aqui ele precisa se separar da linha
   de apoio, e cor e corpo sozinhos não bastavam — as duas liam como um bloco
   cinza só. A escolhida continua se distinguindo pelo accent e pela fita. */
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option:has(.search-picker__option-meta) .search-picker__option-main {
  font-weight: var(--weight-strong);
  line-height: 1.25;
}

/* As duas linhas empilham; o `min-width: 0` é o que permite as duas truncarem
   em vez de esticar o item para fora da caixa. */
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option:has(.search-picker__option-meta) .search-picker__option-content {
  display: grid;
  gap: 2px;
  min-width: 0;
  overflow: visible;
  white-space: normal;
}

:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__option-meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-base, 400);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A segunda linha NÃO acompanha o accent da escolhida: ela é o dado de apoio,
   e pintá-la junto faz a linha inteira gritar e o rótulo perder o destaque. */
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option--selected .search-picker__option-meta,
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option[aria-selected="true"] .search-picker__option-meta {
  color: var(--text-muted);
}

/* A âncora de varredura: iniciais do servidor, "V" da viatura. Mesma caixa do
   avatar da faixa de equipe, para as duas telas lerem como o mesmo sistema.
   Só aparece onde há identidade — no item genérico o `picker.js` põe um "•",
   que é ruído. */
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option--person .search-picker__option-visual,
:is(html[data-theme]) .search-picker__dropdown--v2
  .search-picker__option--vehicle .search-picker__option-visual {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: var(--radius-field);
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  /* 36px: a altura das DUAS linhas de texto. Nos 28px do controle miúdo ela
     ficava do tamanho de uma linha só, ao lado de um bloco com o dobro da
     altura — parecia um selo perdido, e não a âncora da faixa. */
  height: 36px;
  justify-content: center;
  width: 36px;
}

/* O vazio ocupa uma OPÇÃO: mesma altura, mesmo raio, mesmo recuo lateral. Solto
   na caixa ele ficava sem caixa nenhuma e com recuos diferentes em cima e
   embaixo — o de cima vinha do `padding` da própria lista, o de baixo do dele.
   Como opção, a caixa não muda de forma quando a busca deixa de achar. */
:is(html[data-theme]) .search-picker__dropdown--v2 .search-picker__empty {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: 6px;
  box-sizing: border-box;
  color: var(--text-muted);
  display: flex;
  font-size: var(--text-size-base);
  justify-content: center;
  margin: 0;
  min-height: var(--listbox-option-height);
  padding: 0 12px;
  text-align: center;
}
/* <<< css/v2/listbox.css <<< */

/* >>> css/v2/toggle.css >>> */
/* Toggle — alterna entre duas ou três vistas da mesma lista.
 *
 * Duas variantes, porque a semântica difere de verdade:
 *   `--nav`    segmentos são LINKS  -> ativo por `aria-current="page"`
 *   `--state`  segmentos são BOTÕES -> ativo por `aria-pressed="true"`
 *
 * Link não aceita `aria-pressed`. Foi essa confusão que, no sistema antigo,
 * fazia o hover cair justamente sobre o item já ativo.
 *
 * Uma peça de fora usa as MESMAS regras, por seletor adicional em vez de valores
 * repetidos na folha dela: as pílulas de formato e saída do seletor de download,
 * que são `<label>` com `<input type="radio">` dentro — o ativo é
 * `:has(input:checked)`, não `aria-pressed`, porque quem guarda o estado é o
 * rádio.
 *
 * O seletor de tipo do anexar assinado não aparece aqui: em vez de ensinar esta
 * folha a classe que o JS criava, o JS passou a criar os segmentos JÁ como
 * `toggle__item` quando o grupo é este toggle.
 *
 * `--sm` é o tamanho pequeno, para toggle que AJUSTA e não navega.
 * `--fill` ocupa a linha inteira e reparte os segmentos em colunas IGUAIS — para
 * quando o toggle é a escolha da vez (o tipo de documento a anexar, por exemplo)
 * e não um filtro ao lado de outra coisa. Colunas iguais e não `flex: 1`: com
 * `flex` cada segmento cresce a partir do próprio texto, e "Diário" ficava menor
 * que "Viatura".
 */

:is(html[data-theme]) .toggle {
  align-items: center;
  /* Segue a escada: o toggle é um controle, então assume o degrau oposto ao do
     contêiner, igual ao campo e ao select. Lia `--ui-surface`, variável do
     sistema v1 que nunca chega aqui — na prática ficava sempre no fallback. */
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: inline-flex;
  gap: 2px;
  padding: 3px;
}

:is(html[data-theme]) .toggle--fill {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
}

/* Com o segmento maior que o texto, o rotulo tem de ir para o MEIO dele: alinhado
   a esquerda (padrao do flex), tres colunas iguais pareciam tres textos soltos com
   uma faixa colorida atras de um deles. */
:is(html[data-theme]) .toggle--fill .toggle__item {
  justify-content: center;
}

:is(html[data-theme]) .toggle--sm {
  --toggle-item-height: 26px;
  --toggle-item-padding: 10px;
  --toggle-item-size: var(--text-size-eyebrow);
  padding: 2px;
}

:is(html[data-theme]) .toggle__item {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: var(--toggle-item-size, var(--text-size-base));
  gap: 6px;
  min-height: var(--toggle-item-height, 34px);
  padding: 0 var(--toggle-item-padding, 14px);
  text-decoration: none;
  white-space: nowrap;
}

/* Três formas de dizer "este é o escolhido", porque três tipos de elemento
   vivem aqui: link de navegação (`aria-current`), botão de estado
   (`aria-pressed`), rádio dentro de label (`:checked`) — e a ABA de um
   `tablist`, que por especificação usa `aria-selected` (a origem das pastas do
   Drive). */
:is(html[data-theme]) .toggle__item[aria-current="page"],
:is(html[data-theme]) .toggle__item[aria-pressed="true"],
:is(html[data-theme]) .toggle__item[aria-selected="true"],
:is(html[data-theme]) .toggle__item:has(input:checked) {
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: var(--weight-strong);
}

/* O ativo declara o hover junto: sem isso o realce do inativo pinta por cima
   dele e o estado desaparece justamente onde importa. */
:is(html[data-theme]) .toggle__item[aria-current="page"]:hover,
:is(html[data-theme]) .toggle__item[aria-pressed="true"]:hover,
:is(html[data-theme]) .toggle__item:has(input:checked):hover {
  background: var(--accent);
  color: var(--text-on-accent);
}

:is(html[data-theme]) .toggle__item:hover:not([aria-current="page"]):not([aria-pressed="true"]):not(:has(input:checked)) {
  background: var(--surface, var(--surface-rail));
  color: var(--text-strong);
}

/* O contador herda a cor do segmento, então serve aos dois estados sem regra
   por estado. */
:is(html[data-theme]) .toggle__count {
  background: color-mix(in srgb, currentColor 16%, transparent);
  border-radius: var(--radius-pill);
  font-size: var(--text-size-eyebrow);
  min-width: 18px;
  padding: 2px 6px;
  text-align: center;
}
/* <<< css/v2/toggle.css <<< */

/* >>> css/v2/chip.css >>> */
/* Chip — o selo de estado (status, contagem, marcador).
 *
 * COLISÃO: `.chip` já existe no legado (7 usos). Usa `--v2` até a migração.
 *
 * O estilo é o tom TRANSLÚCIDO sobre a superfície, escolhido entre quatro
 * alternativas testadas na galeria (sólido, pastel, translúcido e brilhante).
 * É o único que se adapta ao fundo: os outros três fixavam a mistura no branco
 * ou no preenchimento cheio, e um deles precisava de valores diferentes por
 * tema para não desaparecer.
 *
 * A cor vem por `--chip-tone`, declarada por quem usa; sem tom, o chip é
 * neutro. NÃO existe uma classe por cor — era assim que nasciam as 18
 * variantes do botão legado, das quais 8 acabaram mortas.
 */

:is(html[data-theme]) .chip--v2 {
  align-items: center;
  background: color-mix(in srgb, var(--chip-tone, var(--text-muted)) 16%, transparent);
  border-radius: var(--radius-pill);
  color: var(--chip-tone, var(--text-muted));
  display: inline-flex;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  gap: 4px;
  padding: 3px 10px;
  white-space: nowrap;
}


/* O chamador nomeia o estado; o sistema decide a cor. */
:is(html[data-theme]) .chip--v2[data-tone="done"] {
  --chip-tone: var(--status-done);
}

:is(html[data-theme]) .chip--v2[data-tone="progress"] {
  --chip-tone: var(--status-progress);
}

:is(html[data-theme]) .chip--v2[data-tone="late"] {
  --chip-tone: var(--status-late);
}

:is(html[data-theme]) .chip--v2[data-tone="info"] {
  --chip-tone: var(--status-info);
}

:is(html[data-theme]) .chip--v2[data-tone="success"] {
  --chip-tone: var(--status-done);
}

:is(html[data-theme]) .chip--v2[data-tone="pending"] {
  --chip-tone: var(--status-progress);
}

:is(html[data-theme]) .chip--v2[data-tone="warning"],
:is(html[data-theme]) .chip--v2[data-tone="danger"] {
  --chip-tone: var(--status-late);
}

:is(html[data-theme]) .chip--v2[data-tone="entity"],
:is(html[data-theme]) .chip--v2[data-tone="neutral"],
:is(html[data-theme]) .chip--v2[data-tone="muted"] {
  --chip-tone: var(--text-muted);
}
/* <<< css/v2/chip.css <<< */

/* >>> css/v2/panel.css >>> */
/* Panel — a superfície que agrupa uma lista ou um conjunto de blocos. */

:is(html[data-theme]) .panel {
  --surface-contrast: var(--surface-field);
  background: var(--surface, var(--surface-rail));
  border-radius: var(--radius-rail);
  box-sizing: border-box;
  display: grid;
  /* O vão entre registros é o mesmo `--gap` do recuo interno deles: a distância
     ENTRE itens e a distância DENTRO do item ficam no mesmo ritmo. */
  gap: var(--gap);
  min-width: 0;
  padding: var(--gap);
}

/* O `gap` do painel separa cabeçalho, corpo e rodapé — mas o CORPO é um único
   filho, então os blocos DENTRO dele não herdavam vão nenhum e encostavam um no
   outro (dois `form_block` empilhados liam como um bloco só, de duas cabeças).
   O corpo repete a grade do painel para que a distância entre blocos seja a
   mesma distância entre as seções. */
:is(html[data-theme]) .panel__body {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* NOTA (2026-08-16): por algumas horas o painel de cartões ficou transparente,
   para acabar com a sensação de moldura dupla. Voltou a ser caixa: o que causava
   a moldura dupla não era o painel, era o CARTÃO ter ganhado cor de caixa e
   contorno próprio ao mesmo tempo. Corrigida a escada (o cartão é o degrau
   `field`, sem borda), uma caixa só desenha o grupo e as linhas sobem um degrau
   dentro dela — que é o desenho do sistema desde o começo. */
:is(html[data-theme]) .panel__empty {
  color: var(--text-muted);
  display: grid;
  gap: var(--gap-tight);
  justify-items: center;
  padding: var(--gap-loose) 0;
  text-align: center;
}

/* O `display` acima vence o `[hidden]`, que é regra de agente do usuário — e o
   vazio de filtro NASCE oculto. Sem este guarda ele aparece embaixo da lista
   cheia, dizendo que não há nada logo abaixo de tudo o que há. */
:is(html[data-theme]) .panel__empty[hidden] {
  display: none;
}

:is(html[data-theme]) .panel__empty-title {
  color: var(--text-strong);
  font-size: var(--text-size-title);
  font-weight: var(--weight-strong);
  margin: 0;
}

/* Cabeçalho da seção — mesma tipografia do `form_block`, para o título de uma
   seção e o de um bloco lerem como a mesma família. */
:is(html[data-theme]) .panel__header {
  align-items: baseline;
  display: flex;
  gap: var(--gap);
  justify-content: space-between;
  min-width: 0;
}

/* Cabeçalhos com ação de ícone alinham o conjunto título + descrição pelo
   centro do botão, em vez de tentar compartilhar uma linha de base que o
   botão circular não possui. */
:is(html[data-theme]) .panel__header--centered {
  align-items: center;
}

:is(html[data-theme]) .panel__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .panel__description {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

:is(html[data-theme]) .panel__actions {
  align-items: center;
  display: flex;
  flex: none;
  gap: var(--gap-tight);
}

/* Na etapa de planejamento do evento, os dois painéis são irmãos diretos da
   página. O segundo repete o ritmo global entre seções sem alterar os demais
   painéis do wizard. */
:is(html[data-theme]) .evento-planning-panel + .evento-planning-panel {
  margin-top: var(--gap);
}

/* A faixa do vazio de FILTRO, quando a lista não tem painel envolvente: é um
   painel sem miolo, e nasce oculta. O par `[hidden]` é obrigatório porque o
   `display: grid` do `.panel` vence a regra de agente do usuário — sem ele a
   faixa aparece embaixo da lista cheia, dizendo que não há nada logo abaixo de
   tudo o que há. */
:is(html[data-theme]) .panel--empty-band[hidden] {
  display: none;
}
/* <<< css/v2/panel.css <<< */

/* >>> css/v2/alert.css >>> */
/* Alert — a pilha de mensagens. Depende de `v2/tokens.css`.
 *
 * O tom vem de `data-tone`, com os MESMOS tokens de estado do chip: uma
 * mensagem de sucesso e um selo "Concluído" são a mesma informação em formatos
 * diferentes, e precisam da mesma cor.
 */

:is(html[data-theme]) .alert-stack {
  display: grid;
  gap: var(--gap-tight);
}

:is(html[data-theme]) .alert {
  /* Mesma fórmula do chip: o tom a 16% sobre TRANSPARENTE, não sobre a
     superfície. Misturar com transparente deixa o fundo da camada aparecer por
     baixo, então o resultado se adapta aos dois temas sozinho.
     
     Foi isso que apagou a única regra do v2 com valor por tema: a versão
     anterior misturava com `--surface-field` e sujava no escuro — amarelo e
     vermelho perdiam o tom esperado, conforme medição. */
  background: color-mix(in srgb, var(--alert-tone, var(--status-info)) 16%, transparent);
  /* A fitinha lateral fica: ela dá o sinal mesmo em leitura rápida, quando o
     fundo translúcido é sutil demais para ser percebido de canto de olho. É a
     única borda do componente. */
  border: 0;
  border-left: 3px solid var(--alert-tone, var(--status-info));
  border-radius: var(--radius-field);
  color: var(--alert-tone, var(--status-info));
  font-size: var(--text-size-base);
  margin: 0;
  /* Recuo menor à esquerda: a fitinha já ocupa parte do espaço, e o padding
     cheio dos dois lados afastava o texto do sinal. */
  padding: 12px 14px 12px 10px;
  /* ---- as quatro declarações abaixo vieram de `feedback/notice.css` ----
   *
   * Até 2026-08-20 elas chegavam de lá, e o componente do v2 dependia de uma
   * folha do sistema antigo para saber que forma tinha. Duas ficaram como
   * estavam (o peso do texto e o `position`, âncora da animação de saída) e
   * duas mudaram para o que o v2 diz:
   *
   * - `display: block` no lugar de uma grade de duas colunas `auto minmax(0,
   *   1fr)`. A segunda coluna existia para o PONTO de `::before`, e o sinal do
   *   v2 é a fitinha lateral — o ponto sai logo abaixo.
   * - `box-shadow: none`: o v2 separa camadas por superfície, não por
   *   profundidade. Era a última sombra de bloco do sistema. */
  box-shadow: none;
  display: block;
  font-weight: 600;
  position: relative;
}

/* O ponto de 8px do aviso antigo. O sinal do v2 é a fitinha, e dois sinais na
   mesma caixa dizem a mesma coisa duas vezes. */
:is(html[data-theme]) .alert::before {
  content: none;
}

:is(html[data-theme]) .alert[data-tone="success"] {
  --alert-tone: var(--status-done);
}

:is(html[data-theme]) .alert[data-tone="warning"] {
  --alert-tone: var(--status-progress);
}

:is(html[data-theme]) .alert[data-tone="error"] {
  --alert-tone: var(--status-late);
}

:is(html[data-theme]) .alert[data-tone="info"] {
  --alert-tone: var(--status-info);
}

/* O aviso que um motor preenche existe VAZIO, para haver onde escrever quando a
   falha chegar — e vazio ele não pode ocupar espaço nem desenhar a fitinha.
   `:empty` some e volta sozinho a cada `textContent`, o que `hidden` não faz: o
   motor escreve o texto e não sabe desfazer o atributo. */
:is(html[data-theme]) .alert:empty {
  display: none;
}


/* ---- a pilha de avisos da página -------------------------------------------
 *
 * São as mensagens do Django, no topo do conteúdo. Elas ganham respiro embaixo
 * para não encostar no cabeçalho da tela — sem isso o aviso e o título ficam
 * colados e leem como uma peça só.
 *
 * A saída é animada por `js/components/notice-auto-dismiss.js`: depois de cinco
 * segundos o aviso perde opacidade e altura, e o conteúdo sobe. As duas
 * propriedades precisam estar na transição DAQUI — o JS só troca os valores.
 */
:is(html[data-theme]) .notice-stack,
:is(html[data-theme]) .alerts,
:is(html[data-theme]) .alert-stack {
  margin-bottom: var(--gap);
  padding-bottom: var(--gap-tight);
}

:is(html[data-theme]) .notice-stack .notice,
:is(html[data-theme]) .alerts .alert,
:is(html[data-theme]) .alert-stack .alert {
  transition:
    height var(--ease),
    margin var(--ease),
    opacity var(--ease),
    padding var(--ease);
}

:is(html[data-theme]) .notice--saindo {
  opacity: 0;
}

/* Quem pediu menos movimento não recebe transição nenhuma: o aviso some, e é
   isso. A remoção continua acontecendo no JS. */
@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .notice-stack .notice,
  :is(html[data-theme]) .alerts .alert,
  :is(html[data-theme]) .alert-stack .alert {
    transition: none;
  }
}


/* ---- alerta com lista ------------------------------------------------------
 *
 * A pendência de etapa: a mesma caixa, o mesmo tom, mas com título e itens em
 * vez de uma frase. Ela substituiu `.pendencias*` (`ui/feedback/`), que era um
 * QUARTO desenho de "atenção" na mesma tela onde já viviam o alerta, o selo e o
 * erro de campo — com caixa, marcador e tipografia próprios.
 *
 * O `<section>` sobrepõe o `display` do `.alert`, que é de parágrafo: aqui há
 * três filhos empilhados, e o recuo à esquerda volta ao cheio porque o texto
 * não é mais uma linha rente à fitinha.
 */
:is(html[data-theme]) .alert--list {
  display: grid;
  gap: 6px;
  /* A COLUNA é declarada, e não herdada. As folhas de página do sistema antigo
     ainda vivem nas rotas não migradas e dão a `.alert` uma grade de DUAS
     colunas (`auto minmax(0,1fr)`) mais um marcador em `::before`, feita para
     um parágrafo só. Com três filhos, o título ia para a coluna do marcador e a
     lista subia para o lado da frase — medido na etapa de documentos do ofício.
     Uma coluna só, e o marcador desligado, tornam o bloco independente de quem
     mais tenha opinião sobre `.alert`. */
  grid-template-columns: minmax(0, 1fr);
  padding: 12px 14px;
}

/* O sinal do v2 é a fitinha lateral, e ela já está no `.alert`. O ponto extra
   vinha da folha legada; aqui ele some sem que ela precise mudar. */
:is(html[data-theme]) .alert--list::before {
  content: none;
}

:is(html[data-theme]) .alert__title {
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .alert__lead {
  margin: 0;
}

/* Os itens herdam a cor do tom, mas o marcador fica DENTRO da caixa
   (`inside`): com o padrão do navegador, o disco cai fora do recuo e encosta na
   fitinha lateral. */
:is(html[data-theme]) .alert__items {
  display: grid;
  gap: 2px;
  list-style-position: inside;
  margin: 0;
  padding: 0;
}
/* <<< css/v2/alert.css <<< */

/* >>> css/v2/menu.css >>> */
/* Menu — a lista de ações de um registro. Depende de `v2/tokens.css`.
 *
 * O desenho é o do `.action-menu` legado (`actions/action-system.css:498-608`),
 * portado com os tokens do v2. A primeira versão desta folha inventou um
 * desenho próprio e o dono preferiu o original — o que já existia estava certo,
 * só precisava do vocabulário novo.
 *
 * As medidas vêm de lá: raio 16 no painel e 11 no item, ícone em caixa de 34px
 * com contorno, altura mínima de 52px, sombra funda.
 */

/* Caixa na cor do PAINEL e realce na do campo — a mesma inversão feita na lista
   suspensa, e pelo mesmo motivo: aberto sobre um formulário, um menu na cor do
   campo vira mais uma faixa igual às que já estão na tela; na cor do painel ele
   lê como camada por cima, e o item sob o cursor é que sobe. */
:is(html[data-theme]) .menu {
  background: var(--surface-rail);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 20px 52px rgb(5 22 38 / 0.28);
  display: grid;
  gap: 4px;
  min-width: 260px;
  padding: 8px;
  /* O menu pode abrir para cima e cruzar o rail sticky do wizard. Como ele é
     uma ação ativa, precisa continuar por cima da navegação durante o uso. */
  z-index: calc(var(--z-sticky-stepper, 1100) + 10);
}

/* O `display` acima vence o `[hidden]` do navegador, que é regra de agente do
   usuário. Sem esta linha o menu fechado fica VISÍVEL no meio da lista — e o
   `overlay.js` abre e fecha justamente pelo atributo `hidden`. */
:is(html[data-theme]) .menu[hidden] {
  display: none;
}

/* O menu é transplantado para o `<body>` ao abrir; o degrau precisa vir dele
   mesmo, porque nenhum contêiner o acompanha. */
:is(html[data-theme]) .menu[data-menu-v2] {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
}

/* O menu que não deu certo. O corpo vem do servidor no primeiro clique (PF-04);
   se a busca falhar, o `overlay.js` monta este aviso no lugar — clicar e não
   acontecer nada seria falha silenciosa. Largura em `ch` porque o que limita a
   linha aqui é a frase, não a lista de ações que não veio. */
:is(html[data-theme]) .menu__erro {
  color: var(--status-late);
  margin: 0;
  max-width: 34ch;
  padding: 10px 12px;
}

/* Item que é `<button>`: o navegador lhe dá fundo, borda e fonte próprios, e
   sem zerá-los ele fica visivelmente diferente do item que é link — lado a
   lado, no mesmo menu. */
:is(html[data-theme]) button.menu__item {
  background: none;
  cursor: pointer;
  font: inherit;
  text-align: left;
  width: 100%;
}

:is(html[data-theme]) .menu__form {
  display: contents;
}

:is(html[data-theme="dark"]) .menu {
  /* Sombra mais funda no escuro: a do claro some contra o fundo. */
  box-shadow: 0 22px 58px rgb(0 0 0 / 0.5);
}

/* No CLARO o menu vai para `field` (o branco), e não para `rail`.
 *
 * A razão é a distância entre os degraus, que é diferente nos dois temas: no
 * escuro rail→field mede 1,27 e o menu em `rail` se separa bem do que está
 * atrás; no claro mede 1,106 (`v2/tokens.css`), e o menu em `rail` sobre um
 * painel `rail` praticamente encostava — flutuava sem se anunciar. O branco lhe
 * dá o degrau que o token não dá.
 *
 * `:root:not([data-theme="dark"])` cobre também quem nunca escolheu tema: o claro
 * é o padrão e vive no `:root`, então testar `[data-theme="light"]` sozinho
 * deixaria de fora a primeira visita.
 *
 * O contraste dos itens acompanha, senão o item sob o cursor sairia da mesma cor
 * da caixa. */
:is(html:not([data-theme="dark"])) .menu,
:is(html[data-theme="light"]) .menu {
  background: var(--surface-field);
}

:is(html:not([data-theme="dark"])) .menu[data-menu-v2],
:is(html[data-theme="light"]) .menu[data-menu-v2] {
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
}

:is(html[data-theme]) .menu__item {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 11px;
  color: var(--text-strong);
  display: flex;
  gap: 10px;
  min-height: 52px;
  padding: 7px;
  text-decoration: none;
  transition: border-color 140ms ease;
}

/* O realce é só o CONTORNO. Com fundo, o item sob o cursor virava uma faixa
   cheia dentro de uma caixa pequena — muita tinta para dizer "é este". A borda
   já estava reservada (o item base tem 1px transparente, então nada se move ao
   acender) e diz o mesmo com um traço. */
:is(html[data-theme]) .menu__item:hover,
:is(html[data-theme]) .menu__item:focus-visible {
  border-color: var(--line-strong, var(--line));
  outline: none;
}

/* O item que existe mas não dá para usar ainda: apagado, sem cursor e sem
   realce no hover. Ele fica na lista para dizer o que caberia ali — "Diário de
   bordo — ainda não foi criado" —, e some do caminho do teclado por
   `aria-disabled`. O contorno do hover é desligado explicitamente: sem isso o
   item se acende ao passar o mouse e promete um clique que não acontece. */
:is(html[data-theme]) .menu__item[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.48;
}

:is(html[data-theme]) .menu__item[aria-disabled="true"]:hover {
  border-color: transparent;
}

/* O item não pisca para quem pediu menos movimento. Veio de
   `actions/action-system.css`, apagada em 2026-08-20: era a única linha da
   folha que ainda tinha efeito sobre o menu, e ela não pertence ao legado —
   pertence ao componente. */
@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .menu__item {
    transition-duration: 0.01ms;
  }
}

/* O ícone tem caixa própria, com contorno — é o que dá ao menu o aspecto de
   lista de ações, e não de lista de links. */
:is(html[data-theme]) .menu__icon {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 10px;
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 34px;
  height: 34px;
  justify-content: center;
}

:is(html[data-theme]) .menu__icon svg {
  height: 16px;
  width: 16px;
}

:is(html[data-theme]) .menu__copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

:is(html[data-theme]) .menu__title {
  color: var(--text-strong);
  font-size: 0.84rem;
  font-weight: var(--weight-strong);
  line-height: 1.2;
}

:is(html[data-theme]) .menu__description {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  line-height: 1.3;
}

/* ---- COR POR FUNÇÃO ------------------------------------------------------
 *
 * Um item de menu diz o que faz por duas vias: o `data-tone` do ITEM, que tinge
 * o rótulo inteiro, e o `data-tone` do ÍCONE, que tinge só a caixinha. A
 * primeira é reservada ao destrutivo — um rótulo vermelho é um aviso, e barato
 * demais para gastar em "baixar". A segunda é a que dá a cor da função, e é a
 * que deixa o menu legível de relance, antes de ler os rótulos.
 *
 * É por isso que excluir e baixar PDF podem dividir o vermelho sem ambiguidade:
 * um pinta o rótulo, o outro pinta só o ícone, e os dois nunca aparecem no mesmo
 * canal.
 *
 * Uma regra só desenha a caixa, e cada tom apenas ESCOLHE a cor em `--tom-acao`.
 * Antes eram cinco blocos repetindo as mesmas três declarações com a cor trocada,
 * e foi assim que `preview` e `edit` acabaram sem bloco nenhum — os dois caíam no
 * accent, e ninguém percebeu porque nada quebra quando uma cor não chega.
 *
 * `color-mix` com `transparent`, e não com a superfície: misturar com a
 * superfície transforma dourado sobre azul-marinho em oliva.
 */
:is(html[data-theme]) .menu__icon[data-tone] {
  background: color-mix(in srgb, var(--tom-acao, currentColor) 14%, transparent);
  border-color: color-mix(in srgb, var(--tom-acao, currentColor) 30%, transparent);
  color: var(--tom-acao, currentColor);
}

/* O vocabulário canônico: um tom por FUNÇÃO. */
:is(html[data-theme]) .menu__icon[data-tone="view"]    { --tom-acao: var(--action-view); }
:is(html[data-theme]) .menu__icon[data-tone="pdf"]     { --tom-acao: var(--action-pdf); }
:is(html[data-theme]) .menu__icon[data-tone="docx"]    { --tom-acao: var(--action-docx); }
:is(html[data-theme]) .menu__icon[data-tone="attach"]  { --tom-acao: var(--action-attach); }
:is(html[data-theme]) .menu__icon[data-tone="cancel"]  { --tom-acao: var(--action-cancel); }
:is(html[data-theme]) .menu__icon[data-tone="amend"]   { --tom-acao: var(--action-amend); }
:is(html[data-theme]) .menu__icon[data-tone="delete"]  { --tom-acao: var(--action-delete); }
:is(html[data-theme]) .menu__icon[data-tone="edit"]    { --tom-acao: var(--action-edit); }
:is(html[data-theme]) .menu__icon[data-tone="neutral"] { --tom-acao: var(--action-neutral); }
:is(html[data-theme]) .menu__icon[data-tone="whatsapp"] { --tom-acao: var(--channel-whatsapp); }

/* Apelidos do vocabulário ANTIGO, que falava de estado ("late", "progress") onde
   queria dizer função. As chamadas foram migradas para os nomes acima; estes
   apelidos ficam porque o `icon_tone` chega de presenter e de template, e um
   apelido esquecido em algum canto deve continuar recebendo a cor CERTA da
   função em vez de cair no accent em silêncio — que é exatamente o defeito que
   este bloco corrige. */
:is(html[data-theme]) .menu__icon[data-tone="preview"]  { --tom-acao: var(--action-view); }
:is(html[data-theme]) .menu__icon[data-tone="late"]     { --tom-acao: var(--action-pdf); }
:is(html[data-theme]) .menu__icon[data-tone="progress"] { --tom-acao: var(--action-docx); }
:is(html[data-theme]) .menu__icon[data-tone="success"]  { --tom-acao: var(--action-attach); }
:is(html[data-theme]) .menu__icon[data-tone="warning"]  { --tom-acao: var(--action-cancel); }
:is(html[data-theme]) .menu__icon[data-tone="danger"]   { --tom-acao: var(--action-delete); }
:is(html[data-theme]) .menu__icon[data-tone="info"]     { --tom-acao: var(--action-neutral); }

/* Ação destrutiva: o tom tinge rótulo, ícone e a caixa dele — sem isso o ícone
   fica no accent ao lado de um rótulo vermelho, e o sinal se contradiz. */
:is(html[data-theme]) :is(.menu__item[data-tone="delete"], .menu__item[data-tone="late"]) .menu__title {
  color: var(--action-delete);
}

:is(html[data-theme]) :is(.menu__item[data-tone="delete"], .menu__item[data-tone="late"]) .menu__icon {
  /* Pinta por conta própria, e não só declarando `--tom-acao`: o ícone do
     excluir chega SEM `data-tone` em quem ainda não foi migrado, e a regra base
     acima exige o atributo para casar. Foi assim que o excluir saiu no accent na
     primeira medição desta mudança — vermelho no rótulo e dourado no ícone. */
  background: color-mix(in srgb, var(--action-delete) 14%, transparent);
  border-color: color-mix(in srgb, var(--action-delete) 30%, transparent);
  color: var(--action-delete);
}

/* O cabeçalho de grupo do menu foi APAGADO em 2026-08-16, com o componente
   `v2/menu_header.html`: nenhum menu do sistema leva cabeçalho. Ele repetia o que
   o gatilho e o cartão atrás já diziam, e gastava a altura de um item para não
   oferecer ação nenhuma. Prova de grep no PR, como manda o `AGENTS.md` §3.6. */
/* <<< css/v2/menu.css <<< */

/* >>> css/v2/record.css >>> */
/* Record — o card de um registro na lista. Depende de `v2/tokens.css`.
 *
 * Segue a escada: assume o degrau oposto ao do contêiner, como os demais.
 */

/* SEM caixa própria: cor, raio e recuo vêm da classe `panel`, que a raiz do
   componente também carrega. Aqui fica só o que é do registro.

   O CARTÃO é a grade de seis colunas — o miolo (`record__body`) foi dissolvido
   com `display: contents` (2026-08-16, a pedido do dono: "diminua essa camada
   intermediária"). Sobravam três níveis de caixa entre o cartão e uma linha de
   pessoa; agora é um. Seis colunas porque as larguras do cartão são 1/2 (linha
   de pessoa, 3 colunas) e 1/3 (bloco de fato, 2 colunas), e 6 divide as duas. */
:is(html[data-theme]) .record {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: repeat(6, minmax(0, 1fr));
  min-width: 0;
}

:is(html[data-theme]) .record__body {
  display: contents;
}

/* Cabeçalho e rodapé atravessam a grade inteira. */
:is(html[data-theme]) .record__row,
:is(html[data-theme]) .record__footer {
  grid-column: 1 / -1;
}

/* `center` e não `start`: o alvo de ação fica na mesma altura em todos os
   registros, mesmo quando um deles tem meta mais longa e quebra.

   SEM `space-between`: quem vai para a ponta direita é dito por
   `margin-left: auto` no selo e nas ações — com `space-between` o espaço se
   distribuiria também ENTRE eles, e os dois se afastariam um do outro no meio
   do vazio em vez de fecharem a linha juntos. */
:is(html[data-theme]) .record__row {
  align-items: center;
  display: flex;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .record__row > .record__actions {
  margin-left: auto;
}

/* A régua do cabeçalho só existe quando há MIOLO logo abaixo: num registro de
   uma linha só, uma linha horizontal sob o título fecharia um bloco vazio. É a
   mesma condição que manda as ações para a linha do título nesse caso. */
:is(html[data-theme]) .record__row:has(+ .record__body) {
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--gap-tight);
}

/* O selo não encolhe quando o título é longo: uma pílula espremida vira texto
   solto. Na lista simples ele já mora em `record__title-row`, logo após o título. */
:is(html[data-theme]) .record__status {
  align-items: center;
  display: inline-flex;
  flex: none;
  /* Com dois selos (situação + temporal) eles precisam de um vão entre si; com
     um só, o `gap` não faz nada. */
  gap: var(--gap-tight);
}

/* Só a LISTA DE CARDS cria a coluna de estado à direita. Na lista simples o
   selo permanece junto do texto, e as ações continuam sendo o único conteúdo
   empurrado para a ponta da linha. */
:is(html[data-theme]) .record.panel > .record__row > .record__status {
  margin-left: auto;
}

/* Com o selo empurrado para a direita, as ações não precisam empurrar de novo —
   e não podem: dois `margin-left: auto` na mesma linha abrem um vão ENTRE eles.
   O primeiro elemento a empurrar já leva os dois para a ponta. */
:is(html[data-theme]) .record.panel > .record__row > .record__status ~ .record__actions {
  margin-left: 0;
}

/* Sobrou para o eyebrow, que continua ao lado do título. */
:is(html[data-theme]) .record__title-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .record__heading {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* Inline, não em bloco: ele divide a primeira linha com título e selo. */
:is(html[data-theme]) .record__eyebrow {
  color: var(--text-muted);
  flex: none;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:is(html[data-theme]) .record__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .record__meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

/* ---- o MIOLO é uma grade de SEIS colunas ---------------------------------
 *
 * O cartão perdeu o nível da faixa (`record__band`) em 2026-08-16: as peças são
 * filhas diretas do miolo, e o miolo é `div.panel` + `form-block`, nada entre um
 * e outro.
 *
 * Seis colunas porque as duas larguras que o cartão usa são 1/2 (linha de
 * pessoa) e 1/3 (bloco de fato), e 6 é o menor número que divide as duas: a
 * pessoa ocupa 3 colunas, o bloco ocupa 2. Uma grade só arruma os dois tipos, o
 * que era exatamente o que a faixa existia para resolver.
 *
 * A `ul` da equipe segue dissolvida (`display: contents`, em `v2/person-row.css`),
 * então as linhas são itens desta grade — a `ul` fica na marcação pela semântica.
 */
/* `.record .person-row`, com DESCENDENTE e não `>`: a `ul` está com
   `display: contents`, o que dissolve a caixa dela para o LAYOUT mas não muda a
   árvore — o `li` continua filho da `ul` no DOM, e um seletor de filho direto
   nunca casa. Custou uma medição: as linhas simplesmente não recebiam largura
   nenhuma e a grade colocava tudo em colunas de 1. */
:is(html[data-theme]) .record .person-row {
  grid-column: span 3;
}

/* Em número ímpar, o último ocupa a linha inteira — sozinho em meia largura ele
   fica ao lado de um vazio, e o vazio se lê como alguém faltando. A conta de
   `nth-child` olha a marcação, não a caixa, e por isso sobrevive ao
   `display: contents` da `ul`. */
:is(html[data-theme]) .person-list > .person-row:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

/* DESCENDENTE, não `>`: o `record__body` está com `display: contents`, o que
   dissolve a caixa dele para o layout mas não muda a árvore — o bloco continua
   filho do miolo no DOM. É a mesma armadilha que já custou uma medição com as
   linhas de pessoa, e ela reaparece a cada camada que se dissolve. */
/* O corpo do bloco: SEM vão e alinhado ao TOPO.
 *
 * Esta regra já existiu e foi apagada por engano num corte de linhas quando as
 * faixas saíram — foi ela que levou os degraus de corpo por quantidade de fatos
 * embora, e o que eu na hora atribuí ao `clamp` apertado era isto.
 *
 * `align-content: start` e `row-gap: 0` porque distribuir folga É criar vão: com
 * `space-between` e dois fatos, abria-se entre eles um espaço do tamanho de um
 * deles. Agora ficam juntos e a folga sobra embaixo, junta.
 *
 * `container-type: inline-size` é o que dá sentido ao `cqw` do `fact__value`:
 * por cento da largura do BLOCO, não da janela. Sem ele o corpo ideal do texto
 * passa a se medir pela viewport, e um bloco estreito recebe corpo de tela cheia.
 */
:is(html[data-theme]) .record .form-block--v2 > .form-block__body {
  align-content: start;
  container-type: inline-size;
  min-height: 0;
  overflow: hidden;
  row-gap: 0;
}

:is(html[data-theme]) .record .form-block--v2 {
  grid-column: span 2;
  /* O teto vive no BLOCO, e não numa linha da grade: `grid-auto-rows` não sabe
     limitar só a faixa dos fatos, e é ela que precisa de altura previsível para
     os cartões da lista não variarem de tamanho conforme o roteiro. */
  max-height: 173px;
  min-height: 0;
  overflow: hidden;
}

/* Os três assuntos do resumo de evento comportam listas variáveis de efetivo
   e atividades. O teto compacto do cartão comum (173px) corta esses dados;
   nesta composição eles podem crescer até 250px e então rolam por dentro. */
:is(html[data-theme]) .record.plan-event-summary .plan-event-summary__block {
  max-height: 250px;
}

/* No resumo de um plano, "Evento N de N" qualifica o título, não o antecede.
   Ele permanece dentro da linha de título (não no header da página) e usa a
   mesma construção visual do selo neutro do sistema. */
:is(html[data-theme]) .record.plan-event-summary .record__title {
  order: 1;
}

:is(html[data-theme]) .record.plan-event-summary .record__eyebrow {
  background: color-mix(in srgb, var(--text-muted) 16%, transparent);
  border-radius: var(--radius-pill);
  letter-spacing: normal;
  order: 2;
  padding: 3px 10px;
}

:is(html[data-theme]) .record.plan-event-summary .plan-event-summary__block > .form-block__body {
  max-height: 250px;
  overflow-y: auto;
}

:is(html[data-theme]) .plan-event-summary__effective-list {
  gap: 4px;
  margin-top: 2px;
}

:is(html[data-theme]) .plan-event-summary__effective-chip {
  font-size: var(--text-size-micro);
  padding: 2px 8px;
}

/* A composição tem a mesma hierarquia do valor financeiro. Como sua frase é
   mais longa, ela quebra em vez de ser encolhida pelo ajuste de linha única. */
:is(html[data-theme]) .plan-event-summary__allowance-primary .fact__value {
  white-space: normal;
}

/* Atividades são uma sequência, não estados: uma lista textual compacta
   mantém os nomes legíveis e rola sem levar os fatos financeiros junto. */
:is(html[data-theme]) .plan-event-summary__activity-list {
  color: var(--text-muted);
  display: grid;
  font-size: var(--text-size-eyebrow);
  gap: 4px;
  list-style-position: inside;
  margin: var(--gap-tight) 0 0;
  max-height: 112px;
  overflow-y: auto;
  padding: 0 var(--gap-tight) 0 0;
}

/* O bloco financeiro OBEDECE ao mesmo teto dos outros dois (2026-08-20).
 *
 * Tinha `max-height: none` para caber a composição integral das diárias, e com
 * isso era o único bloco da faixa que crescia: medido na lista, 187px contra
 * 173px dos blocos de viatura e de trechos. O cartão ficava com uma coluna mais
 * alta que as vizinhas e a faixa perdia a linha de base.
 *
 * A composição continua inteira — o que mudou não foi o teto, foi o que ocupa a
 * altura: os fatos deste bloco usam a escala compacta abaixo, e os 163px de
 * conteúdo passam a caber nos 149px úteis sem cortar nada. É a diferença entre
 * truncar a informação (o que a regra antiga evitava, com razão) e compor a
 * mesma informação na altura disponível.
 */
:is(html[data-theme]) .record .form-block--v2.oficio-card__allowance-facts > .form-block__body {
  /* `stretch` e não `start`: é o que dá ao `fact-list` a altura útil inteira do
     bloco, e sem altura definida não há folga para o vão variável distribuir. */
  align-content: stretch;
  overflow: hidden;
}

/* O vão entre os fatos de um bloco de cartão é VARIÁVEL (2026-08-20; passou a
 * valer para TODO cartão em 2026-08-21).
 *
 * Era `row-gap: 12px` fixo, e 12px fixos não cabiam: medido na lista, 155px de
 * conteúdo em 149px úteis — o "1,5" saía cortado 6px embaixo. Um vão fixo é a
 * primeira coisa a ceder quando falta altura, e a última que se deveria
 * defender: ele não carrega informação nenhuma.
 *
 * `margin-top: auto` numa coluna flex distribui a SOBRA: quando há folga, ela
 * vira o vão (aqui, 15px — mais respiro do que os 12px de antes); quando o
 * conteúdo cresce, a sobra é zero e o vão fecha sozinho, sem cortar nada. É o
 * comportamento que um `gap` fixo não tem em nenhuma unidade.
 */
:is(html[data-theme]) .record .form-block--v2 .fact-list {
  display: flex;
  flex-direction: column;
  row-gap: 0;
}

:is(html[data-theme]) .record .form-block--v2 .fact + .fact {
  margin-top: auto;
}

/* Para o vão ter folga a distribuir, o `fact-list` precisa da altura útil
   inteira do bloco — `start` deixaria a lista do tamanho do conteúdo e a sobra
   ficaria embaixo, fora do alcance do `margin-top: auto`.

   O `:has` é parte do contrato: sem ele, o stretch também alcança os blocos de
   Ofícios e Documentos no cartão de Evento e transforma a única `person-row`
   deles numa faixa da altura inteira da coluna vizinha. */
:is(html[data-theme]) .record .form-block--v2 > .form-block__body:has(> .fact-list) {
  align-content: stretch;
}

/* A quantidade é linha de APOIO do bloco — o que se lê primeiro é "R$ 420,00".
   Com o vão variável isto sozinho já não seria preciso, mas os dois juntos são
   o que garante folga em vez de encaixe exato: sem a escala compacta o conteúdo
   fecha em 151px contra os 149px úteis, e volta a faltar. */
:is(html[data-theme]) .record .oficio-card__allowance-facts .fact + .fact .fact__label {
  line-height: 1.25;
}

:is(html[data-theme]) .record .oficio-card__allowance-facts .fact + .fact .fact__value {
  font-size: var(--text-size-lg, 1.125rem);
  line-height: 1.2;
}

/* Uma coluna em tela estreita: tudo ocupa a largura inteira. */
@media (max-width: 720px) {
  :is(html[data-theme]) .record .person-row,
  /* DESCENDENTE, não `>`: o `record__body` está com `display: contents`, o que
   dissolve a caixa dele para o layout mas não muda a árvore — o bloco continua
   filho do miolo no DOM. É a mesma armadilha que já custou uma medição com as
   linhas de pessoa, e ela reaparece a cada camada que se dissolve. */
/* O corpo do bloco: SEM vão e alinhado ao TOPO.
 *
 * Esta regra já existiu e foi apagada por engano num corte de linhas quando as
 * faixas saíram — foi ela que levou os degraus de corpo por quantidade de fatos
 * embora, e o que eu na hora atribuí ao `clamp` apertado era isto.
 *
 * `align-content: start` e `row-gap: 0` porque distribuir folga É criar vão: com
 * `space-between` e dois fatos, abria-se entre eles um espaço do tamanho de um
 * deles. Agora ficam juntos e a folga sobra embaixo, junta.
 *
 * `container-type: inline-size` é o que dá sentido ao `cqw` do `fact__value`:
 * por cento da largura do BLOCO, não da janela. Sem ele o corpo ideal do texto
 * passa a se medir pela viewport, e um bloco estreito recebe corpo de tela cheia.
 */
:is(html[data-theme]) .record .form-block--v2 > .form-block__body {
  align-content: start;
  container-type: inline-size;
  min-height: 0;
  overflow: hidden;
  row-gap: 0;
}

:is(html[data-theme]) .record .form-block--v2 {
    grid-column: 1 / -1;
  }
}

:is(html[data-theme]) .record__actions {
  align-items: center;
  display: flex;
  flex: none;
  gap: var(--gap-tight);
}

/* Rodapé do registro: as ações fecham o cartão, alinhadas à direita e separadas
   do miolo por uma RÉGUA.

   O vão da grade não bastava: num cartão que cresce por faixas, o vão entre o
   último bloco e os botões é o mesmo vão que existe ENTRE os blocos — então a
   fileira de ações lia como mais uma faixa de conteúdo. A linha diz o que o
   espaço não dizia: daqui para baixo não é mais informação, é o que se pode
   fazer com ela.

   O recuo acompanha a linha. Sem ele o traço encosta nos botões e parece borda
   de um deles. */
:is(html[data-theme]) .record__footer {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  justify-content: flex-end;
  min-width: 0;
  padding-top: var(--gap-tight);
}

/* O primeiro botão do rodapé abre a ESQUERDA. Ele é o menu do registro — o que
   dá acesso a tudo —, e as ações diretas (excluir) ficam na ponta oposta: a
   distância entre um clique e o outro é o que evita excluir querendo abrir.
   `margin-right: auto` no primeiro, e o resto se empurra para a direita. */
:is(html[data-theme]) .record__footer > *:first-child {
  margin-right: auto;
}

/* ---- linha de prestação: a que se edita na própria lista --------------------
 *
 * Cada servidor traz um formulário com o número da solicitação e o período das
 * diárias. Os dois controles ficam juntos, ANTES do nome, na mesma linha: são
 * dados operacionais do mesmo servidor e separá-los em pontas opostas escondia
 * essa relação.
 */
:is(html[data-theme]) .prestacao-row__form {
  align-items: center;
  display: flex;
  flex: 1 1 320px;
  gap: var(--gap-tight);
  min-width: 0;
  order: -1;
}

:is(html[data-theme]) .prestacao-row__solicitacao {
  background: var(--surface-rail);
  flex: 0 1 120px;
  max-width: 120px;
  min-width: 0;
}

:is(html[data-theme]) .prestacao-row__form .date-field {
  flex: 0 0 auto;
}

/* Os três blocos de fato do cartão dividem a largura; em tela estreita eles
   empilham, como no cartão de ofício.

   `grid-column: 1 / -1` porque este invólucro é ITEM da grade de seis colunas do
   cartão: sem a faixa inteira ele ficava com uma coluna (112px) e os blocos de
   220px vazavam para fora dela, um por cima do outro. As linhas de pessoa e os
   blocos de fato soltos têm o span declarado; este, que chegou depois, não
   tinha. */
:is(html[data-theme]) .prestacao-card__facts,
:is(html[data-theme]) .oficio-card__facts,
:is(html[data-theme]) .evento-card__docs {
  display: grid;
  gap: var(--gap);
  grid-column: 1 / -1;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  min-width: 0;
}

/* Dentro do invólucro, o bloco volta a valer UMA coluna. O `span 2` acima é da
   grade de seis colunas do CARTÃO e chega aqui por descendência — numa grade de
   três colunas ele fazia cada bloco ocupar duas, e os três fatos empilhavam um
   por linha em vez de dividirem a faixa. */
:is(html[data-theme]) :is(.prestacao-card__facts, .oficio-card__facts, .evento-card__docs) .form-block--v2 {
  grid-column: auto;
}

/* Ofícios e documentos podem crescer muito dentro do card do evento. Aqui a
   lista volta a ser uma caixa de grade (fora daqui `person-list` é dissolvida)
   para poder ter vão próprio e rolagem sem aumentar o card inteiro. */
:is(html[data-theme]) .evento-card__docs .person-list {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: minmax(0, 1fr);
  max-height: calc(3 * var(--control-height) + 4 * var(--gap-tight));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}

/* As linhas deixam de participar da grade de seis colunas do record quando a
   lista ganha caixa própria; cada item ocupa uma linha inteira dessa caixa. */
:is(html[data-theme]) .evento-card__docs .person-list > .person-row,
:is(html[data-theme]) .evento-card__docs .person-list > .person-row:last-child:nth-child(odd) {
  grid-column: 1;
}

/* Nestes dois blocos a linha já está no degrau rail; repetir rail no botão o
   fazia desaparecer. A ação usa field, como os demais controles sobre rail. */
:is(html[data-theme]) .evento-card__docs .person-row__actions .icon-button {
  --icon-button-surface: var(--surface-field);
}

/* O formulário de uma ação só não quebra a fila de ações do rodapé. */
:is(html[data-theme]) .prestacao-card__inline-action {
  display: contents;
}

/* A dica de vazio dentro de um bloco do cartão. */
:is(html[data-theme]) .record__empty-hint {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

/* A PILHA de registros. Veio de `lists/record-list.css` em 2026-08-20, que
   morreu com ela: as outras oito regras da folha vestiam `record-row`,
   `list-panel` e `collection-panel` — vocabulário que nenhum template emite
   desde que a linha de catálogo virou `c-v2.catalog_row`.

   O vão é 8px, e não `--gap`: esta pilha vive DENTRO de um painel (modelos de
   texto, vínculos da área), onde o `--gap` do painel já separa as seções. */
:is(html[data-theme]) .record-list {
  display: grid;
  gap: 8px;
  min-width: 0;
}
/* <<< css/v2/record.css <<< */

/* >>> css/v2/route-editor.css >>> */
/* Editor de roteiro — as cinco peças da tela `roteiros:novo`/`:editar`.
 *
 * Uma folha só, e não cinco, porque as peças não existem separadas: origem,
 * bate-volta, mapa, trechos e diárias são o MESMO editor, e a medida de uma
 * depende da outra (o mapa herda a largura do bloco, os tempos do retorno usam a
 * mesma grade dos horários do bate-volta). Cinco arquivos dariam cinco lugares
 * para procurar o mesmo `gap`.
 *
 * O legado disto era `static/css/pages/roteiros.css`, com 2.332 linhas. O que
 * sobrou aqui é o que a tela realmente usa: o resto era do editor antigo, de
 * variantes que sumiram e do card de lista, que agora vem do `record`.
 */

/* ---- origem e destinos ---------------------------------------------------- */

:is(html[data-theme]) .route-source__saved,
:is(html[data-theme]) .route-source__new {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* Par obrigatório: o `display` acima vence a regra de agente do usuário, e sem
   ele os DOIS modos aparecem ao mesmo tempo — o de roteiro salvo e o de roteiro
   novo, um embaixo do outro. */
:is(html[data-theme]) .route-source__saved[hidden],
:is(html[data-theme]) .route-source__new[hidden] {
  display: none;
}

/* Estado e cidade lado a lado, e em uma coluna quando não couberem: são um par
   em cascata (escolher o estado é o que enche a cidade), e separá-los em linhas
   distintas desfaz a leitura de "de onde sai". */
:is(html[data-theme]) .route-source__sede-fields {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  min-width: 0;
}

/* ---- bate-volta diário ---------------------------------------------------- */

:is(html[data-theme]) .route-daily__grid {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .route-daily__times {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  min-width: 0;
}

:is(html[data-theme]) #bate-volta-body[hidden] {
  display: none;
}

/* ---- mapa ------------------------------------------------------------------ */

/* As quatro medidas em auto-fit, e não em quatro colunas fixas: "Distância (ida
   e volta)" é rótulo longo, e em coluna fixa ele quebrava no meio da palavra. */
:is(html[data-theme]) .route-map__metrics {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  margin-bottom: var(--gap);
  min-width: 0;
}

/* A moldura do mapa é uma CAIXA em `rail`, com a barra de ações dentro dela: o
   mapa e os botões que o comandam são a mesma peça, e sobre o fundo do bloco os
   botões pareciam soltos entre as medidas e o mapa. Os botões sobem para `field`,
   que é o degrau seguinte — é o que os separa da caixa. */
:is(html[data-theme]) .route-map__shell {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
  padding: var(--gap-tight);
  position: relative;
}

:is(html[data-theme]) .route-map__action {
  background: var(--surface-field);
}

:is(html[data-theme]) .route-map__toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  justify-content: flex-end;
}

/* O `hidden` dos dois botões que só aparecem depois da primeira rota. */
:is(html[data-theme]) .route-map__action[hidden] {
  display: none;
}

/* Altura fixa: o Leaflet mede o contêiner ao montar, e um contêiner de altura
   automática nasce com 0 — o mapa fica invisível e nada acusa. 380px é o que
   cabe numa tela de notebook sem esconder o bloco de trechos abaixo. */
:is(html[data-theme]) .route-map__canvas {
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  height: 380px;
  min-width: 0;
  overflow: hidden;
  width: 100%;
}

:is(html[data-theme]) .route-map__loading {
  align-items: center;
  background: color-mix(in srgb, var(--surface-rail) 88%, transparent);
  border-radius: var(--radius-field);
  color: var(--text-strong);
  display: flex;
  gap: var(--gap-tight);
  inset: auto 0 0 0;
  justify-content: center;
  padding: var(--gap-tight);
  position: absolute;
}

:is(html[data-theme]) .route-map__loading[hidden] {
  display: none;
}

:is(html[data-theme]) .route-map__spinner {
  animation: route-map-spin 0.9s linear infinite;
  border: 2px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 50%;
  border-top-color: var(--accent);
  height: 16px;
  width: 16px;
}

@keyframes route-map-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ---- trechos --------------------------------------------------------------- */

:is(html[data-theme]) .route-segments,
:is(html[data-theme]) .route-segments__host {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .route-segments__park[hidden] {
  display: none;
}

:is(html[data-theme]) .route-segments__stack {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* O vazio é um BLOCO como os trechos serão, para a pilha não mudar de forma
   quando eles chegarem. O texto ao centro é a única diferença. */
:is(html[data-theme]) .route-segments__empty {
  text-align: center;
}

:is(html[data-theme]) .route-segments__empty-title {
  color: var(--text-strong);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .route-segments__empty-text {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

/* Cada trecho é um CARD dentro da pilha: rótulo em cima ("Trecho 2" e a rota),
   corpo embaixo. O card é montado pelo `editor/trechos.js`, e por isso o nome da
   classe estrutural (`roteiro-trecho-card`) continua o antigo — ele é o seletor
   que o editor usa para achar os cards (`TRECHO_CARD_SELECTOR`). O desenho é o
   do v2. */
/* Pinta com `--surface-rail` À MÃO, e não com `--surface-contrast`: o próprio
   card redefine `--surface-contrast` para os campos dele (regra abaixo), então
   ler a variável aqui devolvia a cor DOS CAMPOS — card e campo saíam do mesmo
   tom, e as caixas de data e hora sumiam dentro do card. Medido. */
/* O card do trecho É um `form-block--v2` (o `editor/trechos.js` o monta com essa
   classe), então caixa, raio e recuo vêm de lá. Aqui fica só o que é próprio
   dele. A classe estrutural `roteiro-trecho-card` continua no elemento porque é
   por ela que o editor acha os cards. */

/* Dentro do card os campos já estão no degrau `rail`, então o controle sobe para
   `field` — é a mesma escada do resto do formulário, uma camada adiante. */
:is(html[data-theme]) .route-leg {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
}

/* ---- retorno --------------------------------------------------------------- */

/* `align-items: stretch` (padrão) mais `grid-auto-rows: 1fr`: as duas pernas
   ficam da MESMA altura mesmo quando um dos nomes de cidade quebra em duas
   linhas — sem isso a caixa da chegada descia em relação à da saída, e as duas
   deixavam de ler como um par. */
:is(html[data-theme]) .route-return__legs {
  display: grid;
  gap: var(--gap);
  grid-auto-rows: 1fr;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  min-width: 0;
}

/* Saída e chegada são CAIXAS, e não duas colunas de campos soltos: são os dois
   lados do mesmo deslocamento, e com os campos soltos "Cidade / Data / Hora"
   aparecia duas vezes seguidas sem nada dizendo onde uma metade termina e a
   outra começa. Foi o desenho que o dono pediu. */
:is(html[data-theme]) .route-return__leg {
  background: var(--surface);
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
  padding: var(--gap);
}

:is(html[data-theme]) .route-return__leg-title {
  color: var(--text-strong);
  font-size: 1.05rem;
  font-weight: var(--weight-strong);
}

/* Cidade ocupando a linha inteira, data e hora dividindo a de baixo: a cidade é
   nome próprio e cresce; data e hora têm largura conhecida. */
:is(html[data-theme]) .route-return__leg-fields {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
}

:is(html[data-theme]) .route-return__city {
  grid-column: 1 / -1;
}

/* Sem `margin-top`: quem separa esta faixa das pernas é o vão do corpo do bloco
   (no retorno) e o do próprio card (no trecho). A margem somava um segundo
   espaçamento em cima do primeiro, e a linha dos tempos ficava descolada. */
:is(html[data-theme]) .route-return__times {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  min-width: 0;
}

/* O campo e os dois botões de 15 em 15 minutos na mesma linha: o passo só faz
   sentido colado ao número que ele muda. */
:is(html[data-theme]) .route-return__stepper {
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .route-return__stepper .input__control {
  flex: 1 1 auto;
  min-width: 0;
}

/* Quadrados: são dois botões de um sinal só (− e +), e com o recuo lateral do
   botão comum saíam estreitos e altos — 29x44 medidos. Lado do quadrado é a
   altura do controle, para casarem com o campo ao lado. */
:is(html[data-theme]) .route-return__stepper .trecho-tempo-add-btn {
  aspect-ratio: 1;
  flex: none;
  justify-content: center;
  padding: 0;
  width: var(--control-height);
}

/* A caixa da perna assume o degrau do bloco, e os campos dentro dela sobem para
   o contraste — sem isto o campo e a caixa saem da mesma cor e a moldura do
   campo desaparece, que foi o defeito medido no card de trecho. */
:is(html[data-theme]) .route-return__leg {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
}

/* As pernas do TRECHO usam o mesmo degrau das do retorno — a regra acima vale
   para as duas. Havia aqui uma inversão (`field` na caixa, `rail` no campo) que
   deixava o card do trecho mais claro que o do retorno, lado a lado na mesma
   pilha. */

/* ---- diárias --------------------------------------------------------------- */

/* Seletor COMPOSTO (`.fact-list.travel-allowance__facts`): `v2/fact.css` entra
   DEPOIS desta folha no pacote, e com a mesma especificidade quem decide é a
   ORDEM — a grade de três colunas do `fact-list` se reimpunha e o resumo saía em
   três colunas, não em duas com os secundários empilhados. Medido.

   Duas colunas: o VALOR TOTAL ocupa a esquerda inteira, em caixa própria e com o
   número grande; tipo de destino e quantidade ficam empilhados à direita, cada um
   na sua. É o resumo financeiro, e o que se procura nele é uma cifra só — as
   outras duas explicam de onde ela veio. */
:is(html[data-theme]) .fact-list.travel-allowance__facts {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto auto;
}

:is(html[data-theme]) .fact-list.travel-allowance__facts .fact {
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  padding: var(--gap);
}

/* `margin-top` entre fatos é do cartão da lista, onde eles se empilham. Aqui a
   grade já dá o vão, e a margem somava um degrau extra na segunda linha. */
:is(html[data-theme]) .fact-list.travel-allowance__facts .fact + .fact {
  margin-top: 0;
}

:is(html[data-theme]) .fact-list.travel-allowance__facts .fact:first-child {
  grid-row: span 2;
}

/* O número grande de verdade: é a resposta da tela inteira. `clamp` porque o
   valor cresce com o número de diárias e a caixa não. */
:is(html[data-theme]) .fact-list.travel-allowance__facts .fact:first-child .fact__value {
  font-size: clamp(1.8rem, 6cqw, 3.2rem);
  line-height: 1.05;
}

:is(html[data-theme]) .fact-list.travel-allowance__facts .fact:first-child .fact__note {
  margin-top: var(--gap-tight);
}

@media (max-width: 640px) {
  :is(html[data-theme]) .fact-list.travel-allowance__facts {
    grid-template-columns: minmax(0, 1fr);
  }

  :is(html[data-theme]) .fact-list.travel-allowance__facts .fact:first-child {
    grid-row: auto;
  }
}

/* ---- as etiquetas de cidade no mapa ----------------------------------------
 *
 * O Leaflet desenha tooltip com caixa branca, borda cinza e seta — a cara dele,
 * não a do sistema. O desenho delas morava em `pages/roteiros.css`, que saiu da
 * tela na migração (2026-08-18), e por isso voltaram ao padrão da biblioteca no
 * meio de um mapa dentro de uma tela escura.
 *
 * Aqui elas são pílulas na superfície do sistema, com o nome em caixa alta e
 * miúda — legível sobre o mapa claro sem pedir atenção. Sede e destino diferem
 * pela cor da borda: a sede usa o accent, o destino a linha comum.
 */
:is(html[data-theme]) .roteiro-mapa__city-tooltip.leaflet-tooltip {
  background: var(--surface-rail);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  box-shadow: 0 6px 16px rgb(0 0 0 / 0.28);
  color: var(--text-strong);
  cursor: pointer;
  font-size: 11px;
  font-weight: var(--weight-strong);
  letter-spacing: 0.04em;
  padding: 4px 10px;
  pointer-events: auto;
  text-transform: uppercase;
  white-space: nowrap;
}

/* A seta do balão é desenhada por `::before` com `border-top-color`; sem esta
   linha ela continuava branca, apontando para uma pílula escura. */
:is(html[data-theme]) .roteiro-mapa__city-tooltip.leaflet-tooltip-top::before {
  border-top-color: var(--surface-rail);
}

:is(html[data-theme]) .roteiro-mapa__city-tooltip.leaflet-tooltip-bottom::before {
  border-bottom-color: var(--surface-rail);
}

:is(html[data-theme]) .roteiro-mapa__city-tooltip--sede.leaflet-tooltip {
  border-color: var(--accent);
}

/* O ponto no traçado: o Leaflet o pinta com `fill`/`stroke` no atributo, então
   a folha só alcança o que ele deixa livre — o contorno branco em volta, que é
   o que separa o ponto do mapa por baixo. */
:is(html[data-theme]) .route-map__canvas .leaflet-interactive {
  paint-order: stroke;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * A PELE DO EDITOR DENTRO DO WIZARD DE OFÍCIO — vinda dos dois arquivos de tema
 * em 2026-08-20.
 *
 * Eram 130 regras (1.084 linhas) espalhadas entre
 * `components/theme-shared-components.css` e `components/theme-dark-components.css`,
 * todas escritas sob `[data-travel-document-wizard-roteiro]`,
 * `.roteiro-editor--*`, `.route-sede-block` e as outras classes DESTE editor. Elas
 * viviam lá porque o sistema antigo separava "geometria compartilhada" de
 * "aparencia por tema" — e o preço era que um terco da folha de tema fosse, na
 * verdade, uma tela só.
 *
 * O texto veio INTACTO, `!important` inclusive: mover de arquivo e mudar valor
 * na mesma passagem torna impossível atribuir qualquer diferença a uma das duas
 * coisas. Medido antes e depois nas três telas do editor (avulso novo, avulso
 * editar, etapa do ofício): nenhuma diferença.
 *
 * O que fica para depois é o de sempre: as regras que começam com
 * `[data-travel-document-wizard-roteiro]` só existem porque o editor se veste
 * diferente dentro do wizard. Quando as duas telas convergirem, some metade
 * disto.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── de `components/theme-shared-components.css` ── */

:is(html[data-theme])
  .roteiro-editor--oficio .roteiro-editor__oficio-card > .form-section-body {
  line-height: normal;
}

:is(html[data-theme])
  .roteiro-editor--oficio .roteiro-editor__oficio-card > .form-section-body > .form-block {
  line-height: normal;
}

:is(html[data-theme])
  .roteiro-editor--oficio .roteiro-editor__section--fonte {
  margin-top: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block) > .form-block__header {
  align-items: flex-start;
  gap: 12px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block) > .form-block__header .form-block__copy {
  align-items: start;
  display: grid;
  gap: 3px;
  justify-content: start;
  width: auto;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block) .form-block__description {
  text-align: left;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block).form-block--split {
  align-items: center;
  gap: 16px;
  grid-template-columns: minmax(148px, 0.62fr) minmax(0, 2.1fr);
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block).form-block--split > .form-block__body {
  align-self: center;
}

/* Pickers sem casca extra — o painel da seção já é a camada intermediária. */
:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) :is(
    .search-picker,
    .search-picker--people,
    .search-picker--people.search-picker--roster,
    .search-picker--vehicle
  ) {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0;
  box-shadow: none !important;
  gap: 10px;
  padding: 0 !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .search-picker__selected-panel {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  gap: 8px;
  padding: 0 !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .search-picker__selected-empty {
  border-radius: 10px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .search-picker__selected-empty {
  background: var(--step1-empty, var(--surface-contrast, var(--surface-field))) !important;
  border: 0 !important;
  color: var(--color-muted);
  padding: 12px 14px !important;
  text-align: left;
}

/* Sugestões de viatura: mesmo poço dos campos; ativo = linguagem do card motorista. */
:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .viatura-sugestao-chip {
  background: var(--step1-field, var(--surface-contrast, var(--surface-field)));
  border: 0;
  border-radius: 12px;
  box-shadow: none;
  color: var(--color-text);
  min-height: 40px;
  padding: 8px 12px 8px 14px;
  transition: background-color 140ms ease, box-shadow 140ms ease;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .viatura-sugestao-chip:hover,
:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .viatura-sugestao-chip:focus-visible {
  background: color-mix(in srgb, var(--color-accent) 5%, var(--step1-field));
  outline: 0;
}

/* Escolher uma sugestão é o mesmo estado semântico de marcar o motorista:
   superfície selecionada e filete de accent, sem transformar todo o chip numa
   massa de cor de navegação. */
:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .viatura-sugestao-chip[aria-pressed="true"],
:is(html[data-theme])
  :is([data-travel-document-wizard-step1], [data-travel-document-wizard-roteiro], [data-travel-document-wizard-justificativa], [data-travel-document-wizard-documentos], [data-travel-document-wizard-rt], [data-travel-document-wizard-diario], [data-travel-document-wizard-consolidado]) .viatura-sugestao-chip[aria-pressed="true"]:hover {
  background: var(--surface-selected);
  box-shadow: inset 3px 0 0 0 var(--accent);
  color: var(--text-strong);
}

@media (max-width: 900px) {
  :is(html[data-theme])
    :is([data-travel-document-wizard-step1] .travel-document-block, [data-travel-document-wizard-rt] .travel-document-block, [data-travel-document-wizard-diario] .travel-document-block, [data-travel-document-wizard-consolidado] .travel-document-block, [data-travel-document-wizard-roteiro] .route-section-block, [data-travel-document-wizard-justificativa] .oficio-justificativa-block, [data-travel-document-wizard-documentos] .oficio-documentos-block, [data-travel-document-wizard-documentos] .travel-document-block).form-block--split {
    align-items: stretch;
    grid-template-columns: minmax(0, 1fr);
  }}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split > .form-block__header {
  max-width: 14rem;
  min-width: 14rem;
  width: 14rem;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split > .form-block__body {
  align-self: center;
  min-width: 0;
  width: 100%;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .route-sede-block .field-grid.roteiro-sede-grid {
  gap: 10px 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split .field-grid.field-grid--cols-2 {
  gap: 12px 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split .cv-field {
  margin: 0;
  min-width: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split + .route-destinos-block--split,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split + .form-subsection {
  border-top: 0;
  padding-top: 0;
}

/* Destinos: mesmo card/split da Sede; rail 14rem | editor. */
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block.route-destinos-block--split,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block.route-destinos-block--split:hover {
  align-items: start;
  background: var(--step1-surface) !important;
  border: 0 !important;
  border-radius: 14px;
  box-shadow: none !important;
  column-gap: 16px;
  display: grid;
  filter: none !important;
  grid-template-columns: 14rem minmax(0, 1fr);
  margin: 14px 0 0;
  padding: 14px;
  row-gap: 0;
  transform: none !important;
  transition: none !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1])
  .travel-schedule
  .route-destinos-block.route-destinos-block--split {
  margin-top: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split > .route-destinos-block__rail {
  align-self: start;
  display: grid;
  gap: 4px;
  max-width: 14rem;
  min-width: 14rem;
  width: 14rem;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__copy {
  display: grid;
  gap: 3px;
  min-height: 44px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__title {
  color: var(--color-heading);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-black);
  letter-spacing: 0;
  line-height: 1.2;
  margin: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__subtitle,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__description {
  color: var(--color-muted);
  font-size: var(--font-size-xs);
  line-height: 1.45;
  margin: 0;
  text-align: left;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-trechos {
  display: grid;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-trechos[hidden] {
  display: none !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-trechos__item {
  align-items: center;
  color: var(--color-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: var(--font-size-xs);
  gap: 0.35em;
  line-height: 1.35;
  min-height: 44px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__subtitle:has(.route-destinos-trechos__from) {
  /* Primeiro trecho ocupa o lugar do subtítulo — sem altura de linha. */
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35em;
  min-height: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split > .route-destinos-block__body {
  display: grid;
  gap: 10px;
  min-width: 0;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-block__editor,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .ordered-field-collection__list {
  display: grid;
  gap: 10px;
  min-width: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single:hover {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row__half {
  align-items: center;
  display: flex;
  gap: 10px;
  min-width: 0;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row__field {
  flex: 1 1 auto;
  margin: 0;
  min-width: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__badge.sr-only {
  clip: rect(0, 0, 0, 0);
  display: none !important;
  height: 1px;
  overflow: hidden;
  position: absolute;
  width: 1px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__drag-handle .icon {
  display: block;
  height: 16px;
  width: 16px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single .ordered-field-row__drag-handle {
  display: none;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .route-destinos-add,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__add,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__remove,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-remove-button {
  align-items: center;
  border: 0 !important;
  border-radius: 10px !important;
  box-shadow: none !important;
  cursor: pointer;
  display: inline-flex;
  flex: 0 0 auto;
  height: 44px;
  justify-content: center;
  line-height: 1;
  margin: 0 !important;
  min-width: 44px;
  opacity: 1 !important;
  padding: 0 !important;
  transform: none !important;
  transition: none;
  width: 44px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__remove::before {
  content: none !important;
  display: none !important;
}@media (max-width: 720px) {
  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block.travel-period-block--split,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block.route-destinos-block--split {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 12px;
  }

  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split > .form-block__header,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split > .travel-period-block__rail,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split > .route-destinos-block__rail {
    max-width: none;
    min-width: 0;
    width: auto;
  }

  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .route-sede-block .field-grid.roteiro-sede-grid,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .travel-period-block--split .field-grid.field-grid--cols-2 {
    grid-template-columns: 1fr !important;
  }}
@media (max-width: 600px) {
  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .route-sede-block .field-grid.roteiro-sede-grid {
    grid-template-columns: 1fr !important;
  }}

:is(html[data-theme])
  [data-travel-document-wizard-documentos]
  :is(
    .summary-item:not(.oficio-documentos-route-trecho-scroll-item),
    .oficio-documentos-fact,
    .oficio-documentos-traveller-tile:not(.oficio-documentos-traveller-tile--motorista),
    .oficio-documentos-traveller-line:not(.oficio-documentos-traveller-line--motorista),
    .oficio-documentos-vehicle-executive__driver,
    .document-inline-card,
    .oficio-documentos-route-card__diarias-subblock,
    .oficio-documentos-route-card__fallback-fact,
    .oficio-documentos-route-card__trecho
  ) {
  border-radius: 10px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__selected-list {
  display: grid;
  gap: 8px;
  max-height: 280px;
  overflow: auto;
}

/* Busca de roteiro salvo: mesma altura do picker de Equipe. */
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__field {
  gap: 7px;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single:hover {
  grid-template-columns: 42px minmax(0, 1fr);
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row__fields > .field {
  gap: 6px;
  margin: 0;
  min-width: 0;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single .ordered-field-row__remove {
  display: none;
}@media (max-width: 720px) {
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row,
:is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row:hover,
:is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single,
:is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single:hover {
    grid-template-columns: 42px minmax(0, 1fr);
    row-gap: 8px;
  }

  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row--single .ordered-field-row__remove {
    display: none;
  }}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row:hover {
  align-items: center;
  background: transparent !important;
  border: 0 !important;
  border-radius: 0;
  box-shadow: none !important;
  column-gap: 12px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  min-height: 0;
  padding: 0 !important;
  row-gap: 0;
  transition: none !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single:hover {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row__half {
  align-items: center;
  display: flex;
  gap: 10px;
  min-width: 0;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single .ordered-field-row__drag-handle {
  display: none;
}@media (max-width: 720px) {
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row:hover,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single,
  :is(html[data-theme])
    :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row--single:hover {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 8px;
  }}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  #sec-mapa-rota > .form-block__header {
  display: none !important;
}

:is(html[data-theme])
  .roteiro-editor--oficio :is(
    .roteiro-mapa__frame,
    .roteiro-mapa__frame #map,
    .roteiro-mapa__frame .leaflet-container
  ) {
  height: 600px;
  min-height: 600px;
}@media (max-width: 720px) {
  :is(html[data-theme])
    .roteiro-editor--oficio :is(
      .roteiro-mapa__frame,
      .roteiro-mapa__frame #map,
      .roteiro-mapa__frame .leaflet-container
    ) {
    height: 420px;
    min-height: 420px;
  }}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg.route-bate-volta-leg.form-block--split > .form-block__header {
  max-width: 14rem;
  min-width: 14rem;
  width: 14rem;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg.route-bate-volta-leg.form-block--split > .form-block__body {
  align-self: center;
  min-width: 0;
  width: 100%;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__fields > .field {
  gap: 6px;
  margin: 0;
  min-width: 0;
}@media (max-width: 720px) {
  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg.route-bate-volta-leg.form-block--split {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 10px;
  }

  :is(html[data-theme])
    [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg.route-bate-volta-leg.form-block--split > .form-block__header {
    max-width: none;
    min-width: 0;
    width: auto;
  }}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--trecho
  > .form-block__header {
  align-items: center;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--trecho
  > .form-block__header
  .form-block__actions {
  align-items: center;
  display: flex;
  flex: 0 0 auto;
  margin-left: auto;
}

/* Dentro de cada bloco de trecho: conteúdo plano (sem mini-card aninhado). */
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trecho .roteiro-deslocamento,
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trecho .roteiro-trecho-card,
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trechos-empty .roteiro-editor__empty {
  border-radius: 0;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trecho .roteiro-deslocamento,
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trecho .roteiro-trecho-card,
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trechos-empty .roteiro-editor__empty {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-editor__section--trecho .roteiro-trecho-card {
  gap: var(--space-3, 12px);
}

/* Saída/Chegada: poço escuro (= inputs do wizard); sem borda. */
:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-trecho-card__leg {
  border-radius: 12px;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro] .roteiro-trecho-card__leg {
  background: var(--step1-field, var(--color-input-bg));
  border: 0;
  box-shadow: none;
}

/* Toggle bate-volta (ofício): pill compacta — controle real, não texto dourado. */
:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 12px;
  box-shadow: none !important;
  cursor: pointer;
  display: inline-flex;
  font-size: 0.8125rem;
  font-weight: var(--font-weight-bold, 700);
  gap: 8px;
  height: 38px;
  justify-content: center;
  letter-spacing: 0;
  line-height: 1.2;
  min-height: 38px;
  min-width: 11.5rem;
  padding: 0 14px;
  text-transform: none;
  transform: none !important;
  transition:
    background-color 140ms ease,
    border-color 140ms ease,
    color 140ms ease;
  white-space: nowrap;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(:hover, :focus, :focus-visible, :active) {
  box-shadow: none !important;
  filter: none;
  transform: none !important;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--color-accent) 55%, transparent);
  outline-offset: 2px;
}

/* OFF — painel muted */
:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(.field-side-action--danger, .is-inactive),
:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(.field-side-action--danger, .is-inactive):is(:hover, :focus, :focus-visible) {
  background: var(--step1-panel, var(--color-surface-soft)) !important;
  border-color: color-mix(in srgb, var(--color-border) 55%, transparent) !important;
  color: var(--color-muted-strong) !important;
}

/* ON — success soft filled (evita texto/fill dourado do accent) */
:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(.field-side-action--success, .is-active, [aria-pressed="true"]),
:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(.field-side-action--success, .is-active, [aria-pressed="true"]):is(:hover, :focus, :focus-visible) {
  background: color-mix(in srgb, var(--color-success) 22%, var(--step1-panel, var(--color-surface-soft))) !important;
  border-color: var(--color-success-border-soft, color-mix(in srgb, var(--color-success) 40%, transparent)) !important;
  color: var(--color-heading) !important;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--toggle:is(.field-side-action--danger, .is-inactive):is(:hover, :focus-visible) {
  background: color-mix(in srgb, var(--color-white) 4%, var(--step1-panel, var(--color-surface-soft))) !important;
  border-color: color-mix(in srgb, var(--color-border) 70%, transparent) !important;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--state::before {
  border-radius: 999px;
  box-shadow: none !important;
  flex: 0 0 auto;
  height: 7px;
  width: 7px;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--state:is(.field-side-action--success, .is-active)::before {
  background: var(--color-success) !important;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .oficio-roteiro-bate-volta-toggle
  .field-side-action--state:is(.field-side-action--danger, .is-inactive)::before {
  background: var(--color-muted) !important;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden]) {
  align-content: center;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden])
  > .form-block__body {
  display: none;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden])
  > .form-block__header {
  align-items: center;
  display: flex;
  justify-content: space-between;
  max-width: none;
  text-align: left;
  width: 100%;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden])
  > .form-block__header .form-block__copy {
  align-items: start;
  justify-content: start;
  text-align: left;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden])
  > .form-block__header .form-block__description {
  text-align: left;
}

:is(html[data-theme])
  [data-travel-document-wizard-roteiro]
  .roteiro-editor__section--bate-volta.route-section-block:has(#bate-volta-body[hidden])
  > .form-block__header .form-block__actions {
  align-items: center;
  display: flex;
  flex: 0 0 auto;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker.search-picker--people.search-picker--roster
  .search-picker__selected-card.related-route-item,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker.search-picker--people.search-picker--roster
  .search-picker__selected-card.related-route-item:hover {
  appearance: none;
  -webkit-appearance: none;
  color: inherit;
  cursor: pointer;
  display: grid;
  font: inherit;
  grid-template-columns: 42px minmax(0, 1fr);
  text-align: left;
  width: 100%;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__selected-avatar {
  font-size: 0;
  letter-spacing: 0;
  line-height: 0;
  overflow: hidden;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__selected-avatar .related-route-icon,
:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__selected-avatar .icon {
  color: inherit;
  display: block;
  flex: 0 0 20px;
  height: 20px !important;
  max-height: 20px;
  max-width: 20px;
  min-height: 20px;
  min-width: 20px;
  overflow: visible;
  width: 20px !important;
}

:is(html[data-theme])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker.search-picker--people.search-picker--roster
  .search-picker__selected-list:is(#roteiro-lista, #termo-oficio-lista, #os-oficio-lista) {
  display: grid;
  gap: 8px;
  max-height: 280px;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 2px;
  scrollbar-gutter: stable;
}

:is(html[data-theme])
  :is(.oficio-external-driver, [data-travel-document-wizard-roteiro]) .segment-toggle {
  border-radius: 10px;
}

:is(html[data-theme])
  [data-travel-document-wizard-diario]
  .diario-trecho-block
  .roteiro-trecho-card__leg {
  background: var(--step1-field, var(--color-input-bg));
  border: 0;
  border-radius: 12px;
  box-shadow: none;
}

:is(html[data-theme])
  [data-travel-document-wizard-diario]
  .diario-trecho-block
  :is(.roteiro-time-calc-grid, .oficio-roteiro-time-calc-grid, .roteiro-trecho-card__time-grid) {
  background: transparent;
  border: 0;
  box-shadow: none;
}

/* A regra que pintava a LISTA ABERTA dentro dos wizards saiu em 2026-08-20.

   Ela vinha de `theme-dark-components.css`, qualificava
   `.custom-select__menu--v2.floating-dropdown--active` com os sete escopos de
   wizard e por isso vencia a folha do componente. `v2/listbox.css` é o dono
   único da aparência da lista de opções — há contrato que o cobra
   (`test_nenhuma_outra_folha_v2_descreve_a_lista`), e foi assim que as duas
   listas do sistema divergiram da primeira vez. */

:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split,
:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] .route-sede-block.form-block--split:hover {
  align-items: center;
  background: var(--step1-surface) !important;
  border: 0 !important;
  border-radius: 14px;
  box-shadow: none !important;
  column-gap: 16px;
  filter: none !important;
  grid-template-columns: 14rem minmax(0, 1fr);
  margin: 0;
  padding: 14px;
  transform: none !important;
  transition: none !important;
}

/* Calendário do período: mesmo filled soft de "Novo viajante". */
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1])
  .travel-period-block--split
  :is(
    .date-picker__control:hover .date-picker__trigger--icon,
    .date-picker__control:focus-within .date-picker__trigger--icon,
    .date-picker--open .date-picker__trigger--icon
  ) {
  background: var(--step1-surface) !important;
  border: 0 !important;
  box-shadow: none !important;
  color: var(--color-heading) !important;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1])
  .travel-period-block--split
  .date-picker__trigger--icon:is(:hover, :focus-visible) {
  background: color-mix(in srgb, var(--color-accent) 14%, var(--color-surface-muted)) !important;
  border: 0 !important;
  box-shadow: none !important;
  color: var(--color-accent-text) !important;
  outline: 0;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block--split .route-destinos-trechos__sep {
  opacity: 0.7;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-row:hover {
  align-items: center;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  /* Duas metades iguais à sede: [drag + add + UF] | [Cidade + ×] */
  column-gap: 12px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  min-height: 0;
  padding: 0 !important;
  transition: none !important;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__drag-handle {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: 10px;
  color: var(--color-muted);
  cursor: grab;
  display: inline-flex;
  flex: 0 0 auto;
  height: 44px;
  justify-content: center;
  margin: 0;
  padding: 0;
  touch-action: none;
  user-select: none;
  width: 28px;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__drag-handle:active {
  cursor: grabbing;
  color: var(--color-heading);
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .route-destinos-add {
  background: color-mix(in srgb, var(--color-success) 14%, var(--step1-panel)) !important;
  color: var(--color-heading) !important;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__remove,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-remove-button {
  background: color-mix(in srgb, var(--color-danger) 12%, var(--step1-panel)) !important;
  color: var(--color-heading) !important;
  font-size: 1.25rem;
  justify-self: auto;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] :is(.roteiro-editor__empty, .summary-item) {
  background: var(--step1-field, color-mix(in srgb, var(--color-surface-muted) 88%, var(--color-primary) 12%));
  border-color: transparent;
  box-shadow: none;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-documentos]
  :is(
    .summary-item:not(.oficio-documentos-route-trecho-scroll-item),
    .oficio-documentos-fact,
    .oficio-documentos-traveller-tile:not(.oficio-documentos-traveller-tile--motorista),
    .oficio-documentos-traveller-line:not(.oficio-documentos-traveller-line--motorista),
    .oficio-documentos-vehicle-executive__driver,
    .document-inline-card,
    .oficio-documentos-route-card__diarias-subblock,
    .oficio-documentos-route-card__fallback-fact,
    .oficio-documentos-route-card__trecho
  ) {
  background: var(--step1-field, var(--color-input-bg)) !important;
  border-color: transparent !important;
}

/* Depois do poço geral: itens do scroll usam o mesmo fundo do form-block da seção */
:is(html[data-theme="dark"])
  [data-travel-document-wizard-documentos]
  .oficio-documentos-route-section
  .oficio-documentos-route-trecho-scroll-item {
  background: var(--step1-panel, var(--color-surface-soft)) !important;
  border-color: transparent !important;
  box-shadow: none !important;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker {
  --form-control-height: var(--control-height-md, 44px);
  --search-picker-height: var(--control-height-md, 44px);
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__label {
  color: var(--color-heading);
  font-size: 0.78rem;
  font-weight: var(--font-weight-black);
  text-transform: none;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row:hover {
  align-items: center;
  background: color-mix(in srgb, #fff 3.5%, var(--step1-panel, var(--color-surface-soft)));
  border: 1px solid color-mix(in srgb, var(--color-border) 40%, transparent);
  border-radius: 12px;
  box-shadow: none;
  column-gap: 12px;
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) 40px;
  min-height: 78px;
  padding: 11px 10px 11px 12px;
  row-gap: 0;
  transition: background-color 140ms ease, border-color 140ms ease;
  user-select: none;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.destination-row:hover {
  background: color-mix(in srgb, var(--color-accent) 6%, var(--step1-panel, var(--color-surface-soft)));
  border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row__fields .app-form-label {
  color: var(--color-muted-strong);
  font-size: 0.72rem;
  font-weight: var(--font-weight-bold);
  margin: 0;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row__remove:hover,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row__remove:focus-visible,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .destination-row > .ordered-field-row__remove:hover,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .destination-row > .ordered-field-row__remove:focus-visible {
  background: transparent;
  border-color: color-mix(in srgb, var(--color-border) 55%, transparent);
  border-left-color: color-mix(in srgb, var(--color-border) 55%, transparent);
  box-shadow: none;
  color: transparent;
  outline: 0;
  transform: none;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.is-dragging {
  opacity: 0.72;
  transform: scale(0.985);
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], .termos-page, [data-travel-document-wizard-step1], [data-evento-guided-form]) .ordered-field-row.is-drop-target {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--color-accent) 55%, transparent);
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .route-destinos-add,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__add,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row__remove,
:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .destination-remove-button {
  align-self: center;
  border: 0 !important;
  border-radius: 10px !important;
  cursor: pointer;
  flex: 0 0 auto;
  height: 44px;
  margin: 0 !important;
  min-width: 44px;
  opacity: 1 !important;
  transform: none !important;
  width: 44px;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .route-destinos-block .ordered-field-row.is-drop-target {
  box-shadow: none;
}

:is(html[data-theme="dark"])
  .roteiro-editor--oficio .roteiro-editor__switch-row .field-side-action--danger {
  background: var(--color-input-bg);
  border-color: var(--color-border);
  box-shadow: none;
  color: var(--color-muted-strong);
}

:is(html[data-theme="dark"])
  .roteiro-editor--oficio .roteiro-editor__switch-row .field-side-action--danger:hover {
  background: var(--color-input-bg);
  border-color: color-mix(in srgb, var(--color-border) 78%, var(--color-text) 22%);
  box-shadow: none;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg.route-bate-volta-leg.form-block--split {
  align-items: center;
  background: var(--step1-surface, var(--color-surface-muted));
  border: 0;
  border-radius: 14px;
  box-shadow: none;
  column-gap: 16px;
  /* Mesma coluna fixa da Sede (14rem) — Ida/Volta não encolhem no texto. */
  grid-template-columns: 14rem minmax(0, 1fr);
  margin: 0;
  padding: 12px 14px;
  row-gap: 0;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__leg .form-block__title {
  color: var(--color-heading);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-black);
  letter-spacing: 0;
  text-transform: none;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-roteiro] .oficio-roteiro-bate-volta__fields .cv-field__label {
  color: var(--color-muted-strong);
  font-size: 0.72rem;
  font-weight: var(--font-weight-bold);
  margin: 0;
}

:is(html[data-theme="dark"])
  :is([data-travel-document-wizard-roteiro], [data-travel-document-wizard-step1]) .related-route-picker .search-picker__selected-avatar .related-route-icon path {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

:is(html[data-theme="dark"])
  :is(.oficio-external-driver, [data-travel-document-wizard-roteiro]) .segment-toggle {
  background: var(--step1-field, var(--color-input-bg));
  border-color: transparent;
  box-shadow: none;
  display: inline-grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 3px;
}

/* ── de `fields/forms.css` ── */

.roteiro-editor__actions .btn-outline-secondary {
  background: var(--route-button-secondary-bg);
  border-color: var(--route-button-secondary-border);
  color: var(--route-button-secondary-text);
}

.roteiro-editor__actions .btn-outline-secondary:hover,
.roteiro-editor__actions .btn-outline-secondary:focus-visible {
  background: var(--route-button-secondary-hover-bg);
  border-color: var(--route-button-secondary-hover-border);
  color: var(--route-button-secondary-text);
}
/* <<< css/v2/route-editor.css <<< */

/* >>> css/v2/pdf-place.css >>> */
/* Posicionar algo sobre um PDF — o palco, as caixas arrastáveis e a legenda.
 *
 * Par de `js/components/pdf-place.js`. Vale para a tela interna de ajuste do carimbo do
 * número de solicitação.
 *
 * A tela PÚBLICA de assinatura tem o mesmo comportamento e desenho próprio
 * (`css/pages/prestacoes-assinatura.css`, classes `asgn-*`): ela roda fora do casco do
 * sistema, com paleta própria, e trazê-la para os tokens do v2 é uma mudança visual de
 * outra conversa. O que as duas telas compartilham é o MOTOR, não a pele.
 */

:is(html[data-theme]) .pdf-place__pager {
  align-items: center;
  display: flex;
  gap: var(--space-1);
}

:is(html[data-theme]) .pdf-place__pager-label {
  color: var(--text-muted);
  font-size: var(--font-size-sm);
  min-width: 3.2rem;
  text-align: center;
}

/* O palco é o cinza de trás da folha: sem ele a página branca do PDF encosta no fundo
   do painel e some a silhueta do documento, que é o que diz onde a página começa. */
:is(html[data-theme]) .pdf-place__viewer {
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  display: flex;
  justify-content: center;
  overflow: auto;
  padding: var(--space-2);
}

:is(html[data-theme]) .pdf-place__stage {
  position: relative;
}

/* A folha é BRANCA nos dois temas, e por token: não é cor de interface, é o papel do
   documento. Escurecê-la no tema escuro mudaria o que o operador vê em relação ao PDF
   que vai sair impresso. */
:is(html[data-theme]) .pdf-place__stage canvas {
  background: var(--paper);
  box-shadow: var(--shadow-soft);
  display: block;
}

/* A caixa é TRACEJADA e translúcida de propósito: ela cobre um pedaço do ofício, e um
   retângulo opaco esconderia justamente a linha da tabela que o operador está mirando. */
:is(html[data-theme]) .pdf-place__box {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1.5px dashed var(--accent);
  cursor: move;
  display: flex;
  justify-content: flex-start;
  position: absolute;
  touch-action: none;
}

:is(html[data-theme]) .pdf-place__box-text {
  /* Preto porque é a tinta do carimbo: `carimbo_services` desenha em
     `setFillColorRGB(0, 0, 0)`, e a prévia tem de mostrar o que vai para o PDF. */
  color: var(--paper-ink);
  font-family: Helvetica, Arial, sans-serif;
  line-height: 1;
  /* O texto acompanha a altura da caixa porque é dela que sai o corpo da fonte do
     carimbo — o que se vê aqui tem de ser o tamanho que vai para o PDF. */
  font-size: inherit;
  pointer-events: none;
  white-space: nowrap;
}

:is(html[data-theme]) .pdf-place__box--ativa {
  border-style: solid;
}

:is(html[data-theme]) .pdf-place__box-handle {
  background: var(--accent);
  border: 2px solid var(--paper);
  border-radius: 50%;
  bottom: -9px;
  cursor: nwse-resize;
  height: 18px;
  position: absolute;
  right: -9px;
  touch-action: none;
  width: 18px;
}

:is(html[data-theme]) .pdf-place__legenda {
  display: grid;
  gap: var(--space-1);
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
}

:is(html[data-theme]) .pdf-place__legenda-item {
  align-items: center;
  background: var(--surface-contrast, var(--surface));
  border-radius: var(--radius-field);
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2);
}

:is(html[data-theme]) .pdf-place__legenda-nome {
  color: var(--text-strong);
  flex: 1 1 auto;
  min-width: 0;
}

:is(html[data-theme]) .pdf-place__legenda-numero {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* <<< css/v2/pdf-place.css <<< */

/* >>> css/v2/person-row.css >>> */
/* Linha de pessoa — o item da faixa de um registro. Depende de `v2/tokens.css`.
 *
 * A faixa é o degrau seguinte ao do registro: `--surface-contrast` já aponta
 * para ele, então a lista não precisa de borda para se separar do cartão. Foi
 * a mesma decisão da caixa dos escolhidos no picker.
 */

/* A lista NÃO tem superfície própria: ela é só a grade que arruma as linhas.
   A caixa que existia aqui punha um terceiro degrau entre o registro e as
   linhas — três tons empilhados para uma informação só, e a linha ficava
   afundada num quadro que não delimitava nada que o registro já não
   delimitasse. Sem ela, as linhas seguem o degrau do PAI, que é quem sabe em
   qual superfície está.

   E não tem CAIXA: `display: contents` a dissolve, e quem arruma as colunas é o
   contêiner — o miolo do registro, em `v2/record.css`. Enquanto ela era um
   bloco havia um nível a mais entre o cartão e a linha, e a lista não batia com
   a régua do título logo acima. A `ul` continua na marcação pela semântica: uma
   equipe é uma lista, e o leitor de tela anuncia quantos são. */
:is(html[data-theme]) .person-list {
  display: contents;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Algumas equipes são o conteúdo principal do bloco, sem a grade de um
   `record` ao redor. Nesses casos a própria lista assume as duas colunas; o
   modificador mantém a semântica da `ul` e reutiliza integralmente a linha V2. */
:is(html[data-theme]) .person-list.person-list--two-columns {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
}

/* Em número ímpar, o último ocupa a linha inteira — sozinho em meia largura ele
   fica ao lado de um vazio, e o vazio se lê como alguém faltando. A conta de
   `nth-child` continua valendo com `display: contents`: ela olha a marcação,
   não a caixa. */
:is(html[data-theme]) .person-list > .person-row:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

:is(html[data-theme]) .person-row {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: auto minmax(0, 1fr) auto;
  min-width: 0;
  padding: var(--gap-tight);
}

/* Iniciais em caixa quadrada, no accent — é a âncora de varredura da faixa. */
:is(html[data-theme]) .person-row__avatar {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: var(--radius-field);
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  /* Do tamanho das DUAS linhas que ela ancora — nome e cargo. Na medida menor a
     caixa flutuava no meio da linha, sem encostar em nada, e a fileira de
     iniciais perdia a régua que a torna varrível. */
  height: var(--control-height);
  justify-content: center;
  letter-spacing: 0.02em;
  width: var(--control-height);
}

/* A viatura é a mesma linha com outro tom: o selo já diz o que ela é, e mudar
   a forma faria a faixa parecer duas listas. */
/* A linha de DOCUMENTO leva ícone no lugar das iniciais, e o avatar vai cheio:
   é o mesmo escolhido do picker — accent sólido, desenho na cor de cima do
   accent. Translúcido com um traço fino dentro, que é como o das iniciais
   funciona, sumia na fileira. */
:is(html[data-theme]) .person-row__avatar--icon {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}

:is(html[data-theme]) .person-row__avatar--icon svg {
  height: 20px;
  width: 20px;
}

:is(html[data-theme]) .person-row--viatura .person-row__avatar {
  background: color-mix(in srgb, var(--status-info) 16%, transparent);
  border-color: color-mix(in srgb, var(--status-info) 32%, transparent);
  color: var(--status-info);
}

:is(html[data-theme]) .person-row__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* `nowrap` porque o selo pertence ao nome: mandado para a linha de baixo ele
   vira um rótulo solto, sem dizer de quem é. O componente permite um selo só,
   então não há fila para quebrar. */
:is(html[data-theme]) .person-row__name-row {
  align-items: center;
  display: flex;
  flex-wrap: nowrap;
  gap: var(--gap-tight);
  min-width: 0;
}

/* `min-width: 0` é o que faz as reticências existirem: como item de flex o
   nome não encolhe abaixo do próprio conteúdo por padrão, então um nome de
   arquivo comprido empurrava o selo para a segunda linha e o
   `text-overflow` abaixo nunca chegava a agir. */
:is(html[data-theme]) .person-row__name {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Selo informativo, no tom accent e na mesma linguagem do `chip--v2`: fundo
   translúcido a 16% e a cor cheia no texto. Em cinza sobre a superfície vizinha
   ele desaparecia — e um selo que não se vê não informa nada. */
:is(html[data-theme]) .person-row__badge {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-radius: var(--radius-pill);
  color: var(--accent);
  flex: 0 0 auto;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  padding: 3px 10px;
  white-space: nowrap;
}

:is(html[data-theme]) .person-row__meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .person-row__actions {
  align-items: center;
  display: flex;
  flex: 0 0 auto;
  gap: var(--gap-tight);
}

/* Linha de FATO: um par rótulo + texto na mesma faixa das pessoas — motivo da
   viagem, quem assina. Não tem âncora porque não é alguém: as iniciais existem
   para achar uma pessoa na lista, e uma caixa vazia no lugar delas só abriria
   um buraco no alinhamento. */
:is(html[data-theme]) .person-row--fact {
  grid-template-columns: minmax(0, 1fr) auto;
}

:is(html[data-theme]) .person-row--fact .person-row__avatar {
  display: none;
}

/* Aqui o rótulo é que é miúdo, e o texto embaixo é o dado — o contrário da
   linha de pessoa, onde o nome lidera. */
:is(html[data-theme]) .person-row--fact .person-row__name {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

:is(html[data-theme]) .person-row--fact .person-row__meta {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  white-space: normal;
}

/* O motorista é o único servidor com realce na faixa — mesmo critério do picker:
   numa lista em que todos foram escolhidos, o que se precisa saber de relance é
   quem dirige. Cor própria e âncora cheia, como o escolhido em destaque. */
:is(html[data-theme]) .person-row--driver {
  /* `--surface-driver`, e não `--surface-selected`: a linha do motorista é
     marca de PAPEL, não item escolhido numa lista. Ver a nota do token. */
  background: var(--surface-driver);
  box-shadow: inset 3px 0 0 0 var(--accent);
}

:is(html[data-theme]) .person-row--driver .person-row__avatar {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}

/* O botão da linha no RAIL, e SEM contorno: a linha está no degrau `field`, e o
   botão desce um degrau — a diferença de superfície já o separa do que está
   atrás. O contorno em cima disso era a segunda vez que a mesma borda era dita,
   e é a regra do sistema (`v2/surface.css`) que só a primeira camada sobre a
   página tem linha. */
:is(html[data-theme]) .person-row__actions .icon-button {
  --icon-button-surface: var(--surface-rail);

  border: 0;
}
/* <<< css/v2/person-row.css <<< */

/* >>> css/v2/choice-card.css >>> */
/* Cartão de escolha — o rádio que ocupa uma caixa, com título e explicação.
 * Depende de `v2/tokens.css`.
 *
 * Duas marcações, UMA declaração: `.choice-card`/`.choice-grid` são o
 * componente do v2 (`c-v2.choice_card`, `c-v2.choice_grid`); `os-model-card` é a
 * marcação que a Ordem de Serviço ainda escreve à mão e que o componente vai
 * absorver. Enquanto as duas existem elas dividem os MESMOS blocos de regra —
 * duplicar o desenho é como ele passa a ter dois donos e começa a divergir.
 *
 * SEM hover: aqui o cartão inteiro é o alvo do clique, e um realce que segue o
 * cursor pela grade compete com a marca do que está de fato escolhido. Numa
 * lista de opções o que importa é qual delas vale, não por onde o mouse passou.
 *
 * O estado escolhido é o MESMO do resto do sistema — cor própria
 * (`--surface-selected`) e fita de accent à esquerda —, o mesmo que marca a
 * opção do menu, o motorista da equipe e a viatura do termo. Uma quarta forma
 * de dizer "este é o escolhido" seria uma quarta coisa para aprender.
 */

:is(html[data-theme]) .os-model-picker {
  border: 0;
  margin: 0;
  min-width: 0;
  padding: 0;
}

:is(html[data-theme]) .os-model-picker__grid,
:is(html[data-theme]) .choice-grid {
  display: grid;
  gap: var(--gap-tight);
  /* DUAS colunas, ou uma. `auto-fit` com mínimo estreito deixava a grade cair
     para três em tela larga, e com três a explicação de cada opção fica com uma
     coluna de texto fina demais para se ler de corrida. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
}

/* Em número ímpar, o último ocupa a linha inteira. Sozinho em meia largura ele
   fica ao lado de um vazio, e o vazio se lê como opção faltando. */
:is(html[data-theme]) .os-model-picker__grid > .os-model-card:last-child:nth-child(odd),
:is(html[data-theme]) .choice-grid:not(.choice-grid--dense) > .choice-card:last-child:nth-child(odd),
:is(html[data-theme]) .choice-grid:not(.choice-grid--dense) > .choice-card-field:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

@media (max-width: 720px) {
  :is(html[data-theme]) .os-model-picker__grid,
  :is(html[data-theme]) .choice-grid:not(.choice-grid--dense) {
    grid-template-columns: minmax(0, 1fr);
  }
}

:is(html[data-theme]) .os-model-card,
:is(html[data-theme]) .choice-card {
  /* `center`: a marca do rádio acompanha o bloco de texto inteiro, e não a
     primeira linha dele. Alinhada ao topo, ela ficava solta acima da explicação
     nos cartões de duas ou três linhas. */
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 0;
  border-radius: var(--radius-field);
  box-shadow: none;
  box-sizing: border-box;
  cursor: pointer;
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: minmax(0, 1fr);
  margin: 0;
  min-width: 0;
  padding: var(--gap);
}

/* O `<input>` de verdade fica invisível mas continua no fluxo do teclado: quem
   navega por Tab precisa alcançá-lo, e `display: none` o tiraria da ordem. */
/* Vale para QUALQUER `<input>` dentro do cartão, e não só para o que o
   componente escreve: quando o controle vem do formulário do Django
   (`{{ form.ativo }}`), a classe é a que o Python deu — medido, a caixa nativa
   aparecia inteira no meio do cartão e dobrava a altura dele. */
:is(html[data-theme]) .os-model-card input[type="radio"],
:is(html[data-theme]) .choice-card input[type="checkbox"],
:is(html[data-theme]) .choice-card input[type="radio"],
:is(html[data-theme]) .choice-card__input {
  height: 0;
  opacity: 0;
  position: absolute;
  width: 0;
}

/* SEM marca de rádio (2026-08-16). O cartão escolhido já se anuncia por três
   coisas ao mesmo tempo — cor própria (`--surface-selected`), fita de accent à
   esquerda e título no accent —, e o círculo era uma quarta. Numa lista de duas a
   quatro opções, quatro sinais para "este é o escolhido" é ruído, não reforço.

   O `<input>` continua no fluxo do teclado (invisível, mas presente) e o anel de
   foco vai no CARTÃO, mais abaixo: quem navega por Tab não perde a posição. */
:is(html[data-theme]) .os-model-card__mark {
  display: none;
}

:is(html[data-theme]) .os-model-card__body,
:is(html[data-theme]) .choice-card__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .os-model-card__title,
:is(html[data-theme]) .choice-card__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  line-height: 1.25;
}

:is(html[data-theme]) .os-model-card__hint,
:is(html[data-theme]) .choice-card__hint {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  line-height: 1.35;
}

/* ---- o escolhido ---------------------------------------------------------- */

:is(html[data-theme]) .os-model-card.is-selected,
:is(html[data-theme]) .os-model-card:has(input:checked),
:is(html[data-theme]) .choice-card.is-selected,
:is(html[data-theme]) .choice-card:has(input:checked) {
  background: var(--surface-selected);
  box-shadow: inset 3px 0 0 0 var(--accent);
}

:is(html[data-theme]) .os-model-card.is-selected .os-model-card__title,
:is(html[data-theme]) .os-model-card:has(input:checked) .os-model-card__title,
:is(html[data-theme]) .choice-card.is-selected .choice-card__title,
:is(html[data-theme]) .choice-card:has(input:checked) .choice-card__title {
  color: var(--accent);
}

/* O anel vai no CARTÃO somente quando o navegador reconhece navegação por
   teclado. `:focus-within` puro também acendia no clique e deixava o destaque
   preso depois da escolha, competindo com o estado selecionado. */
:is(html[data-theme]) .os-model-card:has(input:focus-visible),
:is(html[data-theme]) .choice-card:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}


/* ---- a grade densa --------------------------------------------------------
 *
 * Quando cada cartão carrega SÓ um nome — as atividades do plano de trabalho —
 * duas colunas deixam trinta opções numa rolagem longa e metade da largura
 * vazia. Aqui o número de colunas vem da largura disponível, com 220px de piso:
 * abaixo disso o nome de uma atividade quebra em três linhas.
 */
:is(html[data-theme]) .choice-grid--dense {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* Numa grade densa o cartão vive de um nome só: o padding cheio do cartão de
   duas linhas empilharia altura por trinta itens. */
:is(html[data-theme]) .choice-grid--dense > .choice-card {
  padding: var(--gap-tight) var(--gap);
}

/* O vazio da BUSCA, não o da lista: nasce oculto e é o script da tela que o
   mostra quando o filtro não acha nada. Some junto com a grade — quem digitou
   precisa saber que digitou, não achar que a lista esvaziou. */
:is(html[data-theme]) .choice-grid__empty {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  margin: var(--gap-tight) 0 0;
}

/* O cartão que vem de um formulário carrega o erro EMBAIXO, e não dentro: um
   `<label>` só aceita conteúdo de frase, e o parágrafo de erro dentro dele é
   documento inválido. O invólucro só existe nesse caso — na grade de opções o
   cartão continua sendo filho direto, que é o que faz a regra de "ímpar ocupa a
   linha" funcionar. */
:is(html[data-theme]) .choice-card-field {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

/* A faixa de controles da grade — filtrar, aplicar um modelo, limpar. Mesma
   forma da faixa de uma lista (`rail__form`): tudo na linha, o campo de busca
   crescendo e os botões no tamanho do próprio rótulo. */
:is(html[data-theme]) .choice-grid__toolbar {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  margin-bottom: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .choice-grid__toolbar > .input {
  flex: 1 1 220px;
  min-width: 0;
}

:is(html[data-theme]) .choice-grid__toolbar > .select {
  flex: 0 1 240px;
  min-width: 0;
}

/* Busca/limpeza ficam juntas à esquerda; o preset gerenciável ocupa o extremo
   direito com o `select_with_action` global. */
:is(html[data-theme]) .choice-grid__toolbar-start,
:is(html[data-theme]) .choice-grid__toolbar-end {
  align-items: center;
  display: flex;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .choice-grid__toolbar-start[hidden],
:is(html[data-theme]) .choice-grid__toolbar-end[hidden] {
  display: none;
}

:is(html[data-theme]) .choice-grid__toolbar-start {
  flex: 1 1 420px;
}

:is(html[data-theme]) .choice-grid__toolbar-start > .input {
  flex: 1 1 220px;
  min-width: 0;
}

:is(html[data-theme]) .choice-grid__toolbar-end {
  flex: 0 1 320px;
  margin-left: auto;
}

:is(html[data-theme]) .choice-grid__toolbar-end > .field-with-action {
  flex: 1 1 auto;
  min-width: 0;
}

/* Na etapa de atividades, a busca ocupa uma metade completa; limpar e aplicar
   preset compartilham a outra. A marcação agrupada continua sendo a do
   componente, mas aqui as duas responsabilidades têm pesos iguais. */
:is(html[data-theme]) [data-pt-activity] .choice-grid__toolbar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

:is(html[data-theme]) [data-pt-activity] .choice-grid__toolbar-start,
:is(html[data-theme]) [data-pt-activity] .choice-grid__toolbar-end {
  margin-left: 0;
  width: 100%;
}

@media (max-width: 720px) {
  :is(html[data-theme]) [data-pt-activity] .choice-grid__toolbar {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* <<< css/v2/choice-card.css <<< */

/* >>> css/v2/icon-button.css >>> */
/* Icon button — ação sem rótulo, circular. Depende de `v2/tokens.css`. */

:is(html[data-theme]) .icon-button {
  align-items: center;
  /* A superfície de repouso vive numa VARIÁVEL, e não no `background` direto:
     três lugares do sistema precisam de um degrau diferente (a linha de pessoa,
     o cartão do evento, a linha do file picker), e cada um deles sobrescrevia o
     `background` com seletor mais específico — que também vencia no `:hover`.
     Resultado medido: o botão da linha de ofício não reagia ao ponteiro.
     Trocando a variável, o realce continua saindo da regra de hover. */
  background: var(--icon-button-surface, var(--surface-contrast, var(--surface-field)));
  border: 0;
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  flex: none;
  height: var(--control-height);
  justify-content: center;
  text-decoration: none;
  transition: background var(--ease), color var(--ease);
  width: var(--control-height);
}

:is(html[data-theme]) .icon-button svg {
  height: 18px;
  width: 18px;
}

/* Mesmo hover do botão secundário (`v2/button.css:107`): a superfície recebe
   14% do accent e o conteúdo assume o accent. Os dois são ações de mesma
   ênfase; ter realces diferentes faria a lista piscar em dois padrões. */
:is(html[data-theme]) .icon-button:hover {
  background: color-mix(
    in srgb,
    var(--accent) 14%,
    var(--icon-button-surface, var(--surface-contrast, var(--surface-rail)))
  );
  color: var(--accent);
}

:is(html[data-theme]) .icon-button[data-tone="late"]:hover {
  color: var(--status-late);
}

:is(html[data-theme]) .icon-button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
/* <<< css/v2/icon-button.css <<< */

/* >>> css/v2/modal.css >>> */
/* Modal — diálogo. Depende de `v2/tokens.css`.
 *
 * O `<dialog>` nativo já dá camada de topo, foco preso e Esc. Não há JS aqui.
 */

:is(html[data-theme]) .modal {
  /* O diálogo DECLARA o próprio degrau, e não só a cor de fundo. Sem isto o botão
     secundário dentro dele — que se pinta com `--surface-contrast` — herdava o
     contraste da página e saía da MESMA cor da caixa: o "Voltar" ficava invisível
     nos três diálogos de ação, e só se achava pelo texto.

     As duas cores vêm dos tokens BASE: pintar de `--surface-contrast` e redefinir
     essa mesma variável para os filhos é referência circular, e a escada
     desaparece sem erro. É a terceira vez que este par aparece nesta migração
     (faixa de pessoas, painel do quick add, aqui). */
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
  background: var(--surface-rail);
  border: 0;
  border-radius: var(--radius-rail);
  color: var(--text-strong);
  max-width: min(560px, calc(100vw - 32px));
  padding: 0;
  width: 100%;
}

:is(html[data-theme]) .modal::backdrop {
  background: rgb(0 0 0 / 0.5);
}

:is(html[data-theme]) .modal__shell {
  display: grid;
  gap: var(--gap);
  padding: var(--gap-loose);
}

:is(html[data-theme]) .modal__title {
  font-size: var(--text-size-title);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .modal__body {
  display: grid;
  gap: var(--gap);
}

:is(html[data-theme]) .modal__actions {
  display: flex;
  gap: var(--gap-tight);
  justify-content: flex-end;
}

/* A mensagem do diálogo de confirmação: texto corrido, com o nome do registro em
   destaque. O `<strong>` é o que o `overlay.js` preenche — o rótulo vem do gatilho
   e não do template, porque um diálogo serve a lista inteira. */
:is(html[data-theme]) .modal__message {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  margin: 0 0 var(--gap);
}

/* ---- anexar assinado ------------------------------------------------------
   O seletor de TIPO nasce oculto e o JS monta os botoes dentro dele: ele so
   existe quando o gatilho declara mais de um documento anexavel. O par
   `[hidden]` e obrigatorio porque o `display` daqui vence a regra de agente do
   usuario -- sem ele o seletor aparece vazio em todo diálogo. */
:is(html[data-theme]) .attach-signed__kind {
  display: grid;
  gap: var(--gap-tight);
  /* Estica (padrão da grade): aqui o toggle é `--fill`, ocupa a linha e reparte
     os tipos em colunas iguais. Ele já ficou ancorado à esquerda, no tamanho do
     texto — e a faixa vazia à direita fazia a escolha parecer secundária, quando
     é ela que decide o que o diálogo vai anexar. */
  min-width: 0;
}

:is(html[data-theme]) .attach-signed__kind[hidden] {
  display: none;
}

:is(html[data-theme]) .attach-signed__kind-status {
  color: var(--accent);
  font-weight: var(--font-weight-bold);
  margin-inline-start: var(--gap-tight);
}

:is(html[data-theme]) .attach-signed__kind-status[hidden] {
  display: none;
}

/* O corpo do diálogo é uma PILHA com vão: seletor de tipo, seletor de arquivo,
   erro, arquivo já anexado. Sem isto o toggle encostava no bloco do picker, como
   se fossem a mesma peça. Grade, e não margem em cada filho: quem entra ou sai da
   pilha (o tipo só existe com dois ou mais documentos) não precisa saber de vão —
   e filho oculto não deixa buraco, que é o que margem faria. */
:is(html[data-theme]) .modal--attach-signed [data-attach-signed-form] {
  display: grid;
  gap: var(--gap);
}

/* A lista do arquivo ja anexado tambem nasce oculta: so faz sentido quando existe
   um assinado, e e o JS que a revela com o nome preenchido. */
:is(html[data-theme]) .attach-signed__current[hidden] {
  display: none;
}
/* <<< css/v2/modal.css <<< */

/* >>> css/v2/form-errors.css >>> */
/* Resumo de erros do formulário. Depende de `v2/tokens.css`. */

/* A caixa vem do `alert` global — fundo, fitinha, raio e recuo. Aqui fica só o
   que é do RESUMO: as duas partes empilhadas com respiro entre si.

   O que estava aqui antes misturava o tom com `--surface-field` a 14%, e era a
   última regra do v2 a fazer isso: no escuro o vermelho virava arroxeado. O
   alerta mistura com transparente e se adapta aos dois temas. */
:is(html[data-theme]) .form-errors {
  display: grid;
  gap: 6px;
}

:is(html[data-theme]) .form-errors__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .form-errors__list {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  margin: 0;
  padding-left: 18px;
}
/* <<< css/v2/form-errors.css <<< */

/* >>> css/v2/card-footer.css >>> */
/* Rodapé de ações. Depende de `v2/tokens.css`. */

:is(html[data-theme]) .card-footer {
  align-items: center;
  /* Declarada, e não omitida: `.card-footer` colide com uma classe legada que
     desenha a régua. Não declarar aqui é deixar a régua viva — omissão não
     vence regra nenhuma. */
  border: 0;
  display: flex;
  /* Sem recuo próprio: o rodapé se alinha com os blocos do painel, e quem dá o
     respiro é o painel. O legado põe `padding: 16px 24px` aqui — e, como a
     classe colide, não declarar é herdar: os botões nasciam 24px para dentro da
     borda dos blocos, desalinhados de tudo na página. */
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
  gap: var(--gap);
  justify-content: space-between;
}

/* Sem linha de separação: o rodapé mora DENTRO do painel, e ali a separação já
   vem do vão entre ele e o último bloco. A régua era necessária quando ele
   flutuava solto no fundo da página, sem nada em volta que o contivesse. */

:is(html[data-theme]) .card-footer__side {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
}
/* <<< css/v2/card-footer.css <<< */

/* >>> css/v2/stepper.css >>> */
/* Stepper — etapas do wizard. Depende de `v2/tokens.css`.
 *
 * O estado vem de `data-state`, não de classe: são três valores mutuamente
 * exclusivos, e atributo deixa isso explícito no markup.
 *
 * O desenho é uma CORDA COM NÓS, escolhido pelo dono em 2026-08-19 entre
 * quatro modelos provados lado a lado na galeria (trilha segmentada, fita,
 * compacto e este). Os outros três saíram da folha junto com o painel de
 * prova; o histórico está no git.
 *
 * Duas ideias sustentam o desenho:
 *
 * 1. A corda é UMA. O trecho vai de centro a centro dos nós e some por trás do
 *    círculo, que é opaco. O desenho anterior parava a linha antes de cada
 *    marcador — eram quatro traços separados, e a fileira lia como corrente,
 *    não como caminho.
 *
 * 2. Uma cor só. Accent no que já andou — trecho e nó —, e a diferença entre
 *    feito e atual é INTENSIDADE (nó contornado × nó cheio), não outro matiz.
 *    Verde de `--status-done` ao lado do accent punha duas cores saturadas
 *    competindo na mesma fileira; no tema escuro, verde contra dourado.
 *    `--status-done` segue verde nos selos, onde a leitura é mesmo de estado.
 */

/* A corda ocupa o trilho INTEIRO, tenha ele três nós ou seis. O stepper entra
   como filho da fila de controles do rail, que é um flex: sem `flex: 1` a
   fileira fica do tamanho do conteúdo e a corda morre no meio da faixa, com o
   vão sobrando à direita. */
:is(html[data-theme]) .stepper {
  flex: 1;
  min-width: 0;
}

:is(html[data-theme]) .stepper__list {
  display: grid;
  gap: 0;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Colunas iguais (`1fr`), e não largura por conteúdo: com "Justificativa" e
   "Dados e viajantes" na mesma fileira, a distância entre nós mudaria a cada
   etapa e a corda sairia com vãos de tamanhos diferentes. */
:is(html[data-theme]) .stepper__item {
  color: var(--text-muted);
  display: grid;
  gap: 8px;
  min-width: 0;
  padding: 0 var(--gap-tight);
  position: relative;
  text-align: center;
}

:is(html[data-theme]) .stepper__item[data-state="current"] {
  color: var(--text-strong);
}

/* O vão: do centro do nó anterior ao centro deste, na linha do meio do círculo
   (13px, com os 2px do traço fechando os 14px de metade do nó). De centro a
   centro, e não de borda a borda, para sumir POR TRÁS do nó — é o que faz os
   trechos lerem como uma corda só. */
:is(html[data-theme]) .stepper__item::before {
  background: var(--line);
  border-radius: var(--radius-pill);
  content: "";
  height: 2px;
  left: -50%;
  position: absolute;
  top: 13px;
  width: 100%;
}

:is(html[data-theme]) .stepper__item:first-child::before {
  display: none;
}

/* O trecho que entra na etapa atual também é corda andada: foi por ele que se
   chegou aqui. */
:is(html[data-theme]) .stepper__item[data-state="done"]::before,
:is(html[data-theme]) .stepper__item[data-state="current"]::before {
  background: var(--accent);
}

/* O nó. Opaco de propósito — é ele que corta a corda que passa atrás. O
   `--surface` do contêiner, com o trilho como reserva, porque nem toda camada
   declara o token (em `v2/surface.css` quem declara são as camadas). */
:is(html[data-theme]) .stepper__marker {
  align-items: center;
  background: var(--surface, var(--surface-rail));
  border: 2px solid var(--line);
  border-radius: var(--radius-pill);
  box-sizing: border-box;
  color: var(--text-muted);
  display: inline-flex;
  flex: none;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  height: 28px;
  justify-content: center;
  justify-self: center;
  position: relative;
  width: 28px;
  z-index: 1;
}

/* Nó já dado: contorno em accent e check em accent, sem preenchimento. Cheio
   ele pesaria igual ao da etapa atual; e preencher com accent DILUÍDO não é
   opção — `color-mix` do dourado com a superfície escura cai em oliva
   (medido: `#78611b`), que é a armadilha anotada em `v2/tokens.css`. */
:is(html[data-theme]) .stepper__item[data-state="done"] .stepper__marker {
  border-color: var(--accent);
  color: var(--accent);
}

:is(html[data-theme]) .stepper__item[data-state="done"] .stepper__marker svg {
  height: 14px;
  width: 14px;
}

/* O nó apertado: accent cheio e um halo, que marca a etapa sem AUMENTAR o
   círculo — crescer o nó levantaria a ponta da corda e o vão sairia torto. */
:is(html[data-theme]) .stepper__item[data-state="current"] .stepper__marker {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--text-on-accent);
}

:is(html[data-theme]) .stepper__copy {
  display: grid;
  gap: 1px;
  min-width: 0;
}

/* Rótulo no menor degrau da escala: a fileira é navegação, não conteúdo, e
   quem carrega a etapa aqui é o nó. */
:is(html[data-theme]) .stepper__label {
  font-size: var(--text-size-micro);
  font-weight: var(--weight-normal);
  line-height: 1.35;
}

:is(html[data-theme]) .stepper__item[data-state="current"] .stepper__label {
  color: var(--text-strong);
  font-weight: var(--weight-strong);
}

/* Fora da tela, não fora do documento: em caixa alta sob cada etapa o status
   repetia o que o nó e o check já dizem, mas quem usa leitor de tela continua
   ouvindo "Concluída" / "Em andamento" ao percorrer a lista. */
:is(html[data-theme]) .stepper__status {
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* A etapa navegável (painel do evento). O link herda a cor do item — pintá-lo
   de azul de link faria as cinco etapas competirem com o conteúdo da página —,
   e é ele quem carrega o alvo do clique, do tamanho da etapa inteira. Repete o
   empilhamento do item porque, com `url`, nó e rótulo são filhos DELE. */
:is(html[data-theme]) .stepper__link {
  color: inherit;
  display: grid;
  gap: 8px;
  min-width: 0;
  text-decoration: none;
}

:is(html[data-theme]) .stepper__link:hover .stepper__label {
  text-decoration: underline;
}

/* Em tela estreita a corda fica de pé: o mesmo trecho reto, agora de nó a nó
   na vertical, e o rótulo passa para o lado. Quatro rótulos lado a lado em
   360px quebram cada um em três linhas e a fileira perde a leitura. */
@media (max-width: 720px) {
  :is(html[data-theme]) .stepper__list {
    gap: 14px;
    grid-auto-flow: row;
  }

  :is(html[data-theme]) .stepper__item {
    align-items: center;
    grid-template-columns: auto 1fr;
    padding: 0;
    text-align: left;
  }

  :is(html[data-theme]) .stepper__item::before {
    height: 14px;
    left: 13px;
    top: -14px;
    width: 2px;
  }

  :is(html[data-theme]) .stepper__link {
    align-items: center;
    grid-template-columns: auto 1fr;
  }
}

/* Header e stepper formam a navegação do wizard; o conteúdo da etapa começa
   depois de um intervalo completo, sem colar a primeira lista ao rail.

   O espaço pertence ao próprio rail: algumas etapas inserem um `<script>` JSON
   antes do painel e, com um seletor de irmão adjacente, a margem era aplicada ao
   elemento invisível em vez de separar visualmente o painel. */
:is(html[data-theme]) .wizard-page > .rail {
  margin-bottom: var(--gap);
}

/* A faixa do stepper acompanha a rolagem (2026-08-19, a pedido do dono): fica
   colada ao header enquanto ele está na tela e, quando ele sobe, para no topo
   e passa a flutuar sobre o conteúdo da etapa. Em wizard longo é a única peça
   que diz onde se está — rolando três telas de formulário, ela sumia.
   `sticky`, e não JS: o comportamento é do navegador, e o componente legado
   `wizard-sticky-header.js` media posição a cada quadro para chegar no mesmo
   lugar. A sombra existe para a faixa não encostar no conteúdo que passa por
   baixo dela. */
:is(html[data-theme]) .wizard-page > .rail,
:is(html[data-theme]) .wizard-sticky-scope > .rail {
  box-shadow: var(--shadow-menu);
  position: sticky;
  /* Não `0`: parada no topo, a faixa fica colada na borda da janela e perde a
     leitura de peça flutuante — o intervalo do sistema é o que a descola. */
  top: var(--gap);
  z-index: var(--z-sticky, 900);
}

/* Os cantos da junção se abrem quando a faixa descola.
 *
 * Parada a peça é UMA: o header perde os cantos de baixo e a faixa os de cima,
 * e a costura entre as duas é reta. Quando a faixa sobe e passa a flutuar, ela
 * deixou de ser a metade de baixo de alguma coisa — e cada uma volta a ter o
 * seu contorno inteiro. A transição faz o corte virar canto no tempo da
 * rolagem, em vez de trocar de forma num quadro só.
 *
 * `is-detached` vem de `wizard-sticky-header.js`, que compara o rodapé do
 * header com o topo da faixa: CSS não tem seletor para "está parado no topo".
 * O script zera a transição sob `prefers-reduced-motion`. */
:is(html[data-theme]) .wizard-page > .header,
:is(html[data-theme]) .wizard-page > .rail,
:is(html[data-theme]) .wizard-sticky-scope > .header,
:is(html[data-theme]) .wizard-sticky-scope > .rail {
  transition: border-radius var(--ease);
}

:is(html[data-theme]) .wizard-page > .header.is-detached,
:is(html[data-theme]) .wizard-sticky-scope > .header.is-detached {
  border-bottom-left-radius: var(--radius-brand);
  border-bottom-right-radius: var(--radius-brand);
}

:is(html[data-theme]) .wizard-page > .rail.is-detached,
:is(html[data-theme]) .wizard-sticky-scope > .rail.is-detached {
  border-top-left-radius: var(--radius-rail);
  border-top-right-radius: var(--radius-rail);
}
/* <<< css/v2/stepper.css <<< */

/* >>> css/v2/destination-row.css >>> */
/* Linha de destino. Depende de `v2/tokens.css`. */

/* Duas metades EXATAS.
 *
 * Esquerda: alça, "+" e o campo de estado. Direita: o campo de cidade e o "×".
 * Cada lado é 1fr, então o que entra ou sai de um não mexe no outro — foi essa
 * a regra que faltava nas tentativas anteriores.
 *
 * As duas que não deram certo, para não voltarem: colunas fixas para cada
 * controle fazem o campo de estado pagar por tudo que nasce à esquerda (a alça
 * o levou de 200 para 131); e fixar o grupo da direita em 256px funciona na
 * largura em que foi medido e desanda em qualquer outra (numa tela larga o
 * estado ia a 690 com a cidade presa em 256). */
:is(html[data-theme]) .destination-row {
  align-items: center;
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
  /* Âncora do indicador de destino do arraste, que é desenhado no vão. */
  position: relative;
}


/* As duas metades. Dentro de cada uma, o campo estica e os botões não. */
:is(html[data-theme]) .destination-row__start,
:is(html[data-theme]) .destination-row__end {
  align-items: center;
  display: flex;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .destination-row__start > .search-picker,
:is(html[data-theme]) .destination-row__end > .search-picker {
  flex: 1 1 0;
  min-width: 0;
}

/* Com um destino só, o `location-rows.js` marca o "×" com `hidden` — não faz
   sentido remover o único. Estando os dois no MESMO flex, o vão dele some junto
   com o botão, e a cidade fica com a metade inteira. */

/* Os dois botões da linha são o `button` do sistema, na forma `--icon`: o de
   adicionar é `primary`, o de remover é `danger`. Nenhum desenho próprio aqui —
   foi assim que o sistema antigo acumulou dezoito variantes que ninguém tinha
   decidido. Só o que é POSIÇÃO fica nesta folha. */

/* ---- reordenar por arraste ------------------------------------------------
 *
 * O motor é o `initDragDrop` do `location-rows.js`, que só precisa da alça e
 * das três classes de estado abaixo. Elas existiam apenas em
 * `pages/roteiros.css`, folha de uma tela — fora dela o arraste funcionava sem
 * dar nenhum retorno visual, que é o mesmo que não funcionar.
 */
:is(html[data-theme]) .destination-row__handle {
  align-items: center;
  color: var(--text-muted);
  cursor: grab;
  display: inline-flex;
  justify-content: center;
  /* `touch-action` é o que faz o arraste valer no toque: sem ela o navegador
     interpreta o gesto como rolagem e o `pointermove` nunca chega. */
  touch-action: none;
  width: 20px;
}

:is(html[data-theme]) .destination-row__handle:hover {
  color: var(--accent);
}

:is(html[data-theme]) .destination-row__handle svg {
  height: 16px;
  width: 16px;
}

/* Reordenar sem desenhar nada: a linha na mão apaga, e a vizinha ABRE ESPAÇO
 * para onde ela vai cair. O vão que se alarga já diz o lugar — não precisa de
 * fio, e some sozinho quando o ponteiro sai dali.
 *
 * `is-drop-before` significa "entra ANTES desta", então a vizinha desce e o vão
 * de cima cresce; `is-drop-after` faz o contrário. São 4px sobre um vão de 8:
 * o suficiente para ler o lugar, pouco para não sacudir a lista.
 */
:is(html[data-theme]) .destination-row {
  transition: transform 140ms ease, opacity 140ms ease;
}

:is(html[data-theme]) .destination-row.is-dragging {
  cursor: grabbing;
  opacity: 0.4;
}

:is(html[data-theme]) .destination-row.is-drop-target.is-drop-before {
  transform: translateY(4px);
}

:is(html[data-theme]) .destination-row.is-drop-target.is-drop-after {
  transform: translateY(-4px);
}

/* Durante o arraste, nada de seleção de texto pelo caminho. */
:is(html[data-theme]) .is-dragging-destination,
:is(html[data-theme]) .is-dragging-destination * {
  user-select: none;
}

/* A alça só existe quando há o que reordenar. Com um destino só ela oferece um
   gesto que não faz nada — e ocupa a largura que o campo de estado precisa.
   Some por `display`, para o vão sumir junto com ela.
 *
 * O `:has` olha se existe uma SEGUNDA linha na lista; como é avaliado ao vivo,
 * a alça aparece sozinha assim que o segundo destino é criado e some quando ele
 * é removido, sem o `location-rows.js` precisar saber disso.
 */
:is(html[data-theme]) .destinations__list:not(:has(> [data-location-row] ~ [data-location-row]))
  .destination-row__handle {
  display: none;
}
/* <<< css/v2/destination-row.css <<< */

/* >>> css/v2/destinations.css >>> */
/* Destinos — a seção que gerencia as linhas. Depende de `v2/tokens.css`.
 *
 * As classes `search-picker__*` dentro das linhas são geradas pelo `picker.js`
 * e vestidas por `v2/picker.css`; aqui só entra o arranjo da seção.
 */

:is(html[data-theme]) .destinations {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .destinations__header {
  align-items: center;
  display: flex;
  gap: var(--gap);
  justify-content: space-between;
  min-width: 0;
}

:is(html[data-theme]) .destinations__title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
}

/* O botão de adicionar mora na coluna do número da linha, onde estaria o "4" da
   próxima. `justify-self: start` porque a seção é uma grade de coluna única: sem
   isso ele esticaria pela largura toda. */
:is(html[data-theme]) .destinations__add {
  justify-self: start;
}

:is(html[data-theme]) .destinations__list {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

/* A lista vazia não colapsa: sem altura mínima, remover a última linha faz o
   bloco inteiro pular de tamanho. */
:is(html[data-theme]) .destinations__list:empty {
  min-height: var(--control-height);
}
/* <<< css/v2/destinations.css <<< */

/* >>> css/v2/picker.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/search-picker.css` em 2026-08-20.
 *
 * Esta parte NÃO é legado: são as declarações do próprio componente do v2, que
 * moravam numa pasta com nome do sistema antigo porque foi lá que nasceram. O
 * arquivo v2 carregava só o DELTA — e por isso apagar a pasta antiga teria
 * apagado o componente.
 *
 * A ordem foi preservada: base primeiro, delta depois, exatamente como os dois
 * bundles as entregavam.
 * ══════════════════════════════════════════════════════════════════════════ */

/* ==========================================================================
   search-picker
   Campo customizado de busca, dropdown e selecao. O select nativo permanece
   oculto apenas para compatibilidade de formulario.
   ========================================================================== */

/* Tokens globais — o dropdown flutuante (body) precisa destes valores */
:root {
  --sp-field-bg: var(--theme-input-bg, var(--color-input-bg));
  --sp-field-bg-soft: var(--theme-surface-card-soft, var(--color-card-soft));
  --sp-field-border: var(--theme-input-border, var(--color-input-border));
  --sp-field-border-focus: var(--route-button-primary-border, var(--color-secondary));
  --sp-field-text: var(--theme-input-text, var(--color-input-text));
  --sp-field-focus-ring: var(--route-focus-ring, var(--color-info-border));
  --sp-dropdown-bg: var(--theme-surface-card, var(--color-card));
  --sp-dropdown-option-hover: var(--theme-list-row-hover, var(--color-primary-soft));
  --sp-selected-panel-bg: var(--theme-surface-card-soft, var(--color-card-soft));
  --sp-selected-panel-border: var(--theme-border-card, var(--color-border));
  --sp-selected-card-bg: var(--theme-surface-card, var(--color-card));
  --sp-selected-card-border: var(--theme-border-card, var(--color-border-soft));
}

.search-picker {
  --field-bg: var(--sp-field-bg);
  --field-bg-soft: var(--sp-field-bg-soft);
  --field-border: var(--sp-field-border);
  --field-border-hover: var(--color-border-strong);
  --field-border-focus: var(--sp-field-border-focus);
  --field-text: var(--sp-field-text);
  --field-placeholder: var(--color-input-placeholder);
  --field-focus-ring: var(--sp-field-focus-ring);
  --dropdown-bg: var(--sp-dropdown-bg);
  --dropdown-border: var(--sp-field-border-focus);
  --dropdown-shadow: var(--shadow-panel);
  --dropdown-option-hover: var(--sp-dropdown-option-hover);
  --dropdown-option-selected: var(--color-info-bg);
  --selected-panel-bg: var(--sp-selected-panel-bg);
  --selected-panel-border: var(--sp-selected-panel-border);
  --selected-card-bg: var(--sp-selected-card-bg);
  --selected-card-border: var(--sp-selected-card-border);
  --control-active-bg: var(--state-success-bg-active);
  --control-active-border: var(--state-success-border-hover);
  --control-active-text: var(--state-success-text-active);
  --control-inactive-bg: var(--state-warning-bg-active);
  --control-inactive-border: var(--state-warning-border-hover);
  --control-inactive-text: var(--state-warning-text-active);
  --danger-bg: color-mix(in srgb, var(--color-danger) 92%, black 8%);
  --danger-border: color-mix(in srgb, var(--color-danger) 78%, black 22%);
  --danger-text: var(--state-danger-text-active);
  --remove-rail-width: calc(var(--space-10) + var(--space-2));
  --selected-card-open-gap: var(--space-2);
  --driver-bg: var(--color-bg-subtle, var(--color-primary-soft));
  --driver-border: var(--btn-secondary-active-border, var(--color-primary));
  --driver-text: var(--btn-secondary-active-color, var(--color-primary-strong));
  --search-picker-height: var(--control-height-md);
  --search-picker-radius: var(--radius-control);
  --search-picker-card-radius: var(--radius-card);
  --search-picker-focus-shadow: 0 0 0 var(--space-1) var(--field-focus-ring), var(--shadow-xs);
  display: grid;
  gap: var(--space-4);
  min-width: 0;
  position: relative;
  width: 100%;
}

.search-picker__native,
.search-picker__termos-native {
  display: none !important;
}

.search-picker__field {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
  position: relative;
}

.search-picker__label {
  color: var(--color-label, var(--color-label-strong));
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.2;
  margin: 0;
}

.search-picker__hint {
  color: var(--theme-text-muted, var(--color-muted));
  font-size: var(--font-size-xs);
  line-height: 1.45;
}

/* Controle e dropdown repetem tokens — dropdown no body não herda do .search-picker */
.search-picker__control,
.search-picker__dropdown {
  --field-bg: var(--sp-field-bg);
  --field-bg-soft: var(--sp-field-bg-soft);
  --field-border: var(--sp-field-border);
  --field-border-hover: var(--color-border-strong);
  --field-border-focus: var(--sp-field-border-focus);
  --field-text: var(--sp-field-text);
  --field-placeholder: var(--color-input-placeholder);
  --field-focus-ring: var(--sp-field-focus-ring);
  --dropdown-bg: var(--sp-dropdown-bg);
  --dropdown-border: var(--sp-field-border-focus);
  --dropdown-shadow: var(--shadow-panel);
  --dropdown-option-hover: var(--sp-dropdown-option-hover);
  --dropdown-option-selected: var(--color-info-bg);
  --search-picker-radius: var(--radius-control);
}

.search-picker__control {
  align-items: center;
  background:
    linear-gradient(var(--field-bg), var(--field-bg)) padding-box,
    linear-gradient(var(--field-border), var(--field-border)) border-box;
  border: 1px solid transparent;
  border-radius: var(--search-picker-radius);
  box-shadow: var(--shadow-xs);
  box-sizing: border-box;
  display: flex;
  gap: var(--space-2);
  min-height: var(--search-picker-height);
  min-width: 0;
  padding: 0 var(--space-3);
  transition:
    background var(--transition-fast),
    border-color var(--transition-fast),
    border-radius var(--transition-fast),
    box-shadow var(--transition-fast);
}

/* Com menu no body, mantém cantos arredondados no campo */
.search-picker--open:not(.search-picker--menu-portal) .search-picker__control {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: none;
}

.search-picker__icon {
  color: var(--field-placeholder);
  flex: 0 0 auto;
  height: var(--space-4);
  position: relative;
  width: var(--space-4);
}

.search-picker__icon::before {
  border: 2px solid currentColor;
  border-radius: var(--radius-pill);
  box-sizing: border-box;
  content: "";
  height: var(--space-3);
  left: 0;
  position: absolute;
  top: 0;
  width: var(--space-3);
}

.search-picker__icon::after {
  background: currentColor;
  border-radius: var(--radius-pill);
  content: "";
  height: 2px;
  position: absolute;
  right: 0;
  top: calc(var(--space-3) - 1px);
  transform: rotate(45deg);
  transform-origin: center;
  width: var(--space-2);
}

.search-picker__input {
  appearance: none;
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--field-text);
  flex: 1 1 auto;
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  min-height: calc(var(--search-picker-height) - var(--space-3));
  min-width: 0;
  outline: 0;
  padding: 0;
  width: 100%;
}

.search-picker__input:focus,
.search-picker__input:focus-visible {
  box-shadow: none;
  outline: none;
}

.search-picker__input::placeholder {
  color: var(--field-placeholder);
  opacity: 1;
}

.search-picker__input::-webkit-search-cancel-button {
  appearance: none;
}

.search-picker__clear,
.search-picker__remove {
  align-items: center;
  appearance: none;
  background: transparent;
  border: 1px solid var(--selected-card-border);
  border-radius: var(--radius-pill);
  color: var(--theme-text-muted, var(--color-muted));
  cursor: pointer;
  display: inline-flex;
  flex: 0 0 auto;
  font: inherit;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-black);
  height: var(--space-6);
  justify-content: center;
  line-height: 1;
  padding: 0;
  text-transform: uppercase;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    box-shadow var(--transition-fast);
  width: var(--space-6);
}

/* Limpar busca: só o "x", sem cápsula/fundo. */
.search-picker__clear {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  color: var(--color-muted-strong, var(--theme-text-muted, var(--color-muted)));
  font-size: 0.95rem;
  font-weight: var(--font-weight-semibold);
  height: auto;
  min-height: 1.25rem;
  min-width: 1.25rem;
  text-transform: none;
  width: auto;
}

.search-picker__selected-card > .search-picker__remove {
  background: var(--danger-bg);
  align-self: center;
  border: 0;
  border-radius: calc(var(--search-picker-radius) - 1px) 0 0 calc(var(--search-picker-radius) - 1px);
  border-right: 1px solid var(--danger-border);
  box-shadow: none;
  color: var(--danger-text);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-black);
  grid-column: 1;
  grid-row: 1;
  height: auto;
  margin: calc(var(--space-3) * -1) 0 calc(var(--space-3) * -1) calc(var(--space-3) * -1);
  min-width: 0;
  opacity: 0;
  overflow: hidden;
  text-transform: uppercase;
  transform: translateX(calc(var(--space-2) * -1));
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    opacity var(--transition-base),
    transform var(--transition-base),
    width var(--transition-base);
  width: var(--remove-rail-width);
}

/* Com driver: remove cobre as 2 linhas (corpo + driver-control) */
.search-picker__selected-card--with-driver > .search-picker__remove {
  grid-row: 1 / span 2;
}

/* Cards simples (sem term nem driver): rail de excluir mais estreito */
.search-picker__selected-card:not(.search-picker__selected-card--with-term):not(.search-picker__selected-card--with-driver) {
  --remove-rail-width: var(--space-9);
}

.search-picker__selected-card:hover > .search-picker__remove {
  opacity: 1;
  transform: translateX(0);
}

.search-picker__clear {
  display: none;
}

.search-picker--has-query .search-picker__clear {
  display: inline-flex;
}

.search-picker__clear:hover,
.search-picker__clear:focus-visible {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--color-text, var(--theme-text-heading));
  outline: none;
}

.search-picker__remove:hover,
.search-picker__remove:focus-visible {
  background: var(--danger-bg);
  border-color: var(--danger-border);
  color: var(--danger-text);
  outline: none;
}

.search-picker__selected-card > .search-picker__remove:hover,
.search-picker__selected-card > .search-picker__remove:focus-visible {
  background: color-mix(in srgb, var(--danger-bg) 86%, var(--theme-text-heading) 14%);
  border-color: var(--danger-border);
  color: var(--danger-text);
  outline: 2px solid var(--danger-border);
  outline-offset: -2px;
}

.search-picker__dropdown {
  animation: cv-search-picker-menu-in var(--transition-base) both;
  background: var(--dropdown-bg);
  border: 1px solid var(--dropdown-border);
  border-radius: 0 0 var(--search-picker-radius) var(--search-picker-radius);
  border-top: 0;
  box-shadow: var(--dropdown-shadow);
  box-sizing: border-box;
  left: 0;
  overflow: hidden;
  position: absolute;
  right: 0;
  top: 100%;
  transform-origin: top;
  z-index: var(--z-dropdown);
}

.search-picker__dropdown.floating-dropdown--active {
  background: var(--dropdown-bg);
  border-radius: var(--search-picker-radius);
  border-top: 1px solid var(--dropdown-border);
  overflow: hidden;
  /* Portal no body: precisa ficar acima do modal (--z-modal), senão o menu
     some atrás do painel do diálogo (ex.: Vincular usuário). */
  z-index: calc(var(--z-modal, 100) + 20);
}

.search-picker--open .search-picker__dropdown {
  box-shadow: var(--search-picker-focus-shadow), var(--dropdown-shadow);
  clip-path: inset(0 calc(var(--space-1) * -1) calc(var(--space-1) * -1) calc(var(--space-1) * -1));
}

@keyframes cv-search-picker-menu-in {
  from {
    opacity: 0;
    transform: translateY(calc(var(--space-1) * -1)) scaleY(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scaleY(1);
  }
}

.search-picker__list {
  display: grid;
  gap: var(--space-1);
  max-height: calc(var(--control-height-lg) * 5);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--field-border-hover) transparent;
  scrollbar-width: thin;
}

.search-picker__list::-webkit-scrollbar {
  width: var(--space-1);
}

.search-picker__list::-webkit-scrollbar-track {
  background: transparent;
}

.search-picker__list::-webkit-scrollbar-thumb {
  background: var(--field-border-hover);
  border-radius: var(--radius-pill);
}

.search-picker__option {
  align-items: center;
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  color: var(--theme-text-body, var(--color-text));
  cursor: pointer;
  display: flex;
  font: inherit;
  gap: var(--space-3);
  min-height: var(--control-height-md);
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  text-align: left;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
  width: 100%;
}

.search-picker__option:first-child {
  border-top-left-radius: calc(var(--search-picker-radius) - var(--space-1));
  border-top-right-radius: calc(var(--search-picker-radius) - var(--space-1));
}

.search-picker__option:last-child {
  border-bottom-left-radius: calc(var(--search-picker-radius) - var(--space-1));
  border-bottom-right-radius: calc(var(--search-picker-radius) - var(--space-1));
}

.search-picker__option:hover,
.search-picker__option--active {
  background: var(--dropdown-option-hover);
}

.search-picker__option--selected {
  background: var(--dropdown-option-selected);
  border-color: var(--color-info-border-strong);
}

.search-picker__option-marker {
  align-items: center;
  border: 1px solid var(--field-border-hover);
  border-radius: var(--radius-pill);
  box-sizing: border-box;
  color: var(--color-white);
  display: inline-flex;
  flex: 0 0 auto;
  height: var(--space-5);
  justify-content: center;
  position: relative;
  width: var(--space-5);
}

.search-picker__option--selected .search-picker__option-marker {
  background: var(--color-primary);
  border-color: var(--color-primary);
}

.search-picker__option--unidade .search-picker__option-marker {
  border-radius: var(--radius-sm);
  border-style: dashed;
}

.search-picker__option--unidade .search-picker__option-main::before {
  color: var(--color-description);
  content: "Unidade";
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  margin-right: var(--space-2);
  text-transform: uppercase;
}

.search-picker__option--selected .search-picker__option-marker::after {
  border-bottom: 2px solid currentColor;
  border-right: 2px solid currentColor;
  content: "";
  height: var(--space-2);
  transform: translateY(calc(var(--space-1) * -1)) rotate(45deg);
  width: var(--space-1);
}

.search-picker__option-content {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}

.search-picker__option-main {
  color: var(--theme-text-heading, var(--color-heading));
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-picker__option-meta {
  color: var(--theme-text-muted, var(--color-muted));
  font-size: var(--font-size-xs);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Estrutura enriquecida usada pelo tema escuro. Mantida oculta na base para
   não iniciar o redesign do tema claro nesta etapa. */
.search-picker__option-visual,
.search-picker__option-status {
  display: none;
}

.search-picker__empty,
.search-picker__selected-empty {
  background: var(--field-bg-soft);
  border: 1px dashed var(--selected-panel-border);
  border-radius: var(--radius-md);
  color: var(--theme-text-muted, var(--color-muted));
  font-size: var(--font-size-sm);
  line-height: 1.45;
  margin: 0;
  padding: var(--space-4);
  text-align: center;
}

.search-picker__empty {
  border-radius: 0;
  border-width: 0;
}

.search-picker__selected-panel {
  background: var(--selected-panel-bg);
  border: 1px solid var(--selected-panel-border);
  border-radius: var(--search-picker-card-radius);
  display: grid;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-4);
}

.search-picker__selected-header {
  align-items: center;
  display: flex;
  gap: var(--space-3);
  justify-content: space-between;
  min-width: 0;
}

.search-picker__selected-title {
  color: var(--color-label);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-black);
  letter-spacing: var(--letter-spacing-label);
  line-height: 1.2;
  margin: 0;
  text-transform: uppercase;
}

.search-picker__selected-count {
  align-items: center;
  background: var(--color-primary);
  border: 1px solid var(--color-info-border-strong);
  border-radius: var(--radius-pill);
  color: var(--color-white);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  justify-content: center;
  min-height: var(--space-6);
  min-width: var(--space-6);
  padding: 0 var(--space-2);
}

.search-picker__selected-list {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
  min-width: 0;
}

.search-picker--compact .search-picker__selected-list {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.search-picker--compact .search-picker__selected-card:only-child,
.search-picker--compact .search-picker__selected-card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.search-picker__selected-card {
  align-items: start;
  background: var(--selected-card-bg);
  border: 1px solid var(--selected-card-border);
  border-radius: var(--search-picker-radius);
  box-shadow: var(--shadow-xs);
  display: grid;
  column-gap: 0;
  grid-template-columns: 0 minmax(0, 1fr) auto;
  min-width: 0;
  overflow: hidden;
  padding: var(--space-3);
  row-gap: 0;
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast),
    background-color var(--transition-fast),
    grid-template-columns var(--transition-base);
}

.search-picker__selected-card--with-term {
  align-items: center;
  grid-template-columns: 0 minmax(0, 1fr) auto;
}

.search-picker__selected-card:hover,
.search-picker__selected-card--with-term:hover {
  column-gap: var(--space-1);          /* gap pequeno entre rail X e corpo */
  grid-template-columns: var(--remove-rail-width) minmax(0, 1fr) auto;
}

/* row-gap só quando o botão de motorista existir */
.search-picker__selected-card--with-driver:hover {
  row-gap: var(--space-4);
}

.search-picker__selected-card--has-term {
  border-color: var(--selected-card-border);
  box-shadow: var(--shadow-xs);
}

.search-picker__selected-main {
  display: grid;
  gap: var(--space-1);
  grid-column: 2;
  min-width: 0;
}

.search-picker__selected-title-row {
  align-items: center;
  display: flex;
  gap: var(--space-2);
  min-width: 0;
}

.search-picker__selected-name {
  color: var(--theme-text-heading, var(--color-heading));
  flex: 0 1 auto;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-picker__driver-chip {
  background: var(--driver-bg);
  border: 1px solid var(--driver-border);
  border-radius: var(--radius-pill);
  color: var(--driver-text);
  display: none;
  flex: 0 0 auto;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  padding: var(--space-1) var(--space-2);
}

.search-picker__selected-card--driver .search-picker__driver-chip {
  display: inline-flex;
}

.search-picker__selected-meta,
.search-picker__selected-detail {
  color: var(--theme-text-muted, var(--color-muted));
  font-size: var(--font-size-xs);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-picker__selected-detail {
  display: none;
}

.search-picker--detailed .search-picker__selected-detail {
  display: block;
}

.search-picker--detailed .search-picker__selected-list {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.search-picker--detailed .search-picker__selected-card:only-child,
.search-picker--detailed .search-picker__selected-card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.search-picker__term-control {
  align-items: center;
  border-top: 0;
  display: grid;
  gap: var(--space-1);
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  padding-top: 0;
}

.search-picker__term-label {
  color: var(--theme-text-muted-strong, var(--color-muted-strong));
  display: none;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
}

/* O toggle de Termo usa field-side-action--state (dot colorido).
   Os estilos visuais já existem em buttons.css — nenhuma regra extra. */

.search-picker__driver-control {
  grid-column: 2 / -1;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transform: translateY(calc(var(--space-2) * -1));
  transition:
    max-height var(--transition-base),
    opacity var(--transition-base),
    transform var(--transition-base);
}

.search-picker__selected-card:hover .search-picker__driver-control {
  max-height: calc(var(--control-height-md) + var(--space-2));
  opacity: 1;
  transform: translateY(0);
}

/* Viatura selecionada: o "Editar" usa o slot do `__driver-control`, mas fica
   SEMPRE visível — no multiselect de servidores o botão só aparece no hover, e
   aqui não há segunda linha que explique o que o card faz.
   As três regras vinham de `pages/oficios.css`, que desde a migração v2 não era
   carregada por página nenhuma; sem elas o link herdava o estado fechado
   (`max-height: 0; opacity: 0`) e só aparecia ao passar o mouse.
   Emitidas por `js/components/picker-parts.js`. */
.oficio-viatura-selected-card .oficio-viatura-edit-row {
  max-height: none;
  opacity: 1;
  transform: none;
  transition: none;
}

.oficio-viatura-edit-link,
.oficio-viatura-edit-link:hover,
.oficio-viatura-edit-link:focus-visible {
  text-decoration: none;
}

.oficio-viatura-busca__wrap {
  position: relative;
  width: 100%;
}

/* Estrutura compartilhada do roster: o card seleciona o motorista, enquanto
   termo e remoção continuam como ações independentes acima da área clicável. */
.search-picker--roster .search-picker__selected-card {
  position: relative;
}

.search-picker--roster .search-picker__driver-surface {
  appearance: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  inset: 0;
  padding: 0;
  position: absolute;
  width: 100%;
  z-index: 1;
}

.search-picker--roster :is(.search-picker__selected-avatar, .search-picker__selected-main) {
  pointer-events: none;
  position: relative;
  z-index: 2;
}

.search-picker--roster .search-picker__selected-actions {
  position: relative;
  z-index: 3;
}

.search-picker--roster .search-picker__driver-control {
  display: none;
}

.search-picker__driver-toggle {
  align-items: center;
  appearance: none;
  background: var(--field-bg-soft);
  border: 1px solid var(--selected-card-border);
  border-radius: var(--search-picker-radius);
  color: var(--theme-text-body, var(--color-text));
  cursor: pointer;
  display: flex;
  font: inherit;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  gap: var(--space-2);
  min-height: var(--control-height-md);
  padding: var(--space-2) var(--space-4);
  text-align: left;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    box-shadow var(--transition-fast);
  width: 100%;
}

.search-picker__driver-toggle:hover,
.search-picker__driver-toggle:focus-visible {
  border-color: var(--driver-border);
  outline: none;
}

.search-picker__driver-toggle--active {
  background: var(--driver-bg);
  border-color: var(--driver-border);
  color: var(--driver-text);
}

.search-picker__driver-marker {
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  display: inline-flex;
  flex: 0 0 auto;
  height: var(--space-4);
  position: relative;
  width: var(--space-4);
}

.search-picker__driver-toggle--active .search-picker__driver-marker::after {
  background: currentColor;
  border-radius: var(--radius-pill);
  content: "";
  inset: 3px;
  position: absolute;
}

.search-picker__driver-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-picker--error {
  --field-border: var(--danger-border);
  --field-border-hover: var(--danger-border);
  --field-border-focus: var(--danger-border);
  --field-focus-ring: var(--danger-border);
}

.search-picker--error .search-picker__selected-panel {
  border-color: var(--danger-border);
}

.search-picker--disabled {
  opacity: 1;
}

.search-picker--disabled .search-picker__control,
.search-picker--disabled .search-picker__selected-panel,
.search-picker--disabled .search-picker__selected-card {
  background: var(--color-input-disabled-bg);
  box-shadow: none;
}

.search-picker--disabled .search-picker__control {
  cursor: not-allowed;
}

.search-picker--disabled .search-picker__input,
.search-picker--disabled .search-picker__selected-name,
.search-picker--disabled .search-picker__selected-meta,
.search-picker--disabled .search-picker__selected-detail {
  color: var(--color-input-disabled-text);
}

.search-picker--disabled .search-picker__clear,
.search-picker--disabled .search-picker__remove,
.search-picker--disabled .search-picker__term-control .field-side-action,
.search-picker--disabled .search-picker__driver-toggle {
  cursor: not-allowed;
  pointer-events: none;
}

.search-picker--disabled .search-picker__selected-card,
.search-picker--disabled .search-picker__term-control,
.search-picker--disabled .search-picker__driver-control {
  opacity: 0.72;
}

.search-picker--disabled .search-picker__selected-card:hover {
  column-gap: 0;
  grid-template-columns: 0 minmax(0, 1fr) auto;
}

.search-picker--disabled .search-picker__remove {
  display: none;
}

@media (max-width: 720px) {
  .search-picker--compact .search-picker__selected-list,
  .search-picker--detailed .search-picker__selected-list {
    grid-template-columns: 1fr;
  }

  .search-picker--compact .search-picker__selected-card:only-child,
  .search-picker--compact .search-picker__selected-card:last-child:nth-child(odd),
  .search-picker--detailed .search-picker__selected-card:only-child,
  .search-picker--detailed .search-picker__selected-card:last-child:nth-child(odd) {
    grid-column: auto;
  }

  .search-picker__term-control {
    border-top: 1px solid var(--selected-card-border);
    grid-column: 2 / -1;
    grid-row: auto;
    grid-template-columns: 1fr;
    justify-self: stretch;
    padding-top: var(--space-3);
  }

  .search-picker__selected-card--with-driver .search-picker__remove {
    grid-column: 1;
    grid-row: 1 / span 2;
  }
}

.search-picker--single.search-picker--detailed .search-picker__selected-card > .search-picker__remove {
  margin: calc(var(--space-4) * -1) 0 calc(var(--space-4) * -1) calc(var(--space-5) * -1);
}

.search-picker--single.search-picker--detailed .search-picker__selected-name {
  font-size: var(--font-size-md);
  overflow: visible;
  text-overflow: unset;
  white-space: normal;
}




/* ═══════════════════════════════════════════════════════════════════════════
 * VINDAS DAS FOLHAS DE TEMA E DO CASCO ANTIGO, em 2026-08-20.
 *
 * Descreviam este componente DE FORA dele — em `theme-shared-components.css`,
 * `theme-dark-components.css`, `layout/page-shell.css`, `fields/forms.css` ou
 * `lists/list-header.css`. Enquanto ficaram lá, o componente do v2 dependia de
 * folhas do sistema antigo para ter forma, e toda tela migrada carregava
 * aquelas folhas por causa dele.
 *
 * Vieram com o texto INTACTO — `!important` e escopo de wizard inclusive —, e
 * ANTES da divisa: elas chegavam pelo bundle do shell, que é anterior ao
 * `ui.bundle.css`, e por isso perdiam para o delta do v2. Anexá-las no fim
 * inverteria a disputa sem mudar um valor sequer. Medido antes e depois em 20
 * telas: nenhuma diferença.
 * ═══════════════════════════════════════════════════════════════════════════ */

:is(html[data-theme])
  .search-picker__input,
:is(html[data-theme])
  .search-picker__input:focus,
:is(html[data-theme])
  .search-picker__input:focus-visible {
  border-radius: 0;
}

:is(html[data-theme])
  .form-card .search-picker__selected-panel {
  gap: 8px;
  padding: 12px;
}

:is(html[data-theme])
  .form-card .search-picker__selected-empty {
  padding: 9px 12px;
  text-align: left;
}

:is(html[data-theme])
  :is(.app-form-label, .cv-field__label, .search-picker__label) {
  color: var(--color-heading);
  font-size: 0.78rem;
  font-weight: var(--font-weight-black);
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: none;
}

:is(html[data-theme])
  .search-picker--people {
  gap: 12px;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-panel {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-list {
  gap: 8px;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-main {
  gap: 2px;
  grid-column: 1;
  grid-row: 1;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-name {
  white-space: normal;
}

:is(html[data-theme])
  .search-picker--people .search-picker__driver-chip {
  display: none;
}

:is(html[data-theme])
  .search-picker--people .search-picker__driver-toggle {
  border-radius: var(--radius-pill);
}

:is(html[data-theme])
  .search-picker--people .search-picker__term-control {
  grid-column: 3;
  grid-row: 1;
  justify-self: auto;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-card > .search-picker__remove,
:is(html[data-theme])
  .search-picker--people .search-picker__selected-card:hover > .search-picker__remove {
  align-self: center;
  background: transparent;
  border: 1px solid var(--color-danger-border-soft);
  border-radius: var(--radius-pill);
  color: var(--color-danger);
  grid-column: 4;
  grid-row: 1;
  height: 34px;
  margin: 0;
  opacity: 1;
  transform: none;
  width: 34px;
}

:is(html[data-theme])
  .search-picker--people .search-picker__selected-empty {
  background: var(--color-surface-muted);
  border-style: solid;
}

:is(html[data-theme])
  .search-picker--vehicle {
  background: color-mix(in srgb, var(--color-surface-muted) 88%, var(--color-primary) 12%);
  border: 1px dashed var(--color-input-border);
  border-radius: 16px;
  gap: 13px;
  padding: 14px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__field {
  gap: 7px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__label {
  color: var(--color-heading);
  font-size: 0.78rem;
  text-transform: none;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__control {
  background: var(--color-input-bg);
  border-color: var(--color-input-border);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-panel {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-panel {
  background: transparent;
  border: 0;
  gap: 8px;
  padding: 0;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-title {
  color: var(--color-muted-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0;
  text-transform: none;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-list {
  gap: 8px;
  grid-template-columns: minmax(0, 1fr);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card,
:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card:hover {
  align-items: center;
  background: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface-muted));
  border: 0 !important;
  border-color: transparent !important;
  border-radius: 12px;
  box-shadow: inset 4px 0 0 var(--color-accent);
  column-gap: 12px;
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  min-height: 78px;
  outline: 0;
  padding: 11px 12px;
  position: relative;
  row-gap: 0;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-avatar {
  border-radius: 12px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-avatar {
  align-items: center;
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
  color: var(--color-on-accent);
  display: inline-flex;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-black);
  grid-column: 1;
  height: 42px;
  justify-content: center;
  letter-spacing: 0.04em;
  width: 42px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-main {
  gap: 3px;
  grid-column: 2;
  grid-row: 1;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-title-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-name {
  color: var(--color-heading);
  font-weight: var(--font-weight-bold);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__vehicle-chip {
  border-radius: 999px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__vehicle-chip {
  align-items: center;
  background: var(--color-accent);
  color: var(--color-on-accent);
  display: inline-flex;
  font-size: 10px;
  font-weight: var(--font-weight-black);
  letter-spacing: 0.04em;
  min-height: 21px;
  padding: 2px 8px;
  text-transform: uppercase;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-meta {
  color: var(--color-muted-strong);
  font-size: var(--font-size-xs);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card > .search-picker__remove,
:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card:hover > .search-picker__remove {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card > .search-picker__remove,
:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card:hover > .search-picker__remove {
  align-self: center;
  background: transparent;
  border: 0;
  border-left: 1px solid var(--color-border-soft);
  color: var(--color-muted);
  grid-column: 3;
  grid-row: 1;
  height: 34px;
  margin: 0;
  opacity: 1;
  transform: none;
  width: 38px;
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card > .search-picker__remove:hover {
  background: transparent;
  color: var(--color-muted-strong);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-empty {
  background: transparent;
  border: 0;
  padding: 9px 12px;
  text-align: left;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster {
  background: color-mix(in srgb, var(--color-surface-muted) 88%, var(--color-primary) 12%);
  border: 1px dashed var(--color-input-border);
  border-radius: 16px;
  gap: 13px;
  padding: 14px;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__field {
  gap: 7px;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__label {
  color: var(--color-heading);
  font-size: 0.78rem;
  text-transform: none;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__control {
  background: var(--color-input-bg);
  border-color: var(--color-input-border);
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-panel {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-panel {
  background: transparent;
  border: 0;
  gap: 8px;
  padding: 0;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-title {
  color: var(--color-accent-text);
  padding: 0 2px;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-list {
  background: transparent;
  border: 0;
  border-radius: 0;
  gap: 8px;
  overflow: visible;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card,
:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card:hover {
  border-radius: 12px;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card,
:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card:hover {
  align-items: center;
  background: var(--color-input-bg);
  border: 0;
  box-shadow: none;
  column-gap: 12px;
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  min-height: 78px;
  padding: 11px 12px;
  position: relative;
  row-gap: 0;
  transition: background-color 140ms ease, box-shadow 140ms ease;
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card:hover {
  background: color-mix(in srgb, var(--color-accent) 5%, var(--color-input-bg));
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card--driver,
:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card--driver:hover {
  background: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface-muted));
  border: 0;
  box-shadow: inset 4px 0 0 var(--color-accent);
}

:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card:last-child {
  border-bottom: 0;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-avatar {
  border-radius: 12px;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-avatar {
  align-items: center;
  background: var(--color-accent-soft);
  border: 1px solid var(--color-accent-border-soft);
  color: var(--color-accent-text);
  display: inline-flex;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-black);
  grid-column: 1;
  height: 42px;
  justify-content: center;
  letter-spacing: 0.04em;
  pointer-events: none;
  position: relative;
  width: 42px;
  z-index: 2;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-card--driver .search-picker__selected-avatar {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-main {
  gap: 3px;
  grid-column: 2;
  grid-row: 1;
  pointer-events: none;
  position: relative;
  z-index: 2;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__driver-chip {
  align-items: center;
  background: var(--color-accent);
  border-radius: 999px;
  color: var(--color-on-accent);
  display: none;
  font-size: 10px;
  font-weight: var(--font-weight-black);
  letter-spacing: 0.04em;
  min-height: 21px;
  padding: 2px 8px;
  text-transform: uppercase;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-card--driver .search-picker__driver-chip {
  display: inline-flex;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__driver-surface {
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  inset: 0;
  padding: 0;
  position: absolute;
  width: 100%;
  z-index: 1;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: 0;
  display: flex;
  gap: 10px;
  grid-column: 3;
  grid-row: 1;
  padding: 0;
  position: relative;
  z-index: 3;
}

:is(html[data-theme])
  .search-picker--roster :is(.search-picker__driver-control, .search-picker__term-control) {
  border: 0;
  display: block;
  grid-column: auto;
  grid-row: auto;
  justify-self: auto;
  max-height: none;
  opacity: 1;
  overflow: visible;
  padding: 0;
  transform: none;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__driver-control {
  display: none;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions :is(.search-picker__driver-toggle, .field-side-action) {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions :is(.search-picker__driver-toggle, .field-side-action) {
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--color-muted-strong);
  min-height: 30px;
  min-width: 0;
  padding: 0 3px;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions :is(.search-picker__driver-toggle, .field-side-action)[aria-pressed="true"] {
  background: transparent;
  border-color: transparent;
  color: var(--color-accent-text);
}

:is(html[data-theme])
  .search-picker--roster .search-picker__term-control .field-side-action {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  color: var(--color-muted-strong);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  gap: 6px;
  letter-spacing: 0.01em;
  line-height: 1;
  min-height: 28px;
  min-width: 0;
  padding: 0 3px;
  transform: none;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__term-control .field-side-action:is(:hover, :focus-visible) {
  transform: none;
}

:is(html[data-theme])
  .search-picker--roster
  .search-picker__term-control
  .field-side-action:is(.field-side-action--success, .is-active, [aria-pressed="true"]) {
  background: transparent;
  border-color: transparent;
  color: var(--color-success);
}

:is(html[data-theme])
  .search-picker--roster
  .search-picker__term-control
  .field-side-action.field-side-action--danger,
:is(html[data-theme])
  .search-picker--roster
  .search-picker__term-control
  .field-side-action.is-inactive {
  background: transparent;
  border-color: transparent;
  color: var(--color-danger);
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions .field-side-action--state::before {
  background: currentColor;
  box-shadow: none;
  flex: 0 0 auto;
  height: 6px;
  width: 6px;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions .search-picker__remove {
  border-radius: 0;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions .search-picker__remove {
  align-self: center;
  background: transparent;
  border: 0;
  border-left: 1px solid var(--color-border-soft);
  color: var(--color-muted);
  height: 32px;
  margin: 0;
  opacity: 1;
  position: static;
  transform: none;
  padding-left: 10px;
  width: 38px;
}

:is(html[data-theme])
  .search-picker--roster .search-picker__selected-actions .search-picker__remove:hover {
  background: transparent;
  color: var(--color-muted-strong);
}

@media (max-width: 720px) {
:is(html[data-theme])
    .search-picker--people.search-picker--roster .search-picker__selected-card,
:is(html[data-theme])
    .search-picker--people.search-picker--roster .search-picker__selected-card:hover {
    grid-template-columns: 42px minmax(0, 1fr);
    row-gap: 8px;
  }

:is(html[data-theme])
    .search-picker--roster .search-picker__selected-actions {
    background: transparent;
    border: 0;
    grid-column: 2;
    grid-row: 2;
    justify-content: flex-start;
    padding: 0;
  }
}

@media (max-width: 640px) {
:is(html[data-theme])
    .search-picker--people .search-picker__selected-card,
:is(html[data-theme])
    .search-picker--people .search-picker__selected-card:hover {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 8px;
  }

:is(html[data-theme])
    .search-picker--people .search-picker__driver-control {
    grid-column: 1;
    grid-row: 2;
    justify-self: start;
  }

:is(html[data-theme])
    .search-picker--people .search-picker__term-control {
    border-top: 0;
    grid-column: 2;
    grid-row: 2;
    padding-top: 0;
  }

:is(html[data-theme])
    .search-picker--people .search-picker__selected-card > .search-picker__remove {
    grid-column: 2;
    grid-row: 1;
  }
}

:is(html[data-theme])
  .search-picker__selected-list {
  gap: 8px;
  grid-template-columns: minmax(0, 1fr);
}

:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card,
:is(html[data-theme])
  .search-picker--vehicle .search-picker__selected-card:hover,
:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card,
:is(html[data-theme])
  .search-picker--people.search-picker--roster .search-picker__selected-card:hover {
  border: 0;
  border-color: transparent;
}

:is(html[data-theme])
  .oficio-external-driver .search-picker__control {
  border-radius: 10px;
}

:is(html[data-theme="dark"])
  .termo-oficio-summary-panel .search-picker__selected-header {
  background: transparent;
  border: 0;
  padding: 0 0 var(--space-2);
}

:is(html[data-theme="dark"])
  .search-picker {
  --search-picker-focus-shadow: none;
  --field-border-focus: var(--color-accent-border-strong);
}

:is(html[data-theme="dark"])
  .search-picker__input,
:is(html[data-theme="dark"])
  .search-picker__input:focus,
:is(html[data-theme="dark"])
  .search-picker__input:focus-visible {
  background: transparent;
  border: 0;
  box-shadow: none;
  outline: none;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__selected-panel {
  background: transparent;
  border: 0;
  gap: 10px;
  padding: 0;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__selected-title {
  color: var(--color-muted-strong);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0;
  text-transform: none;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__selected-card,
:is(html[data-theme="dark"])
  .search-picker--people .search-picker__selected-card:hover,
:is(html[data-theme="dark"])
  .search-picker--people .search-picker__selected-card--with-term:hover {
  align-items: center;
  background: var(--color-surface-soft);
  border-color: var(--color-border);
  box-shadow: none;
  column-gap: 10px;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  min-height: 64px;
  padding: 9px 10px 9px 12px;
  row-gap: 0;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__driver-control {
  grid-column: 2;
  grid-row: 1;
  max-height: none;
  opacity: 1;
  overflow: visible;
  transform: none;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__driver-toggle {
  background: var(--color-surface-muted);
  border-color: var(--color-border-strong);
  box-shadow: none;
  min-height: 34px;
  padding: 0 11px;
  width: auto;
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__driver-toggle--active {
  background: var(--color-accent-soft);
  border-color: var(--color-accent-border-strong);
  color: var(--color-accent-text);
}

:is(html[data-theme="dark"])
  .search-picker--people .search-picker__term-control .field-side-action {
  box-shadow: none;
  min-height: 34px;
  white-space: nowrap;
}

html[data-theme="dark"] :is(.search-picker__selected-panel, .search-picker__selected-card) {
  background: var(--color-surface-soft);
  border-color: var(--color-border-strong);
  box-shadow: none;
}

:is(html[data-theme="dark"])
  .search-picker__list {
  display: grid;
  gap: 4px;
  padding: 0;
  scrollbar-color: var(--color-border-strong) transparent;
}

:is(html[data-theme="dark"])
  .search-picker__selected-card,
:is(html[data-theme="dark"])
  .search-picker__selected-card:hover {
  background: var(--color-input-bg);
  border-color: transparent;
  box-shadow: none;
  transform: none;
}

:is(html[data-theme="dark"])
  .search-picker__selected-card > .search-picker__remove,
:is(html[data-theme="dark"])
  .search-picker__selected-card > .search-picker__remove:hover,
:is(html[data-theme="dark"])
  .search-picker__selected-card > .search-picker__remove:focus-visible {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--color-muted-strong);
  outline: none;
}

:is(html[data-theme="dark"])
  .oficio-external-driver__identity > .search-picker {
  background: transparent;
  border: 0;
  box-shadow: none;
  margin: 0;
  padding: 0;
}

:is(html[data-theme="dark"])
  .oficio-external-driver .search-picker__control {
  background: var(--color-input-bg) !important;
  border: 1px solid var(--color-border) !important;
  box-shadow: none !important;
  min-height: var(--control-height-md);
  padding: 0 12px;
}

:is(html[data-theme="dark"])
  .oficio-external-driver .search-picker__input {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  min-height: 44px;
  padding: 0;
}

:is(html[data-theme="dark"])
  .termos-page .termo-oficio-summary-panel.search-picker__selected-panel {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

.main-form-panel .search-picker__input {
  line-height: 1.25;
  min-height: 0;
  padding: 0 5px;
}

.main-form-panel .field-with-action--search-picker .search-picker__field {
  position: relative;
}

.main-form-panel .field-with-action--search-picker .search-picker__control {
  box-sizing: border-box;
  max-width: 100%;
  min-width: 0;
  transition: width var(--transition-fast), max-width var(--transition-fast);
  width: 100%;
}

.main-form-panel .field-with-action--search-picker:hover .search-picker__control,
.main-form-panel .field-with-action--search-picker:focus-within .search-picker__control {
  max-width: calc(100% - var(--field-manage-btn-size) - var(--field-manage-btn-gap));
  width: calc(100% - var(--field-manage-btn-size) - var(--field-manage-btn-gap));
}

.main-form-panel .search-picker:not(:has(.search-picker__selected-panel)) {
  gap: var(--space-2);
}

.main-form-panel .search-picker__field {
  gap: var(--space-2);
}

.main-form-panel .search-picker:has(.search-picker__selected-panel) {
  gap: var(--space-3);
}

.list-header--inline-create .inline-create__panel
  :is(
    .form-control,
    .form-select,
    .cv-field__control,
    .custom-select__trigger,
    .search-picker__control,
    .search-picker__input
  ) {
  background: var(--step1-field, var(--list-header-control-bg, var(--color-input-bg)));
  border: 0;
  border-radius: var(--radius-control);
  box-shadow: none;
  box-sizing: border-box;
  color: var(--text-filter);
  font-size: var(--font-size-sm);
  transition: none;
}

.list-header--inline-create .inline-create__panel
  :is(
    input.form-control,
    select.form-control,
    .form-select,
    input.cv-field__control,
    select.cv-field__control,
    .custom-select__trigger,
    .search-picker__control
  ) {
  height: var(--list-header-control-height);
  min-height: var(--list-header-control-height);
}

.list-header--inline-create .inline-create__panel
  :is(
    .form-control,
    .form-select,
    .cv-field__control,
    .custom-select__trigger,
    .search-picker__control
  ):is(.is-invalid, [aria-invalid="true"]),
.list-header--inline-create .inline-create__panel
  :is(.app-form-field, .cv-field):has(.field-error)
  :is(
    .form-control,
    .form-select,
    .cv-field__control,
    .custom-select__trigger,
    .search-picker__control
  ) {
  border: 1px solid var(--color-danger);
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`: as asserções de
 * aparência do v2 descrevem ESTA metade. Medir o arquivo inteiro faria o teste
 * ler a regra base que o delta sobrescreve — foi o que aconteceu na fusão de
 * 2026-08-20, com sete asserções apontando para a declaração antiga da mesma
 * classe, três telas acima.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Picker — busca de entidade. Depende de `v2/tokens.css`.
 *
 * As classes `search-picker__*` são geradas por `js/components/picker.js` e
 * pertencem a ele; não são renomeadas aqui. Renomear sem tocar o JS quebraria
 * em silêncio, como já aconteceu com o select.
 *
 * A raiz é `.picker` OU `.destination-row`: nos destinos o picker não tem
 * invólucro próprio no template — o `data-entity-picker` fica no `<select>` e
 * quem monta a estrutura é o JS, que não conhece a classe `.picker`. Sem a
 * linha de destino aqui, aqueles dois campos caíam no desenho legado, com raio
 * de 12px e fonte de 16px onde o resto do sistema usa 8 e 14.
 *
 * De qualquer forma nenhuma regra alcança o picker das telas ainda não
 * migradas: as duas raízes são do v2.
 */

:is(html[data-theme]) .picker {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* O select é a fonte de dados do motor, não um segundo controle visível. Nas
   páginas que carregam apenas o bundle v2, a regra equivalente do CSS legado
   não existe; sem este contrato o select multiple fica exposto acima do picker
   já inicializado. */
:is(html[data-theme]) .picker > .search-picker__native {
  display: none !important;
}

/* A ação nasce no componente ao lado do select-fonte e o motor a transplanta
   para a linha do controle. Antes dessa inicialização ela não pode ocupar uma
   linha própria nem piscar no carregamento. */
:is(html[data-theme]) .picker > .picker__action {
  display: none;
}

/* ---- o campo de busca ---------------------------------------------------
 *
 * `.field` entrou na lista em 2026-08-17: um picker posto dentro do campo do v2
 * (a sede do roteiro, por exemplo) não casava com nenhuma das duas raízes e
 * ficava com a pintura do legado — fundo transparente e raio de 12px, contra o
 * `#223348` e os 8px do picker de destinos, na mesma tela e um debaixo do outro.
 */

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__control {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  /* Sem sombra. O legado punha `0 1px 2px rgb(0 0 0 / .3)` aqui, e como esta
     folha não declarava nada a regra antiga sobrevivia — o campo de busca era o
     único controle do sistema com relevo. No v2 a única sombra de campo é a
     vermelha do erro; separação entre camadas é superfície, não profundidade. */
  box-shadow: none;
  box-sizing: border-box;
  color: var(--text-strong);
  display: flex;
  /* 14px como todo campo do sistema. O legado deixava o texto do picker em
     16px e numa cor própria quase-branca, e o campo de busca era o único
     controle com letra maior que os vizinhos — lado a lado com um `input`, a
     diferença aparecia sem que nada a explicasse. */
  font-size: var(--text-size-base);
  gap: var(--gap-tight);
  min-height: var(--control-height);
  padding: var(--pad-field);
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__input {
  color: var(--text-strong);
  font: inherit;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__control:focus-within {
  border-color: var(--focus-ring);
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__input {
  background: none;
  border: 0;
  color: var(--text-strong);
  flex: 1 1 auto;
  font: inherit;
  font-size: var(--text-size-base);
  min-width: 0;
  outline: none !important;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__input::placeholder {
  color: var(--text-muted);
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__icon {
  align-items: center;
  color: var(--text-muted);
  display: inline-flex;
  flex: none;
  height: 16px;
  position: relative;
  width: 16px;
}

/* O desenho da lupa pertence ao picker V2. Antes ele só existia na folha
   legada `fields/search-picker.css`: páginas com bundle enxuto recebiam um
   espaço vazio à esquerda e denunciavam a dependência do componente antigo. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__icon::before {
  border: 2px solid currentColor;
  border-radius: var(--radius-pill);
  box-sizing: border-box;
  content: "";
  height: 12px;
  left: 0;
  position: absolute;
  top: 0;
  width: 12px;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__icon::after {
  background: currentColor;
  border-radius: var(--radius-pill);
  content: "";
  height: 2px;
  position: absolute;
  right: 0;
  top: 11px;
  transform: rotate(45deg);
  transform-origin: center;
  width: 8px;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__clear {
  align-items: center;
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  display: none;
  flex: none;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker--has-query .search-picker__clear {
  display: inline-flex;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__clear[hidden] {
  display: none;
}


/* A lista de resultados não é descrita aqui: ela é o modelo global e vive em
   `v2/listbox.css`, compartilhada com o menu do select.
 *
 * ---- os selecionados ----------------------------------------------------
 *
 * O cartão fica no degrau OPOSTO ao do campo, para a lista de escolhidos não
 * se confundir com a caixa de busca logo acima.
 */

/* A caixa dos escolhidos: sem borda, e declarando o degrau que os itens usam.
 *
 * Ela estava na MESMA cor dos itens (`surface-field` nos dois), porque nenhuma
 * das duas declarava o próprio degrau — as duas liam o `--surface-contrast` do
 * painel da página. O resultado era uma lista chapada, com o contorno fazendo o
 * trabalho que a superfície devia fazer.
 *
 * Declarando aqui, a caixa fica num degrau e os itens no oposto, que é a regra
 * do resto do sistema. A borda sai junto: separação entre camadas é superfície,
 * não linha. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-panel {
  /* A caixa dos escolhidos não desenha mais NADA: quem faz o box é o
     `form_block` em volta, e o painel dentro dele era caixa dentro de caixa —
     dois raios, dois recuos e duas superfícies para uma seção só. Sobrou a
     lista, direto no bloco.

     O degrau continua declarado aqui porque os cartões o usam: o bloco é
     `field`, então cada escolhido sobe para `rail` e se separa do fundo sem
     precisar de borda. */
  --surface-contrast: var(--surface-rail);

  background: none;
  border: 0;
  border-radius: 0;
  box-sizing: border-box;
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
  padding: 0;
}

/* O cabeçalho ("Selecionados" e o contador em accent) sai junto com a caixa: o
   título do `form_block` já nomeia a seção, e repeti-lo logo abaixo dizia duas
   vezes a mesma coisa. O contador some com ele — a lista tem no máximo três
   itens visíveis, e contar até três não precisa de selo. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-header {
  display: none;
}

/* Nada escolhido também é um estado, e ele ocupa uma FAIXA — a mesma geometria
   do cartão que vai aparecer ali quando houver escolha: altura, raio e degrau
   iguais. Assim a caixa não salta de tamanho no primeiro item, e o lugar onde
   os escolhidos vão morar já está visível antes de existir algum. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-empty {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 0;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-muted);
  display: flex;
  font-size: var(--text-size-base);
  justify-content: center;
  margin: 0;
  /* Altura FIXA, e não a do cartão daquele picker: a faixa de vazio diz a mesma
     coisa em todos eles, e três pickers na mesma tela com faixas de alturas
     diferentes leem como três estados diferentes. O preço é que, no picker de
     documento vinculado — cujos cartões são mais altos —, a caixa cresce ao
     aparecer o primeiro resultado. Entre saltar uma vez e desalinhar sempre,
     escolhi o salto. */
  min-height: 56px;
  padding: 10px 12px;
  text-align: center;
}

/* O `display` acima vence o `[hidden]`, que é regra de agente do usuário — e o
   picker de ofício vinculado esconde o aviso de "nenhum resultado" por esse
   atributo, mostrando-o só quando a busca não acha nada. Sem este guarda, a
   frase ficava permanente na tela, embaixo da lista cheia.

   É a TERCEIRA vez que este mesmo descuido aparece nesta migração: aconteceu
   com o menu de ações e com o estado vazio do painel. Sempre que uma regra do
   v2 declara `display`, ela precisa declarar o par `[hidden]`. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-empty[hidden] {
  display: none;
}

/* Teto de TRÊS escolhidos; do quarto em diante, rola.
 *
 * A conta é a mesma do menu do select (`v2/listbox.css`): três itens inteiros e
 * três vãos — os dois entre eles e mais um de respiro, que é o que denuncia
 * haver um quarto. Sem esse terceiro vão, o item de baixo encosta na borda e a
 * lista parece terminar ali.
 *
 * A altura do item é DECLARADA, não deduzida do conteúdo: é ela que define
 * quantos cabem, e o teto é um múltiplo exato dela. Deduzir faria o corte cair
 * no meio de um cartão assim que um nome ocupasse duas linhas. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-list {
  --escolhido-height: 56px;

  display: grid;
  gap: var(--gap-tight);
  max-height: calc(
    var(--escolhido-height) * 3 + var(--gap-tight) * 3
  );
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-card {
  min-height: var(--escolhido-height);
}

/* Estar na lista já é o estado normal do escolhido: um degrau da escada, sem
   realce. O destaque de accent fica reservado ao que se DESTACA entre eles —
   ver o bloco do motorista e da viatura, mais abaixo. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-card {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 0;
  box-shadow: none;
  border-radius: var(--radius-field);
  color: var(--text-strong);
  cursor: pointer;
  display: flex;
  gap: var(--gap);
  padding: 10px 12px;
  text-align: left;
  width: 100%;
}

/* A mesma âncora da opção da lista (`v2/listbox.css`): o item que se escolhe e
   o que fica escolhido têm de ser reconhecíveis como a mesma coisa. Antes o
   contorno vinha de uma regra legada, num azul que não era o accent do tema. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-avatar {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: var(--radius-field);
  color: var(--accent);
  display: inline-flex;
  flex: none;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  height: 36px;
  justify-content: center;
  width: 36px;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-name {
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-empty {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  margin: 0;
  padding: 12px;
}

/* Sempre visível, e encostado na direita da faixa.
 *
 * O legado o deixava com `opacity: 0`, revelando no hover — quem usa toque não
 * tem hover, e mesmo no mouse a ação de remover ficava escondida até alguém
 * passar por cima por acaso. E uma margem negativa de -12px o puxava para junto
 * do texto: com o conteúdo curto, ele parava no meio do cartão.
 *
 * `margin-left: auto` empurra para o fim da faixa e cancela a margem negativa
 * numa declaração só. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove {
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  flex: none;
  /* Margem inteira: o legado usa `margin: -12px`, e sobrescrever só a da
     esquerda deixava as de cima e de baixo negativas — o botão transbordava a
     altura do cartão. */
  margin: 0 0 0 auto;
  opacity: 1;
  /* O legado ainda o desloca 8px para a esquerda com `translateX(-8px)` — o
     botão já estava no lugar certo e era movido depois. Zerar a margem não
     resolvia porque o deslocamento não é margem. */
  transform: none;
}

/* A geometria do botão é a MESMA em todo estado — repouso, sob o mouse, com
 * foco, no clique, e também quando o mouse está sobre a faixa inteira.
 *
 * O legado mexe na posição dele em mais de um estado (o `translateX(-8px)` do
 * repouso é só um deles), e o resultado é um botão que dá um pulo quando o
 * cursor entra no cartão. Botão que se move sob o cursor é botão que se erra:
 * a mira é feita antes do movimento.
 *
 * Trava a caixa inteira, não só o `transform`: largura, altura, margem e recuo
 * juntos, porque qualquer um deles desloca o que está ao lado. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:hover,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:focus,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:focus-visible,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:active,
:is(html[data-theme]) :is(.picker, .destination-row, .field)
  .search-picker__selected-card:hover .search-picker__remove,
:is(html[data-theme]) :is(.picker, .destination-row, .field)
  .search-picker__selected-card:focus-within .search-picker__remove {
  background: none;
  border: 0;
  /* Pílula sempre: é um botão de ícone quadrado. O legado deixava o raio
     assimétrico (`11px 0 0 11px`), e era ele que o anel de foco seguia. */
  border-radius: var(--radius-pill);
  box-shadow: none;
  height: var(--control-height-sm);
  margin: 0 0 0 auto;
  opacity: 1;
  padding: 0;
  transform: none;
  translate: none;
  width: var(--control-height-sm);
}

/* O conteúdo ocupa o que sobra, para o botão ter para onde ser empurrado. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-main {
  flex: 1 1 auto;
}

/* Anel SÓ no teclado, e redondo.
 *
 * `:focus:not(:focus-visible)` é o clique do mouse: o foco existe — o botão
 * acabou de ser acionado —, mas nenhum anel aparece. O legado marcava `:focus`
 * puro, que dispara nos dois casos, e era por isso que o anel nascia ao clicar
 * e ficava lá até o clique seguinte.
 *
 * `:focus-visible` é o que o navegador entende como "chegou por teclado". O
 * anel segue o `border-radius` do elemento, então o raio de pílula num botão
 * quadrado de 28px dá um círculo.
 *
 * O `!important` nos dois é para vencer o de `base/base.css`, que impõe o anel
 * a todo controle como garantia global — aqui ela não cai, só troca de gatilho
 * e de forma. */
/* Sob o mouse muda a COR, e só: vermelho de perigo, avisando o que o botão faz.
   Nenhum anel, nenhum fundo, nenhuma borda — foi o anel de `outline` no hover,
   herdado do legado, que parecia foco e aparecia sem ninguém ter usado o Tab. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:hover {
  color: var(--danger);
}

/* Nada de anel fora do teclado. O legado põe `outline` no HOVER — é ele que
   aparecia ao passar o mouse e que parecia foco. E `:focus:not(:focus-visible)`
   cobre o clique, onde o foco existe mas não deve se anunciar. */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:hover,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:active,
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:focus:not(:focus-visible) {
  outline: none !important;
}

:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__remove:focus-visible {
  border-radius: var(--radius-pill);
  outline: 2px solid var(--focus-ring) !important;
  outline-offset: 2px;
}

/* ---- a raiz das apresentações detalhadas ---------------------------------
 *
 * O legado desenha uma CAIXA em volta do picker de pessoas e de veículos —
 * fundo próprio e contorno TRACEJADO —, herança de quando ele era uma área de
 * soltar. No v2 quem faz a caixa é o `form_block` em volta, e o tracejado
 * aparecia como um retângulo pontilhado dentro de outro retângulo.
 *
 * Os seletores repetem as combinações exatas do legado
 * (`--people.--roster`, `--vehicle`) porque é assim que aquelas regras
 * alcançam a raiz; um seletor mais curto empataria e perderia a disputa.
 */
:is(html[data-theme]) .picker .search-picker--detailed,
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster,
:is(html[data-theme]) .picker .search-picker--vehicle {
  background: none;
  border: 0;
  padding: 0;
}

/* ---- o escolhido nas apresentações detalhadas ----------------------------
 *
 * O legado descreve o cartão de pessoa e o de veículo com UMA CLASSE A MAIS que
 * as regras acima (`--people.--roster`, `--vehicle`), e por isso vencia todas
 * elas: o cartão saía com o fundo do campo — igual ao do bloco em volta, sem se
 * destacar de nada —, raio de 12px que não é o do sistema, uma grade com coluna
 * fixa de 42px e uma LINHA VERTICAL separando o "×" do resto.
 *
 * Repetir aqui as combinações exatas é o que devolve a disputa. Um seletor mais
 * curto empata e perde.
 */
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster .search-picker__selected-card,
:is(html[data-theme]) .picker .search-picker--vehicle .search-picker__selected-card,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__selected-card {
  align-items: center;
  background: var(--surface-contrast, var(--surface-rail));
  border: 0;
  border-radius: var(--radius-field);
  box-shadow: none;
  display: flex;
  gap: var(--gap);
  grid-template-columns: none;
  min-height: var(--escolhido-height);
  padding: 14px 12px;
}

/* O "×" não é uma coluna com divisória: é o mesmo botão redondo de sempre, à
   direita, do tamanho do controle miúdo. A LINHA VERTICAL à esquerda dele era o
   que fazia o cartão parecer uma tabela de duas células.

   São duas formas porque o motor monta o cartão de dois jeitos: em alguns ele
   embrulha o botão num grupo de ações, em outros o botão é filho direto. O
   legado descreve as duas, cada uma com uma classe a mais que a regra geral do
   v2 — cobrir só uma deixava a divisória viva na outra, e foi o que aconteceu:
   sumiu do cartão de pessoa e continuou no de viatura. */
:is(html[data-theme]) .picker :is(.search-picker--detailed, .search-picker--roster, .search-picker--people, .search-picker--vehicle) .search-picker__selected-actions .search-picker__remove,
:is(html[data-theme]) .picker :is(.search-picker--detailed, .search-picker--roster, .search-picker--people, .search-picker--vehicle) .search-picker__selected-card > .search-picker__remove {
  align-self: center;
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  height: var(--control-height-sm);
  margin: 0 0 0 auto;
  padding: 0;
  width: var(--control-height-sm);
}

:is(html[data-theme]) .picker .search-picker__selected-actions {
  border: 0;
  margin-left: auto;
  padding: 0;
}

/* O selo "Viatura" do cartão escolhido. O legado o pintava de dourado CHEIO —
 * num tom fixo (`#d8a21b`) que nem é o accent do tema —, em 10px, peso 900,
 * caixa alta e com espaçamento entre letras. Um selo assim grita mais que a
 * placa que ele acompanha, e o olho lê primeiro a palavra "VIATURA", que é a
 * mesma em todos os cartões, antes do dado que distingue um do outro.
 *
 * Vale para os dois selos informativos do cartão — "Viatura" e "Motorista" —,
 * que o legado pintava do mesmo jeito. Aqui usam a linguagem de selo do sistema,
 * a do `chip--v2`, com o tom ACCENT: fundo translúcido a 16% e a cor cheia no
 * texto. Translúcido porque é o único tom que se adapta ao fundo; o dourado
 * cheio dominava o cartão e obrigava o texto a virar escuro para sobreviver.
 *
 * Sobre o cartão do motorista, que JÁ está na cor da escolha, o translúcido
 * continua legível — foi por isso que ele venceu as outras três alternativas
 * testadas na galeria.
 */
:is(html[data-theme]) .picker .search-picker__driver-chip,
:is(html[data-theme]) .picker .search-picker__vehicle-chip {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 0;
  border-radius: var(--radius-pill);
  color: var(--accent);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: normal;
  padding: 3px 10px;
  text-transform: none;
  white-space: nowrap;
}

/* ---- o que se destaca entre os escolhidos --------------------------------
 *
 * Numa equipe de cinco, todos foram escolhidos — o que a lista precisa
 * responder de relance é OUTRA coisa: quem dirige. Por isso o realce de accent
 * (cor própria, fita à esquerda e âncora cheia) marca só o MOTORISTA, e não
 * todo cartão. Com todos realçados, o realce não dizia nada.
 *
 * A viatura entra no mesmo desenho porque ali só existe uma: o cartão dela É a
 * escolha da seção, não um item entre vários.
 *
 * Os seletores repetem as variantes COMPOSTAS (`--people.--roster`) em vez de
 * um `:is(...)`: a especificidade de um `:is()` é a do seu argumento MAIS
 * específico — uma classe —, e por isso a primeira versão desta regra perdia
 * para a que pinta o cartão neutro logo acima, que soma duas. O motorista
 * ficava com a âncora cheia e sem a cor e a fita, um estado pela metade.
 */
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster .search-picker__selected-card--driver,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__selected-card--driver,
:is(html[data-theme]) .picker .search-picker--vehicle .search-picker__selected-card--vehicle,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__selected-card--vehicle {
  background: var(--surface-selected);
  box-shadow: inset 3px 0 0 0 var(--accent);
}

/* Âncora CHEIA só nesses dois: na lista de opções ela concorre com as irmãs e
   precisa ser translúcida; aqui ela aponta um item só. */
:is(html[data-theme]) .picker .search-picker__selected-card--driver .search-picker__selected-avatar,
:is(html[data-theme]) .picker .search-picker__selected-card--vehicle .search-picker__selected-avatar {
  background: var(--accent);
  border: 0;
  color: var(--text-on-accent);
}

/* O campo de busca é O MESMO nas três apresentações. O legado dá ao de pessoas
 * (`--people.--roster`) fundo e borda próprios, com uma classe a mais que a
 * regra geral do v2 — e por isso vencia: lado a lado, o picker de equipe tinha
 * um campo em outro tom e com contorno cinza visível, enquanto o de viatura e o
 * de uma linha ficavam sem contorno. Nada explicava a diferença; ela era só o
 * resto de uma folha que ninguém apagou.
 */
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster .search-picker__control,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__control,
:is(html[data-theme]) .picker .search-picker--vehicle .search-picker__control {
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
}

/* O vão entre o campo de busca e a lista de escolhidos. O legado o deixa em
 * 16px, e com o vão da própria lista somando por baixo o campo ficava distante
 * do que ele acabou de produzir — as duas peças são uma coisa só, e o espaço
 * entre elas tem de ser menor que o que separa um bloco do outro.
 */
:is(html[data-theme]) .picker .search-picker {
  gap: var(--gap-tight);
}

/* A lista vazia continua sendo uma LINHA da grade, de altura zero, e o vão dela
   para a faixa seguinte soma ao vão do campo — 8 + 8, quando o desenho pede 8.
   Um contêiner sem filhos não ocupa lugar nenhum.

   Vale também para a lista de RESULTADOS do picker de documento vinculado, que
   nasce vazia no HTML e é preenchida pelo script da página. Cheguei a excluí-la
   daqui achando que a regra a escondia para sempre — não esconde: `:empty` é
   avaliado ao vivo e deixa de casar no instante em que o script insere o
   primeiro cartão. O que eu tinha visto era uma lista vazia porque não havia
   ofício a mostrar, e a exclusão só devolveu o vão dobrado entre o campo e a
   faixa de "nenhum resultado". */
:is(html[data-theme]) :is(.picker, .destination-row, .field) .search-picker__selected-list:empty {
  display: none;
}

/* ---- o que a varredura das três apresentações encontrou ------------------
 *
 * Comparando propriedade a propriedade o picker de uma linha, o de pessoas e o
 * de veículos, sobraram duas diferenças que ninguém decidiu — as demais são de
 * conteúdo (largura de texto) ou de estado (o realce do motorista e o da
 * viatura).
 */

/* 1. O vão interno do campo saía 8px numa apresentação e 7px nas outras. Um
      pixel de diferença não se vê sozinho, mas é o tipo de resto que faz duas
      telas nunca fecharem quando alguém tenta alinhá-las. */
:is(html[data-theme]) .picker .search-picker__field,
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster .search-picker__field,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__field {
  gap: var(--gap-tight);
}

/* 2. O cartão com selo ficava 6px mais alto que o sem selo (62 contra 56), e a
      conta do teto de três escolhidos é feita sobre 56 — a lista cortava no
      lugar errado assim que um item tinha "Viatura" ou "Motorista". O selo
      agora cabe DENTRO da linha do nome em vez de esticá-la. */
:is(html[data-theme]) .picker .search-picker__driver-chip,
:is(html[data-theme]) .picker .search-picker__vehicle-chip {
  /* Altura FIXA, igual à caixa de linha do nome ao lado (18px). Só o
     `line-height` não bastava: o legado ainda somava altura mínima própria, e o
     selo continuava esticando a linha em 3px. */
  box-sizing: border-box;
  height: 18px;
  line-height: 1;
  min-height: 0;
  padding: 0 8px;
}

/* ---- picker de documento vinculado ---------------------------------------
 *
 * A lista fica à vista o tempo todo, então ela é quem rola — o teto é o mesmo
 * de três cartões dos outros pickers, para as duas listas do formulário
 * pararem na mesma altura.
 */
/* O cartão daqui é mais alto que o dos outros pickers: ele carrega um documento
   inteiro — número, rota, período, equipe e viatura —, e os 56px que bastam
   para um nome e um cargo deixavam as duas linhas espremidas contra as bordas.
   A altura vive numa variável porque é ela que fecha a conta do teto de três. */
/* A altura do item daqui vale para o picker INTEIRO, e não só para a lista: a
   faixa de "nenhum resultado" é irmã da lista, não filha dela, e sem esta
   declaração na raiz ela ficava nos 56px genéricos enquanto os cartões tinham
   68 — a caixa mudava de altura no instante em que o primeiro resultado
   aparecia. */
:is(html[data-theme]) .picker--related {
  --escolhido-height: 52px;
}

:is(html[data-theme]) .picker--related .search-picker__selected-list {
  /* 52px, a MESMA altura do item de duas linhas da lista suspensa
     (`--listbox-option-height` em `v2/listbox.css`): as duas peças mostram o
     mesmo tipo de coisa — um item com nome em cima e detalhe embaixo —, e é a
     mesma escolha feita duas vezes na tela. Com 68 aqui e 52 lá, o cartão do
     ofício vinculado parecia de outra família (2026-08-16).

     Repetida NA LISTA porque a regra geral declara `--escolhido-height: 56px`
     nela mesma, e o valor da própria lista vence o herdado da raiz — tanto para
     ela quanto para os cartões dentro dela. */
  --escolhido-height: 62px;

  max-height: calc(var(--escolhido-height, 56px) * 3 + var(--gap-tight) * 3);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}

/* O cartão da lista é um BOTÃO, e o navegador lhe dá fonte e alinhamento
   próprios. O arranjo também precisa ser declarado aqui: o legado empilha ícone
   e texto numa grade centralizada, e o cartão saía com 92px e o ícone acima do
   nome — em vez dos 56px e do ícone à esquerda dos outros pickers. */
:is(html[data-theme]) .picker--related .search-picker__selected-card {
  align-items: center;
  cursor: pointer;
  display: flex;
  /* `row` declarado: o legado empilha em coluna, e com o ícone em cima do nome
     o cartão saía com 92px onde o conteúdo pede 56. */
  flex-direction: row;
  flex-wrap: nowrap;
  font: inherit;
  gap: var(--gap);
  grid-template-columns: none;
  min-height: var(--escolhido-height, 56px);
  /* O conteúdo de duas linhas mede 36px; 8px verticais deixam o cartão dentro
     dos 62px canônicos. Com 32px de cada lado, dois resultados sozinhos
     encostavam no teto de 210px e eram comprimidos para preencher a lista. */
  padding: var(--gap-tight) var(--gap);
  text-align: left;
  width: 100%;
}

/* O texto do cartão empilha em duas linhas e se alinha à esquerda; centralizado
   ele lia como um aviso, não como um item de lista. */
:is(html[data-theme]) .picker--related .search-picker__selected-main {
  align-items: flex-start;
  display: grid;
  gap: 2px;
  justify-items: start;
  min-width: 0;
  text-align: left;
}

/* O escolhido da lista usa o MESMO estado da opção escolhida no menu e do
   cartão do motorista: cor própria e fita de accent. `is-active` é a classe que
   `CV.pickerParts.createRelatedCard` escreve — nome do motor, não do desenho. */
:is(html[data-theme]) .picker--related .search-picker__selected-card.is-active {
  background: var(--surface-selected);
  box-shadow: inset 3px 0 0 0 var(--accent);
}

:is(html[data-theme]) .picker--related .search-picker__selected-card.is-active .search-picker__selected-avatar {
  background: var(--accent);
  border: 0;
  color: var(--text-on-accent);
}

:is(html[data-theme]) .picker--related .search-picker__selected-avatar svg {
  height: 18px;
  width: 18px;
}

/* O DESENHO do ícone dentro do avatar segue a cor do avatar, sempre. O ícone de
   rota do ofício vinculado traz `fill`/`stroke` no próprio SVG e o legado ainda
   pinta `.related-route-icon path` por fora — resultado: no picker de ofício o
   avatar saía num verde que não existe em nenhum outro escolhido do sistema,
   enquanto o de pessoa e o de viatura seguiam o accent. Herdar a cor do avatar
   é o que torna as três apresentações a mesma peça. */
:is(html[data-theme]) .picker .search-picker__selected-avatar :is(svg, .icon, .related-route-icon) {
  color: inherit;
  fill: none;
}

:is(html[data-theme]) .picker .search-picker__selected-avatar :is(svg, .icon, .related-route-icon) circle {
  fill: currentColor;
  stroke: none;
}

:is(html[data-theme]) .picker .search-picker__selected-avatar :is(svg, .icon, .related-route-icon) path {
  fill: none;
  stroke: currentColor;
}

/* Ícone de traço puro (`use` do sprite): ele pinta por `fill`, e a regra acima o
   apagaria. O sprite não tem `stroke`, então separar os dois casos pelo `use` é
   o que mantém os dois visíveis. */
:is(html[data-theme]) .picker .search-picker__selected-avatar svg:has(use) {
  fill: currentColor;
}

/* O teto de três escolhidos vale nas apresentações detalhadas também. O legado
 * declara `overflow: visible` na lista de pessoas com uma classe a mais — e o
 * `max-height` do v2 continuava valendo, então a caixa parava em 192px e os
 * cartões seguintes VAZAVAM para fora dela, por cima do bloco de baixo. Teto
 * sem rolagem não corta: só esconde a borda do problema.
 */
:is(html[data-theme]) .picker .search-picker--people.search-picker--roster .search-picker__selected-list,
:is(html[data-theme]) .picker .search-picker--detailed .search-picker__selected-list,
:is(html[data-theme]) .picker .search-picker--vehicle .search-picker__selected-list {
  max-height: calc(var(--escolhido-height, 56px) * 3 + var(--gap-tight) * 3);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}


/* ---- painel de funções da equipe (OS) ------------------------------------
 *
 * O toggle de funções (Condução / Técnico / Apoio) é o `toggle--fill` do
 * sistema, que já reparte a linha em colunas iguais. O que sobra para cá é o
 * que depende de estar DENTRO do picker: a caixa não pode crescer além dele, e
 * o rótulo precisa truncar em vez de esticar a coluna — com três rótulos e o
 * recuo do painel, a fileira ficava mais larga que o contêiner e vazava.
 */
:is(html[data-theme]) .picker .os-servidor-role-panel {
  min-width: 0;
}

:is(html[data-theme]) .picker .os-servidor-role-panel .toggle {
  /* 38 + 3 + 3 = 44px, a MESMA altura do campo de busca que vem logo abaixo.
     Os dois formam uma coluna só de controles, e o toggle no tamanho padrão
     (40px) ficava três pixels mais baixo — o bastante para a borda esquerda dos
     dois não se alinhar. */
  --toggle-item-height: 38px;

  box-sizing: border-box;
  max-width: 100%;
  min-width: 0;
  padding: 3px;
}

:is(html[data-theme]) .picker .os-servidor-role-panel .toggle__item {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O selo de função do servidor. O cartão destacado leva o selo de accent do
   motorista; os demais, o chip neutro do v2 — e os dois têm de medir o MESMO,
   senão a fileira de cartões ganha alturas diferentes conforme a função. 18px é
   a caixa da linha do nome ao lado, a mesma conta do selo de motorista. */
:is(html[data-theme]) .picker .search-picker__selected-card .chip--v2 {
  box-sizing: border-box;
  height: 18px;
  line-height: 1;
  min-height: 0;
  padding: 0 8px;
}

/* ---- documentos vinculáveis ao evento -------------------------------------
 *
 * Cinco painéis de busca, um por tipo de documento, sob o alternador. Só o
 * painel do tipo escolhido fica visível — e o `[hidden]` precisa do par: o
 * `display` do painel venceria a regra do navegador e os cinco apareceriam
 * empilhados.
 */
:is(html[data-theme]) .evento-doc-picker {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .evento-doc-panel {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .evento-doc-panel[hidden] {
  display: none;
}

/* O alternador dos cinco tipos, com o visual do segmented control de função
   dos servidores (Condução / Técnico / Apoio) da Ordem de Serviço.
   Vinha de `pages/oficios.css`, que desde a migração v2 não era carregada por
   página nenhuma: o toggle renderizava sem `display: grid` e os cinco rótulos
   caíam empilhados. O `--step1-field` só é declarado em folha de PÁGINA, e a
   tela de eventos não carrega nenhuma — daí o fallback, na forma que o resto
   do v2 já usa. */
:is(html[data-theme]) .evento-doc-toggle.segment-toggle {
  background: var(--step1-field, var(--color-input-bg));
  border-color: transparent;
  border-radius: 10px;
  box-shadow: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 2px;
  padding: 3px;
  width: 100%;
}

/* Telas estreitas: quebra o toggle em duas colunas para não espremer os rótulos. */
@media (max-width: 720px) {
  :is(html[data-theme]) .evento-doc-toggle.segment-toggle {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* O aviso de evento cancelado e o botão de reativar na mesma faixa: quem lê o
   aviso quer, na mesma linha, saber como desfazer. Em tela estreita o botão cai
   para baixo do texto, em vez de espremer os dois. */
:is(html[data-theme]) .evento-cancelado {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  margin-bottom: var(--gap);
}

:is(html[data-theme]) .evento-cancelado .alert {
  flex: 1 1 320px;
  margin: 0;
}

/* ---- o picker de DOCUMENTO VINCULADO --------------------------------------
 *
 * Veio de `fields/related-route-picker.css` em 2026-08-20. É o mesmo picker
 * desta folha noutro papel: em vez de pessoas ou viaturas, os candidatos são
 * documentos — o roteiro que o ofício vai usar, o ofício que o termo vai citar.
 * Quem monta as linhas é `js/components/picker-parts.js`, e o gêmeo declarativo
 * delas é `cotton/v2/related_row.html`.
 *
 * As classes `related-route-*` e `termo-oficio-*` são do sistema antigo e
 * FICARAM: os três motores de tela (`termos-form.js`, `ordens-servico-form.js`,
 * `justificativas-index.js`) acham a lista e o item por elas. Renomear sem
 * tocar os três deixa a lista sem desenho, em silêncio.
 *
 * Medido em 2026-08-20 no editor de roteiro: desligar estas vinte regras não
 * muda um pixel lá — o `.picker--related` do v2 já desenha o cartão. Elas
 * seguem porque as OUTRAS três telas do picker (termo, OS, justificativa) ainda
 * dependem delas.
 */

.related-route-picker.search-picker--people.search-picker--roster {
  gap: 0 !important;
}

.related-route-picker .search-picker__field {
  gap: 7px;
}

.related-route-picker .search-picker__selected-list.roteiro-editor__route-list {
  gap: 8px;
  margin-top: 8px;
}

/* A cor da barra vinha em `rgba()` literal, do desenho antigo. Aqui ela é o
   texto apagado misturado com transparente — o mesmo par que o resto do v2
   usa para traço discreto, e que acompanha a troca de tema. */
.related-route-list {
  scrollbar-color: color-mix(in srgb, var(--text-muted) 60%, transparent) transparent;
}

.related-route-list::-webkit-scrollbar {
  width: 28px;
}

.related-route-list::-webkit-scrollbar-track {
  background: transparent;
  margin: var(--space-1) 0;
}

.related-route-list::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-muted) 45%, transparent);
  border-radius: var(--radius-pill);
  transition: background 0.2s;
}

.related-route-list::-webkit-scrollbar-thumb:hover {
  background: var(--color-accent);
}

.related-route-list::-webkit-scrollbar-button {
  display: none;
}

.related-route-item {
  background: var(--route-card-inner-bg);
  border: 1px solid var(--route-section-border);
  border-radius: var(--radius-md);
  color: var(--theme-text-body);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2) var(--space-3);
  text-align: left;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast);
}

.related-route-item:hover {
  background: var(--route-card-inner-bg);
  border-color: var(--route-button-secondary-hover-border);
}

.related-route-item.is-active {
  border-color: var(--re-accent-border);
  box-shadow: 0 0 0 2px var(--re-choice-ring);
}

.related-route-item .related-route-title {
  color: var(--theme-text-heading);
  font-weight: 700;
}

.related-route-item .related-route-period {
  color: var(--theme-text-muted);
  font-size: 12px;
}

.related-route-empty {
  border: 1px dashed var(--theme-border-card);
  border-radius: var(--radius-md);
  color: var(--theme-text-muted);
  font-size: 13px;
  padding: var(--space-4);
  text-align: center;
}

.termo-oficio-source-select {
  display: none;
}

.termo-oficio-picker {
  display: grid;
  gap: 0;
}

:is(html[data-theme="dark"])
  [data-travel-document-wizard-step1]
  .related-route-picker.termo-oficio-picker.search-picker--people.search-picker--roster,
.document-form-page .related-route-picker.termo-oficio-picker.search-picker--people.search-picker--roster,
.termo-oficio-picker.search-picker--people.search-picker--roster {
  gap: 0 !important;
}

.termo-oficio-picker .search-picker__field,
:is(html[data-theme="dark"])
  [data-travel-document-wizard-step1]
  .related-route-picker.termo-oficio-picker
  .search-picker__field {
  gap: 7px !important;
}

.termo-oficio-summary-panel {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin-top: 0;
  padding: 0;
}

.termo-oficio-picker .search-picker__selected-list,
.termo-oficio-picker .roteiro-editor__route-list,
.termo-oficio-summary-panel .search-picker__selected-list,
.termo-oficio-summary-panel .related-route-list,
:is(html[data-theme="dark"])
  [data-travel-document-wizard-step1]
  .related-route-picker.termo-oficio-picker
  :is(.search-picker__selected-list, #termo-oficio-lista, #os-oficio-lista) {
  display: grid;
  gap: 8px !important;
  margin-top: 8px;
  max-height: 280px;
  overflow: auto;
}
/* <<< css/v2/picker.css <<< */

/* >>> css/v2/date-picker.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/date-picker.css` em 2026-08-20.
 *
 * Esta parte NÃO é legado: são as declarações do próprio componente do v2, que
 * moravam numa pasta com nome do sistema antigo porque foi lá que nasceram. O
 * arquivo v2 carregava só o DELTA — e por isso apagar a pasta antiga teria
 * apagado o componente.
 *
 * A ordem foi preservada: base primeiro, delta depois, exatamente como os dois
 * bundles as entregavam.
 * ══════════════════════════════════════════════════════════════════════════ */

/* --------------------------------------------------------------------------
   date-picker — componente compartilhado
   -------------------------------------------------------------------------- */

html {
  --date-picker-selected-bg-start: var(--stepper-active-bg, var(--color-accent));
  --date-picker-selected-bg-end: var(--stepper-active-bg, var(--color-accent));
  --date-picker-selected-border: transparent;
  --date-picker-selected-color: var(--stepper-active-color, var(--color-white));
  --date-picker-selected-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
  --date-picker-selected-halo: var(--stepper-active-bg, var(--color-accent));
}

html[data-theme="dark"] {
  --date-picker-selected-shadow: 0 1px 2px rgba(0, 0, 0, 0.22);
}

html[data-theme="light"] {
  --date-picker-selected-shadow: 0 1px 2px rgba(0, 0, 0, 0.16);
}

.date-picker {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
  position: relative;
}

.date-picker__control {
  align-items: stretch;
  display: flex;
  gap: var(--space-2);
  min-width: 0;
  position: relative;
}

/* O CHROME DE FIELD do gatilho saiu em 2026-08-20, com as três regras que o
   desenhavam. Elas valiam para `.date-picker__trigger` que não fosse `--icon`, e
   isso é só a variante `action-button` — que nenhuma tela pede: `control_variant`
   não é passado por chamador nenhum, e o único a exercitá-la é o teste do
   componente. As três se excluíam por `:not(.cv-btn)`, classe do botão do
   sistema antigo, que morreu com `actions/action-system.css` no mesmo dia; a
   guarda já não guardava nada, e o gatilho recebia chrome de CAMPO em vez do
   visual de botão que o comentário original prometia. Sem elas, o `button
   button--secondary` que a variante emite vale por si — que era a intenção. */

.date-picker__trigger--icon {
  align-items: center;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: 50%;
  box-shadow: none;
  color: var(--theme-text-body);
  cursor: pointer;
  display: inline-flex;
  flex: 0 0 auto;
  height: 28px;
  justify-content: center;
  min-height: 0;
  opacity: 0;
  padding: 0;
  pointer-events: none;
  position: absolute;
  right: var(--space-2);
  top: 50%;
  transform: translateY(-50%);
  transition: opacity 150ms ease, transform 150ms ease, box-shadow 150ms ease;
  width: 28px;
  z-index: 2;
}

.date-picker__trigger--icon svg {
  display: block;
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

.date-picker__control:hover .date-picker__trigger--icon,
.date-picker__control:focus-within .date-picker__trigger--icon,
.date-picker--open .date-picker__trigger--icon {
  background: var(--btn-secondary-bg);
  border-color: var(--btn-secondary-border);
  color: var(--btn-secondary-color);
  opacity: 1;
  pointer-events: auto;
}

.date-picker__trigger--icon:hover {
  background: var(--btn-secondary-hover-bg);
  border-color: var(--btn-secondary-hover-border);
  box-shadow: var(--shadow-xs);
  color: var(--btn-secondary-hover-color);
  transform: translateY(calc(-50% - 1px));
}

.date-picker__trigger--icon:active {
  transform: translateY(calc(-50% + 1px));
}

.date-picker__trigger--icon:focus-visible {
  box-shadow: var(--btn-focus-ring);
  opacity: 1;
  pointer-events: auto;
}

.date-picker__summary {
  color: var(--theme-text-muted);
  font-size: var(--font-size-xs);
  line-height: 1.45;
  margin: 0;
}

.date-picker__panel {
  --date-picker-day-gap: 2px;
  --date-picker-day-size: 40px;
  --date-picker-grid-width: calc((7 * var(--date-picker-day-size)) + (6 * var(--date-picker-day-gap)));
  /* Quebra de semana: suaviza apenas as quinas da borda; inicio/fim seguem pill. */
  --date-picker-week-edge-radius: 4px;
  background: var(--route-card-inner-bg, var(--theme-surface-card));
  border: 1px solid var(--route-card-inner-border, var(--theme-border-card));
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-soft);
  box-sizing: border-box;
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
  /* ABSOLUTO, e o `date-picker.js` escreve as coordenadas em documento. Era
     `fixed`, e aí o painel descolava do campo: quando não cabia na janela, a
     conta terminava numa trava contra a borda e ele parava, enquanto a página
     seguia rolando por baixo. */
  position: absolute;
  width: min(calc(var(--date-picker-grid-width) + (2 * var(--space-4))), calc(100vw - 16px));
  z-index: calc(var(--z-sticky-stepper, 1100) + 20);
}

.date-picker--open .date-picker__panel,
.date-picker__panel--entering {
  animation: cv-date-picker-enter 150ms ease-out both;
}

@keyframes cv-date-picker-enter {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

.date-picker__panel-header {
  align-items: center;
  display: grid;
  gap: var(--space-2);
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.date-picker__context {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 var(--space-1) var(--space-1);
}

.date-picker__context-step {
  color: var(--stepper-active-bg, var(--color-accent));
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.date-picker__context-route {
  color: var(--theme-text-heading);
  font-size: 13px;
  font-weight: 800;
  line-height: 1.15;
}

.date-picker__month {
  color: var(--theme-text-heading);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-extrabold);
  letter-spacing: 0;
  text-align: center;
}

.date-picker__nav,
.date-picker__footer-action {
  align-items: center;
  appearance: none;
  background:
    linear-gradient(var(--theme-surface-card), var(--theme-surface-card)) padding-box,
    linear-gradient(var(--color-input-border, var(--color-border-strong)), var(--color-input-border, var(--color-border-strong))) border-box;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--theme-text-body);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  justify-content: center;
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3);
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}

.date-picker__nav:hover,
.date-picker__footer-action:hover {
  background:
    linear-gradient(var(--field-bg-hover), var(--field-bg-hover)) padding-box,
    linear-gradient(var(--color-border-strong, var(--color-border-strong)), var(--color-border-strong, var(--color-border-strong))) border-box;
}

.date-picker__weekdays,
.date-picker__days {
  column-gap: var(--date-picker-day-gap);
  display: grid;
  grid-template-columns: repeat(7, var(--date-picker-day-size));
  justify-content: center;
  row-gap: var(--date-picker-day-gap);
}

.date-picker__weekday {
  color: var(--theme-text-muted);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  padding: var(--space-1) 0;
  text-align: center;
  text-transform: uppercase;
}

.date-picker__day {
  align-items: center;
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--theme-text-body);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-weight-semibold);
  box-sizing: border-box;
  height: var(--date-picker-day-size);
  isolation: isolate;
  justify-content: center;
  min-width: 0;
  padding: 0;
  position: relative;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    filter var(--transition-fast),
    box-shadow var(--transition-fast);
  width: 100%;
}

.date-picker__day::before {
  border-radius: 50%;
  content: "";
  height: var(--date-picker-day-size);
  left: 50%;
  pointer-events: none;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: var(--date-picker-day-size);
  z-index: -1;
}

.date-picker__day:hover {
  filter: brightness(1.08);
  z-index: 2;
}

.date-picker__day:hover:not(.date-picker__day--selected):not(.date-picker__day--range) {
  background-color: rgba(127, 127, 127, 0.1);
}

.date-picker__day--selected:hover,
.date-picker__day--range:hover{
  background-color: transparent;
}

.date-picker__day--muted {
  color: var(--theme-text-muted);
  opacity: 0.55;
}

/* Multi sequencial: dias fora da ordem da rota (antes do trecho anterior) ficam bloqueados. */
.date-picker__day:disabled {
  cursor: not-allowed;
  opacity: 0.35;
}

.date-picker__day:disabled:hover {
  background-color: transparent;
  filter: none;
}

.date-picker__day--today {
  border-color: transparent;
}

.date-picker__day--today::after {
  background: var(--date-picker-selected-bg-start);
  border-radius: 50%;
  bottom: 4px;
  box-shadow: 0 0 0 1px var(--route-card-inner-bg, var(--theme-surface-card));
  content: "";
  height: 5px;
  left: 50%;
  pointer-events: none;
  position: absolute;
  transform: translateX(-50%);
  width: 5px;
  z-index: 3;
}

.date-picker__day--today.date-picker__day--selected::after,
.date-picker__day--today.date-picker__day--range::after{
  background: var(--date-picker-selected-color);
  box-shadow: 0 0 0 1px var(--date-picker-selected-halo);
}

.date-picker__day--selected,
.date-picker__day--range-start,
.date-picker__day--range-end{
  color: var(--date-picker-selected-color);
  z-index: 2;
}

.date-picker__day--selected::before,
.date-picker__day--range-start::before,
.date-picker__day--range-end::before{
  background:
    linear-gradient(180deg, var(--date-picker-selected-bg-start) 0%, var(--date-picker-selected-bg-end) 100%);
  border: 1px solid var(--date-picker-selected-border);
  box-shadow: var(--date-picker-selected-shadow);
}

.date-picker__day--range {
  background: transparent;
  border-color: transparent;
  border-radius: 0;
  color: var(--date-picker-selected-color);
  z-index: 2;
}

.date-picker__day--range::before {
  background:
    linear-gradient(180deg, var(--date-picker-selected-bg-start) 0%, var(--date-picker-selected-bg-end) 100%);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  height: var(--date-picker-day-size);
  width: var(--date-picker-day-size);
}

.date-picker__day--range:nth-child(7n + 1)::before {
  border-bottom-left-radius: var(--date-picker-week-edge-radius);
  border-top-left-radius: var(--date-picker-week-edge-radius);
}

.date-picker__day--range:nth-child(7n)::before {
  border-bottom-right-radius: var(--date-picker-week-edge-radius);
  border-top-right-radius: var(--date-picker-week-edge-radius);
}

.date-picker__day--range.date-picker__day--range-start::before {
  border-bottom-left-radius: var(--radius-pill);
  border-top-left-radius: var(--radius-pill);
}

.date-picker__day--range.date-picker__day--range-end::before {
  border-bottom-right-radius: var(--radius-pill);
  border-top-right-radius: var(--radius-pill);
}

.date-picker__day--range.date-picker__day--range-start.date-picker__day--range-end::before {
  border-radius: var(--radius-pill);
}

.date-picker__day:focus-visible {
  box-shadow: var(--field-shadow-focus);
  outline: none;
  z-index: 1;
}

.date-picker__footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * VINDAS DAS FOLHAS DE TEMA E DO CASCO ANTIGO, em 2026-08-20.
 *
 * Descreviam este componente DE FORA dele — em `theme-shared-components.css`,
 * `theme-dark-components.css`, `layout/page-shell.css`, `fields/forms.css` ou
 * `lists/list-header.css`. Enquanto ficaram lá, o componente do v2 dependia de
 * folhas do sistema antigo para ter forma, e toda tela migrada carregava
 * aquelas folhas por causa dele.
 *
 * Vieram com o texto INTACTO — `!important` e escopo de wizard inclusive —, e
 * ANTES da divisa: elas chegavam pelo bundle do shell, que é anterior ao
 * `ui.bundle.css`, e por isso perdiam para o delta do v2. Anexá-las no fim
 * inverteria a disputa sem mudar um valor sequer. Medido antes e depois em 20
 * telas: nenhuma diferença.
 * ═══════════════════════════════════════════════════════════════════════════ */

html[data-theme] .date-picker__footer .date-picker__footer-action {
  border-radius: 10px;
}

html[data-theme] .date-picker__footer .date-picker__footer-action {
  background: var(--step1-panel, var(--color-surface-soft));
  background-image: none;
  border: 0;
  box-shadow: none;
  color: var(--color-heading, var(--theme-text-heading));
  font-weight: var(--font-weight-bold);
  min-height: var(--control-height-sm, 34px);
  padding: 0 14px;
  transform: none;
}

html[data-theme] .date-picker__footer .date-picker__footer-action:hover,
html[data-theme] .date-picker__footer .date-picker__footer-action:focus-visible {
  background: color-mix(in srgb, var(--color-accent) 14%, var(--color-surface-muted));
  background-image: none;
  border: 0;
  box-shadow: none;
  color: var(--color-accent-text, var(--color-accent));
  outline: 0;
  transform: none;
}

html[data-theme="dark"] :is(.date-picker__panel, .popover) {
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text);
  box-shadow: var(--shadow-elevated);
}

/* ---- a pílula de período --------------------------------------------------
 *
 * Veio de `lists/list-header.css` em 2026-08-20. É o gatilho do calendário na
 * variante `control_variant="filter-pill"` — emitido por este componente
 * (`cotton/v2/date_picker.html`) e aceso por `js/components/date-picker.js`,
 * que põe `travel-period-filter--active` quando há data escolhida.
 *
 * Morava na folha da BARRA DE LISTA porque foi lá que a pílula apareceu
 * primeiro. As regras que a qualificam dentro da barra (altura do controle do
 * rail) ficaram lá — aquelas são da barra.
 *
 * O nome `travel-period-filter*` é contrato do JS e não se renomeia aqui.
 */

:is(html[data-theme="dark"])
  .travel-period-filter--filled
  .travel-period-filter__btn,
:is(html[data-theme="dark"])
  .travel-period-filter--filled
  .travel-period-filter__btn:hover:not(:disabled) {
  background: var(--color-card-soft);
  border-color: transparent;
  box-shadow: none;
}

.travel-period-filter__btn {
  align-items: center;
  background:
    linear-gradient(var(--color-card), var(--color-card)) padding-box,
    linear-gradient(var(--select-border), var(--select-border)) border-box;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  box-shadow: var(--cs-trigger-shadow);
  color: var(--color-input-text);
  cursor: pointer;
  display: inline-flex;
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  gap: var(--space-2);
  height: var(--control-height-md);
  min-height: var(--control-height-md);
  padding: 0 var(--space-3);
  transition: background var(--transition-fast), box-shadow var(--transition-fast);
  white-space: nowrap;
}

.travel-period-filter__btn:hover:not(:disabled) {
  background:
    linear-gradient(var(--field-bg-hover), var(--field-bg-hover)) padding-box,
    linear-gradient(var(--color-secondary), var(--color-secondary)) border-box;
}

.travel-period-filter__btn:focus-visible {
  background:
    linear-gradient(var(--field-bg-hover), var(--field-bg-hover)) padding-box,
    linear-gradient(var(--select-border-focus), var(--select-border-focus)) border-box;
  box-shadow: var(--select-focus-shadow);
  outline: none;
}

.travel-period-filter__label {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.travel-period-filter--active .travel-period-filter__btn {
  background: color-mix(in srgb, var(--color-primary-bright) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-primary-bright) 55%, transparent);
  color: var(--color-heading);
}

.travel-period-filter--active .travel-period-filter__btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-primary-bright) 20%, transparent);
  border-color: var(--color-primary-bright);
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`: as asserções de
 * aparência do v2 descrevem ESTA metade. Medir o arquivo inteiro faria o teste
 * ler a regra base que o delta sobrescreve — foi o que aconteceu na fusão de
 * 2026-08-20, com sete asserções apontando para a declaração antiga da mesma
 * classe, três telas acima.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Date picker — campo de data. Depende de `v2/tokens.css`.
 *
 * A marcação vem do partial global `cotton/ui/forms/date_picker.html` e o painel
 * é montado por `js/components/date-picker.js`; as classes são deles. Esta
 * folha só veste o que chega, sob a raiz `.date-field` — nenhuma regra alcança
 * as telas ainda não migradas.
 */

/* Diâmetro do botão do calendário. Fica na raiz porque três regras dependem
   dele — tamanho, recuo e o espaço que o texto abre para não passar por baixo —
   e é o que garante que ele continue redondo se a altura do campo mudar.
 *
 * Valor próprio, e não a escala miúda dos botões: aqui o que manda é caber
 * dentro do campo de 44px com folga igual nos três lados. Amarrá-lo à escala
 * faria o círculo crescer junto quando um botão de painel crescesse, que são
 * coisas sem relação. */
:is(html[data-theme]) .date-field {
  --trigger-size: 28px;
}

:is(html[data-theme]) .date-field__controls,
:is(html[data-theme]) .date-field .field-grid {
  display: flex;
  gap: var(--gap);
  min-width: 0;
}

/* A faixa de deslocamento intercala data e hora de saída com data e hora de
   chegada. É uma grade de quatro controles irmãos; a composição flexível do
   intervalo comum agruparia primeiro as duas datas e comprimiria seus campos. */
:is(html[data-theme]) .date-field.date-picker--interleaved-range .field-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  width: 100%;
}

/* Âncora do posicionamento. Precisa valer também para `.cv-field`, que é o
   invólucro que o partial usa no modo intervalo — sem isso o botão se
   posicionava por um ancestral mais alto e subia meia altura do campo. */
:is(html[data-theme]) .date-field .date-picker__control,
:is(html[data-theme]) .date-field .cv-field {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
}

/* O campo é o MESMO do select: mesma superfície, altura, raio e recuo. Um
   campo de data não é um controle diferente — só tem outro jeito de preencher. */
:is(html[data-theme]) .date-field .cv-field__control {
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-size-base);
  min-height: var(--control-height);
  padding: var(--pad-field);
  width: 100%;
}

:is(html[data-theme]) .date-field .cv-field__control::placeholder {
  color: var(--text-muted);
}

:is(html[data-theme]) .date-field .cv-field__control:focus-visible {
  border-color: var(--focus-ring);
  outline: none !important;
}

/* ---- o botão do calendário ------------------------------------------------
 *
 * Só aparece no hover — e no FOCO também, senão quem navega por teclado nunca
 * o veria. `opacity` em vez de `display: none` justamente para ele continuar
 * focável e alcançável por Tab enquanto está invisível.
 */
:is(html[data-theme]) .date-field .date-picker__trigger {
  align-items: center;
  /* Fundo na cor do painel — o degrau ACIMA do campo, em cascata. `--surface` é
     o degrau do contêiner e `--surface-contrast` o do campo, então o botão se
     destaca do campo sobre o qual flutua sem cor literal e sem precisar saber
     em que camada da escada o date picker foi parar. */
  background: var(--surface, var(--surface-rail));
  border: 0;
  /* Circular: raio total, com largura e altura presas ao mesmo valor. */
  border-radius: 999px;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  height: var(--trigger-size);
  justify-content: center;
  opacity: 0;
  position: absolute;
  /* Recuo igual ao de cima e de baixo: o círculo fica com folga igual nos três
     lados, em vez de encostar na borda direita do campo. */
  right: calc((var(--control-height) - var(--trigger-size)) / 2);
  /* Centrado pelo meio, não pelo topo: a altura do invólucro varia entre o modo
     simples e o de intervalo, e ancorar no topo desalinhava num deles. */
  top: 50%;
  transform: translateY(-50%);
  transition: opacity var(--ease), color var(--ease);
  width: var(--trigger-size);
}

:is(html[data-theme]) .date-field .date-picker__control:hover .date-picker__trigger,
:is(html[data-theme]) .date-field .date-picker__control:focus-within .date-picker__trigger,
:is(html[data-theme]) .date-field .date-picker__trigger:focus-visible {
  opacity: 1;
}

:is(html[data-theme]) .date-field .date-picker__trigger:hover {
  color: var(--accent);
}

/* ---- o gatilho único ------------------------------------------------------
 *
 * Um botão só, no lugar dos dois campos: o rótulo dele É o valor escolhido.
 * As classes são do partial global (`travel-period-filter__*`); aqui ele veste
 * o botão secundário do sistema, para não ser mais uma aparência de botão.
 */
:is(html[data-theme]) .date-field .travel-period-filter__btn {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  /* SEM sombra, e DECLARADO: a folha legada dá sombra a esta classe, e omitir
     aqui não é escolher — é herdar. O v2 não usa sombra em controle: o degrau de
     superfície é que separa o campo da caixa, e sombra em cima disso dá relevo a
     algo que está no plano. É a mesma armadilha que já custou borda, recuo e
     overflow nesta migração: para classe que colide com o legado, a folha nova
     tem de DECLARAR o valor. */
  box-shadow: none;
  box-sizing: border-box;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: var(--text-size-base);
  gap: var(--gap-tight);
  justify-content: flex-start;
  min-height: var(--control-height);
  padding: var(--pad-field);
  text-align: left;
  transition: background var(--ease), color var(--ease);
  width: 100%;
}

/* Com data escolhida o texto deixa de ser chamada e vira conteúdo — por isso
   assume a cor de leitura. O JS marca a raiz com `--active`. */
:is(html[data-theme]) .date-field.travel-period-filter--active .travel-period-filter__btn,
:is(html[data-theme]) .date-field .travel-period-filter--active .travel-period-filter__btn {
  color: var(--text-strong);
}

/* Sem realce ao passar o mouse, com ou sem data escolhida.
 *
 * Este gatilho é um CAMPO — o rótulo dele é o valor —, e campo não muda de cor
 * sob o cursor. É a mesma regra do gatilho do select (`v2/select.css`).
 *
 * As três formas abaixo são as que a folha legada usa, e cada uma fazia uma
 * coisa: o hover trocava o fundo por um par de gradientes (o truque de borda
 * que já apareceu nos botões do painel); a classe `--active`, que o JS põe
 * quando há data, tingia o botão de accent; e o hover COM data somava as duas.
 * Cobrir só uma delas deixaria as outras aparecendo. */
:is(html[data-theme]) .date-field .travel-period-filter__btn:hover:not(:disabled),
:is(html[data-theme]) .date-field .travel-period-filter--active .travel-period-filter__btn,
:is(html[data-theme]) .date-field.travel-period-filter--active .travel-period-filter__btn,
:is(html[data-theme]) .date-field
  .travel-period-filter--active .travel-period-filter__btn:hover:not(:disabled),
:is(html[data-theme]) .date-field.travel-period-filter--active
  .travel-period-filter__btn:hover:not(:disabled) {
  background: var(--surface-contrast, var(--surface-field));
  background-image: none;
  border-color: transparent;
  box-shadow: none;
}

:is(html[data-theme]) .date-field .travel-period-filter__btn:focus-visible {
  border-color: var(--focus-ring);
  outline: none !important;
}

:is(html[data-theme]) .date-field .travel-period-filter__btn .button__icon {
  align-items: center;
  color: var(--accent);
  display: inline-flex;
  flex: none;
}

:is(html[data-theme]) .date-field .travel-period-filter__btn .button__icon svg {
  height: 16px;
  width: 16px;
}

/* O rótulo trunca em vez de esticar o botão. */
:is(html[data-theme]) .date-field .travel-period-filter__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Na linha de prestação, período e solicitação formam um único grupo
   operacional sobre a superfície da pessoa. Ambos usam o degrau rail; o estado
   preenchido continua indicado pela borda accent, sem trocar o fundo. */
:is(html[data-theme])
  .prestacao-row__form
  .date-field
  .travel-period-filter__btn,
:is(html[data-theme])
  .prestacao-row__form
  .date-field.travel-period-filter--active
  .travel-period-filter__btn,
:is(html[data-theme])
  .prestacao-row__form
  .date-field.travel-period-filter--active
  .travel-period-filter__btn:hover:not(:disabled) {
  background: var(--surface-rail);
}

/* ---- o painel do calendário ----------------------------------------------
 *
 * O painel é transplantado para o `body` e perde os ancestrais, então a raiz
 * aqui é `.date-field__panel` — marca que o JS copia no transplante. Sem ela
 * estas regras alcançariam também o calendário das telas ainda não migradas,
 * que dividem o mesmo partial.
 */

/* Declara o próprio degrau e o oposto. Fora do fluxo da página o painel não
   herda de camada nenhuma, então quem está dentro dele não teria de onde tirar
   a cor. O fundo vem daqui e não do legado: enquanto a folha antiga desse a cor
   e esta desse o contraste, bastava a antiga sair para os dois ficarem iguais —
   foi o que aconteceu na primeira tentativa, painel e botões no mesmo tom. */
:is(html[data-theme]) .date-field__panel {
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
  background: var(--surface-field);
  /* O MESMO traço do painel, nos dois temas: `--line`, que é o único token de
     borda do sistema. O legado usava valores próprios — `rgb(214 227 244 /
     .4)` no escuro e `#d4dde9` no claro —, então o calendário era a única
     superfície com um contorno que não vinha do token e não acompanhava
     mudança de tema junto com o resto. */
  border: 1px solid var(--line);
}

/* Anterior, Próximo, Hoje e Limpar são o botão secundário na altura MIÚDA:
   mesmo degrau alternado, mesmo raio e o mesmo hover do resto do sistema, mas
   28px em vez de 44 — são controles dentro do painel, e quatro botões de altura
   cheia ocupavam mais que o mês inteiro que eles navegam. */
:is(html[data-theme]) .date-field__panel .date-picker__nav,
:is(html[data-theme]) .date-field__panel .date-picker__footer-action {
  align-items: center;
  background: var(--surface-contrast, var(--surface-rail));
  /* `background-image: none` NÃO é redundante. A folha legada desenha a borda
     destes botões com o truque dos dois gradientes — um em `padding-box` para o
     fundo e outro em `border-box` para a borda, com `border: 1px solid
     transparent`. Declarar só a cor de fundo apaga o truque no repouso, mas
     qualquer estado legado que reponha `background-image` traz a borda de volta
     sozinha. Zerar a imagem em todos os estados é o que corta a raiz. */
  background-image: none;
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-normal);
  gap: var(--gap-tight);
  justify-content: center;
  line-height: 1;
  min-height: var(--control-height-sm);
  padding: 0 10px;
  transition: background var(--ease), border-color var(--ease), color var(--ease);
  white-space: nowrap;
}

/* Todos os estados juntos, e não só o `:hover`: o legado tem regra própria para
   `:hover`, `:focus` e `:active` — e a de `:active` ainda deslocava o botão com
   `transform: translateY`. Cobrindo os quatro, nenhuma delas alcança. */
:is(html[data-theme]) .date-field__panel .date-picker__nav:is(:hover, :focus, :active),
:is(html[data-theme]) .date-field__panel
  .date-picker__footer-action:is(:hover, :focus, :active) {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-contrast, var(--surface-rail)));
  background-image: none;
  /* A borda inteira, e não só a cor: sob foco, o legado a zerava (`border: 0`),
     o botão encolhia 2px e o rótulo pulava de lugar. Fixar `border-color`
     sozinho deixava a LARGURA por conta da regra antiga. */
  border: 1px solid transparent;
  box-shadow: none;
  color: var(--accent);
  transform: none;
}

:is(html[data-theme]) .date-field__panel .date-picker__nav:focus-visible,
:is(html[data-theme]) .date-field__panel .date-picker__footer-action:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* O sumário repetia em texto corrido o que os dois campos já mostram. Fica no
   partial porque 11 telas não migradas ainda o exibem; sai de vez quando o
   partial for só do v2. */
:is(html[data-theme]) .date-field .date-picker__summary {
  display: none;
}

/* Enquanto o botão está escondido o texto pode ocupar a largura toda; quando
   ele aparece, o recuo evita que o valor passe por baixo do ícone. */
:is(html[data-theme]) .date-field .date-picker__control:hover .cv-field__control,
:is(html[data-theme]) .date-field .date-picker__control:focus-within .cv-field__control {
  padding-right: calc(var(--trigger-size) + 16px);
}

/* ---- a grade dos dias -----------------------------------------------------
 *
 * Sem vão entre as células, e o realce preenchendo a célula inteira.
 *
 * O legado usa `gap: 2px` e posiciona o realce pelo CENTRO — `top: 50%;
 * left: 50%` com um `translate(-20px, -20px)` de valor FIXO. Os dois só se
 * cancelam se metade da célula for exatamente 20px; quando 50% não cai num
 * inteiro, sobra fração (medido: 19.2 contra 20, ou seja, 0,8px fora do lugar).
 *
 * Numa data solta ninguém vê. Num intervalo longo, cada célula erra para o
 * mesmo lado, as sobras se somam e a grade PARECE ter colunas e linhas de
 * larguras diferentes — com todas as células medindo exatamente o mesmo.
 *
 * Colunas em `1fr` porque, sem vão, largura fixa deixaria sobra à direita da
 * grade. `aspect-ratio` mantém o dia quadrado sem amarrar a altura a um número.
 */
:is(html[data-theme]) .date-field__panel [data-cv-date-picker-days],
:is(html[data-theme]) .date-field__panel [data-cv-date-picker-weekdays] {
  gap: 0;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

:is(html[data-theme]) .date-field__panel .date-picker__day {
  aspect-ratio: 1;
  height: auto;
  width: 100%;
}

:is(html[data-theme]) .date-field__panel .date-picker__day::before {
  height: 100%;
  inset: 0;
  transform: none;
  width: 100%;
}

/* ---- a FAIXA do intervalo ---------------------------------------------------
 *
 * Sem ela o intervalo não se lê como intervalo: os extremos aparecem como dois
 * círculos soltos no mês e o meio fica igual a qualquer outro dia.
 *
 * As regras que desenhavam isso existem, mas em `static/css/ui/date-picker.css`
 * escopadas em `:has(.ui-sub-header)` — o cabeçalho de uma casca LEGADA, que
 * nenhuma tela do v2 tem. Por isso a faixa sumiu no v2 inteiro, galeria
 * incluída.
 *
 * A faixa é o ACCENT CHEIO, do primeiro ao último dia (decisão do dono,
 * 2026-08-17): o intervalo inteiro é uma faixa só, e os extremos se distinguem
 * pela cápsula arredondada, não pela cor. Cheguei a usar um tom de 22% para
 * separar as pontas do miolo — ficou fraco, e o que se quer ver aqui é o
 * PERÍODO, não as duas datas.
 *
 * No painel do v2 a grade de dias tem `gap: 0` e o `::before` cobre a célula
 * inteira, então os retângulos se encostam e viram uma barra contínua sem
 * precisar transbordar de meio vão como a versão legada faz. */
:is(html[data-theme])
  .date-field__panel
  .date-picker__day--range:not(.date-picker__day--range-start):not(.date-picker__day--range-end):not(.date-picker__day--selected)::before {
  background: var(--accent);
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Nas duas pontas da SEMANA a faixa arremata com um canto arredondado, senão ela
   parece cortada no meio ao virar a linha. */
:is(html[data-theme])
  .date-field__panel
  .date-picker__day--range:not(.date-picker__day--range-start):not(.date-picker__day--range-end):not(.date-picker__day--selected):nth-child(7n)::before {
  border-radius: 0 var(--radius-field) var(--radius-field) 0;
}

:is(html[data-theme])
  .date-field__panel
  .date-picker__day--range:not(.date-picker__day--range-start):not(.date-picker__day--range-end):not(.date-picker__day--selected):nth-child(7n + 1)::before {
  border-radius: var(--radius-field) 0 0 var(--radius-field);
}

/* Número BRANCO dentro do que está escolhido — faixa e pontas —, por decisão do
   dono (2026-08-17). É `--text-on-brand`, e não `--text-on-accent`: o segundo é
   ESCURO no tema escuro (lá o accent é amarelo), e o pedido foi branco nos dois.
   `--text-on-brand` é branco nas duas camadas do token, então acompanha o tema
   sem cor literal — literal aqui é reprovado por contrato
   (`test_nao_usa_cor_literal`), e com razão: é cor que não troca com o tema. */
:is(html[data-theme])
  .date-field__panel
  .date-picker__day--range:not(.date-picker__day--range-start):not(.date-picker__day--range-end):not(.date-picker__day--selected) {
  color: var(--text-on-brand);
}

/* ---- as PONTAS do intervalo -------------------------------------------------
 *
 * Elas vinham da folha legada com um gradiente mais escuro que o accent
 * (`#d8a21b` contra `#f3ae00`) e com o número em BRANCO — ou seja, dentro de um
 * mesmo intervalo havia três tratamentos: ponta escura com texto branco, faixa
 * accent com texto escuro, e o fundo do painel. Medido.
 *
 * Aqui o intervalo é UMA cor: as pontas usam o mesmo accent cheio da faixa, com
 * o mesmo texto de contraste. O que as distingue é a FORMA — o arredondado fica
 * só na borda de fora, e o lado que encosta na faixa é reto, para as três peças
 * lerem como uma faixa só com as pontas em cápsula. */
:is(html[data-theme]) .date-field__panel .date-picker__day--selected::before,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-start::before,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-end::before {
  background: var(--accent);
  border: 0;
  box-shadow: none;
}

:is(html[data-theme]) .date-field__panel .date-picker__day--selected,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-start,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-end {
  color: var(--text-on-brand);
}

/* O achatamento só vale quando HÁ intervalo. Com uma data escolhida só — o
   estado entre o primeiro e o segundo clique — o dia é `--range-start` sozinho, e
   com a regra incondicional ele saía como meia cápsula apontando para um fim que
   ainda não existe. Data única é CÍRCULO.
 *
 * O `:has` pergunta à grade se existe o outro extremo (ou algum dia de miolo,
 * para o caso de o fim cair no mês seguinte e não estar à vista). Sem essa
 * pergunta não há como saber: a informação está em OUTRO elemento, não neste. */
:is(html[data-theme])
  .date-field__panel
  .date-picker__days:has(.date-picker__day--range-end, .date-picker__day--range:not(.date-picker__day--range-start))
  .date-picker__day--range-start:not(.date-picker__day--range-end)::before {
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
}

:is(html[data-theme])
  .date-field__panel
  .date-picker__days:has(.date-picker__day--range-start, .date-picker__day--range:not(.date-picker__day--range-end))
  .date-picker__day--range-end:not(.date-picker__day--range-start)::before {
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
}

/* O ponto do "hoje" dentro da seleção fica BRANCO nos dois temas, como o número
   ao lado dele: fora dela o ponto é da cor de destaque, e sobre o accent cheio
   ele desaparecia — no tema escuro virava um furo escuro no meio da faixa
   amarela. `--text-on-brand` é branco nas duas camadas do token. */
:is(html[data-theme]) .date-field__panel .date-picker__day--range::after,
:is(html[data-theme]) .date-field__panel .date-picker__day--selected::after,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-start::after,
:is(html[data-theme]) .date-field__panel .date-picker__day--range-end::after {
  background: var(--text-on-brand);
  box-shadow: none;
}

/* ---- o número da data do MEIO ----------------------------------------------
 *
 * Ficha redonda no canto superior direito do dia, com 2, 3, 4… — a posição
 * daquela data na sequência de deslocamentos. Só as do meio a recebem: a
 * primeira e a última já se leem pelas pontas da cápsula, e numerar as quatro
 * enche o calendário de algo que a forma já diz.
 *
 * Ficha NEUTRA: superfície do painel com o texto forte do tema. O número em
 * accent sobre a cápsula accent era amarelo dentro de amarelo — duas vezes a
 * mesma cor a três pixels de distância.
 *
 * Fica DENTRO da cápsula, não sobre a borda: por fora, o disco na cor do painel
 * abria um buraco no contorno e de longe parecia defeito na faixa, não número.
 *
 * `position` e `z-index` declarados aqui porque a folha legada que os dava
 * (`fields/date-picker.css`) não entra no pacote desta tela — sem eles a ficha
 * cai no fluxo e empurra o número do dia.
 */
:is(html[data-theme]) .date-field__panel .date-picker__day-badge {
  align-items: center;
  background: var(--surface-rail);
  border: 0;
  border-radius: var(--radius-pill);
  box-shadow: none;
  color: var(--text-strong);
  display: inline-flex;
  /* 14px com o número em 9px: dentro de uma célula de 42 ela precisa caber no
     arco da cápsula sem encostar no número do dia. */
  font-size: 9px;
  font-weight: var(--weight-strong);
  height: 14px;
  justify-content: center;
  left: auto;
  line-height: 1;
  min-width: 14px;
  padding: 0 2px;
  pointer-events: none;
  position: absolute;
  right: 3px;
  top: 3px;
  z-index: 4;
}

/* Dia ESCOLHIDO não apaga quando o calendário trava a escolha. Na seleção de
   várias datas o motor desabilita os dias assim que o número fecha (o roteiro
   pede uma por deslocamento), e a regra geral de desabilitado derruba a
   opacidade para 0.35 — as datas já escolhidas ficavam lavadas, enquanto no
   bate-volta, que não trava nada, o intervalo continuava sólido. Duas telas com
   o mesmo estado pintadas de dois jeitos. O que está escolhido é resultado, não
   controle indisponível. */
:is(html[data-theme]) .date-field__panel .date-picker__day--range[disabled],
:is(html[data-theme]) .date-field__panel .date-picker__day--selected[disabled] {
  opacity: 1;
}

/* ---- a faixa arremata na PAREDE DA SEMANA ----------------------------------
 *
 * A grade tem sete colunas: a última é `7n` e a primeira, `7n + 1`. Quando a
 * faixa encosta nelas, o canto que toca a parede arredonda — sem isso a barra
 * parecia cortada a faca ao virar a linha, e a mesma seleção lia como dois
 * blocos sem relação.
 *
 * Vale para o miolo do intervalo (regra acima) e para as pontas que por acaso
 * caem na parede — uma ponta na borda fecha dos dois lados, porque não há
 * vizinho para emendar.
 */
/* O arremate é `--radius-field`, o MESMO do miolo do intervalo (regra acima) —
   não a pílula. A pílula é a forma das PONTAS da seleção, e usá-la também na
   parede fazia cada semana parecer uma seleção fechada em si. */

/* Uma PONTA que calha de cair na parede mantém a pílula do lado de fora e
   arremata com o canto de campo do lado que toca a parede. */
:is(html[data-theme]) .date-field__panel .date-picker__day--range-start:nth-child(7n)::before {
  border-radius: var(--radius-pill) var(--radius-field) var(--radius-field) var(--radius-pill);
}
:is(html[data-theme]) .date-field__panel .date-picker__day--range-end:nth-child(7n + 1)::before {
  border-radius: var(--radius-field) var(--radius-pill) var(--radius-pill) var(--radius-field);
}

/* O campo interno do calendário se comporta como o `.field` do v2 — mesma
   grade, mesmo vão entre rótulo e controle.
 *
 * O partial global monta o próprio invólucro na classe legada (`cv-field`), que
 * no v2 não tem layout nenhum. Lado a lado com um campo do sistema — "Data" ao
 * lado de "Hora", dentro do card de trecho — o rótulo colava no controle e os
 * dois inputs começavam em alturas diferentes. */
:is(html[data-theme]) .date-field .cv-field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

/* O rótulo do calendário usa a MEDIDA do rótulo do sistema. O partial global o
   traz na classe legada (`cv-field__label`, 0.78rem), e ao lado de um campo do
   v2 (`field__label`, 14px) os dois rótulos saíam de tamanhos diferentes — os
   campos "Data" e "Hora" do mesmo trecho começavam em alturas distintas.

   Esta regra já existia e caiu quando esta folha foi cortada para remover a
   lista de trechos do painel; voltou com a medição que a pegou de novo. */
:is(html[data-theme]) .date-field .cv-field__label {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  /* 1.5, a mesma entrelinha do rótulo do sistema: com 1.3 o rótulo do calendário
     media 18,2px contra 21px do vizinho, e os dois campos começavam com 2px de
     diferença — pouco para nomear, o bastante para ver. */
  line-height: 1.5;
}
/* <<< css/v2/date-picker.css <<< */

/* >>> css/v2/pagination.css >>> */
/* Paginação — contagem e controles. Depende de `v2/tokens.css`. */

:is(html[data-theme]) .pagination {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  justify-content: space-between;
  min-width: 0;
}

:is(html[data-theme]) .pagination__info {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

:is(html[data-theme]) .pagination__info strong {
  color: var(--text-strong);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .pagination__controls {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
}

/* Página e seta são o mesmo controle miúdo: quadrados da altura reduzida, no
   degrau oposto ao do contêiner. Um botão por página numa lista longa vira uma
   fileira comprida — por isso a régua de páginas vem pronta da view, com
   reticências, e não é decidida aqui. */
:is(html[data-theme]) .pagination__page,
:is(html[data-theme]) .pagination__nav {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border: 1px solid transparent;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-strong);
  display: inline-flex;
  font-size: var(--text-size-eyebrow);
  height: var(--control-height-sm);
  justify-content: center;
  min-width: var(--control-height-sm);
  padding: 0 8px;
  text-decoration: none;
  transition: background var(--ease), color var(--ease);
}

/* A seta não tem texto, então o respiro lateral do número só a deixa retangular
   ao lado de quadrados. Sem o `padding`, ela fecha nos mesmos 28px. */
:is(html[data-theme]) .pagination__nav {
  padding: 0;
  width: var(--control-height-sm);
}

:is(html[data-theme]) .pagination__nav svg {
  height: 16px;
  width: 16px;
}

/* Mesmo realce do botão secundário: 14% do accent na superfície e o conteúdo
   assumindo o accent. Nunca mistura de matiz com a cor do texto. */
:is(html[data-theme]) .pagination__page:hover,
:is(html[data-theme]) .pagination__nav:hover {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-contrast, var(--surface-rail)));
  color: var(--accent);
}

/* A página atual é o único elemento em accent cheio: é onde se está. */
:is(html[data-theme]) .pagination__page--current {
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: var(--weight-strong);
}

/* Seta sem para onde ir continua ocupando o lugar, apagada: some o alvo, não a
   caixa — senão a fileira de controles muda de largura na última página. */
:is(html[data-theme]) .pagination__nav[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.4;
}

:is(html[data-theme]) .pagination__ellipsis {
  color: var(--text-muted);
  padding: 0 4px;
}

:is(html[data-theme]) .pagination__page:focus-visible,
:is(html[data-theme]) .pagination__nav:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* O aviso de lista paginada sem `page_obj`. É erro de contexto, não estado da
   interface — por isso grita em vez de se acomodar no desenho. */
:is(html[data-theme]) .pagination--erro {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-radius: var(--radius-field);
  color: var(--danger);
  font-size: var(--text-size-base);
  margin: 0;
  padding: var(--gap);
}
/* <<< css/v2/pagination.css <<< */

/* >>> css/v2/file-picker.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `fields/file-picker.css` em 2026-08-20. Mesma história do
 * picker e do calendário: são as declarações do componente do v2, que nasceram
 * na pasta do sistema antigo. Todas as classes vivas dela (`file-picker`,
 * `is-busy`, `is-dragover`, `is-error`, `is-selected`) são emitidas pelo
 * `js/components/file-picker.js` e pelo `v2/file_picker.html`.
 * ══════════════════════════════════════════════════════════════════════════ */

/* Canonical file picker and attached-file list. Page CSS may position it, not skin it. */

.file-input,
.prestacao-file-input {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.file-widget,
.prestacao-file-widget {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.file-widget.is-busy,
.prestacao-file-widget.is-busy {
  cursor: progress;
  opacity: 0.78;
}

.file-picker,
.prestacao-file-picker {
  align-items: stretch;
  background: var(--color-input-bg, var(--color-surface));
  /* NOVO-51: era `border: var(--cv-field-border, 1px solid …)`, a unica leitura
     como shorthand contra 14 como cor. No claro o token resolvia para cor pura e
     esta borda saia com `style=none width=0px` — invisivel. */
  border: 1px solid var(--color-input-border, var(--color-border));
  border-radius: var(--radius-control, 10px);
  box-shadow: var(--shadow-xs, none);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  min-height: 56px;
  min-width: 0;
  overflow: hidden;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background var(--transition-fast);
}

.file-widget.is-selected .file-picker,
.prestacao-file-widget.is-selected .prestacao-file-picker {
  border-color: color-mix(in srgb, var(--color-primary) 64%, var(--color-border-strong));
}

.file-widget.is-dragover .file-picker,
.prestacao-file-widget.is-dragover .prestacao-file-picker {
  background: color-mix(in srgb, var(--color-primary) 16%, var(--color-input-bg, var(--color-surface)));
  border-color: var(--color-primary);
  box-shadow: 0 0 0 var(--space-1) var(--input-focus-ring);
}

.file-widget.is-error .file-picker,
.prestacao-file-widget.is-error .prestacao-file-picker {
  border-color: var(--color-danger);
}

.file-picker:hover,
.prestacao-file-picker:hover {
  border-color: var(--color-border-strong, var(--color-border-strong));
}

.file-picker:focus-within,
.prestacao-file-picker:focus-within {
  border-color: var(--input-border-focus);
  box-shadow: var(--field-shadow-focus, 0 0 0 var(--space-1) var(--input-focus-ring));
}

.file-picker__action,
.prestacao-file-picker__action {
  align-items: center;
  background: color-mix(in srgb, var(--color-primary) 20%, var(--color-input-bg, var(--color-surface)));
  border-right: 1px solid var(--color-border);
  color: var(--color-heading);
  cursor: pointer;
  display: inline-flex;
  font-weight: var(--font-weight-bold, 750);
  gap: var(--space-2);
  justify-content: center;
  min-width: 172px;
  padding: 0 var(--space-4);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.file-picker__action-icon {
  align-items: center;
  color: var(--color-primary-bright, var(--color-primary));
  display: inline-flex;
  flex: 0 0 auto;
}

.file-picker__action-icon .icon {
  height: 18px;
  width: 18px;
}

.file-picker__action:hover,
.prestacao-file-picker__action:hover {
  background: color-mix(in srgb, var(--color-primary) 32%, var(--color-input-bg, var(--color-surface)));
  color: var(--color-heading);
}

.file-picker__value,
.prestacao-file-picker__value {
  align-items: center;
  color: var(--color-muted);
  display: flex;
  min-width: 0;
  overflow: hidden;
  padding: 0 var(--space-4);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-picker__value.prestacao-file-picker__value--selected,
.prestacao-file-picker__value--selected {
  color: var(--color-text);
  font-weight: var(--font-weight-semibold, 650);
}

.file-picker__upload,
.prestacao-file-picker__upload {
  align-items: center;
  border: 0;
  border-left: 1px solid var(--color-border);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-weight: var(--font-weight-bold, 750);
  justify-content: center;
  min-width: 112px;
  padding: 0 var(--space-4);
  transition: background var(--transition-fast), color var(--transition-fast), opacity var(--transition-fast);
}

.file-picker__upload,
.prestacao-file-picker__upload {
  background: var(--btn-primary-bg, var(--color-primary));
  color: var(--color-white, var(--color-white));
}

.file-picker__upload:hover:not(:disabled),
.prestacao-file-picker__upload:hover:not(:disabled) {
  background: var(--btn-primary-hover-bg, var(--color-primary-hover));
}

.file-picker__upload:disabled,
.prestacao-file-picker__upload:disabled {
  display: none;
}

.file-picker__inline-actions,
.prestacao-file-picker__inline-actions {
  align-items: center;
  border-left: 1px solid var(--color-border);
  display: flex;
  gap: var(--space-1);
  padding: 0 var(--space-3);
}

.file-picker__inline-actions[hidden],
.prestacao-file-picker__inline-actions[hidden] {
  display: none;
}

.file-selection,
.prestacao-file-selection {
  display: grid;
  min-width: 0;
}

.file-selection__toggle,
.prestacao-file-selection__toggle {
  align-items: center;
  background: var(--color-surface-soft);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-control, 10px);
  color: var(--color-text);
  cursor: pointer;
  display: flex;
  font: inherit;
  font-weight: var(--font-weight-bold, 750);
  gap: var(--space-3);
  justify-content: space-between;
  min-height: 54px;
  padding: 0 var(--space-4);
  text-align: left;
  width: 100%;
}

.file-selection__toggle:focus-visible,
.prestacao-file-selection__toggle:focus-visible {
  box-shadow: 0 0 0 var(--space-1) var(--input-focus-ring);
  outline: 0;
}

.file-selection__chevron,
.prestacao-file-selection__chevron {
  border-bottom: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
  color: var(--color-accent, var(--color-primary));
  height: 7px;
  transform: rotate(45deg);
  width: 7px;
}

.file-selection__menu,
.prestacao-file-selection__menu,
.prestacao-file-list {
  background: var(--color-surface-soft);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-control, 10px);
  box-shadow: var(--shadow-xs, none);
  min-width: 0;
  overflow: hidden;
}

.file-selection__menu[hidden],
.prestacao-file-selection__menu[hidden] {
  display: none;
}

.file-selection__list,
.prestacao-file-selection__list,
.prestacao-file-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.file-selection__item,
.prestacao-file-selection__item,
.prestacao-file-list__item {
  align-items: center;
  display: flex;
  gap: var(--space-4);
  justify-content: space-between;
  min-height: 64px;
  min-width: 0;
  padding: var(--space-3) var(--space-4);
  transition: background var(--transition-fast);
}

.file-selection__item:hover,
.prestacao-file-selection__item:hover,
.prestacao-file-list__item:hover {
  background: color-mix(in srgb, var(--color-primary) 9%, transparent);
}

.file-selection__item + .file-selection__item,
.prestacao-file-selection__item + .prestacao-file-selection__item,
.prestacao-file-list__item + .prestacao-file-list__item {
  border-top: 1px solid var(--color-border);
}

.file-widget__meta,
.prestacao-file-widget__meta {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.file-widget__name,
.prestacao-file-widget__name {
  color: var(--color-text);
  display: block;
  font-weight: var(--font-weight-semibold, 650);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-widget__subtitle,
.prestacao-file-widget__subtitle {
  color: var(--color-muted);
  display: block;
  font-size: var(--font-size-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-widget__actions,
.prestacao-file-widget__actions {
  align-items: center;
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-2);
}

@media (max-width: 640px) {
  .file-picker,
  .prestacao-file-picker {
    grid-template-columns: 1fr;
  }

  .file-picker__action,
  .prestacao-file-picker__action {
    border-bottom: 1px solid var(--color-border);
    border-right: 0;
    min-height: 46px;
  }

  .file-picker__value,
  .prestacao-file-picker__value {
    min-height: 48px;
  }

  .file-picker__upload,
  .prestacao-file-picker__upload {
    border-left: 0;
    border-top: 1px solid var(--color-border);
    min-height: 44px;
  }

  .file-selection__item,
  .prestacao-file-selection__item,
  .prestacao-file-list__item {
    align-items: stretch;
    flex-direction: column;
  }

  .file-widget__actions,
  .prestacao-file-widget__actions {
    justify-content: flex-end;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 *
 * A divisa é lida por teste — a linha `=== DELTA v2 ===`: as asserções de
 * aparência do v2 descrevem ESTA metade. Medir o arquivo inteiro faria o teste
 * ler a regra base que o delta sobrescreve — foi o que aconteceu na fusão de
 * 2026-08-20, com sete asserções apontando para a declaração antiga da mesma
 * classe, três telas acima.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* File picker v2 — par de `templates/cotton/v2/file_picker.html`.
 *
 * Três blocos empilhados, na ordem em que a tarefa acontece: escolher, ver o que
 * foi escolhido, anexar. No legado os três dividiam UMA faixa, e o resultado era o
 * botão de anexar por cima do nome do arquivo, cortando-o.
 */

:is(html[data-theme]) .file-picker--v2 {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

/* O bloco do picker é FIELD, e não o `rail` que a escada por profundidade lhe daria
   dentro do diálogo: aqui ele é o campo do formulário — o lugar onde se escolhe o
   arquivo —, e campo é `field` em todo o sistema. Declara o degrau seguinte para as
   linhas, que sobem para `rail`. As duas cores vêm dos tokens base: pintar da
   variável que se redefine para os filhos é referência circular. */
/* Classe REPETIDA (`.form-block--v2.form-block--v2`) para vencer a regra da única
   borda em `v2/surface.css`: as duas têm a mesma especificidade, e aquela folha é a
   ÚLTIMA do pacote por projeto — empate resolvido por ordem, e a ordem é dela.
   Repetir a classe sobe um ponto e resolve sem `!important`. Medido: com a
   especificidade igual, o bloco continuava com 0,8px de contorno. */
:is(html[data-theme]) .file-picker--v2 .form-block--v2.form-block--v2 {
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
  background: var(--surface-field);
  /* SEM borda. Ela vinha da regra da "única borda do sistema" em `v2/surface.css`,
     que dá contorno ao contêiner que NÃO é descendente de outro contêiner — e
     `.modal` não está na lista de contêineres dela, então o bloco dentro do diálogo
     era contado como primeira camada sobre a página. Declarar aqui é o remendo
     local; o certo é `.modal` entrar naquela lista, e isso mexe em todos os
     diálogos de uma vez. */
  border: 0;
}

/* O `<input type=file>` nativo sai de vista mas continua no fluxo do teclado — o
   rótulo é que abre o seletor, e `display: none` tiraria o campo da ordem do Tab
   e do anúncio do leitor de tela. */
:is(html[data-theme]) .file-picker__native {
  height: 0;
  opacity: 0;
  position: absolute;
  width: 0;
}

/* ---- escolher: a PRIMEIRA LINHA da lista ---------------------------------- */

/* A linha de escolher não pinta nem recua: ela só posiciona o rótulo, que é o
   botão. Uma coluna `auto` com `justify-content: start`: o botão fica do tamanho
   do próprio texto e ancorado à ESQUERDA. Ele já ocupou a linha inteira, do jeito
   que um primário ocuparia — e escolher arquivo não é a ação principal deste
   diálogo, anexar é. Botão largura-cheia no topo disputava com o do rodapé. */
/* Seletor COMPOSTO (`.file-picker__row.file-picker__row--choose`): a linha carrega
   as duas classes, as duas regras têm a mesma especificidade, e quem decidia era a
   ORDEM no arquivo — a base vinha depois e reimpunha as três colunas, então o
   rótulo caía na primeira (`auto`) e ficava do tamanho do texto: 126px numa linha
   de 520. Medido. Com a classe repetida, a regra vence onde quer que esteja. */
:is(html[data-theme]) .file-picker__row.file-picker__row--choose {
  background: none;
  display: grid;
  grid-template-columns: minmax(0, auto);
  justify-content: start;
  padding: 0;
}

/* Secundário e SEM BORDA: o tracejado dizia "solte o arquivo aqui", mas dentro de
   um bloco que já é o campo isso virou moldura sobre moldura. Quem separa o botão
   do bloco é o degrau de superfície, que é como todo secundário do v2 funciona —
   sem contorno, por contraste. */
:is(html[data-theme]) .file-picker__choose {
  align-items: center;
  background: var(--surface-contrast, var(--surface-rail));
  border: 0;
  border-radius: var(--radius-field);
  color: var(--text-strong);
  cursor: pointer;
  display: inline-flex;
  /* Um degrau ACIMA do `sm`: a 28px com texto de sobrancelha o botão ficou miúdo
     demais para a única ação do bloco. A medida sai dos tokens
     (`--control-height-sm` + `--gap-tight` = 36px) em vez de um número solto, e o
     texto volta ao corpo normal — continua menor que o `Anexar` do rodapé, que é
     quem tem de puxar o olho. */
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  gap: var(--gap-tight);
  justify-content: center;
  min-height: calc(var(--control-height-sm) + var(--gap-tight));
  padding: 0 var(--gap);
  transition: background var(--ease), color var(--ease);
}

/* O hover assume o tom do escolhido, como o secundário do sistema: sem borda, o
   sinal de "isto é clicável" tem de vir da cor. */
:is(html[data-theme]) .file-picker__choose:hover {
  background: var(--surface-selected);
}

:is(html[data-theme]) .file-picker__native:focus-visible + .file-picker__choose {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}


/* ---- 2. o escolhido, como lista ------------------------------------------- */

/* A lista não tem caixa própria: quem a dá é o `form_block` que a envolve
   (`v2/form-block.css`), com degrau, raio e recuo do sistema. Aqui fica só a
   grade das linhas — contorno e recuo à mão eram desenho paralelo. */
:is(html[data-theme]) .file-picker__list {
  display: grid;
  gap: var(--gap-tight);
  list-style: none;
  margin: 0;
  min-width: 0;
  padding: 0;
}

/* A linha VAZIA tem a mesma altura do cartão do arquivo escolhido (medido: 60px,
   que são as duas linhas de texto do cartão mais o recuo). Sem isso o bloco pulava
   de tamanho no instante da escolha — uma linha de uma linha virava um cartão de
   duas, e o rodapé do diálogo saltava com ela. A medida vem dos tokens
   (`--control-height` + dois `--gap-tight`), não de um 60 solto. */
:is(html[data-theme]) .file-picker__row:not(.file-picker__row--choose) {
  min-height: calc(var(--control-height) + var(--gap-tight) * 2);
}

:is(html[data-theme]) .file-picker__row {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: minmax(0, 1fr) auto;
  min-width: 0;
  padding: var(--gap-tight) var(--gap);
}


:is(html[data-theme]) .file-picker__copy {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* O nome CORTA com reticências em vez de quebrar: nome de arquivo é longo por
   natureza, e uma linha de lista que cresce em altura conforme o nome desmonta a
   régua da lista inteira. */
:is(html[data-theme]) .file-picker__name {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .file-picker__meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
}

/* As ações ficam em FIELD: a linha é `rail`, e o `icon-button` do sistema herda a
   superfície de onde está — medido, usava o mesmo tom do fundo e ficava invisível.
   Aqui é o degrau seguinte que separa o controle do fundo, como no resto do v2. */
:is(html[data-theme]) .file-picker__row .icon-button {
  --icon-button-surface: var(--surface-field);
}

:is(html[data-theme]) .file-picker__actions {
  align-items: center;
  display: flex;
  flex: none;
  gap: var(--gap-tight);
}

/* O `display` acima vence o `[hidden]`, que é regra de agente do usuário: as ações
   nascem ocultas e é o JS que as põe quando há arquivo. */
:is(html[data-theme]) .file-picker__actions[hidden] {
  display: none;
}

/* ---- 3. anexar ------------------------------------------------------------ */

:is(html[data-theme]) .file-picker__footer {
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  padding-top: var(--gap-tight);
}

/* ---- vários arquivos ------------------------------------------------------ */

/* Dentro do bloco, o conjunto dos escolhidos é a CONTINUAÇÃO da lista: o mesmo
   vão entre linhas, sem recuo nem contorno próprios.
 *
 * SEM `margin-top`: o corpo do bloco é uma grade com `--gap` (12px), e a margem
 * somava mais 8 — 20px medidos entre o botão e o cartão, quando as duas peças são
 * a mesma lista. Quem dá o vão é o corpo do bloco, na regra abaixo, e é um só. */
:is(html[data-theme]) .file-picker__selection {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

/* O corpo do bloco aqui empilha PEÇAS DA MESMA LISTA (escolher, escolhidos), e não
   seções de formulário — por isso o vão apertado, igual ao de entre linhas. */
:is(html[data-theme]) .file-picker--v2 .form-block__body {
  gap: var(--gap-tight);
}

:is(html[data-theme]) .file-picker__selection[hidden] {
  display: none;
}

:is(html[data-theme]) .file-picker__selection-toggle {
  align-items: center;
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  font: inherit;
  font-size: var(--text-size-eyebrow);
  gap: var(--gap-tight);
  padding: 0;
}

:is(html[data-theme]) .file-picker__selection-menu[hidden] {
  display: none;
}

/* ---- uma representação só do arquivo -------------------------------------- */

/* Com arquivo escolhido, quem mostra é o CARTÃO COMPLETO que o JS clona do
   template — nome, tamanho e as ações de abrir e remover. A linha fixa acima passa
   a ser só o estado VAZIO e sai de cena.
 *
 * Antes as duas apareciam juntas: o mesmo nome duas vezes, uma delas sem tamanho e
 * sem ações. A linha fixa não pode ser APAGADA da marcação porque ela carrega dois
 * ganchos onde o `file-picker.js` escreve (`data-file-picker-name` e
 * `data-file-inline-actions`); esconder é o que preserva o motor.
 *
 * O gatilho é o bloco de seleção perder o `hidden` — é o próprio JS que o revela
 * quando há arquivo, então a regra segue o estado real e não uma classe inventada. */
:is(html[data-theme]) .file-picker--v2:has([data-file-selection-dropdown]:not([hidden]))
  .file-picker__row:not(.file-picker__row--choose):not([data-file-selection-row]) {
  display: none;
}

/* E o bloco de seleção deixa de ser sanfona no modo de UM arquivo: o resumo
   "Arquivos selecionados" com seta escondia o cartão que se acabou de escolher,
   atrás de mais um clique. A lista fica aberta e o resumo sai. */
:is(html[data-theme]) .file-picker--v2 .file-picker__selection-toggle {
  display: none;
}

:is(html[data-theme]) .file-picker--v2 .file-picker__selection-menu[hidden] {
  display: grid;
}
/* <<< css/v2/file-picker.css <<< */

/* >>> css/v2/file-list.css >>> */
/* Lista de arquivos anexados — par de `cotton/v2/file_list.html`.
 *
 * Um arquivo não é um registro: não tem título, selo nem meta, tem nome e duas
 * ações. Por isso ele não usa o `record` — a linha aqui é do tamanho do que
 * mostra, e uma pilha de seis anexos continua cabendo na etapa.
 *
 * A linha assume o degrau oposto ao do bloco que a contém (`--surface-contrast`,
 * a mesma escada do campo e do toggle): dentro de um `form_block` ela precisa
 * se destacar do fundo, e declarar uma cor fixa a faria sumir no tema oposto.
 */

:is(html[data-theme]) .file-list {
  display: grid;
  gap: var(--gap-tight);
  list-style: none;
  margin: 0;
  padding: 0;
}

:is(html[data-theme]) .file-list__item {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: flex;
  gap: var(--gap);
  min-height: 56px;
  padding: 10px 12px;
}

/* O ícone é o mesmo quadrado do avatar do picker: 36px, raio de campo e o
   accent translúcido. Mantém as duas listas do sistema com a mesma cadência
   vertical. */
:is(html[data-theme]) .file-list__icon {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-radius: 8px;
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
  height: 36px;
  justify-content: center;
  width: 36px;
}

:is(html[data-theme]) .file-list__icon svg {
  height: 18px;
  width: 18px;
}

:is(html[data-theme]) .file-list__copy {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* O nome do arquivo é longo e não se corta ao meio: `ellipsis` guarda o começo,
   que é por onde se reconhece o documento, e o `title` mostra o resto. */
:is(html[data-theme]) .file-list__name {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .file-list__meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
}

:is(html[data-theme]) .file-list__actions {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
  margin-left: auto;
}

/* A linha já usa a superfície de campo. As ações voltam ao degrau do painel
   para continuarem visíveis, em vez de desaparecerem na mesma cor da linha. */
:is(html[data-theme]) .file-list__action {
  background: var(--surface-rail);
}

:is(html[data-theme]) .file-list__action:hover {
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-rail));
}

/* O formulário existe só para carregar o POST do excluir; ele não pode ocupar
   espaço nem quebrar a fileira de botões. */
:is(html[data-theme]) .file-list__form {
  display: contents;
}

:is(html[data-theme]) .file-list__empty {
  color: var(--text-muted);
  margin: 0;
  padding: var(--gap-tight) 0;
}
/* <<< css/v2/file-list.css <<< */

/* >>> css/v2/fab.css >>> */
/* Ação flutuante — par de `cotton/v2/fab.html`.
 *
 * Ancorada no canto inferior direito da JANELA (`fixed`), e não do conteúdo:
 * numa etapa com trinta registros, a ação presa ao cabeçalho do painel some na
 * primeira rolagem — e quem chega ao fim da lista teria de voltar ao topo para
 * criar o próximo item.
 *
 * A sombra é o que a separa do conteúdo por baixo. Sem ela, o botão parece
 * grudado na linha que estiver passando atrás dele.
 */

:is(html[data-theme]) .fab {
  align-items: flex-end;
  bottom: var(--gap-loose);
  display: flex;
  flex-direction: column;
  gap: var(--gap-tight);
  position: fixed;
  right: var(--gap-loose);
  /* Acima do conteúdo e abaixo de diálogo e menu, que precisam cobri-la. */
  z-index: 40;
}

/* A sombra vale para QUALQUER botão que a tela ponha aqui dentro — o `fab` não
   sabe se recebeu um ou dois, nem qual é primário. */
:is(html[data-theme]) .fab > .button {
  box-shadow: 0 6px 18px color-mix(in srgb, #000 32%, transparent);
}

:is(html[data-theme]) .fab > .button--primary {
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 34%, transparent);
}

/* Em tela estreita ela encosta menos nas bordas: a faixa útil é menor, e o
   botão grande no canto cobria parte do último registro da lista. */
@media (max-width: 720px) {
  :is(html[data-theme]) .fab {
    bottom: var(--gap);
    right: var(--gap);
  }
}
/* <<< css/v2/fab.css <<< */

/* >>> css/v2/module-card.css >>> */
/* ───────────────────────────────────────────────────────────────────────────
 * VINDA DE `components/theme-dark-components.css`, em 2026-08-20.
 *
 * A sombra do cartão no tema escuro — 11 ocorrências medidas no painel. Era a
 * última regra da folha de tema que ainda vestia um componente.
 *
 * ENTRA NO TOPO DA FOLHA, e isso não é estética. A regra vinha do pacote do
 * shell, anterior ao `ui.bundle.css`, e perdia `background` e `border-color`
 * para o `.module-card` do v2; anexada no FIM daqui, passou a vencer — e como
 * ela pinta `var(--color-surface)`, o cartão do painel ficou BRANCO no tema
 * escuro (medido: `rgb(255,255,255)` em `/`, `rgb(19,34,56)` em `/cadastros/`).
 * No topo, a regra do v2 vem depois com a mesma especificidade e ganha de novo
 * as duas propriedades, exatamente como antes.
 *
 * O que sobra dela é o `box-shadow`, que esta folha não declara — por isso a
 * sombra sumia quando a regra saía do pacote, e por isso ela ainda existe.
 *
 * `.card`, `.app-card` e `.document-card` continuam no seletor porque ele é uma
 * UNIÃO: `.document-card` não é emitida por ninguém, mas `.card` e `.app-card`
 * ainda são, e o texto não pode mudar sem tirar a regra do manifesto.
 * ─────────────────────────────────────────────────────────────────────────── */

:is(html[data-theme="dark"])
  :is(.card, .app-card, .module-card, .document-card) {
  background: var(--color-surface);
  border-color: var(--color-border);
  box-shadow: var(--shadow-xs);
}

:is(html[data-theme="dark"])
  :is(.card, .app-card, .module-card, .document-card):hover {
  box-shadow: var(--shadow-sm);
}

/* Cartão de módulo — o atalho para uma área do sistema. Par de
 * `cotton/v2/module_card.html`.
 *
 * Aparece no Início e no hub de Cadastros: marca de duas letras, sobrancelha,
 * nome, uma linha do que há lá dentro e o botão de entrar.
 *
 * Veio de `lists/content-cards.css` em 2026-08-20, que era uma folha-sacola —
 * desenhava também cartão de resumo, cartão de documento e cartão de
 * assinatura, todos já extintos. Aqui ficou só o que ainda existe, com o
 * vocabulário do v2 (`module-card__*`) no lugar do `cv-module-card__*`.
 *
 * A GRADE mora aqui também. Ela era `metric-grid--4`, de uma folha de
 * indicadores que o painel antigo usava; agora o próprio cartão diz como se
 * arruma em fileira, que é a única coisa que se faz com ele.
 */

:is(html[data-theme]) .module-card-grid {
  display: grid;
  gap: var(--gap);
  /* `auto-fit` com piso de 220px, e não quatro colunas fixas: dentro de um
     painel os quatro atalhos ficavam com 174px cada, e "Combustíveis" não cabia
     numa linha. A fileira decide quantos cabem pela largura que ela tem. */
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  min-width: 0;
}

/* Em tela estreita o piso de 220px sozinho já colapsaria para uma coluna, mas
   declaro para não depender do arredondamento do navegador. */
@media (max-width: 520px) {
  :is(html[data-theme]) .module-card-grid {
    grid-template-columns: 1fr;
  }
}

/* O cartão é a caixa de conteúdo do sistema — mesma superfície, mesmo raio do
   `form_block`. Antes ele acumulava quatro classes (`module-card-v2`,
   `cv-module-card`, `module-card`, `app-card`) para conseguir isso de folhas
   diferentes. */
:is(html[data-theme]) .module-card {
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  display: grid;
  /* Cabeçalho e rodapé do tamanho do conteúdo; o corpo estica. É o que mantém o
     botão "Abrir" na mesma altura em cartões de descrição curta e longa. */
  grid-template-rows: auto 1fr auto;
  min-width: 0;
  overflow: hidden;
}

:is(html[data-theme]) .module-card__header,
:is(html[data-theme]) .module-card__body,
:is(html[data-theme]) .module-card__footer {
  padding: var(--gap) 18px;
}

:is(html[data-theme]) .module-card__header {
  align-items: center;
  display: flex;
  gap: 10px;
}

/* A marca de duas letras: o mesmo quadrado do avatar da linha de pessoa, na
   medida pequena. */
:is(html[data-theme]) .module-card__mark {
  align-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-radius: 8px;
  color: var(--accent);
  display: flex;
  flex: 0 0 auto;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  height: 32px;
  justify-content: center;
  width: 32px;
}

:is(html[data-theme]) .module-card__eyebrow {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  margin: 0;
  text-transform: uppercase;
}

:is(html[data-theme]) .module-card__body {
  display: grid;
  gap: 7px;
}

:is(html[data-theme]) .module-card__title {
  color: var(--text-strong);
  /* O título do CARTÃO, não o da página: `--text-size-title` são 24px e faziam
     "Configuração do sistema" ocupar três linhas dentro do atalho. */
  font-size: 17px;
  font-weight: var(--weight-strong);
  line-height: 1.25;
  margin: 0;
}

:is(html[data-theme]) .module-card__description {
  color: var(--text-muted);
  margin: 0;
}

:is(html[data-theme]) .module-card__footer {
  align-items: center;
  display: flex;
}
/* <<< css/v2/module-card.css <<< */

/* >>> css/v2/quick-add.css >>> */
/* Quick add — criação inline na lista. Depende de `v2/tokens.css`.
 * Par de `templates/cotton/v2/quick_add.html`.
 *
 * O painel é a caixa que se abre ENTRE os filtros e a lista: quem cadastra um
 * cargo ou um combustível não sai da tela para isso, e é essa a razão do quick
 * add existir. Por isso ele assume a superfície do contêiner que o recebe (o
 * trilho), e não a da página.
 */

:is(html[data-theme]) .quick-add__panel {
  /* O form só reúne os campos para um POST. Ele declara a alternância das
     superfícies para os controles, mas não desenha uma caixa própria. */
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
  background: transparent;
  border: 0;
  border-radius: 0;
  box-sizing: border-box;
  box-shadow: none;
  display: grid;
  gap: 0;
  min-width: 0;
  padding: 0;
}

/* O `display: grid` acima vence o `[hidden]`, que é regra de agente do usuário —
   e o painel NASCE oculto: é o `app.js` quem o abre. Sem este par ele aparece
   escancarado embaixo dos filtros em todas as oito telas de cadastro. */
:is(html[data-theme]) .quick-add__panel[hidden] {
  display: none;
}

/* Seção interna sem cartão próprio. O fieldset mantém a relação semântica entre
   título e campos, enquanto o painel fornece a única superfície visual. */
:is(html[data-theme]) .quick-add__section {
  border: 0;
  margin: 0;
  min-inline-size: 0;
  padding: 0;
}

:is(html[data-theme]) .quick-add__panel > .quick-add__section {
  background: var(--surface-field);
  border-radius: var(--radius-field);
  margin-block-end: var(--gap);
  padding: var(--gap);
}

:is(html[data-theme]) .quick-add__panel > .quick-add__section:last-child {
  margin-block-end: 0;
}

:is(html[data-theme]) .quick-add__section-layout {
  align-items: start;
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .quick-add__section-layout--split {
  grid-template-columns: minmax(0, 1fr);
}

:is(html[data-theme]) .quick-add__section-body {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* O GATILHO é a faixa que fecha o trilho: largura inteira, contorno só no topo,
   sem raio próprio — ele encosta nas bordas do trilho e sangra o recuo dele com
   margem negativa. É a forma do legado (`page-shell.css:2151`), e ela existe por
   um motivo: a ação de cadastrar pertence à faixa de controles, não flutua ao
   lado dela.

   Neutro por padrão. O accent entra só com `is-filled`, que o `app.js` marca
   quando algum campo foi preenchido — antes disso o botão não promete salvar
   nada. */
:is(html[data-theme]) .quick-add__toggle {
  align-items: center;
  appearance: none;
  background: var(--surface, var(--surface-rail));
  border: 0;
  border-radius: 0 0 var(--radius-rail) var(--radius-rail);
  border-top: 1px solid var(--line);
  box-sizing: border-box;
  color: var(--text-strong);
  cursor: pointer;
  display: flex;
  font: inherit;
  gap: var(--gap-tight);
  justify-content: center;
  /* Margem só nos três lados que SANGRAM o recuo do contêiner. No topo, zero: o
     `gap` da grade do painel já separa a faixa do que vem acima, e a margem em
     cima somava a ele — 32px onde o ritmo da tela é 16 (2026-08-16). */
  margin: 0 calc(var(--gap) * -1) calc(var(--gap) * -1);
  min-height: var(--control-height);
  padding: 0 var(--gap);
  transition: background var(--ease), color var(--ease);
  width: calc(100% + var(--gap) * 2);
}

:is(html[data-theme]) .quick-add__toggle:hover {
  background: var(--surface-contrast, var(--surface-field));
}

:is(html[data-theme]) .quick-add__toggle:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

/* `is-filled` é do `app.js`: há campo preenchido, então agora o botão salva — e é
   aí que ele fica primário. */
:is(html[data-theme]) .quick-add__toggle.is-filled {
  background: var(--accent);
  color: var(--text-on-accent);
}

:is(html[data-theme]) .inline-create__toggle-icon {
  align-items: center;
  display: inline-flex;
  font-size: 1.1rem;
  justify-content: center;
  line-height: 1;
}

:is(html[data-theme]) .inline-create__toggle-label {
  font-weight: var(--weight-strong);
}
/* <<< css/v2/quick-add.css <<< */

/* >>> css/v2/list-page.css >>> */
/* List page — o esqueleto de uma tela de lista. Depende de `v2/tokens.css`.
 *
 * O componente é composição pura (header + rail + panel + pagination), mas o
 * RITMO entre as peças é dele: sem esta folha as três empilhavam sem vão nenhum
 * e o painel de registros nascia colado na faixa de controles.
 */

:is(html[data-theme]) .list-page {
  display: grid;
  gap: var(--gap);
}

/* Na lista simples, o painel recebe as linhas dentro de um invólucro. Ele é a
   grade que materializa o ritmo entre registros; sem isto o `gap` do painel
   separava apenas o invólucro, e as linhas dentro dele ficavam coladas. */
:is(html[data-theme]) .list-page__panel-rows {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* Header e rail são uma peça só — o rail já perde os cantos de cima quando
   encosta no header, e o vão da grade os separaria de novo. Puxá-lo de volta
   aqui é o que mantém a regra de forma e a de ritmo dizendo a mesma coisa. */
:is(html[data-theme]) .list-page > .header + .rail {
  margin-top: calc(var(--gap) * -1);
}

/* As abas ficam à DIREITA, alinhadas com as ações dos registros logo abaixo, e
   rolam na horizontal em tela estreita em vez de quebrar: uma fileira de abas
   partida ao meio deixa de ser lida como um grupo de opções. */
:is(html[data-theme]) .list-page__tabs {
  display: flex;
  justify-content: flex-end;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

/* Menores que o padrão do toggle: aqui elas são um recorte da lista, não a
   navegação principal da tela — competir em tamanho com o título seria dar a
   elas um peso que não têm. */
:is(html[data-theme]) .list-page__tabs .toggle__item {
  font-size: var(--text-size-eyebrow);
  gap: 5px;
  min-height: var(--control-height-sm);
  padding: 0 10px;
}

:is(html[data-theme]) .list-page__tabs .toggle__count {
  font-size: 10px;
  min-width: 16px;
  padding: 1px 5px;
}

:is(html[data-theme]) .list-page__tabs::-webkit-scrollbar {
  display: none;
}

/* ---- ação principal, flutuante -------------------------------------------
 *
 * Fica no canto inferior direito, fixa na janela. Numa lista longa a ação de
 * criar estava no topo, fora da tela justamente quando a pessoa termina de
 * percorrer a lista e conclui que precisa de um registro novo.
 */
:is(html[data-theme]) .list-page__action {
  align-items: center;
  background: var(--accent);
  border-radius: var(--radius-pill);
  bottom: max(var(--gap-loose), env(safe-area-inset-bottom, 0px));
  box-shadow: 0 12px 32px rgb(5 22 38 / 0.32);
  color: var(--text-on-accent);
  display: inline-flex;
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  gap: var(--gap-tight);
  min-height: var(--control-height);
  padding: 0 var(--gap-loose);
  position: fixed;
  right: max(var(--gap-loose), env(safe-area-inset-right, 0px));
  text-decoration: none;
  transition: box-shadow var(--ease), transform var(--ease);
  z-index: var(--z-sticky, 900);
}

:is(html[data-theme]) .list-page__action:hover {
  box-shadow: 0 16px 40px rgb(5 22 38 / 0.42);
}

:is(html[data-theme]) .list-page__action:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

:is(html[data-theme]) .list-page__action svg {
  height: 18px;
  width: 18px;
}

/* Como BOTÃO (a ação que cria, num `<form>` POST) ele precisa das declarações
   que o navegador dá de graça ao link e não ao botão: fonte própria, borda e
   fundo do agente. Sem elas, a mesma classe saía com a cara do botão do
   sistema operacional.

   A fonte é declarada PROPRIEDADE A PROPRIEDADE, e não pelo atalho `font`
   (2026-08-20). O atalho reescreve TODAS as longhands que não estão nele — e
   `font: inherit` herdava `font-weight` do corpo, apagando o
   `var(--weight-strong)` da regra base logo acima. O efeito era só na variante
   `<button>`: a lista de Ofícios cria por POST e recebia o rótulo em peso 500,
   enquanto as telas cujo botão é `<a>` mostravam os 900 corretos. Dois pesos
   para a mesma ação, e nenhuma regra dizendo isso. */
:is(html[data-theme]) button.list-page__action {
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  line-height: 1;
}

/* O formulário é só o portador do POST: não pode ocupar espaço nem criar uma
   segunda caixa fixa em volta do botão. */
:is(html[data-theme]) .list-page__action-form {
  display: contents;
}

/* O botão paira sobre o fim da lista. Sem esta folga ele cobre a paginação
   exatamente quando a pessoa chega nela. */
:is(html[data-theme]) .list-page:has(.list-page__action) {
  padding-bottom: calc(var(--control-height) + var(--gap-loose));
}

/* Em tela estreita o rótulo sai e fica só o ícone: um botão largo fixo come
   parte útil da lista. */
@media (max-width: 640px) {
  :is(html[data-theme]) .list-page__action {
    border-radius: 999px;
    height: var(--control-height);
    justify-content: center;
    padding: 0;
    width: var(--control-height);
  }

  :is(html[data-theme]) .list-page__action span {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
}

/* A sequência de cartões: o vão entre painéis é o mesmo `--gap` que cada um usa
   de recuo interno, para a distância ENTRE registros e a distância DENTRO do
   registro ficarem no mesmo ritmo. Era o que o painel envolvente fazia antes de
   sair (2026-08-16). */
:is(html[data-theme]) .list-page__rows {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}
/* <<< css/v2/list-page.css <<< */

/* >>> css/v2/form-page.css >>> */
/* Form page — o esqueleto de uma tela de cadastro. Depende de `v2/tokens.css`.
 *
 * Irmã de `list-page.css`: o ritmo entre header, formulário e rodapé é dela.
 * Sem esta folha as peças empilham sem vão, e o rodapé de ações nasce colado no
 * último bloco — que é o pior lugar para uma ação irreversível ficar.
 */

:is(html[data-theme]) .form-page {
  display: grid;
  gap: var(--gap);
}

:is(html[data-theme]) .form-page__form {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* A etapa de identificação envolve resumo(s) de eventos e o painel editável
   numa raiz de dados própria. Essa camada também precisa declarar o ritmo da
   página; sem ele, o último resumo encosta no formulário. */
:is(html[data-theme]) .plan-identification-content {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

/* Header e faixa são uma peça só — a faixa já perde os cantos de cima quando
   encosta no header, e o vão da grade os separava de novo. Mesma regra da tela
   de lista, pelo mesmo motivo: forma e ritmo têm de dizer a mesma coisa. */
:is(html[data-theme]) .form-page > .header + .rail {
  margin-top: calc(var(--gap) * -1);
}
/* <<< css/v2/form-page.css <<< */

/* >>> css/v2/document-inline.css >>> */
/* ══════════════════════════════════════════════════════════════════════════
 * BASE, vinda de `pages/oficios-documentos-inline.css` em 2026-08-20.
 *
 * Mesma história do picker, do calendário e do form-block: estas eram as
 * declarações do PRÓPRIO componente do v2 (`cotton/v2/document_inline.html` e
 * `document_preview.html`), escritas numa folha de página porque a etapa de
 * documentos do ofício foi onde a peça nasceu. Sete telas a usam hoje — quatro
 * delas em prestação de contas.
 *
 * Sem prefixo `:is(html[data-theme])`: o delta abaixo tem, e é ele quem decide.
 * ══════════════════════════════════════════════════════════════════════════ */

.document-inline-stack {
  margin-bottom: 0;
}

.document-inline-card {
  border: 1px solid var(--form-section-border, var(--color-border-soft, #e3eaf2));
  border-radius: var(--radius-control, 12px);
  background: var(--surface-form-section, var(--color-surface, #fff));
  box-shadow: none;
  overflow: hidden;
  margin: 0;
}

.document-inline-card--nested {
  margin-top: var(--space-3, 0.75rem);
}

/* Item estático da pilha (ex.: rótulo + ações agregadas), sem <details>/<summary>. */
.document-inline-card--static .document-inline-card__header {
  cursor: default;
}

/* Termos aninhados são documentos acionáveis dentro do grupo: usam o degrau de
   controle para não se fundirem à superfície da seção que os contém. */
.document-inline-card--termos .document-inline-card--nested,
.document-inline-card--termos
  .document-inline-card--nested
  > .document-inline-card__header {
  background: var(--surface-contrast, var(--surface-field)) !important;
}

.document-inline-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
  padding: var(--space-4, 1rem) var(--space-4, 1rem);
  cursor: pointer;
  list-style: none;
}

.document-inline-card__header::-webkit-details-marker {
  display: none;
}

.document-inline-card__title {
  font-weight: 600;
  color: var(--color-heading, #071a33);
  flex: 1 1 12rem;
  min-width: 0;
  text-align: left;
}

.document-inline-card__header-end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-3, 0.75rem);
  flex: 0 1 auto;
}

.document-inline-card__body {
  padding: 0 var(--space-4, 1rem) var(--space-4, 1rem);
}

.document-inline-card__body--termos {
  padding-top: var(--space-2, 0.5rem);
}

.document-inline-viewer {
  border: 1px solid var(--color-border-soft, #e3eaf2);
  border-radius: var(--radius-control, 12px);
  overflow: hidden;
  background: var(--color-surface-muted, #ffffff);
  min-height: 200px;
}

.document-inline-viewer__frame {
  display: block;
  width: 100%;
  height: min(78vh, 820px);
  border: 0;
}

@media (max-width: 1080px) {
  .document-inline-viewer__frame {
    height: min(72vh, 620px);
  }}

@media (max-width: 640px) {
  .document-inline-viewer__frame {
    height: min(68vh, 520px);
  }}

.document-inline-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 0.75rem);
  margin-top: var(--space-3, 0.75rem);
}

.document-inline-actions--header {
  margin-top: 0;
  gap: var(--space-2, 0.5rem);
}

@media (max-width: 520px) {
  .document-inline-actions--header {
    width: 100%;
    justify-content: stretch;
  }

  .document-inline-actions--header .document-inline-actions__btn {
    flex: 1 1 auto;
    text-align: center;
    justify-content: center;
  }}

@media (max-width: 600px) {

  .document-inline-card__header {
    align-items: stretch;
    flex-direction: column;
  }

  .document-inline-card__header-end,
  .document-inline-actions {
    justify-content: flex-start;
    width: 100%;
  }}

.document-inline-empty {
  margin: 0;
  padding: var(--space-3, 0.75rem);
  color: var(--color-muted, #52657a);
  font-size: var(--font-size-sm, 0.875rem);
}

/* ══════════════════════════════════════════════════════════════════════════
 * DELTA v2 — daqui para baixo é o redesenho, sob a raiz `html[data-theme]`.
 * ══════════════════════════════════════════════════════════════════════════ */
/* === DELTA v2 === */

/* Documento inline — o cartão que abre e mostra o PDF na própria página.
 * Depende de `v2/tokens.css`.
 *
 * É um `<details>`/`<summary>` de verdade: abrir e fechar é do navegador, e o
 * `js/pages/oficios-documentos-inline.js` só carrega o `src` do `<iframe>` no
 * primeiro `toggle` — um PDF por cartão, carregado antes de alguém pedir, é
 * peso que ninguém vê.
 *
 * O desenho veio de `css/pages/oficios-documentos-inline.css`, que saiu do
 * formulário de termo na migração. Sem esta folha o cartão perde a moldura e o
 * `<iframe>` fica com a altura zero que o navegador dá por padrão: o visualizador
 * some da tela sem que nada quebre.
 */

/* O cartão pinta a partir do token BASE e declara o degrau seguinte para quem
   está dentro dele. Enquanto ele se pintava com `--surface-contrast` e não
   declarava nada, o botão de ações no cabeçalho herdava a MESMA variável e saía
   da cor do próprio cartão — um botão invisível em cima do que ele deveria
   destacar. É a mesma referência circular que apagou a escada da faixa de
   equipe. */
:is(html[data-theme]) .document-inline-card {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);

  background: var(--surface-rail);
  border: 0;
  border-radius: var(--radius-field);
  margin: 0;
  overflow: hidden;
}

/* Na conferência do ofício, os três filhos diretos são documentos, não novas
   seções: ficam no poço escuro do componente enquanto o form-block conserva a
   superfície azul que agrupa a área. */
:is(html[data-theme])
  .oficio-documentos-conference
  > .form-block__body
  > .document-inline-card {
  background: var(--surface-rail) !important;
}

/* O `<summary>` traz um triângulo próprio em toda plataforma; ele some porque a
   linha inteira é o alvo do clique, e o marcador competia com o título. */
:is(html[data-theme]) .document-inline-card__header {
  align-items: center;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight) var(--gap);
  justify-content: space-between;
  list-style: none;
  min-height: var(--control-height);
  padding: var(--gap);
}

:is(html[data-theme]) .document-inline-card__header::-webkit-details-marker {
  display: none;
}

:is(html[data-theme]) .document-inline-card__header::marker {
  content: "";
}

:is(html[data-theme]) .document-inline-card__title {
  color: var(--text-strong);
  flex: 1 1 12rem;
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  min-width: 0;
  text-align: left;
}

:is(html[data-theme]) .document-inline-card__header-end {
  align-items: center;
  display: flex;
  flex: 0 1 auto;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  justify-content: flex-end;
}

:is(html[data-theme]) .document-inline-card__body {
  display: grid;
  gap: var(--gap-tight);
  padding: 0 var(--gap) var(--gap);
}

/* Cartão dentro de cartão (os termos por servidor): sobe um degrau, e inverte o
   par de novo para os botões dele continuarem visíveis. */
:is(html[data-theme]) .document-inline-card .document-inline-card {
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);

  background: var(--surface-field);
}

/* ---- o visualizador -------------------------------------------------------
 *
 * A ALTURA é a razão de esta folha existir. `<iframe>` sem altura declarada
 * assume 150px em alguns navegadores e 0 em outros quando está dentro de uma
 * grade — e o documento aparece como uma faixa vazia, ou não aparece.
 *
 * `min()` com `vh` porque o documento tem de caber na tela sem rolar a página
 * inteira: quem lê um termo antes de assinar precisa do documento e do resto do
 * formulário no mesmo campo de visão.
 */
:is(html[data-theme]) .document-inline-viewer {
  background: var(--surface-field);
  border: 1px solid var(--line);
  border-radius: var(--radius-field);
  min-height: 200px;
  overflow: hidden;
}

:is(html[data-theme]) .document-inline-viewer__frame {
  border: 0;
  display: block;
  height: min(78vh, 820px);
  width: 100%;
}

@media (max-width: 1080px) {
  :is(html[data-theme]) .document-inline-viewer__frame {
    height: min(72vh, 620px);
  }
}

@media (max-width: 640px) {
  :is(html[data-theme]) .document-inline-viewer__frame {
    height: min(68vh, 520px);
  }
}

/* A fileira de ações do cabeçalho e a de dentro do corpo. */
:is(html[data-theme]) .document-inline-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
}

/* ---- o título em três linhas ----------------------------------------------
 *
 * O cartão de prévia de uma ETAPA carrega mais que um nome: o tipo do documento
 * em cima ("Documento gerado") e, embaixo, de onde vieram os dados. Empilhados
 * dentro do próprio título, eles seguem o clique do `<summary>` — postos como
 * irmãos, ficariam fora da área que abre e fecha o cartão.
 */
:is(html[data-theme]) .document-inline-card__title:has(.document-inline-card__eyebrow) {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .document-inline-card__eyebrow {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-normal);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

:is(html[data-theme]) .document-inline-card__hint {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-normal);
}

/* O vazio da prévia: a etapa ainda não produziu documento. Fica com o texto
   apagado e sem moldura — uma caixa em volta de "ainda não há nada" desenha
   atenção para o que não existe. */
:is(html[data-theme]) .document-inline-card__empty {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  margin: 0;
}
/* <<< css/v2/document-inline.css <<< */

/* >>> css/v2/document-number.css >>> */
/* Número de documento — o número e o ano na mesma caixa. Depende de
 * `v2/tokens.css` e de `v2/input.css`, de onde vem o desenho do controle.
 *
 * A caixa é uma LINHA, e não um controle novo: o `<input>` continua sendo o
 * `.input__control` do sistema, e o ano é texto ao lado dele. O legado
 * (`composite-field`) desenhava a própria moldura em volta dos dois, e por isso
 * tinha borda, raio e altura que só coincidiam com o resto por acaso.
 *
 * O conjunto ocupa a coluna inteira do formulário. O número cresce até o ano
 * fixo, mantendo as duas partes na mesma linha e sem deixar um vazio artificial
 * depois do sufixo.
 */

:is(html[data-theme]) .document-number {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
  width: 100%;
}

/* Vale para o `<input>` que este componente cria (modo composto) E para o do
   formulário (modo simples). O controle ocupa o espaço restante e o ano fica
   como sufixo fixo da mesma linha. */
:is(html[data-theme]) .document-number__input,
:is(html[data-theme]) .document-number > input {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
}

/* O ano não é rótulo nem valor: é a parte fixa do número, e por isso fica na
   cor de apoio — quem lê "12" precisa ver o "/2026" sem que ele dispute a
   leitura com o que se digita. */
:is(html[data-theme]) .document-number__suffix {
  color: var(--text-muted);
  flex: 0 0 auto;
  font-size: var(--text-size-base);
  white-space: nowrap;
}
/* <<< css/v2/document-number.css <<< */

/* >>> css/v2/document-summary.css >>> */
/* v2 — resumo documental: os fatos e os tiles de viajante.
 *
 * Vocabulário `oficio-documentos-*`: a grade de fatos do resumo executivo e os
 * tiles de pessoa que a etapa de Documentos e as etapas da Prestação usam para
 * listar quem viaja.
 *
 * Por que este arquivo existe (2026-08-20). A família inteira morava em
 * `pages/oficios.css`, que desde a migração v2 não era carregada por página
 * NENHUMA — nem `<link>`, nem bundle, nem `@import`. As regras seguiam no
 * repositório e não chegavam ao navegador: o tile ficava sem fundo, sem borda e
 * sem grade, e o fato do resumo sem cartão.
 *
 * O que continuou funcionando escondeu o problema: três folhas ainda carregam
 * OVERRIDES desta família — `pages/prestacoes_contas.css` estreita a grade do
 * tile e pinta `.prestacao-removidos__tile` com `border-style: dashed`, e
 * `v2/route-editor.css` arredonda o canto na etapa de Documentos. Override sem
 * base não levanta erro: o `dashed` sem largura nem cor simplesmente não
 * desenha nada.
 *
 * A regra do `UI-04` é que componente compartilhado tem dono. Este é o dono.
 */

/* ── Viajantes — tiles ─────────────────────────────────────────────────── */
.oficio-documentos-travellers-grid {
  display: grid;
  gap: var(--space-2);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
}

.oficio-documentos-traveller-tile {
  align-items: center;
  background: var(--color-card-muted);
  border: 1px solid var(--color-border-soft);
  border-radius: 10px;
  column-gap: 12px;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  min-width: 0;
  padding: 10px 12px;
}

.oficio-documentos-traveller-tile__avatar {
  align-items: center;
  background: color-mix(in srgb, var(--color-heading) 8%, transparent);
  border: 1px solid var(--color-border-soft);
  border-radius: 10px;
  color: var(--color-heading);
  display: inline-flex;
  font-size: var(--font-size-xs);
  font-weight: 800;
  height: 40px;
  justify-content: center;
  letter-spacing: 0.04em;
  width: 40px;
}

.oficio-documentos-traveller-tile__main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.oficio-documentos-traveller-tile__title-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.oficio-documentos-traveller-tile__name {
  color: var(--color-heading);
  font-size: var(--font-size-sm);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.25;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.oficio-documentos-traveller-tile__badge {
  align-items: center;
  background: var(--color-accent);
  border-radius: 999px;
  color: var(--color-on-accent);
  display: inline-flex;
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.04em;
  min-height: 21px;
  padding: 2px 8px;
  text-transform: uppercase;
}

.oficio-documentos-traveller-tile__meta {
  color: var(--color-muted);
  font-size: var(--font-size-xs);
  font-weight: 500;
  line-height: 1.3;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .oficio-documentos-travellers-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Resumo executivo — fatos ──────────────────────────────────────────── */
.oficio-documentos-card__body {
  padding: var(--space-4);
}

.oficio-documentos-facts {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  margin: 0;
}

.oficio-documentos-fact {
  background: var(--color-card-muted);
  border: 1px solid var(--color-border-soft);
  border-radius: 10px;
  padding: 10px 12px;
}

.oficio-documentos-fact dt {
  color: var(--color-muted);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  margin-bottom: var(--space-1);
  text-transform: uppercase;
}

.oficio-documentos-fact dd {
  color: var(--color-heading);
  font-size: var(--font-size-sm);
  font-weight: 700;
  margin: 0;
  word-break: break-word;
}
/* <<< css/v2/document-summary.css <<< */

/* >>> css/v2/suggestions.css >>> */
/* Sugestões — a faixa de atalhos que o formulário oferece a partir do que já
 * foi preenchido. Depende de `v2/tokens.css`.
 *
 * A faixa só resolve o ARRANJO. O chip em si é peça do sistema: cada sugestão é
 * um `toggle__item` — o botão de "escolha uma entre poucas", que já tem hover,
 * foco e estado escolhido —, e a razão da sugestão é um `chip--v2`.
 *
 * As classes `viatura-sugestao-chip` e `viatura-sugestao-badge` saíram em
 * 2026-08-19 junto com as 40 linhas que as desenhavam: elas repetiam, com outro
 * nome, a pílula que o toggle e o selo já davam — inclusive o realce do
 * escolhido, que aqui era uma classe `--active` e no sistema é `aria-pressed`.
 */

:is(html[data-theme]) .suggestions {
  display: grid;
  gap: 6px;
  min-width: 0;
}

:is(html[data-theme]) .suggestions__label {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  margin: 0;
  text-transform: uppercase;
}

:is(html[data-theme]) .suggestions__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
}

/* Os itens NÃO ficam sobre a calha do toggle: aqui eles são atalhos soltos, e
   não os segmentos de um controle único. Por isso a faixa é um flex simples e
   não leva a classe `.toggle`. */

/* O selo DENTRO da sugestão escolhida: sobre o accent, a cor de estado do chip
   fica ilegível — medido, "ADILSON" em `--status-progress` sobre o amarelo
   praticamente sumia. Aqui ele passa a ser um véu escuro com a cor de cima do
   accent, que é o mesmo tratamento que o segmento escolhido do `toggle--fill`
   dá ao marcador dele. */
:is(html[data-theme]) .suggestions__chips .toggle__item[aria-pressed="true"] .chip--v2 {
  background: color-mix(in srgb, #000 18%, transparent);
  color: inherit;
}
/* <<< css/v2/suggestions.css <<< */

/* >>> css/v2/fact.css >>> */
/* Fatos e trechos — o miolo informativo do card de lista. Depende de
 * `v2/tokens.css`.
 *
 * O peso das peças fortes sai de `--fact-weight` (800 por padrão). A variável
 * existe para o provador de tipografia poder mexer nele ao vivo: `800` cravado
 * no lugar ignorava o controle de peso, e comparar duas famílias sem poder
 * ajustar o peso mente sobre as duas — a Bahnschrift a 700 parece leve porque o
 * traço dela é mais fino que o da Inter no mesmo número.
 *
 * É a peça que faltava para o cartão do v2 dizer o que o cartão de ofício já
 * dizia: placa e modelo, o itinerário, o valor das diárias. O legado resolvia
 * isso com `.fact-grid`/`.fact-block`/`.itinerary`, nomes que ainda estão
 * vivos nas telas não migradas — declarar os mesmos aqui repintaria a lista de
 * ofícios sem que ninguém pedisse. Por isso os nomes são outros.
 *
 * Um FATO é rótulo miúdo em cima, valor forte embaixo. A ordem importa: numa
 * grade de seis fatos o olho desce pelos rótulos para achar o que procura, e
 * só então lê o valor. Invertido, ele lê seis valores sem saber do que são.
 */

/* UMA COLUNA, sempre (2026-08-19, por decisão do dono). Dois fatos lado a lado
   partem a largura ao meio, e o valor é justamente a peça que precisa dela: com
   `auto-fit` a placa virava "Não informa…" e o total, "R$ 4.111,…" — o `fit-text`
   já tinha encolhido o corpo até o piso e o resto virou reticência. Empilhados,
   cada valor tem a faixa inteira.

   É também o que a conta de altura destes blocos sempre supôs: os degraus de
   `--fact-value-size` mais abaixo somam rótulo, valor e vão POR FATO, um embaixo
   do outro. */
:is(html[data-theme]) .fact-list {
  display: grid;
  gap: var(--gap);
  grid-template-columns: minmax(0, 1fr);
  min-width: 0;
}

/* FAIXA — a exceção à coluna única.
 *
 * Um resumo de documento é uma linha de fatos equivalentes: número, protocolo,
 * criação e custeio têm o mesmo peso e se leem lado a lado. A exceção é um
 * modificador do PRÓPRIO bloco, e não uma classe de tela: eram
 * `document-summary--identity` e `document-summary--vehicle`, dois seletores
 * com o mesmo corpo, modificando um bloco (`document-summary`) que não existia
 * em folha nenhuma — nome de tela vestido de componente.
 *
 * A contagem entra no nome porque é ela que muda: o resumo do ofício tem
 * quatro fatos, o das diárias tem três painéis. `auto-fit` não serve aqui —
 * foi ele que encolheu a placa até "Não informa…" e obrigou a coluna única. */
:is(html[data-theme]) .fact-list--band-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

:is(html[data-theme]) .fact-list--band-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

:is(html[data-theme]) .fact-list--band-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Três linhas EMPILHADAS: rótulo, valor, apoio.
 *
 * Tentei o apoio ao lado do valor para economizar altura dentro do teto de
 * 170px; o dono preferiu empilhado (2026-08-16). A conta fecha pelo corpo do
 * texto, que cede por faixa de quantidade em `v2/record.css` — é lá que o
 * bloco de três fatos aperta rótulo, valor e entrelinha para caber. */
:is(html[data-theme]) .fact {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* Entre dois fatos do mesmo bloco o vão é maior que o de dentro de um fato —
   é o que faz "PLACA / ABC-1D23" ler como um par, e não como quatro linhas
   soltas em sequência. */
:is(html[data-theme]) .fact + .fact {
  margin-top: var(--fact-gap, var(--gap-tight));
}

/* O fato que ocupa a faixa inteira — o itinerário e o valor por extenso são os
   dois casos: texto longo em coluna estreita vira uma torre de duas palavras. */
:is(html[data-theme]) .fact--wide {
  grid-column: 1 / -1;
}

/* Rótulo no ACCENT, e não em cinza. É o desenho do cartão de ofício original, e
   a razão dele: numa faixa de três blocos, o rótulo é a única coisa que diz de
   que assunto é o número logo abaixo. Em cinza ele sumia contra a superfície e
   sobravam três valores soltos; no accent ele vira a etiqueta que o olho segue
   para achar o que procura. */
:is(html[data-theme]) .fact__label {
  color: var(--accent);
  /* Menor que o `eyebrow` do sistema: o rótulo é etiqueta, e no cartão ele divide
     uma caixa apertada com um valor grande. Do tamanho anterior, "MOTORISTA
     EXTERNO" ocupava quase a mesma altura visual do número que ele nomeia. O
     accent e o peso 800 continuam dando a ele o destaque de que precisa para ser
     achado de relance — não precisa de corpo para isso. */
  font-size: 0.68rem;
  /* 800, não 700: a Inter é variável e o peso extra é o que faz o rótulo miúdo
     aguentar o valor gigante logo abaixo sem parecer legenda esquecida. */
  font-weight: var(--fact-weight, 800);
  letter-spacing: 0.07em;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
  margin-bottom: 8px;
}

/* O valor é GRANDE. No original a placa e o total ocupam a altura de duas
   linhas de texto, e é isso que faz o cartão ser legível de longe: numa lista,
   quem varre procura o número, não a frase.

   A medida é em `cqw` — por cento da largura do BLOCO, não da janela (o
   `container-type` está no corpo do bloco, em `v2/record.css`). É o que faz o
   valor ocupar o bloco: numa coluna larga ele cresce, numa estreita ele cede,
   e o cartão não depende do tamanho da tela para caber. Com `vw` o mesmo bloco
   dentro de uma coluna estreita recebia corpo de tela cheia e vazava.

   O `clamp` continua: um piso para o valor não virar nota de pé de página em
   tela pequena, e um teto ajustado ao teto de 190px da faixa — no limite
   anterior (2.4rem) três fatos não caíam na caixa e o bloco da viatura nascia
   rolando. */
:is(html[data-theme]) .fact__value {
  color: var(--text-strong);
  font-size: var(--fact-value-size, clamp(1.05rem, 11cqw, 1.65rem));
  font-weight: var(--fact-weight, 800);
  letter-spacing: -0.02em;
  line-height: 1.1;
  min-width: 0;
  /* UMA linha, e o `fit-text.js` reduz o corpo até caber. O `overflow-wrap` que
     morava aqui deixava "JOÃO PEREIRA" e "R$ 1.248,00" quebrarem em duas linhas
     no bloco estreito — e valor em duas linhas estoura o teto de altura do
     cartão. O `ellipsis` é rede de segurança para o caso em que o piso do JS
     ainda não basta. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O corpo do valor CEDE por quantidade de fatos no bloco.
 *
 * Estes são os degraus que o comentário acima diz terem sido apagados por
 * engano num corte. Eles voltam porque a conta é de ALTURA, e o `fit-text.js`
 * só sabe de largura: ele encolhe o que não cabe na linha, e nunca o que não
 * cabe na caixa.
 *
 * A caixa útil do bloco são ~133px (157 menos o recuo). Um rótulo mede 13px e o
 * vão entre fatos, 8. Com DOIS fatos sobram ~50px por valor, que é o que os
 * 2,2rem ocupam com a entrelinha de 1,1 — o bloco fica cheio sem empurrar os
 * vizinhos. Com TRÊS, o teto volta ao valor conservador, senão a terceira linha
 * nasce cortada.
 *
 * Um fato só (a placa sozinha, quando não há modelo) pode crescer mais: é o
 * caso em que a caixa inteira é dele.
 */
/* A exceção do valor forte vai DENTRO das duas regras, e não numa terceira: os
   seletores de contagem usam `:has()` e `:not()` e somam especificidade alta, e
   a terceira regra — mais simples — perdia para eles em silêncio. Onde já há o
   destaque do cartão, o outro fato cede: medido, "Valor total" a 48px mais a
   linha do por extenso mais um segundo fato crescido transbordavam a caixa em
   11px. */
:is(html[data-theme]) .fact-list:not(:has(> .fact:nth-child(2))):not(:has(.fact__value--strong)) {
  --fact-value-size: clamp(1.2rem, 20cqw, 2.6rem);
}

:is(html[data-theme]) .fact-list:has(> .fact:nth-child(2)):not(:has(> .fact:nth-child(3))):not(:has(.fact__value--strong)) {
  --fact-value-size: clamp(1.1rem, 16cqw, 2.2rem);
}

/* O valor forte ACOMPANHADO cede um degrau. Sozinho ele fica nos 3rem; com um
   segundo fato no mesmo bloco — "Valor total" e "Quantidade de diárias" — a
   soma passava a caixa por 1px. Um pixel não se vê, mas é o começo do corte. */
:is(html[data-theme]) .fact-list:has(> .fact:nth-child(2)):has(.fact__value--strong) {
  --fact-value-size-strong: clamp(1.15rem, 18cqw, 2.8rem);
}

/* O total das diárias é o valor que a lista existe para comparar — um degrau
   acima dos outros, e só ele. */
:is(html[data-theme]) .fact__value--strong {
  /* 18cqw e teto de 3rem: é o número que a lista existe para comparar, e com o
     `fit-text.js` medindo não há risco de estourar — se não couber, ele desce. O
     valor anterior (13cqw / 1,95rem) deixava o total menor do que a caixa
     permitia. Este é o FALLBACK e hoje é o valor efetivo: os degraus por
     quantidade de fatos que ficavam em `v2/record.css` foram apagados por engano
     num corte e não voltaram — quando voltarem, é aqui que se comparam. */
  font-size: var(--fact-value-size-strong, clamp(1.15rem, 18cqw, 3rem));
}

/* Valor ausente não vira espaço em branco: um cartão com um buraco no lugar da
   placa parece um cartão quebrado, e não um ofício sem viatura. */
/* Ausência não é dado: volta ao corpo do texto normal. Um "Não informado" no
   mesmo tamanho do valor grita tão alto quanto o número que existe. */
:is(html[data-theme]) .fact__value--empty {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
}

/* A linha de apoio fica logo sob o valor, miúda, com um respiro que a separa do
   próximo rótulo — e em UMA linha, como o valor: "mil duzentos e quarenta e oito
   reais" quebrando em duas somava altura que o teto do bloco não tem, e empurrava
   o fato seguinte para fora. Quem encolhe é o `fit-text.js`, com piso de 9px
   (mais baixo que o do valor, porque aqui o texto é longo por natureza). */
:is(html[data-theme]) .fact__note {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  line-height: var(--fact-note-line, 1.35);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O valor por extenso precisa preservar legibilidade na coluna estreita do
   resumo do roteiro. Só esse fato pode ocupar uma segunda linha; as demais
   notas continuam obedecendo ao contrato compacto global. */
:is(html[data-theme]) .fact--two-line-note .fact__note {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  display: -webkit-box;
  white-space: normal;
}

/* A composição das diárias é uma expressão contábil, não uma legenda. Ela
   precisa permanecer completa mesmo quando a coluna do cartão estreita: pode
   quebrar linha, mas nunca recebe reticências nem perde conteúdo. */
:is(html[data-theme]) .fact--never-truncate .fact__value {
  overflow: visible;
  overflow-wrap: anywhere;
  text-overflow: clip;
  white-space: normal;
}

/* ---- trechos --------------------------------------------------------------
   Cada trecho é rota em cima e horário embaixo. Em duas colunas quando cabe:
   uma ida e volta ocupa duas linhas, e lado a lado elas se leem como o par que
   são. */

/* `min(220px, 100%)` e não `220px` seco: `auto-fit` com um mínimo FIXO cria uma
   trilha desse tamanho mesmo quando o contêiner é menor, e o conteúdo vaza para
   fora dele. Dentro de um dos três blocos do cartão a coluna tem ~200px — foi
   ali que o trecho passou por cima da borda do bloco. O `min()` faz o mínimo
   ceder para a largura disponível. */
:is(html[data-theme]) .route-legs {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  list-style: none;
  margin: 0;
  min-width: 0;
  padding: 0;
}

:is(html[data-theme]) .route-legs__leg {
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: grid;
  gap: 2px;
  min-width: 0;
  padding: 14px var(--gap-tight);
}

/* A rota QUEBRA em vez de truncar: cortada com "…", o que se perde é o destino
   — justamente o que a linha existe para dizer. Duas linhas custam menos que um
   trecho que não se sabe para onde vai. */
:is(html[data-theme]) .route-legs__path {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--fact-weight, 800);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* UMA linha, com corpo variável. A rota quebrando em duas fazia cada trecho
   ocupar 81px e dois deles estouravam o teto da faixa; e uma rota em duas linhas
   se lê como dois trechos, não como um.
 *
 * O corpo é medido em `cqw` — por cento da largura do BLOCO —, então a rota
 * encolhe junto com a coluna em vez de quebrar. 6,2cqw dá ~13px na coluna de
 * 215px a 6,2cqw dava 14,5px e a rota de 26 caracteres AINDA cortava — medido,
 * não estimado. A 5cqw (~11px) ela entra inteira com folga.
 *
 * O `ellipsis` é rede de segurança para o caso extremo (uma rota de nome muito
 * longo), não o comportamento esperado: nas medidas reais nada corta. */
:is(html[data-theme]) .form-block--v2 .route-legs__path {
  font-size: clamp(0.7rem, 5cqw, 0.95rem);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .route-legs__time {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-variant-numeric: tabular-nums;
}

/* ---- os trechos dentro de um bloco do cartão -----------------------------
 *
 * Altura FIXA de dois trechos, e rolagem no resto. Um ofício com seis pernas
 * fazia o bloco de trechos esticar sozinho e arrastava os outros dois com ele —
 * numa lista, isso significa cartões de alturas diferentes conforme o roteiro,
 * e a varredura vertical perde a régua. Dois é o caso comum (ida e volta); o
 * sexto trecho continua alcançável, rolando.
 *
 * Uma coluna só: dentro de um terço do cartão não há largura para duas.
 */
:is(html[data-theme]) .form-block--v2 .route-legs {
  /* Dois trechos têm de caber no teto da faixa (170px) menos o recuo do bloco:
     ~146px, ou seja 69px por trecho. É por isso que a rota volta a caber em uma
     linha aqui — ver a regra do `__path` abaixo. Medido: a caixa do bloco entrega
     146px, e 2 x 68,8 + 8 de vão fecham em 145,6. Subir para 4,4rem estoura por
     2,8px e o segundo trecho volta a aparecer cortado. */
  --leg-height: 4.3rem;
  /* Uma coluna só: dentro de um terço do cartão não há largura para duas. */
  grid-template-columns: minmax(0, 1fr);
  /* Os trechos OCUPAM a caixa: `1fr` por linha divide a altura disponível entre
     eles, em vez de deixá-los encolhidos no topo com vazio embaixo. É o que faz
     dois trechos preencherem o teto da faixa.

     SEM `height: 100%`: com ele a lista media 100% da caixa do bloco, recuo
     incluído, e vazava 24px por baixo. Quem estica é o `align-content: stretch`
     do corpo (`v2/record.css`), que respeita o recuo. */
  /* CENTRALIZADOS quando cabem. Esticados em `1fr` eles dividiam os 170px e
     abriam entre si um vão do tamanho de um trecho — o bloco parecia dois
     blocos distantes. Centrado, o par fica junto e a folga se reparte em cima e
     embaixo, alinhando com o miolo dos blocos vizinhos. Quando a lista rola,
     a regra abaixo devolve o alinhamento ao topo.
   *
   * Fileiras de altura FIXA, e não `min-content`: é o que garante que a caixa
   * mostre DOIS trechos inteiros. Com altura natural cada trecho media um tanto
   * (65,7px aqui, 68,9px no que tinha rota mais longa) e o segundo terminava
   * cortado ao meio, com a metade do terceiro aparecendo por baixo. */
  align-content: center;
  grid-auto-rows: var(--leg-height);
}

:is(html[data-theme]) .form-block--v2 .route-legs__leg {
  overflow: hidden;
  scroll-snap-align: start;
}

/* O teto e a barra só existem a partir do TERCEIRO trecho.
 *
 * Com `max-height` e `overflow-y: auto` fixos, o caso comum — ida e volta —
 * nascia com barra de rolagem e a calha reservada comendo a largura do texto,
 * para rolar dois itens que já cabiam. O `:has(> :nth-child(3))` faz a regra
 * valer só quando há de fato o que rolar; com um ou dois trechos a lista é uma
 * lista, sem cromo nenhum.
 */
:is(html[data-theme]) .form-block--v2 .route-legs:has(> :nth-child(3)) {
  /* Do TOPO quando rola: `align-content: center` numa caixa que rola empurra o
     começo da lista para fora pela borda de cima, e o primeiro trecho fica
     inalcançável — a rolagem só desce. */
  align-content: start;
  max-height: calc(2 * var(--leg-height) + var(--gap-tight));
  overflow-y: auto;
  /* A rolagem PARA em trecho inteiro. Sem isto ela para onde o dedo soltou, e
     o que se vê é meio cartão em cima e meio embaixo — o mesmo corte que as
     fileiras fixas resolvem no estado parado. */
  scroll-snap-type: y mandatory;
  /* Aqui a calha vale: ela reserva o espaço da barra para o texto não mudar de
     largura enquanto se rola. */
  scrollbar-gutter: stable;
  /* A MESMA barra do resto do v2 — picker, listbox e seletor de download já a
     declaram assim. Sem estas duas linhas o navegador desenha a barra do
     sistema, larga e clara, e ela era a única peça do cartão fora do modelo. */
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-width: thin;
}

/* O horário segue a mesma regra da rota: UMA linha, corpo medido pela largura do
   bloco. "12/08 08:00 → 12/08 09:10" são 25 caracteres e, no corpo fixo, caíam
   para a segunda linha na coluna estreita — e um trecho de três linhas dentro de
   um bloco de altura fixa é o que empurrava o segundo para fora. */
:is(html[data-theme]) .form-block--v2 .route-legs__time {
  font-size: clamp(0.6rem, 4.6cqw, 0.8rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O rótulo da linha de apoio (o "valor por extenso") ganha respiro em cima: ele
   abre um segundo par rótulo/valor dentro do mesmo fato, e colado ao número
   parecia legenda dele. */
:is(html[data-theme]) .fact__label--note {
  margin-top: var(--gap-tight);
}

/* Duas faixas de fatos empilhadas precisam de vão entre elas — sem isto o
   rótulo da segunda encosta na nota da primeira e as duas leem como uma. */
:is(html[data-theme]) .fact-list + .fact-list,
:is(html[data-theme]) .fact-chips + .fact-list {
  margin-top: var(--gap);
}


/* ---- a lista que vira chip ------------------------------------------------
 *
 * Efetivo e atividades de um plano são LISTAS de itens curtos. Como valor de um
 * fato elas viram uma frase corrida que não se lê; como `record` cada item
 * ganharia 68px de altura para mostrar duas palavras. O chip é o meio-termo que
 * o sistema já tem, e ele quebra em linha sozinho.
 */
:is(html[data-theme]) .fact-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  margin-top: var(--gap-tight);
  min-width: 0;
}

/* Resumo do roteiro: três assuntos, três colunas. Cada coluna usa o mesmo
   form-block dos demais resumos da etapa; a grade apenas define a relação
   espacial entre trechos, valor e composição das diárias. */
:is(html[data-theme]) .route-summary {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  min-width: 0;
}

:is(html[data-theme]) .route-summary__column {
  min-width: 0;
}

/* O título identifica o percurso à esquerda; a explicação curta pertence ao
   lado oposto do mesmo cabeçalho, imediatamente antes do selo de status. */
:is(html[data-theme]) .route-summary-block > .form-block__header > div:first-child {
  flex: 1;
  min-width: 0;
}

@media (max-width: 900px) {
  :is(html[data-theme]) .route-summary {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* <<< css/v2/fact.css <<< */

/* >>> css/v2/stat.css >>> */
/* Contagem com ícone — par de `cotton/v2/stat.html`.
 *
 * Uma linha: ícone, assunto, número. O número fica à direita e em destaque,
 * porque é o que se lê; o assunto explica de que ele é.
 *
 * O fundo é o poço de campo, e não um cartão: três contagens seguidas com
 * borda e sombra viram três caixas competindo com o conteúdo da tela — foi o
 * que o `metric` fazia no painel antigo.
 */

:is(html[data-theme]) .stat-row {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  min-width: 0;
}

:is(html[data-theme]) .stat {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: flex;
  gap: 10px;
  min-width: 0;
  padding: 10px 12px;
}

:is(html[data-theme]) .stat__icon {
  align-items: center;
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
}

:is(html[data-theme]) .stat__icon svg {
  height: 18px;
  width: 18px;
}

/* O assunto cede a largura; o número nunca. */
:is(html[data-theme]) .stat__label {
  color: var(--text-muted);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .stat__value {
  color: var(--text-strong);
  flex: 0 0 auto;
  font-size: var(--text-size-base);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-strong);
}
/* <<< css/v2/stat.css <<< */

/* >>> css/v2/progress.css >>> */
/* Barra de progresso — par de `cotton/v2/progress.html`.
 *
 * Uma linha de cabeçalho (rótulo, estado, porcentagem) e a barra. O estado fica
 * NO MEIO e cresce: é ele que muda a cada consulta, e a porcentagem à direita
 * dá o ponto fixo para o olho voltar.
 *
 * Veio da reorganização do Drive, que era a única barra do sistema e vivia numa
 * folha de página (2026-08-20).
 */

:is(html[data-theme]) .progress {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .progress[hidden] {
  display: none;
}

:is(html[data-theme]) .progress__head {
  align-items: baseline;
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .progress__label {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* O estado empurra a porcentagem para a direita e cede primeiro quando falta
   largura — o número é curto e não pode virar reticência. */
:is(html[data-theme]) .progress__state {
  color: var(--text-strong);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .progress__percent {
  color: var(--text-strong);
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-strong);
}

/* O trilho é o `<progress>` NATIVO, e vesti-lo custa três blocos: o elemento
   traz aparência de sistema operacional, e cada motor pinta o preenchimento
   pelo seu próprio pseudo-elemento. `appearance: none` é o que desliga a
   aparência nativa; sem ele o Chrome ignora o `background` do trilho.

   O trilho é um poço de campo, como todo fundo de controle do sistema. */
:is(html[data-theme]) .progress__track {
  appearance: none;
  background: var(--surface-contrast, var(--surface-field));
  border: 0;
  border-radius: var(--radius-pill);
  display: block;
  height: 8px;
  overflow: hidden;
  width: 100%;
}

/* Chrome/Safari: o trilho de novo (o `background` acima não alcança) e o
   preenchimento. A transição existe para o salto de 12% para 40% não parecer um
   redesenho da tela. */
:is(html[data-theme]) .progress__track::-webkit-progress-bar {
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-pill);
}

:is(html[data-theme]) .progress__track::-webkit-progress-value {
  background: var(--accent);
  border-radius: var(--radius-pill);
  transition: inline-size 240ms ease;
}

/* Firefox. */
:is(html[data-theme]) .progress__track::-moz-progress-bar {
  background: var(--accent);
  border-radius: var(--radius-pill);
}

:is(html[data-theme]) .progress.is-done .progress__track::-webkit-progress-value {
  background: var(--status-done);
}

:is(html[data-theme]) .progress.is-done .progress__track::-moz-progress-bar {
  background: var(--status-done);
}

:is(html[data-theme]) .progress.is-error .progress__track::-webkit-progress-value {
  background: var(--status-late);
}

:is(html[data-theme]) .progress.is-error .progress__track::-moz-progress-bar {
  background: var(--status-late);
}

:is(html[data-theme]) .progress__hint {
  color: var(--text-muted);
  font-size: var(--text-size-micro);
  margin: 0;
}

:is(html[data-theme]) .progress__hint[hidden] {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .progress__track::-webkit-progress-value {
    transition: none;
  }
}
/* <<< css/v2/progress.css <<< */

/* >>> css/v2/folder-browser.css >>> */
/* Linha do navegador de pastas — par de `cotton/v2/folder_row.html`.
 *
 * A linha inteira é o alvo de ESCOLHER; "Abrir" é um botão à direita, separado,
 * porque entrar numa pasta é outra coisa. A escolhida marca-se por
 * `aria-pressed`, como todo estado de escolha do sistema.
 *
 * Veio de `pages/gdrive-config.css` em 2026-08-20, quando a tela do Drive
 * passou para o v2.
 */

:is(html[data-theme]) .folder-list {
  display: grid;
  gap: 4px;
  max-height: 320px;
  min-width: 0;
  overflow-y: auto;
}

:is(html[data-theme]) .folder-list[hidden] {
  display: none;
}

:is(html[data-theme]) .folder-row {
  align-items: center;
  border-radius: var(--radius-field);
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
  padding: 2px;
}

:is(html[data-theme]) .folder-row:hover {
  background: var(--surface-contrast, var(--surface-field));
}

/* A escolhida ganha o tom do sistema — o mesmo do segmento escolhido no
   `toggle` e do item marcado no picker. */
:is(html[data-theme]) .folder-row.is-selected {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}

:is(html[data-theme]) .folder-row__select {
  align-items: center;
  background: none;
  border: 0;
  border-radius: var(--radius-field);
  color: var(--text-strong);
  cursor: pointer;
  display: flex;
  flex: 1 1 auto;
  font: inherit;
  font-size: var(--text-size-base);
  gap: 10px;
  min-width: 0;
  padding: 8px 10px;
  text-align: left;
}

:is(html[data-theme]) .folder-row__icon {
  align-items: center;
  color: var(--text-muted);
  display: inline-flex;
  flex: 0 0 auto;
}

:is(html[data-theme]) .folder-row__icon svg {
  height: 18px;
  width: 18px;
}

:is(html[data-theme]) .folder-row.is-selected .folder-row__icon {
  color: var(--accent);
}

:is(html[data-theme]) .folder-row__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* "Abrir" é o secundário do sistema em tamanho de linha: aparece sempre, e não
   só no hover — numa lista de doze pastas, ação que só existe sob o cursor é
   ação que ninguém encontra. */
:is(html[data-theme]) .folder-row__enter {
  background: var(--surface-contrast, var(--surface-field));
  border: 0;
  border-radius: var(--radius-field);
  color: var(--text-muted);
  cursor: pointer;
  flex: 0 0 auto;
  font: inherit;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  padding: 6px 12px;
}

:is(html[data-theme]) .folder-row__enter:hover {
  color: var(--text-strong);
}

:is(html[data-theme]) .folder-row__select:focus-visible,
:is(html[data-theme]) .folder-row__enter:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

:is(html[data-theme]) .folder-list__empty {
  color: var(--text-muted);
  font-size: var(--text-size-base);
  margin: 0;
  padding: 12px;
}

:is(html[data-theme]) .folder-list__empty[hidden] {
  display: none;
}

/* A pasta escolhida e o atalho para o Drive, na mesma linha. */
:is(html[data-theme]) .folder-browser__current {
  align-items: end;
  display: flex;
  gap: var(--gap);
  justify-content: space-between;
  min-width: 0;
}

/* ---- a casca do navegador -------------------------------------------------
 *
 * Barra de origem (Meu Drive / compartilhados), linha de navegação com o
 * caminho, a lista, e o rodapé com criar/usar. As classes são emitidas pela
 * tela do Drive; a linha e a lista, pelo `folder_row` e pelo motor.
 */

:is(html[data-theme]) .folder-browser {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .folder-browser__toolbar {
  display: grid;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .folder-browser__nav {
  align-items: center;
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
}

/* O caminho cede a largura: numa pasta funda ele é a parte que pode encurtar
   sem perder o sentido — o fim do caminho é o que importa. */
:is(html[data-theme]) .folder-browser__path {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .folder-browser__body[hidden],
:is(html[data-theme]) .folder-browser__actions[hidden],
:is(html[data-theme]) .folder-browser__new[hidden] {
  display: none;
}

:is(html[data-theme]) .folder-browser__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  justify-content: flex-end;
}

:is(html[data-theme]) .folder-browser__new {
  display: grid;
  gap: var(--gap-tight);
}

:is(html[data-theme]) .folder-browser__new-row {
  display: flex;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .folder-browser__new-row .field {
  flex: 1 1 auto;
  min-width: 0;
}

/* A prévia da reorganização reusa a lista: são linhas de texto, com a mesma
   rolagem e o mesmo ritmo das pastas. */
:is(html[data-theme]) .folder-list__line {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  padding: 4px 10px;
}
/* <<< css/v2/folder-browser.css <<< */

/* >>> css/v2/signature-fonts.css >>> */
/* v2 — as fontes de assinatura da tela pública. Par de
 * `templates/cotton/v2/signature_fonts.html`.
 *
 * As seis `@font-face` moram AQUI, e não na folha daquela página, porque o
 * componente é do sistema: quem o coloca numa tela não deveria também ter de
 * lembrar de carregar uma folha de página para que os chips não saiam todos na
 * mesma cursiva. Foi exatamente o que aconteceu quando a galeria o adotou.
 *
 * Declarar `@font-face` não baixa nada: o navegador só busca o arquivo quando
 * alguma regra que casa com um elemento pede a família. As seis viajam no
 * `ui.bundle.css` como seis declarações de texto, e continuam sendo baixadas
 * só na tela de assinatura.
 *
 * O prefixo `asgn-` ficou. Ele não é decoração: `js/pages/prestacoes-assinatura.js`
 * acha os chips por `.asgn-fontchip`, e renomear a classe não dá erro nenhum —
 * o chip só para de responder ao clique.
 */

@font-face {
  font-family: "Great Vibes";
  src: url("../vendor/fonts/GreatVibes-Regular.d1358c495233.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Alex Brush";
  src: url("../vendor/fonts/AlexBrush-Regular.63834d2c5edd.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Parisienne";
  src: url("../vendor/fonts/Parisienne-Regular.4be239f61c4f.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Sacramento";
  src: url("../vendor/fonts/Sacramento-Regular.c3264a2601f8.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Allura";
  src: url("../vendor/fonts/Allura-Regular.ec47de04a5f2.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Herr Von Muellerhoff";
  src: url("../vendor/fonts/HerrVonMuellerhoff-Regular.0417b4b0f198.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

.asgn-fontlist {
  display: grid;
  gap: 0.6rem;
}

/* O chip é um degrau `field` sobre a caixa, como qualquer opção do sistema. A
   fonte é grande de propósito: o chip É a prévia da assinatura, e em corpo de
   texto as seis cursivas ficam indistinguíveis. */
.asgn-fontchip {
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  background: var(--surface-field);
  padding: 0.5rem 1rem;
  font-size: 2rem;
  line-height: 1.4;
  color: var(--text-strong);
  cursor: pointer;
  text-align: center;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.asgn-fontchip:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.asgn-fontchip--classica { font-family: "Great Vibes", cursive; }
.asgn-fontchip--profissional { font-family: "Alex Brush", cursive; }
.asgn-fontchip--moderna { font-family: "Parisienne", cursive; }
.asgn-fontchip--simples { font-family: "Sacramento", cursive; }
.asgn-fontchip--natural { font-family: "Allura", cursive; }
.asgn-fontchip--luxuosa { font-family: "Herr Von Muellerhoff", cursive; }

/* Escolhido: superfície própria e a fita do accent, que é como o sistema marca
   uma opção em toda parte (`choice-card`). O anel azul de antes era do desenho
   da página e não sobrevive ao tema escuro. */
.asgn-fontchip.is-selected {
  border-color: var(--accent);
  background: var(--surface-selected);
  color: var(--accent);
}
/* <<< css/v2/signature-fonts.css <<< */

/* >>> css/v2/number-stepper.css >>> */
/* Stepper numérico — o campo com "−" e "+" ao lado.
 * Depende de `v2/tokens.css`.
 *
 * Os botões ficam NAS PONTAS e o campo no meio, com o número centralizado: é a
 * forma que o olho já conhece de qualquer contador, e ela dispensa rótulo para
 * dizer o que cada botão faz.
 *
 * Os três têm a mesma altura do campo do sistema (`--control-height`). Com o
 * botão mais baixo que o campo o conjunto lia como campo com dois adereços
 * soltos, e não como um controle só.
 */

:is(html[data-theme]) .number-stepper {
  align-items: center;
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: var(--control-height) minmax(0, 1fr) var(--control-height);
}

/* O campo herda a moldura do input do sistema; aqui só o número vai ao centro,
   porque encostado à esquerda ele fica longe dos dois botões que o mudam.
   Os dois seletores existem porque o controle chega das duas formas: cru, quando
   vem do widget do Django (`{{ form.quantidade }}`), e dentro de `.input`,
   quando vem do `c-v2.input`. */
:is(html[data-theme]) .number-stepper > input,
:is(html[data-theme]) .number-stepper > .input {
  min-width: 0;
}

:is(html[data-theme]) .number-stepper input {
  text-align: center;
}

/* As setinhas nativas saem: com "−" e "+" do lado, elas são um terceiro par de
   controles para a mesma coisa, e num campo estreito comem a largura do
   número. */
:is(html[data-theme]) .number-stepper input[type="number"] {
  appearance: textfield;
}

:is(html[data-theme]) .number-stepper input[type="number"]::-webkit-inner-spin-button,
:is(html[data-theme]) .number-stepper input[type="number"]::-webkit-outer-spin-button {
  appearance: none;
  margin: 0;
}

:is(html[data-theme]) .number-stepper__button {
  height: var(--control-height);
  padding: 0;
  width: var(--control-height);
}
/* <<< css/v2/number-stepper.css <<< */

/* >>> css/v2/efetivo-row.css >>> */
/* Linha de efetivo — unidade, cargo e quantidade.
 * Depende de `v2/tokens.css`.
 *
 * Mesma anatomia da linha de destino: o "+" que insere uma linha abaixo, os
 * campos no meio e o "×" na ponta. O que muda é o miolo — lá são dois campos e
 * aqui são três, e um deles é estreito por natureza.
 *
 * Os botões ficam alinhados pela BASE da faixa dos campos, e não pelo centro da
 * linha: os campos têm rótulo em cima, e centralizado o "+" flutuava na altura
 * do rótulo, longe do controle que ele acompanha.
 */

:is(html[data-theme]) .efetivo-row {
  align-items: end;
  display: grid;
  gap: var(--gap);
  grid-template-columns: var(--control-height) minmax(0, 1fr) var(--control-height);
  min-width: 0;
}

/* Unidade e cargo repartem o que sobra; a quantidade recebe o suficiente para o
   stepper e não mais — é um número de um ou dois dígitos, e em 1fr ela ficava
   tão larga quanto o nome de uma unidade. */
:is(html[data-theme]) .efetivo-row__fields {
  display: grid;
  gap: var(--gap);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 148px;
  min-width: 0;
}

@media (max-width: 720px) {
  :is(html[data-theme]) .efetivo-row__fields {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Com uma linha só, o "×" nasce oculto — não há o que remover. A grade também
   perde a terceira coluna e o gap correspondente; esconder somente o botão
   deixava um vão invisível à direita dos campos. */
:is(html[data-theme]) .efetivo-row--single {
  grid-template-columns: var(--control-height) minmax(0, 1fr);
}

:is(html[data-theme]) .efetivo-row--single .efetivo-row__remove {
  display: none;
}

:is(html[data-theme]) .efetivo-row__add[hidden],
:is(html[data-theme]) .efetivo-row__remove[hidden] {
  display: none;
}

/* As linhas seguintes repetem os rótulos no HTML para manter cada controle
   acessível, mas só a primeira linha os mostra. O motor atualiza esta classe
   depois de inserir ou remover linhas, inclusive quando a primeira é apagada. */
:is(html[data-theme]) .efetivo-row--without-labels .field__label {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* Os dois botões são o `button` do sistema na forma `--icon`. Só o que é
   POSIÇÃO fica aqui: o desenho é de `v2/button.css`, e uma segunda definição é
   como o sistema antigo chegou a dezoito variantes de botão. */
:is(html[data-theme]) .efetivo-row__add,
:is(html[data-theme]) .efetivo-row__remove {
  align-self: end;
  margin-bottom: 0;
}

:is(html[data-theme]) .efetivo-rows {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}
/* <<< css/v2/efetivo-row.css <<< */

/* >>> css/v2/live-list.css >>> */
/* Lista viva — o que a escolha de cima produz, contado e listado.
 * Depende de `v2/tokens.css`.
 *
 * A coluna é um bloco de conteúdo dentro do bloco de formulário, então ela
 * pinta com o degrau seguinte da escada (`--surface-rail` dentro do
 * `--surface-field` do bloco) e usa o raio de campo, não o de painel: quem está
 * dentro nunca tem o arredondamento de quem está fora.
 */

:is(html[data-theme]) .live-list {
  background: var(--surface-rail);
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  max-height: 190px;
  min-width: 0;
  overflow-y: auto;
  padding: var(--gap);
  /* A mesma barra fina dos pickers, listboxes e áreas de texto do V2. */
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

/* Título e contagem na mesma linha, nas pontas: o número é a resposta curta, e
   ele fica onde o olho já para ao terminar de ler o título. */
:is(html[data-theme]) .live-list__head {
  align-items: center;
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: minmax(0, 1fr) auto;
  min-height: 24px;
  min-width: 0;
}

:is(html[data-theme]) .live-list__head[hidden] {
  display: none;
}

:is(html[data-theme]) .live-list__title {
  align-items: center;
  color: var(--text-strong);
  display: flex;
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  line-height: 1.2;
  min-height: 24px;
}

:is(html[data-theme]) .live-list__title[hidden] {
  display: none;
}

:is(html[data-theme]) .live-list__count {
  align-items: center;
  display: flex;
  min-height: 24px;
}

:is(html[data-theme]) .live-list__count[hidden] {
  display: none;
}

:is(html[data-theme]) .live-list__items {
  display: grid;
  gap: var(--gap-tight);
  list-style: none;
  margin: 0;
  min-width: 0;
  padding: 0;
}

/* Cada item é uma caixa própria, e não uma linha de lista com marcador: são
   frases inteiras — a meta de uma atividade —, e com marcador a segunda linha
   de cada uma começava desalinhada da primeira. */
:is(html[data-theme]) .live-list__item {
  background: var(--surface-field);
  border-radius: var(--radius-field);
  min-width: 0;
  padding: var(--gap-tight) var(--gap);
}

:is(html[data-theme]) .live-list__text {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  overflow-wrap: anywhere;
}

/* O vazio é duas linhas: o estado, e o que fazer a respeito. */
:is(html[data-theme]) .live-list__empty {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .live-list__empty strong {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .live-list__empty span {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
}

/* Duas colunas, ou uma. É o par metas/recursos do plano de trabalho: são listas
   irmãs, e empilhadas em tela larga a segunda só aparece depois de rolar. */
:is(html[data-theme]) .live-list-pair {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-width: 0;
}

@media (max-width: 720px) {
  :is(html[data-theme]) .live-list-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* <<< css/v2/live-list.css <<< */

/* >>> css/v2/font-try.css >>> */
/* Provador de tipografia do UI Lab — par de
 * `templates/core/main_preview/tipografia.html`.
 *
 * As pilhas moram AQUI, e não em `style=` no template: o contrato
 * `test_dark_redesign` proíbe estilo inline, e com razão — foi assim que o
 * sistema antigo acumulou desenho espalhado por dezenas de templates. O JS do
 * provador lê a pilha da amostra por `getComputedStyle`, e por isso não precisa
 * conhecer nenhuma delas.
 */

:is(html[data-theme]) .font-try__sample {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .font-try__title {
  color: var(--text-strong);
  font-size: 1.05rem;
  font-weight: var(--weight-strong);
  margin: 0;
}

:is(html[data-theme]) .font-try__meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0 0 var(--gap);
}

:is(html[data-theme]) .font-try__value {
  color: var(--text-strong);
  font-size: 2rem;
  font-weight: var(--fact-weight, 800);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* Inter Variable (atual) */
:is(html[data-theme]) .font-try--inter {
  font-family: "Inter Variable", Inter, "Segoe UI", system-ui, sans-serif;
}

/* Segoe UI Variable */
:is(html[data-theme]) .font-try--segoe {
  font-family: "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
}

/* Bahnschrift (DIN) */
:is(html[data-theme]) .font-try--bahnschrift {
  font-family: Bahnschrift, "DIN Next", "Segoe UI", sans-serif;
}

/* Bahnschrift SemiBold */
:is(html[data-theme]) .font-try--bahnschrift-semibold {
  font-family: "Bahnschrift SemiBold", "Bahnschrift SemiBold Condensed", Bahnschrift, "Segoe UI", sans-serif;
}

/* Bahnschrift Condensed */
:is(html[data-theme]) .font-try--bahnschrift-condensed {
  font-family: "Bahnschrift Condensed", "Bahnschrift SemiCondensed", Bahnschrift, "Segoe UI", sans-serif;
}

/* Bahnschrift SemiCondensed */
:is(html[data-theme]) .font-try--bahnschrift-semicondensed {
  font-family: "Bahnschrift SemiCondensed", Bahnschrift, "Segoe UI", sans-serif;
}

/* Franklin Gothic */
:is(html[data-theme]) .font-try--franklin {
  font-family: "Franklin Gothic Medium", "Franklin Gothic", "Segoe UI", sans-serif;
}

/* Corbel */
:is(html[data-theme]) .font-try--corbel {
  font-family: Corbel, "Segoe UI", sans-serif;
}

/* Candara */
:is(html[data-theme]) .font-try--candara {
  font-family: Candara, "Segoe UI", sans-serif;
}

/* Trebuchet MS */
:is(html[data-theme]) .font-try--trebuchet {
  font-family: "Trebuchet MS", "Segoe UI", sans-serif;
}

/* Cambria (serifada) */
:is(html[data-theme]) .font-try--cambria {
  font-family: Cambria, Georgia, serif;
}

/* Georgia (serifada) */
:is(html[data-theme]) .font-try--georgia {
  font-family: Georgia, Cambria, serif;
}
/* <<< css/v2/font-try.css <<< */

/* >>> css/v2/download-picker.css >>> */
/* Seletor de download — o miolo do modal que escolhe QUAIS documentos baixar.
 * Depende de `v2/tokens.css`. Par de `templates/cotton/v2/download_picker.html`.
 *
 * Reusa o vocabulário que a lista de pessoas e os cartões de escolha já
 * firmaram: a linha marcável é a mesma peça do `os-model-card` (fundo no degrau
 * de cima, marca à esquerda, título forte e explicação miúda), e a fila abaixo
 * é a mesma linha em versão de estado. Nada aqui inventa forma nova.
 */

:is(html[data-theme]) .download-picker {
  display: grid;
  gap: var(--gap);
  min-width: 0;
}

:is(html[data-theme]) .download-picker__hint {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  margin: 0;
}

/* A lista tem teto: com dez servidores o modal passava da altura da tela e o
   rodapé com o botão "Baixar" saía de vista — o botão que a caixa existe para
   oferecer. */
:is(html[data-theme]) .download-picker__list {
  max-height: 11.7rem;
  overflow-y: auto;
  /* A barra é a MESMA das outras caixas roláveis do v2 (listbox e picker): fina e
     na cor do texto secundário. Sem estas duas linhas o navegador desenha a barra
     do sistema — larga, clara e com seta, que no tema escuro fica um risco branco
     colado na lista. */
  scrollbar-color: var(--text-muted) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

:is(html[data-theme]) .download-picker__list,
:is(html[data-theme]) .download-picker__queue {
  display: grid;
  gap: var(--gap-tight);
  list-style: none;
  margin: 0;
  min-width: 0;
  padding: 0;
}

/* O `display` acima vence o `[hidden]`, que é regra de agente do usuário: sem
   este par a fila aparece vazia antes de existir fila. */
:is(html[data-theme]) .download-picker__queue[hidden] {
  display: none;
}

/* A marca fica à DIREITA, e o quadradinho do navegador sai de cena. O check
   nativo é pequeno, muda de forma entre sistemas e não aceita cor de maneira
   confiável; e à esquerda ele disputava a entrada da linha com o nome do
   documento, que é o que se lê primeiro. À direita, a coluna de marcas se lê de
   cima a baixo e diz de relance o que vai ser baixado. */
:is(html[data-theme]) .download-picker__check {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  cursor: pointer;
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: minmax(0, 1fr) auto;
  min-width: 0;
  padding: var(--gap-tight) var(--gap);
}

/* O `<input>` continua no fluxo do teclado — `display: none` o tiraria da ordem
   do Tab e a lista deixaria de ser marcável sem mouse. */
:is(html[data-theme]) .download-picker__check input[type="checkbox"] {
  height: 0;
  opacity: 0;
  position: absolute;
  width: 0;
}

/* O "V" é DESENHADO com duas bordas e um giro de 45°: não depende de fonte nem
   de emoji, e herda a cor do tema. A caixa dele existe sempre, marcada ou não —
   é o que impede a linha de pular de largura ao ser marcada. */
:is(html[data-theme]) .download-picker__check::after {
  block-size: 0.6em;
  border-bottom: 2px solid currentColor;
  border-right: 2px solid currentColor;
  color: var(--accent);
  content: "";
  grid-column: 2;
  inline-size: 0.35em;
  /* Menor e afastado da borda: o "V" é confirmação, não título — encostado no
     canto ele competia com o nome do documento pela atenção. A margem lateral
     entra no `::after` e não no recuo do rótulo, senão a linha inteira se
     desloca e a coluna de nomes deixa de bater entre uma e outra. */
  margin-inline-end: var(--gap-tight);
  opacity: 0;
  rotate: 45deg;
  transition: opacity var(--ease);
  translate: 0 -0.1em;
}

:is(html[data-theme]) .download-picker__check:has(input:checked)::after {
  opacity: 1;
}

/* Anel de foco no RÓTULO, porque o input é invisível: sem isto quem navega por
   teclado percorre a lista sem ver onde está. */
:is(html[data-theme]) .download-picker__check:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

:is(html[data-theme]) .download-picker__check:has(input:checked) {
  background: var(--surface-selected);
  box-shadow: inset 3px 0 0 0 var(--accent);
}

:is(html[data-theme]) .download-picker__item[data-disabled="true"] {
  opacity: 0.48;
}

:is(html[data-theme]) .download-picker__item[data-disabled="true"] .download-picker__check {
  cursor: not-allowed;
}

:is(html[data-theme]) .download-picker__item-copy {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .download-picker__item-title {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .download-picker__item-meta {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
}

:is(html[data-theme]) .download-picker__options {
  /* Os dois grupos na MESMA LINHA. Eles já foram empilhados em faixas de largura
     cheia, e o problema de então (pílulas de larguras diferentes, "PDF" contra
     "Arquivos separados") não vinha do lado a lado: vinha de pílula esticada.
     Agora cada toggle tem a largura do próprio texto, no tamanho pequeno, e os
     dois ajustes cabem numa linha — a lista do que baixar volta a ser o que pesa. */
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

/* Uma régua separa a ESCOLHA (o que baixar) do AJUSTE (como baixar). São duas
   perguntas diferentes, e empilhadas sem divisão o modal virava uma coluna de
   coisas soltas do mesmo peso. */
:is(html[data-theme]) .download-picker__options {
  border-top: 1px solid var(--line);
  padding-top: var(--gap);
}

/* `fieldset` chega com borda, margem e recuo do navegador — zerar é o que faz o
   grupo parecer parte do modal, e não uma caixa dentro dele. O rótulo fica ao LADO
   do toggle, na mesma linha: com ele em cima, dois grupos lado a lado viravam
   quatro linhas de texto em duas colunas. */
:is(html[data-theme]) .download-picker__option {
  align-items: center;
  border: 0;
  display: flex;
  gap: var(--gap-tight);
  margin: 0;
  min-width: 0;
  padding: 0;
}

:is(html[data-theme]) .download-picker__option[hidden] {
  display: none;
}

:is(html[data-theme]) .download-picker__legend {
  color: var(--text-muted);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.06em;
  padding: 0;
  text-transform: uppercase;
}

/* A pílula É o `toggle__item` do sistema (`v2/toggle.css`), e não uma cópia dos
   valores dele: as regras de lá foram estendidas para cobrir o `<label>` com rádio
   dentro. Aqui fica só o que é próprio deste uso. */
/* O rádio nativo sai de vista mas continua no fluxo do teclado. */
:is(html[data-theme]) .download-picker__radio input[type="radio"] {
  height: 0;
  opacity: 0;
  position: absolute;
  width: 0;
}

:is(html[data-theme]) .download-picker__radio:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---- a fila ---------------------------------------------------------------
   Cada documento é gerado no servidor, um de cada vez. O estado fica à vista
   porque o segundo arquivo chega depois — sem a linha, ele parece um download
   que ninguém pediu. */

:is(html[data-theme]) .download-picker__queue-item {
  align-items: center;
  background: var(--surface-contrast, var(--surface-field));
  border-radius: var(--radius-field);
  display: flex;
  gap: var(--gap-tight);
  justify-content: space-between;
  min-width: 0;
  padding: var(--gap-tight) var(--gap);
}

:is(html[data-theme]) .download-picker__queue-name {
  color: var(--text-strong);
  font-size: var(--text-size-base);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .download-picker__queue-state {
  color: var(--text-muted);
  flex: none;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .download-picker__queue-item[data-state="running"] .download-picker__queue-state {
  color: var(--accent);
}

:is(html[data-theme]) .download-picker__queue-item[data-state="done"] .download-picker__queue-state {
  color: var(--status-done);
}

:is(html[data-theme]) .download-picker__queue-item[data-state="error"] .download-picker__queue-state {
  color: var(--status-late);
}

/* O erro é o `.alert` global; aqui fica só o guarda do `[hidden]`, porque o
   alerta declara `display` e isso vence a regra de agente do usuário — sem o par
   ele apareceria vazio dentro do modal desde a abertura. A folha do picker não
   redesenha o alerta: foi o que evitou uma segunda aparência para "deu erro". */
:is(html[data-theme]) .download-picker .alert[hidden] {
  display: none;
}

/* O gatilho e o diálogo moram no mesmo envoltório para o JS achar um pelo
   outro; ele não deve ocupar espaço nem quebrar a fileira de ações. */
:is(html[data-theme]) .download-picker-mount {
  display: contents;
}
/* <<< css/v2/download-picker.css <<< */

/* >>> css/v2/tooltip.css >>> */
/* Tooltip global — a caixinha que `js/components/icon-tooltips.js` cria no
 * `<body>` e posiciona à mão. Depende de `v2/tokens.css`.
 *
 * POR QUE ISTO MORA AQUI. O desenho existia em `actions/buttons.css`, que passa
 * pelo podador de perfis: numa página v2 sobrou só a regra que DESLIGA o
 * tooltip de `::after`, e a que estiliza o elemento real foi podada. O
 * resultado é o pior tipo de falha — o `<div>` fica com `position: static`,
 * cai no fim do corpo e o texto "Visualizar e baixar" aparece solto embaixo da
 * página, empurrando a altura e fazendo nascer uma barra de rolagem.
 *
 * O `ui.bundle.css` não é podado. Enquanto o motor JS for global, o desenho
 * dele precisa vir de um lugar que chegue a toda tela.
 */

:is(html[data-theme]) .global-tooltip {
  background: var(--surface-field);
  border: 1px solid var(--line);
  border-radius: 7px;
  box-shadow: 0 12px 28px rgb(5 22 38 / 0.24);
  color: var(--text-strong);
  font-size: 11px;
  font-weight: var(--weight-strong);
  line-height: 1.2;
  max-width: min(260px, calc(100vw - 16px));
  opacity: 0;
  padding: 5px 9px;
  pointer-events: none;
  position: fixed;
  text-align: center;
  transform: translateY(4px);
  transition: opacity var(--ease), transform var(--ease);
  white-space: nowrap;
  /* Acima do menu de ações: os dois convivem quando o cursor passa pelo gatilho
     com o menu aberto. */
  z-index: calc(var(--z-modal, 1000) + 20);
}

:is(html[data-theme="dark"]) .global-tooltip {
  box-shadow: 0 12px 28px rgb(0 0 0 / 0.45);
}

:is(html[data-theme]) .global-tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}

:is(html[data-theme]) .global-tooltip.global-tooltip--accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}
/* <<< css/v2/tooltip.css <<< */

/* >>> css/v2/sidebar.css >>> */
/* Sidebar — a barra de navegação do shell, no vocabulário v2.
 *
 * Depende de `v2/tokens.css`. Substitui `layout/sidebar.css`, que resolvia a
 * barra com 28 tokens `--sidebar-*` próprios e um gradiente por tema: dois
 * sistemas de cor para um componente só, e nenhum deles compartilhado com o
 * resto da tela.
 *
 * ## A superfície é `--surface-brand`
 *
 * A barra e o `c-v2.header` são a MESMA faixa de identidade do sistema — a
 * moldura azul-marinho que emoldura o conteúdo em cima e à esquerda. Por isso
 * dividem o único token de marca que existe, em vez de cada um pintar o seu.
 * Consequência direta: nada aqui consulta `html[data-theme]`. O contraste do
 * escuro vem de `--surface-brand` mudar de valor, não de uma folha de exceção.
 *
 * ## Sobre a família de classes
 *
 * Os nomes `.sidebar-*` continuam os mesmos. Não é inércia: `sidebar.js` os usa
 * como seletor (`.sidebar-item--collapsible`, `.sidebar-accordion`,
 * `.sidebar-drawer-close`), `layout/app-shell.css` desenha a gaveta móvel sobre
 * eles e três testes os citam. Renomear exigiria mover template + CSS + JS +
 * testes no mesmo PR (`AGENTS.md` §3.2) para não mudar um pixel — custo alto,
 * ganho nenhum. O que muda aqui é de onde vem a COR e como o item se desenha.
 */

/* ---- casca ---------------------------------------------------------------- */

:is(html[data-theme]) .sidebar {
  background: var(--surface-brand);
  border-right: 1px solid var(--line-on-brand);
  box-sizing: border-box;
  color: var(--text-on-brand);
  display: flex;
  flex-direction: column;
  /* Altura presa na viewport, transbordo cortado: quem rola é a lista por
     dentro (`.sidebar-nav`), não a página. */
  height: 100vh;
  max-height: 100vh;
  min-height: 100vh;
  min-width: 0;
  overflow: hidden;
  position: sticky;
  top: 0;
  width: 100%;
  z-index: var(--z-sidebar);
}

:is(html[data-theme]) .sidebar-header {
  /* A linha do topo: marca à esquerda, fechar da gaveta à direita. As três
     primeiras declarações vieram de `layout/app-shell.css` em 2026-08-20 — sem
     elas o botão de fechar cai embaixo da marca no celular. */
  align-items: center;
  border-bottom: 1px solid var(--line-on-brand);
  display: flex;
  justify-content: space-between;
  padding: var(--pad-rail);
}

:is(html[data-theme]) .sidebar-brand {
  align-items: center;
  color: var(--text-on-brand);
  display: inline-flex;
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  gap: var(--gap-tight);
  line-height: 1.2;
  min-width: 0;
  text-decoration: none;
}

/* O selo é a única peça com o accent CHEIO na barra: no escuro ele é dourado e
   o texto sobre ele precisa ser escuro — é para isso que `--text-on-accent`
   existe. Escrever `#fff` aqui, como fazia a folha antiga, deixava o "CV"
   ilegível assim que o accent virou dourado. */
:is(html[data-theme]) .sidebar-brand-badge {
  align-items: center;
  background: var(--accent);
  border-radius: var(--radius-field);
  color: var(--text-on-accent);
  display: inline-flex;
  flex-shrink: 0;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  height: 32px;
  justify-content: center;
  width: 32px;
}

:is(html[data-theme]) .sidebar-nav {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  padding: var(--gap-tight);
}

:is(html[data-theme]) .sidebar-item {
  min-width: 0;
}

/* ---- item de módulo -------------------------------------------------------
 *
 * O item em repouso NÃO tem caixa nem contorno. A folha antiga dava a cada um
 * fundo translúcido e borda de 1px, e a barra virava uma pilha de seis caixas
 * onde só uma importa. Aqui o repouso é texto sobre a marca; a caixa aparece no
 * hover e no item escolhido, que é onde ela carrega significado.
 */

:is(html[data-theme]) .sidebar-link {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-field);
  box-sizing: border-box;
  color: var(--text-on-brand);
  display: flex;
  font-size: var(--text-size-base);
  font-weight: var(--weight-normal);
  gap: var(--gap-tight);
  min-height: 38px;
  min-width: 0;
  padding: 0 var(--gap-tight);
  text-align: left;
  text-decoration: none;
  transition: background-color var(--ease), color var(--ease);
  width: 100%;
}

/* Em repouso o rótulo é levemente recuado do branco puro: o item escolhido
   precisa de para onde subir, e no escuro `--text-on-brand` já é o branco. */
:is(html[data-theme]) .sidebar-link--module,
:is(html[data-theme]) .sidebar-link--cadastros {
  color: color-mix(in srgb, var(--text-on-brand) 78%, transparent);
}

:is(html[data-theme]) .sidebar-module-expand {
  cursor: pointer;
  /* `font-family`/`font-weight`, e não `font: inherit`: o atalho zera também o
     `font-size` declarado em `.sidebar-link`, e o botão de módulo ficava 16px
     ao lado de um irmão `<a>` de 14px. */
  font-family: inherit;
  font-weight: inherit;
  justify-content: space-between;
}

:is(html[data-theme]) .sidebar-item-main {
  align-items: center;
  display: inline-flex;
  flex: 1;
  gap: var(--gap-tight);
  min-width: 0;
}

:is(html[data-theme]) .sidebar-item-text,
:is(html[data-theme]) .sidebar-link-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .sidebar-item-icon {
  align-items: center;
  color: inherit;
  display: inline-flex;
  flex-shrink: 0;
  height: 18px;
  justify-content: center;
  width: 18px;
}

:is(html[data-theme]) .sidebar-item-icon svg {
  height: 18px;
  width: 18px;
}

:is(html[data-theme]) .sidebar-module-expand__chevron {
  align-items: center;
  display: inline-flex;
  flex-shrink: 0;
  opacity: 0.7;
  transform: rotate(-90deg);
  transition: transform var(--ease);
}

:is(html[data-theme]) .sidebar-module-expand__chevron svg {
  height: 14px;
  width: 14px;
}

:is(html[data-theme]) .sidebar-item--collapsible.is-open > .sidebar-row--top .sidebar-module-expand__chevron {
  transform: rotate(0deg);
}

:is(html[data-theme]) .sidebar-row--top {
  display: flex;
  min-width: 0;
}

/* ---- hover e escolhido ---------------------------------------------------- */

:is(html[data-theme]) .sidebar-link--module:hover,
:is(html[data-theme]) .sidebar-link--cadastros:hover {
  background: var(--surface-on-brand);
  color: var(--text-on-brand);
}

/* O escolhido são TRÊS sinais somados, e cada um cobre o buraco do outro: a
   superfície um degrau acima, o filete no accent e o peso do rótulo.
 *
   O fundo NÃO é accent diluído, embora essa seja a linguagem do sistema nas
   listas. Sobre a faixa de marca ele não funciona no tema claro: `--accent` ali
   é `#004a90` e a faixa é `#155b9a` — azul escuro sobre azul médio, que lê como
   "mais escuro", não como "escolhido". Foi assim no primeiro corte, e no print
   do tema claro o item ativo simplesmente sumia. O accent fica no filete, onde
   ele marca a borda sem precisar vencer o fundo. */
:is(html[data-theme]) .sidebar-link.is-active {
  background: var(--surface-selected-on-brand);
  box-shadow: inset 3px 0 0 var(--accent);
  color: var(--text-on-brand);
  font-weight: var(--weight-strong);
}

:is(html[data-theme]) .sidebar-link[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.45;
}

:is(html[data-theme]) .sidebar-link:focus-visible {
  outline: 2px solid var(--focus-ring-on-brand);
  outline-offset: -2px;
}

/* ---- submenu -------------------------------------------------------------- */

:is(html[data-theme]) .sidebar-accordion {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--ease);
}

/* `[hidden]` PRECISA ser repetido aqui. A regra do agente do usuário e a de
   `layout/app-shell.css` (`.sidebar-accordion[hidden]`, 0-2-0) perdem para o
   seletor acima, que é 0-2-1 e chega depois no bundle. Sem esta linha o grupo
   fechado continua sendo uma grade de altura zero — invisível, mas com os links
   dentro ainda alcançáveis por Tab. */
:is(html[data-theme]) .sidebar-accordion[hidden] {
  display: none;
}

:is(html[data-theme]) .sidebar-item--collapsible.is-open > .sidebar-accordion {
  grid-template-rows: 1fr;
}

:is(html[data-theme]) .sidebar-accordion__inner {
  min-height: 0;
  overflow: hidden;
}

/* O trilho vertical substitui o recuo por indentação: sem ele, sete filhos
   alinhados 10px à direita do pai leem como uma segunda lista, não como parte
   dele. */
:is(html[data-theme]) .sidebar-panel {
  border-left: 1px solid var(--line-on-brand);
  display: flex;
  flex-direction: column;
  margin: 2px 0 var(--gap-tight) 18px;
  padding-left: var(--gap-tight);
}

:is(html[data-theme]) .sidebar-link--cadastros {
  min-height: 32px;
}

:is(html[data-theme]) .sidebar-link--nested {
  padding-left: var(--gap-loose);
}

/* ---- rodapé --------------------------------------------------------------- */

:is(html[data-theme]) .sidebar-footer {
  border-top: 1px solid var(--line-on-brand);
  display: grid;
  gap: var(--gap-tight);
  padding: var(--gap-tight);
}

/* A conta é o único bloco da barra que sobe um degrau de superfície: ele agrupa
   dado (quem está conectado) em vez de navegação, e a caixa é o que o separa da
   lista sem precisar de mais uma linha divisória. */
:is(html[data-theme]) .sidebar-account {
  background: var(--surface-on-brand);
  border-radius: var(--radius-field);
  display: grid;
  gap: var(--gap-tight);
  padding: var(--gap-tight);
}

:is(html[data-theme]) .sidebar-account__identity {
  display: grid;
  gap: 2px;
  min-width: 0;
}

:is(html[data-theme]) .sidebar-account__label {
  color: var(--text-muted-on-brand);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:is(html[data-theme]) .sidebar-account__name {
  color: var(--text-on-brand);
  font-size: var(--text-size-base);
  font-weight: var(--weight-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:is(html[data-theme]) .sidebar-account__area {
  align-self: start;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: var(--radius-pill);
  color: var(--text-on-brand);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  padding: 2px 8px;
}

:is(html[data-theme]) .sidebar-account__actions {
  display: flex;
  gap: var(--gap-tight);
}

:is(html[data-theme]) .sidebar-account__actions > * {
  flex: 1;
}

:is(html[data-theme]) .sidebar-logout-form {
  display: flex;
  flex: 1;
}

:is(html[data-theme]) .sidebar-logout-form .button {
  width: 100%;
}

/* Os dois botões do rodapé são `c-v2.button` de verdade, mas vivem sobre a
   marca, onde `--surface-contrast` não vale — o token aponta para a escada
   page/rail/field e ali eles sumiriam. Esta é a única regra da folha que
   repinta um componente, e por isso é a mais específica que ela tem. */
:is(html[data-theme]) .sidebar-footer .button--secondary {
  background: var(--surface-on-brand);
  border-color: var(--line-on-brand);
  color: var(--text-on-brand);
  min-height: var(--control-height-sm);
}

:is(html[data-theme]) .sidebar-footer .button--secondary:hover {
  background: var(--surface-selected-on-brand);
}

/* ---- seletor de tema ------------------------------------------------------ */

:is(html[data-theme]) .sidebar-theme {
  display: grid;
  gap: var(--gap-tight);
}

:is(html[data-theme]) .sidebar-theme__label {
  color: var(--text-muted-on-brand);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:is(html[data-theme]) .app-theme-grid {
  display: grid;
  gap: var(--gap-tight);
  grid-template-columns: 1fr 1fr;
}

:is(html[data-theme]) .app-theme-grid__btn {
  background: var(--surface-on-brand);
  border: 1px solid var(--line-on-brand);
  border-radius: var(--radius-field);
  color: var(--text-on-brand);
  cursor: pointer;
  display: grid;
  font: inherit;
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-strong);
  gap: 2px;
  padding: var(--gap-tight);
  text-align: left;
  transition: background-color var(--ease), border-color var(--ease);
}

:is(html[data-theme]) .app-theme-grid__btn small {
  color: var(--text-muted-on-brand);
  font-size: var(--text-size-eyebrow);
  font-weight: var(--weight-normal);
}

:is(html[data-theme]) .app-theme-grid__btn:hover {
  background: var(--surface-selected-on-brand);
}

:is(html[data-theme]) .app-theme-grid__btn[aria-checked="true"],
:is(html[data-theme]) .app-theme-grid__btn[aria-pressed="true"] {
  background: var(--surface-selected-on-brand);
  border-color: var(--accent);
}

:is(html[data-theme]) .app-theme-grid__btn:focus-visible {
  outline: 2px solid var(--focus-ring-on-brand);
  outline-offset: 2px;
}

/* ---- gaveta móvel ---------------------------------------------------------
 *
 * A geometria da gaveta (posição fixa, translado, scrim) continua em
 * `layout/app-shell.css`, que é onde o SHELL mora — a barra só empresta o nome
 * da classe. Aqui fica apenas a pintura dos dois controles que só existem no
 * modo gaveta, para não deixar cor solta no arquivo de layout.
 */

:is(html[data-theme]) .sidebar-drawer-close {
  background: transparent;
  border: 0;
  border-radius: var(--radius-field);
  color: var(--text-on-brand);
}

:is(html[data-theme]) .sidebar-drawer-close:hover {
  background: var(--surface-on-brand);
}

/* A geometria da gaveta mora em `layout/app-shell.css`, mas TRÊS declarações
   dela precisam ser repetidas aqui: `position`, `height` e `max-height`.
   Aquele arquivo as escreve como `.sidebar` (0-1-0) e chega ANTES no bundle;
   a regra de casca desta folha é 0-2-1 e vence, inclusive dentro da media
   query — media query não soma especificidade.
 *
   Sem este bloco a barra fica `sticky` no celular: a gaveta deixa de flutuar,
   volta ao fluxo com 100vh e empurra o conteúdo da página para fora da tela.
   A folha antiga não tinha o problema porque também era 0-1-0, e ali quem
   vinha depois ganhava. */
@media (max-width: 840px) {
  :is(html[data-theme]) .sidebar {
    /* `dvh` e não `vh`: com a barra de endereço do navegador móvel visível, o
       `vh` conta a viewport inteira e o pé da gaveta fica embaixo dela. */
    height: 100dvh;
    max-height: 100dvh;
    min-height: 0;
    position: fixed;
  }
}

@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .sidebar-accordion,
  :is(html[data-theme]) .sidebar-link,
  :is(html[data-theme]) .sidebar-module-expand__chevron {
    transition: none;
  }
}

/* ---- a gaveta (abaixo de 840px) -------------------------------------------
 *
 * Veio de `layout/app-shell.css` em 2026-08-20, quando a pasta `layout/` foi
 * extinta. É comportamento da BARRA, e não da casca: fora da tela por padrão,
 * entra deslizando quando `body` recebe `has-sidebar-open` — a classe que
 * `js/components/sidebar.js` acende.
 *
 * O fundo escurecido (`sidebar-scrim`) e o fechar (`sidebar-drawer-close`)
 * nascem escondidos em `v2/shell.css`; aqui eles aparecem.
 */

:is(html[data-theme]) .sidebar-accordion[hidden] {
  display: none;
}

@media (max-width: 840px) {
  :is(html[data-theme]) body.has-sidebar-open {
    overflow: hidden;
  }

  :is(html[data-theme]) .sidebar {
    height: 100dvh;
    left: 0;
    max-height: 100dvh;
    max-width: min(88vw, 320px);
    position: fixed;
    top: 0;
    transform: translateX(-105%);
    transition: transform 180ms cubic-bezier(.2, .8, .2, 1);
    width: 100%;
    z-index: var(--z-sidebar, 20);
  }

  :is(html[data-theme]) body.has-sidebar-open .sidebar {
    transform: translateX(0);
  }

  :is(html[data-theme]) .sidebar-scrim {
    background: rgba(2, 9, 16, 0.7);
    border: 0;
    cursor: pointer;
    display: block;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    position: fixed;
    transition: opacity 180ms ease;
    z-index: calc(var(--z-sidebar, 20) - 1);
  }

  :is(html[data-theme]) body.has-sidebar-open .sidebar-scrim {
    opacity: 1;
    pointer-events: auto;
  }

  :is(html[data-theme]) .sidebar-drawer-close {
    display: inline-flex;
    flex: 0 0 auto;
    font-size: 1.55rem;
  }

  :is(html[data-theme]) .sidebar-nav {
    display: flex;
    max-height: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  :is(html[data-theme]) .sidebar,
  :is(html[data-theme]) .sidebar-scrim {
    transition: none;
  }
}


/* ---- vindas das folhas de tema, em 2026-08-20 ------------------------------
 *
 * O seletor de tema da barra lateral e a gaveta do celular eram desenhados em
 * `theme-shared-components.css`/`theme-dark-components.css`. São CASCA, e a
 * casca do v2 mora aqui — enquanto ficaram lá, toda tela migrada carregava a
 * folha de tema por causa da barra.
 *
 * O texto veio intacto; elas entram no fim porque no shell também vinham
 * depois da folha da barra.
 */

@media (max-width: 840px) {
html[data-theme] .sidebar {
    height: 100dvh;
    max-height: 100dvh;
    position: fixed;
  }
}

@media (max-width: 600px) {
html[data-theme] .app-theme-grid {
    grid-template-columns: 1fr;
  }

html[data-theme] .app-theme-grid__btn {
    min-height: 36px;
    padding: 5px 6px;
  }

html[data-theme] .app-theme-grid__btn small {
    display: none;
  }
}
/* <<< css/v2/sidebar.css <<< */

/* >>> css/v2/surface.css >>> */
/* Superfícies — o modificador que o chamador escolhe, via `surface="rail"` ou
 * `surface="field"`.
 *
 * Esta folha é a ÚLTIMA do bundle de propósito. Um modificador precisa vencer o
 * padrão do componente, e ele empata em especificidade com ele — quem decide é
 * a ordem. Enquanto essas regras moraram em `base.css`, que carrega antes, o
 * `--surface-contrast` fixo do `form-block` as sobrescrevia e a alternância
 * parava no primeiro nível.
 *
 * Cada camada declara duas coisas: a própria superfície (`--surface`) e a do
 * degrau vizinho (`--surface-contrast`), que é o que os filhos usam. É isso que
 * faz `page → rail → field → rail → field → …` alternar em qualquer
 * profundidade, sem um quarto token.
 */

/* Cada camada declara duas coisas: a própria superfície (`--surface`) e a do
   degrau vizinho (`--surface-contrast`), que é o que os controles internos usam
   para se destacar sem precisar de borda. */
:is(html[data-theme]) .surface--page {
  --surface: var(--surface-page);
  --surface-contrast: var(--surface-rail);
}

:is(html[data-theme]) .surface--rail {
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
}

:is(html[data-theme]) .surface--field {
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
}

/* A alternância não tem limite de profundidade: `page → rail → field → rail →
   field → …`. Quem determina o degrau é o CHAMADOR, via `surface`; o contêiner
   só o respeita e oferece o oposto aos filhos. Um quarto token de superfície
   resolveria um nível e quebraria no seguinte. */


/* ---- a única borda do sistema -------------------------------------------
 *
 * Só a PRIMEIRA camada depois do `page` tem contorno: o contêiner que se apoia
 * direto no fundo da página. O `:not()` diz exatamente isso — "contêiner que
 * não é descendente de outro contêiner".
 *
 * Dentro dela, nada de linha: a separação entre contêineres aninhados é a
 * alternância de superfície, e quem aninha passa `surface` com o degrau oposto.
 * O card também perdeu a borda própria; a regra é do sistema, não do
 * componente, senão cada folha volta a decidir por conta e o desenho se
 * fragmenta de novo.
 */
:is(html[data-theme])
  :is(.panel, .form-block--v2, .record, .rail):not(
    :is(.panel, .form-block--v2, .record, .rail) *
  ) {
  border: 1px solid var(--line);
}

/* ---- alternância automática por profundidade -----------------------------
 *
 * O contêiner aninhado assume sozinho o degrau oposto ao do pai:
 *
 *     page → rail → field → rail → field
 *
 * Não dá para o CSS "inverter uma variável" — referência circular em custom
 * property é inválida. Mas dá para alternar por PROFUNDIDADE, com seletor
 * descendente. Quatro níveis cobrem qualquer tela real; se um dia faltar, a
 * regra seguinte é uma linha.
 *
 * `surface="…"` continua valendo e vence estas regras, para o caso em que a
 * tela quer quebrar a alternância de propósito.
 *
 * Cada nível declara os DOIS: `--surface`, o degrau do próprio contêiner, e
 * `--surface-contrast`, o degrau que os CONTROLES (campo, select) usam para
 * ficar no oposto dele. Enquanto só o contraste era declarado, `var(--surface)`
 * vinha vazio dentro de qualquer aninhamento e quem dependia dele caía no
 * fallback — foi o que deixou o botão do calendário na mesma cor do campo
 * dentro de um bloco split.
 */

:is(html[data-theme]) :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail) {
  background: var(--surface-field);
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
}

:is(html[data-theme]) :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail) {
  background: var(--surface-rail);
  --surface: var(--surface-rail);
  --surface-contrast: var(--surface-field);
}

:is(html[data-theme]) :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail)
  :is(.panel, .form-block--v2, .record, .rail) {
  background: var(--surface-field);
  --surface: var(--surface-field);
  --surface-contrast: var(--surface-rail);
}

/* NOTA (2026-08-16): aqui existiram dois pinos que tiravam o painel de cartões
   da contagem de degraus, para o cartão assumir `rail` e ganhar contorno. Saíram
   junto com o painel transparente: com o painel pintando de novo, a escada por
   profundidade acima já dá o resultado certo — painel `rail` com a única borda
   do sistema, cartão `field` sem borda, e os blocos dentro dele de volta ao
   `rail`. Menos regra, mesmo desenho. */
/* <<< css/v2/surface.css <<< */
