    /* ============================================================
       giandr — sistema visual (revisão de cor/profundidade 2026-09-13)
       Tipografia pequena, densa, muito aproveitamento horizontal.

       A separação entre blocos é feita por PLANO, não por fio: o chão da
       página (--bg) é um verde-ardósia de meio-tom, e toda superfície de
       trabalho é branca. O card não precisa mais de borda forte para
       existir -- ele é o papel em cima da mesa. (Antes: chão #eef0ef e card
       #fff, 3% de diferença de luminância, com fio de 1px quase invisível;
       era a reclamação "não dá pra ver onde termina um div e começa o outro".)

       O RAIO CODIFICA HIERARQUIA -- não é enfeite uniforme:
         --r       (10px) contêiner que flutua sobre o chão: card, seção, painel
         --r-ctl   (5px)  coisa que se aperta ou onde se digita: botão, input
         --r-chip  (3px)  etiqueta pequena
         0px             célula de DADO (linha de tabela, tile): a grade tem
                         que parecer grade; canto redondo em número atrapalha
                         a leitura em coluna.
       ============================================================ */
    :root {
      /* Cor por CLASSE de droga -- o comprimido da coluna Esquema do painel e do
         atendimento (`esquema_badges`). Virou token em 16/09/2026: a cor vinha
         escrita dentro do Python, fixa, e o azul-marinho #1e40af sobre o papel
         escuro do Plantao/Vidro/Dados era um retangulo quase invisivel com texto
         branco por cima. Estes sao os valores do tema CLARO; tema escuro
         redefine para tinta clara e escreve `--drug-ink` escuro por cima.
         Inserido logo apos `:root {`, nunca procurando a chave de fechamento. */
      --drug-nrti:  #1e40af;
      --drug-nnrti: #166534;
      --drug-insti: #db2777;
      --drug-pi:    #881337;
      --drug-ccr5:  #000000;
      --drug-combo: #7c3aed;
      --drug-ink:   #ffffff;   /* tinta SOBRE o comprimido */
      /* Verde de "esta bom" -- CD4 alto, carga viral sem numero (16/09/2026).
         Token, e nao cor fixa, porque NENHUM verde serve aos nove temas: medido
         contra a superficie de cada um, `#0f7a4a` da 5.38 no tema claro e 3.11
         no vidro, e `#34d399` da 9.00 no vidro e 1.92 no claro. Este e o valor
         do tema CLARO; os quatro escuros sobrescrevem.
         Inserido logo apos `:root {`, nunca procurando a chave de fechamento --
         ver o aviso sobre comentarios com chaves no CLAUDE.md. */
      --ok:        #0f7a4a;
      /* superfícies -- do chão para o papel */
      --ink:       #121d1a;   /* quase-preto esverdeado: rail, texto forte */
      --bg:        #ccd8d3;   /* chão da página (meio-tom: é o que faz o card existir) */
      --surface:   #ffffff;   /* papel: toda superfície de trabalho */
      --surface-2: #f7faf9;   /* papel rebaixado (zebra, campo desabilitado) */
      --surface-3: #eaf0ed;   /* prateleira: faixa de cabeçalho, topo de tabela, inset */
      --line:      #b9c8c2;   /* aresta de contêiner -- visível no branco E no chão */
      /* Borda de CAMPO (input/select/textarea). Separada de --line porque campo
         precisa de mais contraste que caixa: a borda e o unico sinal de onde se
         clica para digitar. 3,2:1 no branco -- passa o criterio de elemento nao
         textual, e era 1,6:1 (#c6d1cd) ate 2026-09-13, quando o usuario pediu
         bordas mais faceis de ver em todo o site. */
      --line-ctl:  #84938e;
      --line-2:    #dce5e1;   /* divisória interna */
      --line-3:    #e9efec;   /* divisória de linha (listas densas) */
      /* marca */
      --teal:      #0c7f6c;
      --teal-d:    #0a7260;
      --teal-dd:   #075f50;
      --amber:     #c8911a;
      --red:       #b4453a;
      /* Texto auxiliar. Escurecido de novo em 2026-09-13 a pedido do usuario: a
         escada antiga (#5d6b66 / #6e7c77 / #85938e / #9aa8a3) dava 5,6 / 4,4 / 3,2
         / 2,5 de contraste no branco -- as duas ultimas reprovam em qualquer
         criterio de leitura, e sao justamente os rotulos de 8-9px. A escada nova
         da 8,7 / 7,2 / 5,8 / 5,1 no branco (e >=4,4 ate no --surface-3), entao
         todo tom daqui pode ser usado como TEXTO sobre fundo claro.
         Se precisar de um cinza mais leve, e porque o elemento e borda ou fundo --
         use a familia --line ou --surface, nao um muted novo.
         (Nunca escreva "-- line * -- surface" junto aqui: a sequencia fecha o
         comentario e derruba a declaracao seguinte. Ja aconteceu com --muted.) */
      --muted:     #414e49;
      --muted-2:   #4d5a55;
      --muted-3:   #5b6863;
      --muted-4:   #64716c;
      /* chips / realces */
      --teal-bg:   #dff0ec;  --teal-line:  #b2d8d0;  --teal-ink:  #075f50;
      --amber-bg:  #faf0d3;  --amber-line: #e8d59b;  --amber-ink: #6f5205;
      --red-bg:    #fbe8e6;  --red-line:   #edbdb6;  --red-ink:   #8e2a1f;
      /* fontes */
      --sans: 'IBM Plex Sans', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
      --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
      /* raio (ver bloco acima) / rail */
      --r: 10px;
      --r-ctl: 5px;
      --r-chip: 3px;
      --rail-w: 58px;
      /* Padding lateral do `main`. É token porque não é só do `main`: a faixa
         de índice da Documentação sangra para as bordas com margem NEGATIVA
         deste mesmo valor, e o número precisa bater. Estava escrito `-14px` à
         mão nos dois lugares — quando o tema `contraste` baixou o padding para
         11px no celular, a faixa passou 6px da tela e a página inteira passou a
         arrastar de lado. Tema que mexer no padding mexe no token. */
      --pad-main: 14px;
      /* uma única receita de sombra, só para o que flutua sobre o chão */
      --lift: 0 1px 1px rgba(18,29,26,.04), 0 4px 10px -6px rgba(18,29,26,.22);

      /* aliases de compatibilidade — nomes antigos usados nos <style> dos apps.
         `--cream` continua CLARO de propósito: nos apps ele é fundo de chip /
         hover de lista dentro do card, não o chão da página. */
      --navy: #121d1a;
      --white: #ffffff;
      --cream: #eef3f1;
      --border: rgba(18,29,26,.34);
      --teal-light: #10a189;
    }

    * { box-sizing: border-box; margin: 0; padding: 0; }

    html {
      font-size: 15px;
      /* iOS Safari "text autosizing": em bloco largo o Safari INFLA a fonte por
         conta própria, e por bloco -- era por isso que no iPhone "NOME DA MÃE"
         e "OCUPAÇÃO" (campos que ocupam a linha inteira) saíam bem maiores que
         "CPF" e "PRONTUÁRIO" ao lado. Isto desliga o ajuste sem impedir o zoom
         do usuário. */
      -webkit-text-size-adjust: 100%;
      text-size-adjust: 100%;
    }
    body {
      background: var(--bg);
      font-family: var(--sans);
      font-size: 12px;
      line-height: 1.45;
      color: var(--ink);
      -webkit-font-smoothing: antialiased;
      display: flex;
      align-items: flex-start;
      min-height: 100vh;
    }

    a { color: var(--teal-dd); }

    /* ── "Voltar" do topo das telas internas ──
       Estava COPIADO no <style> de cada template que o usa, e cada cópia
       trazia `color: var(--teal)` -- o teal CLARO, que é a cor de AÇÃO
       (botão, borda de foco), não a de link. Em texto de 0,85rem isso dava
       3,36:1 no `classico` e 3,57:1 no `prontuario`, abaixo do mínimo de
       4,5:1 do AA. Aqui a regra não declara cor nenhuma: herda o `a` acima,
       que é o `--teal-dd` usado por todo link do site e já passa nos nove
       temas. Não reintroduza `color:` nesta regra.

       Os "Voltar" que apenas repetiam um ícone da barra lateral foram
       retirados em 17/09/2026; os que restam levam a lugar que a barra não
       alcança (o histórico de exames, a ficha do paciente). */
    .back {
      font-size: 0.85rem;
      text-decoration: none;
      display: inline-block;
      margin-bottom: 1rem;
    }
    .back:hover { text-decoration: underline; }

    /* ── Rail lateral (substitui a barra de botões superior) ── */
    .rail {
      position: sticky; top: 0;
      flex: none;
      width: var(--rail-w); height: 100vh;
      background: var(--ink);
      display: flex; flex-direction: column; align-items: center;
      gap: 1px;
      padding: 9px 0 8px;
      z-index: 100;
    }
    .rail-logo { margin-bottom: 8px; }
    .rail a, .rail button.rail-link {
      position: relative;
      width: 43px; height: 43px; flex: none;
      display: flex; align-items: center; justify-content: center;
      color: #8b9691;
      background: none; border: none; cursor: pointer;
      transition: color .15s, background .15s;
    }
    .rail a:hover, .rail button.rail-link:hover { color: #d9e2df; background: rgba(255,255,255,.05); }
    .rail a svg, .rail button.rail-link svg { width: 20px; height: 20px; display: block; }
    .rail a.active { color: #eef0ef; background: rgba(255,255,255,.07); }
    .rail a.active::before {
      content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
      width: 2px; background: var(--teal);
    }
    .rail-spacer { flex: 1; }
    .rail-sep { width: 22px; height: 1px; background: rgba(255,255,255,.12); margin: 5px 0; flex: none; }

    /* ── Coluna de conteúdo ── */
    .shell { flex: 1; min-width: 0; max-width: 100%; display: flex; flex-direction: column; min-height: 100vh; }

    /* ── Barra superior unificada (faixa de utilidade + cabeçalho de página) ── */
    .topbar {
      position: sticky; top: 0; z-index: 90;
      background: var(--surface);
    }
    /* A faixa de utilidade (unidade de saúde / conta) fica na PRATELEIRA, e o
       cabeçalho da página no branco: são dois níveis diferentes de informação
       e agora se leem como dois. */
    .topbar-util {
      display: flex; align-items: center; gap: 10px;
      padding: 4px 14px;
      background: var(--surface-3);
      border-bottom: 1px solid var(--line-2);
      font-size: 10px;
    }
    .topbar-util .unit {
      font-family: var(--mono); color: var(--muted-2);
      letter-spacing: .02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .topbar-util .unit a { color: inherit; text-decoration: none; }
    .topbar-util .unit a:hover { color: var(--ink); }

    .topbar-page {
      display: flex; align-items: center; gap: 10px;
      padding: 7px 14px;
      border-bottom: 1px solid var(--line);
      transition: box-shadow .2s ease;
    }
    .topbar.scrolled .topbar-page { box-shadow: 0 10px 20px -16px rgba(18, 29, 26, .65); }
    .topbar-badge {
      flex: none;
      width: 27px; height: 27px; border-radius: var(--r-ctl);
      background: var(--teal-bg); border: 1px solid var(--teal-line);
      color: var(--teal-dd);
      display: flex; align-items: center; justify-content: center;
    }
    .topbar-badge svg { width: 15px; height: 15px; display: block; }
    .topbar-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; line-height: 1.15; }
    .topbar-kicker {
      font-size: 8px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
      color: var(--teal-dd);
    }
    .topbar-title {
      font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -.005em;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .topbar-actions {
      margin-left: auto; flex: none;
      display: flex; flex-wrap: wrap; align-items: center; gap: 5px;
    }

    /* ── Barra de notas de exames (linha extra da topbar, base.html) ──
       O quadradinho no fim da linha abre/fecha; a seta gira para cima quando
       aberto (aria-expanded), sem trocar o SVG. Só tokens que já existem: a
       linha usa a mesma prateleira da faixa de utilidade, e o chip reconhecido
       usa o par teal-bg / teal-line dos chips do site. Chip de texto livre
       (não reconhecido como exame da grade) fica no branco, para o médico ver
       de longe o que vai ter de pedir em "Outros exames". */
    .notas-toggle {
      flex: none; width: 22px; height: 22px; padding: 0;
      display: inline-flex; align-items: center; justify-content: center;
      border: 1px solid var(--line); border-radius: var(--r-ctl);
      background: var(--surface); color: var(--muted); cursor: pointer;
    }
    .notas-toggle svg { width: 14px; height: 14px; display: block; opacity: .55; transition: transform .15s ease, opacity .15s ease; }
    .notas-toggle:hover { color: var(--ink); background: var(--surface-3); }
    .notas-toggle:hover svg { opacity: 1; }
    .notas-toggle[aria-expanded="true"] svg { transform: rotate(180deg); opacity: 1; }
    /* ── O PAINEL DA CONSULTA (23/09/2026, pedido do médico) ──
       As camadas saíram da barra do topo e viraram três cartões `.sec` lado a
       lado no alto do conteúdo: Evolução | Exames, encaminhamentos e
       medicação | Conduta. Mesma estética dos cartões da área de atendimento:
       é o `.sec` de sempre, com a faixa tonal no cabeçalho. `hidden` é o
       estado fechado, posto por notas.js a partir da setinha do topo.

       `minmax(0, 1fr)` e não `1fr`: um chip ou uma frase comprida não pode
       alargar a coluna e empurrar as outras. Abaixo de 900px os três empilham,
       na mesma ordem. */
    .consulta-painel {
      display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 8px; margin-bottom: 8px; font-size: 11px;
    }
    .consulta-painel[hidden] { display: none; }
    .cp-col { display: flex; flex-direction: column; min-width: 0; }
    .cp-col .sec-h { align-items: center; }
    .cp-col .sec-b { flex: 1; display: flex; flex-direction: column; gap: 6px; min-height: 110px; }
    .cp-acoes { flex: none; display: flex; align-items: center; gap: 4px; }
    .cp-acoes .btn-ghost { font-size: 10px; padding: 2px 7px; }
    .cp-acoes .btn-ghost[disabled] { opacity: .45; cursor: default; }
    @media (max-width: 900px) {
      .consulta-painel { grid-template-columns: minmax(0, 1fr); }
      .cp-col .sec-b { min-height: 0; }
    }
    .notas-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
    /* O chip e' um <button>: clicar nele REMOVE o item (o [x] do canto saiu em
       19/09/2026). Daí o `font: inherit` e o `cursor: pointer` -- sem eles o
       navegador impõe a fonte de formulário e o chip muda de corpo no meio da
       barra. */
    .notas-chip {
      display: inline-flex; align-items: center; gap: 4px;
      background: var(--teal-bg); border: 1px solid var(--teal-line); color: var(--teal-dd);
      border-radius: 999px; padding: 2px 8px; line-height: 1.3; max-width: 40ch;
      font: inherit; cursor: pointer; text-align: left;
    }
    .notas-chip:hover { opacity: .75; }
    .notas-chip .txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .notas-chip.livre { background: var(--surface); border-color: var(--line); color: var(--ink); }
    /* Medicações candidatas (19/09/2026): chips em âmbar -- separados dos
       exames pela cor e pela posição. Par amber-bg / amber-line / amber-ink é o
       mesmo do .chip-amber do site.

       A ordem da linha, desde 20/09/2026: campo "+exame" | chips de exame |
       chips de medicação | campo "+medicação" | Limpar. Quem empurra as
       medicações para a direita é o `flex: 1` dos chips de exame, o único que
       cresce; os dois campos são `flex: none` e ficam cada um na sua ponta. */
    .notas-chips:empty { display: none; }
    .notas-chip.med { background: var(--amber-bg); border-color: var(--amber-line); color: var(--amber-ink); }
    /* Encaminhamento (20/09/2026): terceira categoria da barra, e o site só tem
       três pares de cor definidos nos nove temas (teal, âmbar, vermelho) --
       vermelho aqui seria alarme, que ele não é. Então o chip se distingue pela
       FORMA, não por uma cor nova: sólido, no par `--ink` sobre `--surface`
       invertido. Esse par é o do texto do site sobre o cartão, ou seja, o de
       maior contraste de cada tema; invertê-lo mantém a razão intacta em todos
       os nove, inclusive nos escuros, sem criar token novo em 14 arquivos. */
    .notas-chip.esp { background: var(--ink); border-color: var(--ink); color: var(--surface); }
    .notas-form { display: flex; align-items: center; gap: 4px; }
    .notas-form input[type=text] { flex: 1; min-width: 0; width: auto; font-size: 12px; padding: 4px 8px; }
    .notas-form input.notas-med-input { width: 22ch; border-color: var(--amber-line); }
    .notas-form .btn-ghost { font-size: 10px; padding: 2px 7px; }
    /* Feedback de meio segundo no elemento clicado (data-notas): pinta e
       apaga. O JS põe e tira a classe; a transição é quem faz o esmaecer. */
    .notas-add { background: var(--teal-bg) !important; transition: background .6s ease; }

    /* ── Camada EVOLUÇÃO: o cartão da esquerda do painel da consulta ──
       Desde 23/09/2026 ela é um cartão do painel (ver `.consulta-painel`,
       acima): campo "+queixa" em cima, chips abaixo e a FRASE inteira no fim
       -- o produto desta camada. Copiar e Limpar ficam no cabeçalho do cartão.
       Mostrar e esconder é do painel inteiro, não dela.

       Só tokens que já existem nos nove temas. As categorias de bloco se
       distinguem pelo TEXTO do chip, e não por cor: o site tem três pares de
       cor definidos em todos os temas (teal, âmbar, vermelho) -- ver o
       comentário do `.notas-chip.esp`, acima. */
    .evol-form { display: flex; align-items: center; gap: 4px; }
    .evol-form input[type=text] { flex: 1; min-width: 0; width: auto; font-size: 12px; padding: 4px 8px; }
    .evol-form .btn-ghost { font-size: 10px; padding: 2px 7px; }
    .evol-chips { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
    .evol-chips:empty { display: none; }
    /* O chip é um <button>: clicar nele REMOVE o bloco, como na camada de
       cima. `font: inherit` para o navegador não impor a fonte de formulário e
       mudar o corpo do texto no meio da linha. */
    .evol-chip {
      display: inline-flex; align-items: center; gap: 4px;
      background: var(--surface); border: 1px solid var(--line); color: var(--ink);
      border-radius: 999px; padding: 2px 8px; line-height: 1.3; max-width: 100%;
      font: inherit; cursor: pointer; text-align: left;
    }
    .evol-chip:hover { opacity: .75; }
    .evol-chip .txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    /* A queixa é a única que o médico digita aqui — o par teal dos chips do
       site marca o que é dele, e não de um clique noutra tela. */
    .evol-chip.queixa { background: var(--teal-bg); border-color: var(--teal-line); color: var(--teal-dd); }
    /* O curso da queixa (23/09/2026): MELHORA no par vermelho -- é ausência, o
       que ele deixou de ter --, PIORA no âmbar. Surgiu fica no teal de sempre.
       Os botões do campo levam o mesmo par do chip que criam, para ligar botão e chip. */
    .evol-chip.queixa.melhora { background: var(--red-bg); border-color: var(--red-line); color: var(--red-ink); }
    .evol-chip.queixa.piora { background: var(--amber-bg); border-color: var(--amber-line); color: var(--amber-ink); }
    .evol-form .btn-ghost.evol-melhora { background: var(--red-bg); color: var(--red-ink); border-color: var(--red-line); }
    .evol-form .btn-ghost.evol-piora { background: var(--amber-bg); color: var(--amber-ink); border-color: var(--amber-line); }
    /* A frase — o produto da camada. Corpo um degrau acima do resto da barra
       (12px contra 11px): é o único texto daqui que se LÊ, e não se varre.
       `overflow-wrap: break-word` para a palavra gigante não estourar a linha,
       mas a quebra normal continua por palavra: são datas e siglas, e cortar
       `28/08/2026` no meio atrapalha a conferência. `max-width` em `ch` porque
       o limite aqui é de leitura, não de caixa — no monitor largo, uma linha de
       300 caracteres não se acompanha. */
    .evol-texto, .conduta-texto {
      font-size: 12px; line-height: 1.45; color: var(--ink);
      overflow-wrap: break-word;
    }
    .evol-texto.vazio { display: none; }
    /* A conduta (23/09/2026) é o texto que Condutas joga aqui. Vazia, o
       cartão diz como enchê-lo -- `--muted-2`, o cinza que passa sobre o
       `--surface` do cartão nos nove temas. `pre-wrap` porque a conduta pode
       ter quebra de linha digitada à mão. */
    .conduta-texto { white-space: pre-wrap; overflow-wrap: anywhere; }
    .conduta-texto.vazio { color: var(--muted-2); font-style: italic; }

    main { flex: 1; width: 100%; padding: 11px var(--pad-main) 34px; }

    /* ── Avisos de atualização de laboratório (23/09/2026) ──────────────────
       "Atualizar LACS novo" e "Buscar LACS antigos" rodam em segundo plano
       (lacs.paciente_pipeline). Este é o cartão fixo no canto de baixo que
       acompanha o médico por qualquer tela e diz quando terminou
       (static/core/lacs_avisos.js). Só tokens: o cartão tem de passar nos
       nove temas sem regra própria em cada um. Fica ACIMA do rodapé e não
       toma a largura no celular (o `left` de 16px dá a margem lateral). */
    .lacs-avisos {
      position: fixed; right: 16px; bottom: 16px; left: 16px; z-index: 60;
      display: flex; flex-direction: column; gap: 6px; align-items: flex-end;
      pointer-events: none;
    }
    .lacs-avisos[hidden] { display: none; }
    .lacs-aviso {
      pointer-events: auto;
      display: flex; align-items: center; gap: 8px;
      max-width: 100%; width: 360px;
      padding: 8px 10px; border-radius: var(--r-ctl);
      background: var(--surface); color: var(--ink);
      border: 1px solid var(--line); border-left: 3px solid var(--teal);
      box-shadow: var(--lift); font-size: 12px; line-height: 1.35;
    }
    .lacs-aviso.rodando { border-left-color: var(--amber); }
    .lacs-aviso.erro { border-left-color: var(--red); }
    .lacs-aviso .lacs-aviso-txt { flex: 1; min-width: 0; overflow-wrap: anywhere; }
    .lacs-aviso .lacs-aviso-txt strong { font-weight: 600; }
    .lacs-aviso .lacs-aviso-sub { display: block; color: var(--muted); }
    .lacs-aviso.erro .lacs-aviso-sub { color: var(--red-ink); }
    .lacs-aviso a.lacs-aviso-ver { color: var(--teal-ink); font-weight: 600; white-space: nowrap; }
    .lacs-aviso button.lacs-aviso-x {
      background: none; border: 0; color: var(--muted); cursor: pointer;
      font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: var(--r-chip);
    }
    .lacs-aviso button.lacs-aviso-x:hover { background: var(--surface-3); color: var(--ink); }
    /* Pulsar é reservado a estado de carregando (docs/temas.md, Movimento). */
    .lacs-aviso .lacs-aviso-dot {
      width: 8px; height: 8px; border-radius: 50%; flex: none;
      background: var(--teal);
    }
    .lacs-aviso.rodando .lacs-aviso-dot { background: var(--amber); animation: lacs-pulso 1.2s ease-in-out infinite; }
    .lacs-aviso.erro .lacs-aviso-dot { background: var(--red); }
    @keyframes lacs-pulso { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

    /* Barra de progresso das duas telas de portal: `indet` é a versão sem
       fração (o portal novo não avisa por coleta) — anima `transform`, não
       `width`. */
    .lacs-prog { height: 12px; background: var(--surface-3); border-radius: 6px; overflow: hidden; position: relative; }
    .lacs-prog > div { height: 100%; width: 0; background: var(--teal); transition: width .3s; }
    .lacs-prog.indet > div { width: 30%; animation: lacs-indet 1.4s ease-in-out infinite; }
    .lacs-prog.erro > div { background: var(--red); }
    @keyframes lacs-indet { 0% { transform: translateX(-100%); } 100% { transform: translateX(340%); } }

    /* Subtítulo opcional no topo do conteúdo (nome oficial longo de um documento etc.) */
    .page-lead { font-size: 11px; color: var(--muted); margin: -1px 0 12px; max-width: 64ch; }

    /* ── Card ── */
    .card {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: var(--r);
      box-shadow: var(--lift);
      padding: .65rem .8rem;
      margin-bottom: 8px;
    }
    .card > h2:first-child, .card > h3:first-child { margin-top: 0; }

    /* ── Tile de módulo (as "centrais": Exames, Receita, Documentos) ──
       Era copiado em 3 templates, cada um com um valor diferente de padding e
       a mesma sombra genérica `rgba(0,0,0,.1)`. Agora é um componente só, na
       mesma linguagem do tile da home (`core/home.html`). */
    .modules {
      display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
      gap: 7px;
    }
    .module-card {
      display: flex; align-items: center; justify-content: center; text-align: center;
      min-height: 46px; padding: .6rem .7rem;
      background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
      box-shadow: var(--lift);
      text-decoration: none; color: inherit;
      transition: border-color .15s, background .15s;
    }
    .module-card:hover { border-color: var(--teal-line); background: var(--teal-bg); }
    .module-card h2 {
      font-family: var(--sans); font-size: 12px; font-weight: 600;
      color: var(--ink); margin: 0; line-height: 1.25;
    }
    .module-card--off { opacity: .45; pointer-events: none; box-shadow: none; }
    .module-card--off h2 { color: var(--muted); }

    /* ── Tipografia ── */
    h1 { font-size: 15px; font-weight: 600; letter-spacing: -.01em; line-height: 1.2; margin-bottom: .5rem; }
    h2 { font-size: 12.5px; font-weight: 600; line-height: 1.25; margin-bottom: .35rem; }
    h3 { font-size: 11px; font-weight: 600; line-height: 1.25; margin-bottom: .3rem; }
    p { margin-bottom: .4rem; }
    p:last-child { margin-bottom: 0; }
    small, .small { font-size: 10px; color: var(--muted); }

    /* rótulo de seção (caixa-alta, espaçado) */
    .hd {
      font-size: 9.5px; font-weight: 600; letter-spacing: .09em;
      text-transform: uppercase; color: var(--muted);
    }
    /* rótulo de campo (menor) */
    .lbl {
      font-size: 8.5px; font-weight: 600; letter-spacing: .07em;
      text-transform: uppercase; color: var(--muted-3);
    }
    .mono { font-family: var(--mono); }
    .val { font-family: var(--mono); font-size: 11.5px; color: var(--ink); }

    /* ── Botões ── */
    .btn {
      display: inline-block;
      font-family: var(--sans); font-size: 10.5px; font-weight: 600;
      letter-spacing: .02em;
      color: #fff; background: var(--teal);
      border: 1px solid var(--teal-d); border-radius: var(--r-ctl);
      padding: 5px 10px; cursor: pointer; text-decoration: none;
      transition: background .15s, border-color .15s;
    }
    .btn:hover { background: var(--teal-dd); border-color: var(--teal-dd); color: #fff; }
    .btn-sec {
      color: var(--ink); background: var(--surface); border-color: #c6d1cd;
    }
    .btn-sec:hover { background: var(--surface-3); border-color: #aebbb6; color: var(--ink); }
    .btn-ghost {
      color: var(--teal-dd); background: var(--surface); border-color: #c6d1cd;
      font-weight: 600; letter-spacing: .04em; text-transform: uppercase; font-size: 9.5px;
      padding: 4px 8px;
    }
    .btn-ghost:hover { background: var(--teal-bg); border-color: #93c6bc; color: var(--teal-dd); }
    /* Botão desligado: até aqui `disabled` só tirava o clique, e o botão
       continuava verde de botão pronto — o "Salvar" sem paciente em /vacinas/ e o
       "Desmarcar influenza" sem ninguém marcado em /perfil/ pareciam ativos e não
       faziam nada. Vale para os três estilos de botão, e o `:hover` some junto. */
    .btn:disabled, .btn-sec:disabled, .btn-ghost:disabled,
    .btn:disabled:hover, .btn-sec:disabled:hover, .btn-ghost:disabled:hover {
      background: var(--surface-3); border-color: var(--line);
      color: var(--muted); cursor: not-allowed;
    }
    /* Foco visível de teclado -- vale para botão, link de botão e campo. */
    .btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible,
    textarea:focus-visible, button:focus-visible {
      outline: 2px solid var(--teal); outline-offset: 1px;
    }
    .btn-row { display: flex; flex-wrap: wrap; gap: 5px; }

    /* ── Formulários ── */
    label { font-size: 11px; color: var(--ink); }
    input[type=text], input[type=password], input[type=number], input[type=date],
    input[type=email], input[type=tel], input[type=search], select, textarea {
      font-family: var(--sans); font-size: 12px; color: var(--ink);
      background: var(--surface);
      border: 1px solid var(--line-ctl); border-radius: var(--r-ctl);
      padding: 4px 8px;
    }
    textarea { line-height: 1.45; }

    /* ── Campo de data/hora ─────────────────────────────────────────────────
       No iOS o `input` de time/date NÃO é caixa de texto: é um controle NATIVO
       do sistema, com largura intrínseca mínima própria. Some isso à regra de
       16px que existe logo abaixo (para o iOS não dar zoom ao focar) e o
       controle fica mais largo que o container — `width:100%` não o encolhe,
       porque o mínimo intrínseco vence. O campo transborda o card.

       O Chromium desenha o mesmo campo como caixa comum e cabe, então o bug
       NÃO reproduz fora do iPhone: chegou em produção pela tela de Atestado de
       comparecimento e só apareceu num print de celular.

       `min-width:0` libera o encolhimento, `max-width:100%` garante o teto, e
       `appearance:none` é o que faz o iOS parar de impor o tamanho do widget
       nativo. O seletor de data continua abrindo normalmente ao toque. */
    input[type=date], input[type=time], input[type=datetime-local],
    input[type=month], input[type=week] {
      min-width: 0; max-width: 100%;
      -webkit-appearance: none; appearance: none;
    }
    /* Caixa de selecao e radio pintados pela cor do tema. O controle nativo
       vinha no azul do sistema operacional -- era o unico azul numa tela
       inteira de token, e em tema escuro ele brigava com tudo. `accent-color`
       e' a forma suportada de mudar isso sem reconstruir o controle com div,
       o que custaria acessibilidade de teclado e de leitor de tela. O
       navegador escolhe sozinho a cor do "check" contra o acento, entao
       serve tanto ao acento escuro dos temas claros quanto ao acento claro
       dos escuros. */
    input[type=checkbox], input[type=radio] { accent-color: var(--teal); }

    input:focus, select:focus, textarea:focus {
      outline: none; border-color: var(--teal);
      box-shadow: 0 0 0 2px rgba(12,127,108,.16);
    }

    /* ── Tabelas ── */
    table { border-collapse: collapse; width: 100%; font-size: 11px; }
    th {
      font-size: 8.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
      color: var(--muted); text-align: left;
      padding: 5px 7px; border-bottom: 1px solid var(--line);
      background: var(--surface-3);
    }
    td { padding: 4px 7px; border-bottom: 1px solid var(--line-3); }
    td.num, th.num { text-align: right; font-family: var(--mono); }

    /* ── Chips ── */
    /* Comprimido da coluna Esquema (painel, atendimento). A COR chega como
       `--esq-cor` inline (ver painel/templatetags/painel_extras.py); a FORMA e o
       peso ficam aqui, para o tema e o estilo da tela poderem mexer. */
    .esq-badge {
      display: inline-block; background: var(--esq-cor, #64748b);
      color: var(--drug-ink, #fff); font-weight: 700; white-space: nowrap;
      font-size: 10px; line-height: 1.4; padding: 2px 5px;
      border-radius: var(--r-chip); margin: 0 1px;
    }

    .chip {
      display: inline-block;
      font-size: 9.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
      padding: 3px 7px; border-radius: var(--r-chip);
      background: var(--surface-3); border: 1px solid var(--line-2); color: var(--muted);
    }
    .chip-red   { color: #fff; background: var(--red); border-color: var(--red); }
    .chip-amber { color: var(--amber-ink); background: var(--amber-bg); border-color: var(--amber-line); }
    .chip-teal  { color: var(--teal-ink); background: var(--teal-bg); border-color: var(--teal-line); }

    /* ── Lacunas clicáveis da faixa de cobertura do Gantt de TARV ──
       (20/09/2026.) Mora AQUI, e não no <style> de cada tela, porque o
       comportamento é compartilhado pelas duas que desenham esse Gantt (área de
       atendimento e aba Disponibilidade do TARVSTOPS) — o JS é um arquivo só
       (static/core/gantt_lacunas.js) e a cor tem de ser também, senão as duas
       telas dizem a mesma coisa em cores diferentes. O resto da faixa
       (`.gc-track`, `.gc-seg`, `.gc-scope`) continua no <style> de cada tela.

       Sem marca o elemento é TRANSPARENTE: ele é só o alvo do clique, e o que
       se vê embaixo é a hachura de "sem retirada ativa". Marcado, ele pinta o
       período inteiro.

       As três cores saem dos únicos pares sólidos que os nove temas
       redefinem. Vermelho ficou com "de outro paciente" porque, das três, é a
       única que é problema clínico de verdade — compartilhar TARV. */
    .gc-gap { position: absolute; top: 0; bottom: 0; padding: 0; border: 0;
              background: transparent; border-radius: 0; }
    button.gc-gap { cursor: pointer; font: inherit; }
    .gc-gap.j-sem_registro   { background: var(--amber); }
    .gc-gap.j-outro_paciente { background: var(--red); }
    .gc-gap.j-estoque        { background: var(--ink); }
    .gc-gap:focus-visible { outline: 2px solid var(--teal); outline-offset: 1px; }

    /* ── Grid de 12 colunas (aproveitamento horizontal) ── */
    .grid12 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 8px; align-items: start; }
    .col-12 { grid-column: span 12; } .col-8 { grid-column: span 8; }
    .col-6  { grid-column: span 6;  } .col-4 { grid-column: span 4; }
    .col-3  { grid-column: span 3;  }
    @media (max-width: 900px) {
      .col-8, .col-6, .col-4, .col-3 { grid-column: span 12; }
    }

    /* ── Seção com cabeçalho ──
       O cabeçalho é uma FAIXA tonal (--surface-3), não mais branco com um fio
       embaixo: é ela que dá, num relance, onde cada card começa. */
    .sec {
      background: var(--surface);
      border: 1px solid var(--line); border-radius: var(--r);
      box-shadow: var(--lift);
      overflow: hidden;
    }
    .sec-h {
      display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
      padding: 6px 11px;
      background: var(--surface-3);
      border-bottom: 1px solid var(--line-2);
    }
    .sec-h .meta { font-family: var(--mono); font-size: 10px; color: var(--muted-2); }
    .sec-b { padding: 8px 11px; }
    .rowline {
      display: flex; align-items: baseline; gap: 8px;
      padding: 4px 10px; border-bottom: 1px solid var(--line-3);
    }
    .rowline:last-child { border-bottom: none; }

    /* ── Cartão de paciente selecionado (fluxo normal, compacto) ── */
    .paciente-card {
      background: var(--surface);
      border: 1px solid var(--line);
      border-left: 3px solid var(--teal);
      border-radius: var(--r);
      box-shadow: var(--lift);
      padding: .5rem .6rem;
      margin-bottom: 8px;
      position: relative;
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
      gap: 2px 14px;
    }
    .paciente-card > form { display: contents; }
    .paciente-card .pc-head {
      grid-column: 1 / -1;
      font-size: 8px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted-3);
      margin-bottom: 2px;
    }
    .paciente-card .pc-nome {
      grid-column: 1 / -1;
      font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.2; margin-bottom: 2px;
    }
    /* Tres niveis fixos por celula (16/09/2026): rotulo, VALOR, data daquele
       valor. Antes cada linha misturava valor e data no mesmo corpo de texto,
       cada uma com um formato -- "1292 (07/2026)", "Nao Detectavel 27/07/2026",
       "3TC+TDF+DTG , 27/07/2026" --, e o olho nao achava a coluna. Com a data
       sempre embaixo e sempre menor, as celulas alinham sozinhas. */
    .paciente-card .pc-row { font-size: 11px; font-family: var(--mono); color: var(--ink); }
    .paciente-card .pc-row span {
      color: var(--muted-3); text-transform: uppercase; font-size: 8px; letter-spacing: .06em;
      font-family: var(--sans); display: block;
    }
    .paciente-card .pc-row b { font-weight: 600; display: block; line-height: 1.25; }
    .paciente-card .pc-row i {
      font-style: normal; display: block;
      font-size: 9px; color: var(--muted-3); line-height: 1.3;
    }
    /* So o lugar: a aparencia vem de `.btn-x` (folha depois do extra_css). Se as cores
       ficassem aqui, venceriam por especificidade e este [x] seria o unico diferente. */
    .paciente-card .pc-x { position: absolute; top: .25rem; right: .4rem; }

    /* ── Footer ── */
    /* O rodapé vive no CHÃO, sem papel próprio -- senão vira mais um card
       branco competindo com o conteúdo. */
    footer {
      text-align: center;
      padding: .9rem 1rem;
      font-size: 9.5px;
      color: var(--muted);
      background: transparent;
    }

    /* Folha A4 das telas de impressão: ela NÃO reflui -- é geometria de papel
       (o painel de vacinas, por exemplo, tem as caixas de dose em tamanho fixo,
       ajustado para o papel). No celular a folha rola dentro da própria caixa
       em vez de arrastar a página inteira. Só na tela: no papel a largura é a
       da página impressa, e aí nada disso vale. */
    @media screen and (max-width: 720px) {
      .folha { overflow-x: auto; }
    }

    /* ── Impressão ──
       O chão de meio-tom é do papel-tela; no papel de verdade nada disso vai.
       Cada tela de impressão já fazia isso no seu próprio <style>; aqui é a
       garantia para qualquer página nova (e para um Ctrl+P numa tela comum). */
    @media print {
      body { background: #fff; }
      .rail, .topbar, .consulta-painel, footer { display: none !important; }
      .card, .sec, .module-card, .paciente-card, .at-head { box-shadow: none !important; }
      main { padding: 0; }
    }

    /* ── Mobile: rail vira faixa horizontal no topo ── */
    @media (max-width: 720px) {
      /* `align-items: flex-start` é do layout de duas colunas (rail + conteúdo).
         Empilhado, ele passa a valer no eixo HORIZONTAL e a `.shell` deixa de
         ocupar a largura da tela: ela encolhe/cresce conforme o conteúdo, e
         qualquer tabela larga passava a arrastar a PÁGINA INTEIRA de lado --
         com o rail e a topbar saindo de registro. Aqui o eixo volta a esticar. */
      body { flex-direction: column; align-items: stretch; }
      .shell { width: 100%; min-width: 0; }
      main { min-width: 0; }
      .rail {
        flex-direction: row; width: 100%; max-width: 100%; height: auto;
        padding: 4px 6px; gap: 0; overflow-x: auto;
        -webkit-overflow-scrolling: touch;
      }
      .rail-logo { margin: 0 2px 0 0; }
      .rail a.active::before { left: 6px; right: 6px; top: auto; bottom: 0; width: auto; height: 2px; }
      .rail-spacer { flex: 1; }
      .rail-sep { width: 1px; height: 18px; margin: 0 4px; }
      .topbar { position: static; }
      /* Ações da página (ex.: "Encaminhamento A" em Vacinas) passam para a
         linha de baixo em vez de empurrar e cobrir o nome da página. */
      .topbar-page { padding: 6px 12px; flex-wrap: wrap; row-gap: 4px; }
      .topbar-actions { margin-left: 0; width: 100%; }
      .topbar-util { padding: 3px 12px; }

      /* Com o auto-inflate do iOS desligado (ver `-webkit-text-size-adjust`
         no `html`), o tipo passa a sair no tamanho autoral -- que é pensado
         para monitor, não para telefone na mão. Um degrau em cima do que é
         pequeno demais no celular, sem mexer no desktop. */
      body { font-size: 13px; }
      table { font-size: 12px; }
      th { font-size: 9.5px; }
      .hd { font-size: 10.5px; }
      .lbl { font-size: 9.5px; }
      .val { font-size: 12.5px; }
      .btn { font-size: 11.5px; padding: 6px 11px; }
      .btn-ghost { font-size: 10.5px; padding: 5px 9px; }
      .chip { font-size: 10.5px; }
      small, .small { font-size: 11px; }
      .sec-h .meta { font-size: 11px; }
      /* Campo de formulário abaixo de 16px faz o iOS dar zoom sozinho ao focar
         -- e aí a página fica deslocada. 16px é o mínimo que evita isso. */
      input[type=text], input[type=password], input[type=number], input[type=date],
      input[type=email], input[type=tel], input[type=search], select, textarea {
        font-size: 16px;
      }
    }
