@charset "UTF-8";
/* =========================================================================
   A MESA DE LUZ — sistema visual do Grupo Nós do Morro
   Gelatinas nomeadas pelo número real do catálogo Lee Filters.
   Nada aqui é enfeite: todo rótulo técnico na tela tem referente real.
   ========================================================================= */

/* ---------- 1. Tipos auto-hospedados ---------- */
@font-face {
  font-family: 'Archivo';
  src: url('../fontes/archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fontes/archivo-latin-ext.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Chivo Mono';
  src: url('../fontes/chivomono-latin.woff2') format('woff2');
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Chivo Mono';
  src: url('../fontes/chivomono-latin-ext.woff2') format('woff2');
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- 2. A deixa: propriedade animável ---------- */
@property --deixa {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}

/* ---------- 3. Tokens ---------- */
:root {
  /* palco */
  --palco: #0b0a0c;
  --urdimento: #131118;
  --coxia: #1c1a23;
  --praticavel: #262330;

  /* gelatinas (Lee Filters) */
  --gel-181: #141c6e; /* Congo Blue      */
  --gel-119: #1f4fa8; /* Dark Blue       */
  --gel-162: #ffce9a; /* Bastard Amber   */
  --gel-106: #d8232a; /* Primary Red     */
  --gel-128: #c0247b; /* Bright Pink     */
  --gel-764: #f07c1e; /* Sunset — a cor da marca */

  /* tinta: o preto usado quando algo claro precisa de texto escuro
     (botão sólido, seleção). Não há mais fundo claro no site. */
  --tinta: #0f1413;

  /* texto */
  --luz: #fcf8f1;
  --luz-2: #c6b8a6;
  --luz-3: #8d8172;

  /* o quase-preto que carrega texto sobre as poucas superfícies claras do
     sistema: botão primário, faixa de seleção, link de pular conteúdo. */
  --breu: #120b04;

  /* ---- os tokens correntes: é por eles que o tema entra, inteiro ----
     Nenhum componente sabe em que tema está. Quem sabe é esta lista, e o
     bloco html[data-tema='claro'] logo abaixo. */
  --fundo: var(--palco);
  --frente: var(--luz);
  --frente-2: var(--luz-2);
  --frente-3: var(--luz-3);
  /* a segunda camada: barra, quadro, moldura de prévia, trilho de rolagem,
     fundo de imagem que ainda não carregou, topo do degradê da mesa. */
  --camada: var(--coxia);
  /* onde se escreve: no palco é a própria frente a 5%; sobre papel é a folha
     em branco, um degrau ACIMA do papel (o bloco claro troca os dois). */
  --campo: color-mix(in srgb, var(--luz) 5%, transparent);
  --campo-foco: color-mix(in srgb, var(--luz) 9%, transparent);
  --linha: rgba(252, 248, 241, 0.16);
  --linha-forte: rgba(252, 248, 241, 0.34);
  --realce: var(--gel-764);
  /* A GELATINA DE AÇÃO EM TRÊS CARGOS. Sobre o palco os três são a mesma
     L764, porque ali ela dá 7,2:1 e faz tudo. Sobre papel ela dá 2,5:1 e
     precisa se separar: --realce continua sendo a gelatina crua (que só
     PREENCHE, com o breu por cima); --realce-marca é ela com a lâmpada
     baixa, que pode virar TRAÇO; e --realce-texto é o cargo que ela não
     pode exercer no papel, e que passa para a tinta. */
  --realce-marca: var(--gel-764);
  --realce-texto: var(--gel-764);
  /* A BARRA DE ROLAGEM É ESTADO DE REPOUSO, e por isso ela NÃO usa a gelatina
     crua (correção do revisor de acabamento da Fase 6b, F3). O polegar é a
     peça mais alta e mais saturada de qualquer tela rolável: no /acervo ele
     chegava a ser o elemento mais saturado da primeira dobra — mais que a
     fotografia —, contra a regra de que a L764 só aparece em AÇÃO e ESTADO.
     Descida para 62% sobre a segunda camada (o valor da declaração logo
     abaixo; medido no palco, #9F5720), ela continua sendo a marca da casa
     — ninguém a confunde com a barra do sistema — e para de gritar. É um
     token próprio, e não `--realce-marca` reaproveitado, porque o cursor de
     texto e o `accent-color` continuam querendo a gelatina cheia: ali ela é
     ação. */
  --barra-polegar: color-mix(in srgb, var(--gel-764) 62%, var(--camada));
  /* o mesmo para a L162: sobre papel ela dá 1,3:1 e não escreve nada. */
  --quente-texto: var(--gel-162);
  --fio-quente: color-mix(in srgb, var(--gel-162) 50%, transparent);
  /* o vermelho L106 puro sobre o palco dá 4,0:1 e reprova em texto miúdo.
     Esta é a mesma gelatina lida com a lâmpada baixa: passa o piso. */
  --gel-106-tinta: #ef8079;
  --foco: var(--gel-162);
  /* O FOCO EM DUAS PEÇAS: anel e halo. No palco o âmbar sozinho dá 13,7:1 e
     é o anel inteiro; o halo não existe. Sobre papel o âmbar dá 1,3:1, o
     anel passa a ser de tinta e o âmbar vira calor em volta dele. */
  --foco-anel: var(--gel-162);
  --foco-afast: 3px;
  --foco-halo: 0 0 0 0 transparent;
  --foco-borda: var(--gel-162);
  /* a única sombra do sistema, e ela é luz derramando. Sobre papel luz
     derramada vira mancha: o bloco claro a zera. */
  --brilho-botao: 0 6px 26px -8px rgba(240, 124, 30, 0.75);
  /* o breu por trás da lente (secção 23): o palco fechando em volta da
     fotografia. Sobre papel ele vira a própria folha — apagar a sala é o
     gesto, e de dia a sala é clara. */
  --lente-breu: rgba(11, 10, 12, 0.94);

  /* ---- os níveis da luz: o que muda quando a lâmpada troca de lado ----
     A gelatina é a mesma nos dois temas. O que muda é a altura da lâmpada,
     e ela mora nestes números. */
  /* a vinheta da abertura: no palco ela derruba o quadro para o preto; sobre
     papel ela lava o quadro para a folha, que é o mesmo gesto ao contrário. */
  --vinheta: 11 10 12;
  /* o feixe: screen sobre o palco (luz somando); sobre papel screen não faz
     nada, então ele vira multiply — gelatina impressa — e desce de nível. */
  --feixe-mistura: screen;
  --feixe-nivel: 1;
  /* quanto da gelatina sobrevive quando ela precisa ser lida: misturada com
     --frente, ela SOBE no palco e DESCE no papel, sem trocar de cor. */
  --gel-em-texto: 58%;
  --gel-em-traco: 82%;
  /* o trilho do fader e a carga de L119 na tira de comunicado */
  --trilho: rgba(252, 248, 241, 0.15);
  --tira-carga: 22%;
  /* o terciário sobre superfície que se afasta do fundo (ver A Regra do
     Campo Mais Claro) */
  --luz-3-campo: #b2a595;

  /* tipos */
  --face: 'Archivo', 'Segoe UI', system-ui, sans-serif;
  --face-tec: 'Chivo Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* escala tipográfica */
  --t-manifesto: clamp(2.35rem, 3.7vw, 3.95rem);
  --t-titulo: clamp(2.05rem, 4.6vw, 3.55rem);
  --t-secao: clamp(1.5rem, 2.7vw, 2.15rem);
  --t-sub: clamp(1.18rem, 1.6vw, 1.4rem);
  --t-corpo: clamp(1.0625rem, 0.42vw + 0.95rem, 1.1875rem);
  --t-tec: 0.7rem;

  /* ritmo */
  --e0: 0.25rem;
  --e1: 0.5rem;
  --e2: 0.75rem;
  --e3: 1rem;
  --e4: 1.5rem;
  --e5: 2rem;
  --e6: 3rem;
  --e7: 4.5rem;
  --e8: 6.5rem;
  --e9: 9rem;

  --margem: clamp(1.25rem, 5vw, 5rem);
  --rail: 5.5rem;
  --medida: 68ch;

  /* a curva do fader */
  --fader: cubic-bezier(0.16, 1, 0.3, 1);
}

/* =========================================================================
   O TEMA CLARO — a luz de serviço, agora um interruptor
   =========================================================================

   UM MUNDO, DOIS REGISTROS, ESCOLHIDOS PELO VISITANTE. O palco é o padrão e
   é a identidade: sem JavaScript, sem escolha gravada, ou com o interruptor
   desligado, o site inteiro fica escuro. O tema claro é a MESMA casa com a
   luz de serviço acesa — a lâmpada de trabalho que no teatro fica ligada
   enquanto a plateia não entrou —, e ele entra inteiro por esta lista de
   tokens. Nenhum componente sabe em que tema está.

   O QUE A TRADUÇÃO CUSTA. Sobre o palco a página É a luz: o feixe soma em
   "screen", a poça é um especial, o campo de gelatina é uma região acesa.
   Sobre papel nada disso existe — "screen" sobre branco não faz nada. Então
   a luz vira GELATINA IMPRESSA: "multiply" com a mesma gelatina, com a mesma
   aresta dura, em nível medido. É o mesmo rig, visto de dia.

   AS CONTAS DE CONTRASTE, medidas (WCAG 2.x, sobre o papel #f4f1ea):
     tinta   #0f1413  16,8:1   texto, anel de foco
     tinta-2 #4a463f   8,4:1   corpo secundário
     tinta-3 #5f5a51   6,1:1   aparato técnico. DESCEU um degrau do #6b655c
                               do painel (5,1:1) porque no SITE o terciário
                               corre por baixo do feixe impresso, e lá o
                               valor antigo caía para 3,96:1.
     tinta-3-campo #565148     o terciário sobre campo de gelatina impressa
                               (4,8:1 no congo, o mais fundo dos três)
     L106    #d8232a   4,4:1   REPROVA em texto miúdo — vira traço, nunca letra
     L106 ↓  #b4141b   6,2:1   a mesma gelatina com a lâmpada baixa: é a tinta
                               de erro, o mesmo movimento que --gel-106-tinta
                               faz no palco (lá ela sobe; aqui desce)
     L764    #f07c1e   2,5:1   NUNCA carrega texto sobre papel: só preenche
                               (com o breu por cima, 7,1:1) ou vira traço com
                               a lâmpada baixa (--realce-marca, 3,0:1)
     L162    #ffce9a   1,3:1   não sinaliza nada sozinha: é o halo em volta do
                               anel de tinta, calor, não contraste
   ========================================================================= */
html[data-tema='claro'] {
  /* as três camadas de papel: a mesa, a folha e a folha em branco do campo */
  --papel: #f4f1ea;
  --papel-2: #ebe7dd;
  --papel-3: #fffdf8;

  /* a escada de tinta */
  --tinta-2: #4a463f;
  --tinta-3: #5f5a51;
  --tinta-3-campo: #565148;

  --fundo: var(--papel);
  --frente: var(--tinta);
  --frente-2: var(--tinta-2);
  --frente-3: var(--tinta-3);
  --camada: var(--papel-2);
  /* o lugar onde se escreve é MAIS CLARO que a folha em que ele se apoia */
  --campo: var(--papel-3);
  --campo-foco: var(--papel-3);

  /* Fio de separação a 16%: régua, não contorno de controle. Fio de contorno
     a 50%: é ele que desenha campo, botão vazado e selo, e por isso precisa
     dos 3:1 de componente — 16% dá 1,9:1 e reprovaria. Medido: 3,4:1. */
  --linha: rgba(15, 20, 19, 0.16);
  --linha-forte: rgba(15, 20, 19, 0.5);

  --realce: var(--gel-764);
  --realce-marca: color-mix(in srgb, var(--gel-764) 88%, var(--tinta));
  /* SOBRE PAPEL A LÂMPADA JÁ DESCEU. `--realce-marca` aqui é a L764 misturada
     com a tinta (3,0:1) — o polegar da rolagem já não era gelatina crua neste
     registro, e descê-lo de novo o levaria abaixo dos 3:1 que um contorno de
     componente exige. O token existe nos dois lados; o que muda é o quanto
     ele precisa descer. */
  --barra-polegar: var(--realce-marca);
  /* A REGRA DA GELATINA QUE NÃO ESCREVE. Sobre papel nem a L764 nem a L162
     carregam texto: quem escreve é a tinta, e a gelatina fica com o cargo
     que ela pode exercer — preencher, ou virar traço. */
  --realce-texto: var(--frente);
  --quente-texto: var(--frente);
  --fio-quente: var(--realce-marca);
  --gel-106-tinta: #b4141b;
  --lente-breu: rgba(244, 241, 234, 0.96);

  --foco: var(--gel-162);
  --foco-anel: var(--frente);
  --foco-afast: 2px;
  --foco-halo: 0 0 0 5px color-mix(in srgb, var(--gel-162) 72%, transparent);
  --foco-borda: var(--frente);
  --brilho-botao: 0 0 0 0 transparent;

  --vinheta: 244 241 234;
  --feixe-mistura: multiply;
  /* medido: a 0,22 o feixe mais carregado (L119 na frente) derruba o papel a
     0,71 de luminância, e o terciário #5f5a51 ainda dá 5,0:1 por baixo dele.
     Acima disso o aparato técnico começa a reprovar. */
  --feixe-nivel: 0.22;
  --gel-em-texto: 42%;
  --gel-em-traco: 52%;
  --trilho: rgba(15, 20, 19, 0.22);
  --tira-carga: 12%;
  --luz-3-campo: var(--tinta-3-campo);

  /* o trilho da barra de rolagem e o fundo de imagem deixam de ser o
     urdimento do palco */
  --urdimento: var(--papel-2);
  --coxia: var(--papel-2);
}

/* ---------- 4. Base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;

  /* A ÂNCORA PARA ABAIXO DA BARRA FIXA (Fase 6d, caça a bugs, rodada 5).

     A `.ribalta` é `position: sticky; top: 0` e tem 4.5rem de altura mínima;
     sem isto, toda âncora do site parava com o alvo em y=0, isto é, DEBAIXO
     dela. O "Ver comunicado" da tira, que é o único botão dela e leva a
     /comunicados#<slug>, escondia o tipo, a data, o selo e o próprio título do
     comunicado apontado: o visitante lia o TEXTO de um comunicado sem saber
     qual era. O mesmo valia para o recibo de /contato sem JavaScript, para os
     301 e para qualquer link antigo com âncora.

     `scroll-padding-top` no elemento que rola resolve as âncoras TODAS de uma
     vez — presentes e futuras —, e é a folha de estilo dizendo o que a barra
     ocupa, em vez de cada alvo ter de lembrar. Os 4.5rem são a altura mínima
     da `.ribalta__i`; o vão de respiro vem por cima dela. */
  scroll-padding-top: calc(4.5rem + var(--e3));
}
/* O NAVEGADOR PRECISA SABER. Sem isto, o campo de formulário, a barra de
   rolagem nativa e o menu do <select> continuam desenhados para o tema do
   sistema operacional, e não para o tema que o visitante escolheu aqui. */
html[data-tema='escuro'] {
  color-scheme: dark;
}
html[data-tema='claro'] {
  color-scheme: light;
}
body {
  margin: 0;
  background: var(--fundo);
  color: var(--frente);
  font-family: var(--face);
  font-size: var(--t-corpo);
  font-variation-settings: 'wdth' 100, 'wght' 400;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img,
svg,
video {
  display: block;
  max-width: 100%;
}
h1,
h2,
h3,
h4,
p,
figure,
dl,
dd,
ul,
ol {
  margin: 0;
}
ul,
ol {
  padding: 0;
  list-style: none;
}
a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.28em;
}
button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}
/* O MENU DO SELECT NÃO É DESENHADO POR NÓS, e por isso ele precisa ser dito.
   `color-scheme` acima já manda o navegador pintar o popup no registro certo,
   e é ele que resolve o caso comum — mas o valor herdado por `option` vem do
   tema do SISTEMA em vários caminhos (Windows com tema claro e o site no
   palco, a lista aberta dentro de um `<iframe>`, motores que ignoram
   `color-scheme` na lista suspensa). O que o usuário viu em 05/09/2026 foi
   isso: popup branco com as opções em texto claro, ilegíveis, no tema escuro.
   Dizer fundo e tinta por token custa duas linhas e vale nos dois temas.

   POR QUE NÃO `appearance: none`: reinventar o controle nativo custaria a
   seta, o teclado e o menu do sistema operacional no celular. O que se pinta
   aqui é o conteúdo do menu, não o menu. */
select option,
select optgroup {
  background-color: var(--fundo);
  color: var(--frente);
}

/* superfícies do navegador — nada aqui fica no padrão */
::selection {
  /* a L764 preenchendo, com o breu por cima: 7,1:1 nos dois temas */
  background: var(--realce);
  color: var(--breu);
}
:root {
  caret-color: var(--realce-marca);
  accent-color: var(--realce-marca);
}
/* AS DUAS MANEIRAS DE VESTIR UMA BARRA NÃO CONVIVEM, e é o MOTOR que escolhe
   qual delas vale (correção do revisor de acabamento da Fase 6b, rodada de
   design, F4, medida ao vivo antes e depois).

   O DEFEITO: `* { scrollbar-width: thin }` estava escrito solto aqui, para dar
   a barra fina a TODA superfície que rola e não só à página. Só que dizer uma
   propriedade CORRENTE num elemento desliga os `::-webkit-scrollbar` DELE no
   Chromium — e com eles o `::-webkit-scrollbar-button { display: none }` de
   baixo, que é a única regra capaz de tirar os dois BOTÕES DE SETA que o
   sistema desenha nas pontas. Resultado medido no miolo do modal, coluna
   x=1028: dois blocos de `--barra-polegar` em y=101–105 e y=785–789, separados
   do polegar por trilho. A folha prometia, em dois lugares, que eles tinham
   saído; eles estavam lá, e ainda pintados com a nossa tinta.

   ENTÃO CADA MOTOR RECEBE O CAMINHO QUE LHE DÁ CONTROLE, e a chave que os
   separa é `selector(::-webkit-scrollbar)`, sem farejar navegador:

     · onde os pseudo-elementos EXISTEM (o Chromium de hoje), ninguém diz as
       propriedades correntes — nem `auto`, que já basta para desligá-los — e
       quem desenha é o bloco `::-webkit-*`: largura nossa, trilho na camada,
       polegar em `--barra-polegar` e as pontas zeradas. Medido depois, na
       mesma coluna: trilho, polegar, e nada nas duas pontas;
     · onde eles NÃO existem (Firefox), a barra é `thin` e colorida por
       `scrollbar-color`, que herda e vale para toda superfície rolável. Fina,
       ali, não tem seta.

   O universal continua sendo universal — só mudou de bloco. A lista de
   superfícies roláveis cresce a cada tela nova, e a que for esquecida volta ao
   desenho do sistema sem que nada quebre. Não se perde gesto nenhum com as
   setas: quem rola rola com a roda, com o dedo ou com o teclado, e o alvo de
   11px de um botão de seta nunca foi caminho de ninguém. */
@supports not selector(::-webkit-scrollbar) {
  :root {
    /* `scrollbar-color` HERDA e vale para toda superfície que rola; a largura,
       não — e é por isso que ela é dita no universal, logo abaixo. */
    scrollbar-color: var(--barra-polegar) var(--camada);
  }
  * {
    scrollbar-width: thin;
  }
}
@supports selector(::-webkit-scrollbar) {
  /* AQUI NÃO SE DIZ UMA PALAVRA DAS PROPRIEDADES CORRENTES, e a razão é
     medida: dizer `scrollbar-width` ou `scrollbar-color` num elemento desliga
     os `::-webkit-scrollbar` dele MESMO COM O VALOR `auto`. Por isso as duas
     ficam presas ao bloco de cima, que só vale no motor sem pseudo-elemento —
     e por isso o `:root` também não as diz aqui. Quem escrever
     `scrollbar-color` em qualquer regra deste arquivo apaga, sem erro nenhum,
     o desenho abaixo. */
  ::-webkit-scrollbar {
    width: 11px;
    height: 11px;
  }
  ::-webkit-scrollbar-track {
    background: var(--camada);
  }
  /* CANTO VIVO TAMBÉM AQUI. O polegar trazia um raio de pílula com a
     justificativa de que motor nenhum chegava a pintá-lo; forma que não se vê
     não deixa de ser forma escrita, e num motor que leia este bloco ela
     apareceria. Pílula não é peça nossa (DESIGN.md, Shapes): o que separa o
     polegar do trilho é o fio de 3px na cor da camada. */
  ::-webkit-scrollbar-thumb {
    background: var(--barra-polegar);
    border: 3px solid var(--camada);
    border-radius: 0;
  }
  ::-webkit-scrollbar-corner {
    background: var(--camada);
  }
  /* E AQUI AS SETINHAS DAS PONTAS SAEM DE VERDADE. Uma barra desenhada por
     pseudo-elemento vem com os dois BOTÕES de seta do sistema operacional, e é
     esta linha que os tira — a mesma que o `scrollbar-width` universal
     desligava sem que ninguém visse. Medida no miolo do modal, na coluna
     x=1028, antes e depois: com os blocos de âmbar nas duas pontas, e sem. */
  ::-webkit-scrollbar-button {
    display: none;
  }
}

/* COM UM DIÁLOGO ABERTO, A PÁGINA PARA (correção do revisor de acabamento da
   Fase 6b, rodada de design, F5). O `<dialog>` modal prende o foco e escurece
   o resto, mas o navegador continua rolando a página POR BAIXO dele — e a
   390px o preço aparece: a barra do miolo do modal e a barra do documento
   ficam a 19px uma da outra, as duas acesas (o `::backdrop` não pinta a barra
   do documento), lidas como moldura em vez de duas afordâncias de rolagem.
   Com esta regra sobra uma barra só, a do miolo, e o que está atrás fica
   quieto enquanto se digita.

   `scrollbar-gutter: stable` no mesmo fôlego: sem ele a barra que some leva
   junto os seus 11px e a página inteira salta para o lado ao abrir e ao
   fechar o modal.

   EM CSS, E NÃO EM JAVASCRIPT: `:has(dialog[open])` vale para todo diálogo
   modal do sistema — o da edição rápida do painel e a lente da fotografia, no
   site e no painel — sem que os dois arquivos de JavaScript precisem combinar
   uma classe entre si, e sem deixar a página travada para sempre se um erro
   impedir a linha que a destravaria. Onde `:has` não existe, nada acontece: é
   a tela de hoje. */
html:has(dialog[open]) {
  overflow: hidden;
  scrollbar-gutter: stable;
  /* E A CALHA ESCURECE JUNTO (correção do revisor de acabamento da Fase 6b,
     rodada 2, R1). A calha que o `scrollbar-gutter` reserva fica FORA do
     `::backdrop`: o véu do diálogo cobre o bloco da página, não os 10px que a
     barra deixou guardados. Medido com o modal aberto a 1440 — papel a
     244,241,234 na coluna x=1435 contra o véu a 109,103,96 em x=1420, uma
     listra acesa de altura inteira colada à direita da janela.

     A canvas do documento é o único pincel que alcança aquela faixa, e ela só
     aceita COR: o fundo do elemento raiz é promovido à canvas inteira, mas a
     IMAGEM de fundo continua medida pela caixa da raiz — um degradê aqui
     pararia na borda esquerda da calha e não pintaria nada (medido: a calha
     voltava a 244,241,234). Então vai a cor já somada: o mesmo `--breu` a 60%
     do `::backdrop`, misturado com `--fundo` num `color-mix`. Dá 15,11,7 no
     palco, igual ao véu na vírgula, e 108,103,96 no papel contra os 109,103,96
     do véu — um degrau de nada num canal só, que nasce de o navegador compor
     transparência em 8 bits pré-multiplicados enquanto o `color-mix` soma em
     ponto flutuante. Por token, e nos dois temas de uma vez, porque `--breu` e
     `--fundo` já viram o tema.

     O `<body>` tem fundo opaco próprio, então nada disto atravessa para a
     área da página: a canvas só aparece onde o corpo não pinta, que é
     exatamente a calha. */
  background: color-mix(in srgb, var(--breu) 60%, var(--fundo));
}

/* o par anel + halo: no palco o halo é transparente e sobra só o âmbar */
:focus-visible {
  outline: 2px solid var(--foco-anel);
  outline-offset: var(--foco-afast);
  box-shadow: var(--foco-halo);
  border-radius: 2px;
}

/* ---------- 5. Tipografia ---------- */
.manifesto {
  font-size: var(--t-manifesto);
  font-variation-settings: 'wdth' 98, 'wght' 850;
  line-height: 0.94;
  letter-spacing: -0.035em;
  text-wrap: balance;
  margin: 0;
}
.titulo {
  font-size: var(--t-titulo);
  font-variation-settings: 'wdth' 108, 'wght' 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.secao {
  font-size: var(--t-secao);
  font-variation-settings: 'wdth' 104, 'wght' 760;
  line-height: 1.1;
  letter-spacing: -0.024em;
  text-wrap: balance;
}
.sub {
  font-size: var(--t-sub);
  font-variation-settings: 'wdth' 100, 'wght' 620;
  line-height: 1.28;
  letter-spacing: -0.014em;
}
.corpo {
  max-width: var(--medida);
  color: var(--frente-2);
}
.corpo + .corpo {
  margin-top: var(--e3);
}
.corpo strong {
  color: var(--frente);
  font-variation-settings: 'wdth' 100, 'wght' 640;
}

/* o aparato técnico: mono, caixa alta, sempre com referente real */
.tec {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--frente-3);
}
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ---------- 6. Estrutura ---------- */
.faixa {
  padding-inline: var(--margem);
}
.limite {
  max-width: 78rem;
  margin-inline: auto;
}
.ato {
  position: relative;
  padding-block: var(--e8);
}
/* CAMPOS DE GELATINA — a cor toma a região inteira, não pinga como brilho.
   Cada ato roda sob uma gelatina; nenhuma delas é o preto do palco. */
.ato--congo {
  background: linear-gradient(168deg, #141c6e 0%, #101a52 46%, #0d1230 100%);
}
.ato--magenta {
  background: linear-gradient(196deg, #12080f 0%, #3d0f30 52%, #12080f 100%);
}
.ato--brasa {
  background: linear-gradient(172deg, #43140a 0%, #2c0c06 58%, #140704 100%);
}
.ato--congo,
.ato--magenta,
.ato--brasa {
  --linha: rgba(252, 248, 241, 0.2);
  --linha-forte: rgba(252, 248, 241, 0.4);
  /* o campo de gelatina é mais claro que o preto do palco, então o texto
     terciário sobe junto: calibrado no preto, ele reprovaria aqui. */
  --frente-3: var(--luz-3-campo);
  --luz-3: var(--luz-3-campo);
}
/* O CAMPO DE GELATINA SOBRE PAPEL — a gelatina impressa, não uma ilha de
   palco. Foi a decisão de desenho desta fase, e a razão é de composição, não
   de gosto: a home tem três campos seguidos e, mantidos escuros, o "tema
   claro" seria uma folha de papel com o palco inteiro dentro dela — a luz de
   serviço acesa em lugar nenhum. Impressa, a mesma gelatina continua tomando
   a região inteira e continua sendo a mesma cor do catálogo Lee: o que muda é
   que a lâmpada está do outro lado da folha.

   A aresta continua dura: quem recorta o campo é a borda do ato, como no
   palco. E A REGRA DO CAMPO MAIS CLARO vale ao contrário, que é a mesma lei:
   a superfície que se AFASTA do fundo puxa o terciário para longe dela — no
   palco ele sobe para #b2a595, no papel desce para #565148. */
html[data-tema='claro'] .ato--congo {
  background: linear-gradient(
    168deg,
    color-mix(in srgb, var(--gel-181) 12%, var(--fundo)) 0%,
    color-mix(in srgb, var(--gel-181) 18%, var(--fundo)) 46%,
    color-mix(in srgb, var(--gel-119) 24%, var(--fundo)) 100%
  );
}
html[data-tema='claro'] .ato--magenta {
  background: linear-gradient(
    196deg,
    color-mix(in srgb, var(--gel-128) 6%, var(--fundo)) 0%,
    color-mix(in srgb, var(--gel-128) 20%, var(--fundo)) 52%,
    color-mix(in srgb, var(--gel-128) 6%, var(--fundo)) 100%
  );
}
html[data-tema='claro'] .ato--brasa {
  background: linear-gradient(
    172deg,
    color-mix(in srgb, var(--gel-764) 22%, var(--fundo)) 0%,
    color-mix(in srgb, var(--gel-764) 15%, var(--fundo)) 58%,
    color-mix(in srgb, var(--gel-106) 12%, var(--fundo)) 100%
  );
}
html[data-tema='claro'] .ato--congo,
html[data-tema='claro'] .ato--magenta,
html[data-tema='claro'] .ato--brasa {
  /* fios um degrau mais fortes, como no palco, porque o fundo saiu do papel */
  --linha: rgba(15, 20, 19, 0.22);
  --linha-forte: rgba(15, 20, 19, 0.58);
}
.ato > .limite {
  position: relative;
  z-index: 2;
}

/* ---------- 7. O feixe: a luz da própria página ---------- */
.luzes {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
/* Feixes de uma vara só: mesma origem no alto, mesma inclinação,
   cone estreito com miolo aceso e borda que se dissolve na fumaça.
   O recorte dá a forma; a máscara tira a aresta. */
.feixe {
  position: absolute;
  top: -10%;
  width: 20vw;
  height: 126%;
  /* A VARA, NOS DOIS TEMAS. Sobre o palco o feixe SOMA (screen): é luz. Sobre
     papel screen não faz nada — somar luz a uma folha branca não dá feixe
     nenhum —, então ele SUBTRAI (multiply) e vira o que a luz é do outro lado
     da lente: gelatina impressa. Mesma vara, mesma inclinação, mesmo recorte;
     a lâmpada é que desceu. */
  opacity: calc(var(--deixa) * var(--carga, 0.55) * var(--feixe-nivel));
  mix-blend-mode: var(--feixe-mistura);
  filter: blur(20px);
  transform-origin: 50% 0%;
  transform: rotate(var(--rake, 8deg));
  clip-path: polygon(38% 0%, 62% 0%, 104% 100%, -4% 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 52%, transparent 92%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 52%, transparent 92%);
  will-change: opacity;
}
.feixe--a {
  left: 4vw;
  --carga: 0.66;
  --rake: 7deg;
  background: linear-gradient(180deg, var(--gel-119) 0%, var(--gel-181) 58%, transparent 100%);
}
.feixe--b {
  left: 26vw;
  --carga: 0.54;
  --rake: 7deg;
  background: linear-gradient(180deg, var(--gel-162) 0%, var(--gel-764) 62%, transparent 100%);
}
.feixe--c {
  right: 8vw;
  --carga: 0.46;
  --rake: 7deg;
  background: linear-gradient(180deg, var(--gel-128) 0%, var(--gel-181) 60%, transparent 100%);
}
/* poça de luz: o especial que segura o texto */
.poca {
  position: absolute;
  border-radius: 50%;
  opacity: calc(var(--deixa) * 0.9);
  mix-blend-mode: screen;
  filter: blur(60px);
  pointer-events: none;
}

/* ---------- 8. Navegação ---------- */
.ribalta {
  position: sticky;
  top: 0;
  z-index: 60;
  background: color-mix(in srgb, var(--fundo) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--linha);
}
.ribalta__i {
  display: flex;
  align-items: center;
  gap: var(--e4);
  min-height: 4.5rem;
  padding-inline: var(--margem);
}
.marca {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding-block: 0.35rem;
  text-decoration: none;
  flex: 0 0 auto;
}
.marca img {
  height: 2.3rem;
  width: auto;
}
.marca__nome {
  display: grid;
  line-height: 0.96;
  font-variation-settings: 'wdth' 86, 'wght' 800;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.marca__nome span:last-child {
  color: var(--frente-2);
  font-variation-settings: 'wdth' 86, 'wght' 500;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
}
.menu {
  display: flex;
  gap: clamp(0.9rem, 1.7vw, 2rem);
  margin-left: auto;
  align-items: center;
}
.menu a {
  position: relative;
  text-decoration: none;
  font-variation-settings: 'wdth' 90, 'wght' 620;
  font-size: 0.82rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--frente-2);
  padding-block: 0.4rem;
  transition: color 0.22s var(--fader);
}
.menu a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.15rem;
  height: 2px;
  background: var(--realce-marca);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.32s var(--fader);
}
.menu a:hover,
.menu a:focus-visible {
  color: var(--frente);
}
.menu a:hover::after,
.menu a:focus-visible::after {
  transform: scaleX(1);
}
.menu a[aria-current='page'] {
  color: var(--frente);
}
.menu a[aria-current='page']::after {
  transform: scaleX(1);
}
.menu__botao {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  padding: 0.78rem 0.9rem;
  cursor: pointer;
  font-family: var(--face-tec);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ---------- 8b. O INTERRUPTOR DA LUZ DE SERVIÇO ----------
   Um canal da mesa, e não um ícone de sol e lua. O marcador é o mesmo trilho
   de 3px com o cursor transbordando dos faders da abertura: com o tema
   escuro o canal está em zero e só o cursor aparece na base; com a luz de
   serviço acesa ele está em 100. É o referente real do que o botão faz —
   quem acende a luz de serviço sobe um canal —, e é a única peça do sistema
   que já existia e podia dizer isso sem inventar um desenho novo.

   Sem JavaScript o botão não aparece: ele sobe com "hidden" no HTML e é o
   tema.js que o revela. Um interruptor que não interrompe nada seria pior
   do que interruptor nenhum. */
.luz-servico {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex: 0 0 auto;
  padding: 0.5rem 0.72rem;
  background: none;
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  cursor: pointer;
  color: var(--frente-2);
  font-family: var(--face-tec);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.22s var(--fader), border-color 0.22s var(--fader);
}
.luz-servico[hidden] {
  display: none;
}
.luz-servico:hover,
.luz-servico:focus-visible {
  color: var(--frente);
  border-color: var(--frente);
}
.luz-servico__canal {
  --curso: 0.95rem;
  position: relative;
  flex: 0 0 auto;
  width: 3px;
  height: var(--curso);
  background: var(--trilho);
}
/* o preenchimento do canal, e o cursor de 3px transbordando 3px de cada lado
   por cima dele — as duas peças do fader da mesa, na escala do controle.
   Os dois se movem por transform (escala e deslocamento) e não por altura:
   animar altura repagina a barra a cada quadro. */
.luz-servico__canal::before,
.luz-servico__canal::after {
  content: '';
  position: absolute;
  background: var(--realce-marca);
  transition: transform 0.24s var(--fader);
}
.luz-servico__canal::before {
  inset: 0;
  transform-origin: bottom;
  transform: scaleY(0);
}
.luz-servico__canal::after {
  left: -3px;
  right: -3px;
  bottom: 0;
  height: 3px;
}
.luz-servico[aria-pressed='true'] .luz-servico__canal::before {
  transform: scaleY(1);
}
.luz-servico[aria-pressed='true'] .luz-servico__canal::after {
  transform: translateY(calc(3px - var(--curso)));
}

/* ---------- 9. Herói ---------- */
/* ABERTURA — uma peça só: o palco em sangria, o manifesto dentro da poça
   de luz, e a mesa de luz com os oito canais acesa no mesmo feixe.
   Nada aqui é hero-com-frase-e-botão: a prova mora dentro da luz. */
/* No celular a ordem é: palco, manifesto, a frase com a ação, e só então
   a mesa. O manifesto nunca fica partido ao meio por uma peça de hardware. */
.abertura {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto auto;
  background: var(--fundo);
  isolation: isolate;
  overflow: hidden;
}
.abertura__palco {
  grid-column: 1;
  grid-row: 1;
}
.abertura__texto {
  grid-column: 1;
  grid-row: 2;
}
.abertura__rodape {
  grid-column: 1;
  grid-row: 3;
}
.mesa {
  grid-column: 1;
  grid-row: 4;
}
.abertura__palco {
  position: relative;
  overflow: hidden;
  background: var(--fundo);
}
.abertura__palco > img {
  width: 100%;
  height: 34svh;
  object-fit: cover;
  object-position: 50% 40%;
  filter: brightness(calc(0.6 + var(--deixa) * 0.4))
    contrast(calc(1.02 + var(--deixa) * 0.08))
    saturate(calc(0.8 + var(--deixa) * 0.32));
  will-change: filter;
}
/* A VINHETA, NOS DOIS TEMAS. Fora do foco do refletor o palco cai para o
   preto; sobre papel o mesmo gesto lava a foto para a folha, e é ele que
   devolve à coluna da direita o fundo em que a tinta se lê. Um token só
   (--vinheta) faz os dois: 11 10 12 no palco, 244 241 234 no papel. */
.abertura__vinheta {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(
    130% 120% at 42% 46%,
    transparent 0%,
    rgb(var(--vinheta) / 0.1) 50%,
    rgb(var(--vinheta) / 0.72) 100%
  );
}
/* A POÇA: um especial de recorte duro. A borda corta, não desbota —
   é o que separa um refletor de um brilho genérico. É item da grade,
   não posição absoluta, para cair sempre sobre o texto: em cima da foto
   no desktop, sobre o bloco de texto no celular. */
.abertura__poca {
  grid-column: 1;
  grid-row: 2 / 4;
  z-index: 1;
  align-self: stretch;
  margin: -6% -24% -10%;
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(10px);
  opacity: calc(var(--deixa) * 0.95);
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--gel-162) 52%, transparent) 0%,
    color-mix(in srgb, var(--gel-162) 40%, transparent) 58%,
    color-mix(in srgb, var(--gel-764) 26%, transparent) 74%,
    color-mix(in srgb, var(--gel-764) 19%, transparent) 78%,
    transparent 79.5%
  );
}
/* A POÇA SOBRE PAPEL — a mesma âmbar, agora tinta. O especial vira uma poça
   de gelatina impressa, e a PARADA DURA em 79,5% continua sendo a peça: é ela
   que separa um refletor de um brilho genérico, e ela não depende de estar
   sobre o preto. As paradas são gelatina misturada com branco porque em
   multiply o branco é o nada: quanto mais branco, menos tinta. Medido, o
   ponto mais carregado deixa o papel em 0,50 de luminância e o manifesto em
   tinta passa de 7:1 por cima dele. */
html[data-tema='claro'] .abertura__poca {
  mix-blend-mode: multiply;
  opacity: calc(var(--deixa) * 0.9);
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--gel-162) 42%, #fff) 0%,
    color-mix(in srgb, var(--gel-162) 50%, #fff) 58%,
    color-mix(in srgb, var(--gel-764) 46%, #fff) 74%,
    color-mix(in srgb, var(--gel-764) 52%, #fff) 78%,
    #fff 79.5%
  );
}
.abertura__texto {
  position: relative;
  z-index: 3;
  padding: var(--e5) var(--margem) 0;
}
/* A PALAVRA ACESA. No palco ela é a L162: dentro da poça, o miolo do feixe.
   Sobre papel nenhuma gelatina pode marcá-la — laranja sobre âmbar dá 2,5:1 e
   a própria L162 dá 1,3:1 —, então o calor continua vindo da poça em volta e
   a palavra vira a palavra SUBLINHADA: a marca do diretor no texto, em tinta
   cheia, 15:1 por cima da poça. */
.manifesto em {
  font-style: normal;
  color: var(--quente-texto);
}
html[data-tema='claro'] .manifesto em {
  text-decoration: underline;
  text-decoration-thickness: 0.055em;
  text-underline-offset: 0.1em;
}
.abertura__rodape {
  position: relative;
  z-index: 3;
  padding: var(--e4) var(--margem) var(--e6);
}
.abertura__linha {
  max-width: 40ch;
  color: var(--frente-2);
  font-size: clamp(1.02rem, 0.6vw + 0.85rem, 1.16rem);
  line-height: 1.55;
}
.acoes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  margin-top: var(--e4);
}

/* ---------- 10. Botões ---------- */
.botao {
  --bg: var(--gel-764);
  --fg: var(--breu);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.92rem 1.5rem;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid transparent;
  border-radius: 2px;
  text-decoration: none;
  cursor: pointer;
  font-variation-settings: 'wdth' 96, 'wght' 700;
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: background 0.24s var(--fader), transform 0.24s var(--fader),
    box-shadow 0.24s var(--fader), color 0.24s var(--fader);
}
.botao:hover {
  background: var(--gel-162);
  box-shadow: var(--brilho-botao);
}
/* no foco o brilho vem acompanhado do halo do tema; no palco o halo é
   transparente e no papel o brilho é que some — nunca os dois de uma vez */
.botao:focus-visible {
  background: var(--gel-162);
  box-shadow: var(--foco-halo), var(--brilho-botao);
}
.botao:active {
  transform: translateY(1px);
}
.botao--vazado {
  --bg: transparent;
  --fg: var(--frente);
  border-color: var(--linha-forte);
}
/* invertido: o texto passa a ser o FUNDO corrente, não um preto cravado —
   sobre papel um preto cravado sumiria dentro da tinta que virou fundo */
.botao--vazado:hover {
  --fg: var(--fundo);
  background: var(--frente);
  box-shadow: none;
}
.botao--vazado:focus-visible {
  --fg: var(--fundo);
  background: var(--frente);
  box-shadow: var(--foco-halo);
}
.botao[disabled],
.botao[aria-disabled='true'] {
  opacity: 0.45;
  pointer-events: none;
}

/* ---------- 11. A MESA — oito canais na mesma escala ----------
   Um instrumento, não oito cartões: faders idênticos ombro a ombro,
   todos em 100, lidos de uma varredura só. Sem caixa, sem moldura.
   Cada canal traz o número real da gelatina Lee que dá sua cor. */
.mesa {
  position: relative;
  z-index: 3;
  background: linear-gradient(to bottom, var(--camada) 0%, var(--fundo) 88%);
  border-top: 1px solid var(--linha-forte);
}
.mesa__i {
  max-width: 78rem;
  margin-inline: auto;
  padding: var(--e4) var(--margem) var(--e5);
  display: grid;
  gap: var(--e4);
}
/* subgrid: os oito canais compartilham as mesmas quatro linhas de base.
   Sem isso cada um flutua na sua altura e a régua deixa de ser régua.

   E A RÉGUA É O CONTÊINER DO SEU PRÓPRIO NÚMERO (correção do revisor de
   acabamento da Fase 6b, rodada 2, R2): com `container-type: inline-size`
   aqui, o valor de cada canal pode ser dimensionado pela LARGURA DE TRILHO
   que ele de fato recebeu, e não pela largura da janela. O porquê está no
   comentário de `.fader__valor`. Containment em linha não mexe na altura,
   então a subgrade das quatro linhas de base continua de pé — medido: com
   nove canais a 1000px, os oito trilhos ficam todos em y=556 e os oito
   valores em y=607, como antes. */
.faders {
  display: grid;
  container-type: inline-size;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto auto auto;
  column-gap: var(--e3);
  row-gap: var(--e4);
  align-items: end;
}
.fader {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  gap: 0.3rem;
  align-content: end;
  min-width: 0;
}
@supports not (grid-template-rows: subgrid) {
  .fader {
    grid-row: auto;
    grid-template-rows: auto auto auto auto;
  }
}
.fader__id {
  display: flex;
  gap: 0.4rem;
  color: var(--frente-3);
  white-space: nowrap;
}
/* o número da gelatina guarda o matiz dela, mas clareado o bastante
   para se ler sobre a mesa escura — congo blue puro sumiria. */
/* No desktop os oito canais se veem de uma vez. Na fileira rolante do
   celular, cada canal declara o total — o rig tem oito, e isso precisa
   caber na primeira dobra sem custar altura nenhuma. */
.fader__total {
  display: none;
  color: var(--frente-3);
}
/* A LÂMPADA QUE SOBE OU DESCE, num lugar só: a gelatina é misturada com a
   FRENTE corrente. Sobre a mesa escura isso a clareia (congo blue puro
   sumiria); sobre a mesa clara isso a escurece (âmbar puro sobre papel dá
   1,3:1). Mesma gelatina, mesmo cargo, outra altura de lâmpada. */
.fader__id b {
  color: color-mix(in srgb, var(--gel, var(--gel-764)) var(--gel-em-texto), var(--frente));
  font-weight: 500;
}
/* o curso do fader: trilho vertical com o cursor no topo, tudo em 100 */
.fader__trilho {
  position: relative;
  height: 2.75rem;
  width: 3px;
  background: var(--trilho);
  margin-bottom: 0.15rem;
}
.fader__trilho i {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--deixa) * 100%);
  background: color-mix(in srgb, var(--gel, var(--gel-764)) var(--gel-em-traco), var(--frente));
  will-change: height;
}
.fader__trilho i::after {
  content: '';
  position: absolute;
  top: 0;
  left: -4px;
  right: -4px;
  height: 3px;
  background: var(--frente);
}
/* O NÚMERO É MEDIDO PELO TRILHO QUE RECEBEU, e não pela janela (correção do
   revisor de acabamento da Fase 6b, rodada 2, R2). A régua de fileiras
   equilibradas da F3 conta as colunas no servidor, e uma contagem fixa não
   tem piso: entre 56rem e ~69rem os oito canais caem em trilhos de 85 a 110px
   e o "53%/47%" do CH 05, travado em `nowrap` a 1,45rem, media 105px — ele
   forçava a largura mínima automática do seu próprio item e transbordava
   sobre o CH 06. Medido a 1000px: trilho de 97px, valor de 105px.

   O piso de 7rem que o `auto-fit` dava resolvia isso quebrando a fileira — e
   era essa quebra que largava o nono canal órfão, que é o defeito que a F3
   veio consertar. Um não cabe com o outro: a 1000px, oito trilhos de 7rem
   pedem 1.005px e só há 889. O que cabe é a TERCEIRA saída, e é a que a mesa
   já usa no celular: quando aperta, o número encolhe. Aqui ele encolhe na
   medida exata do trilho — `100cqw` é a régua inteira, menos os vãos, dividido
   pela contagem de colunas que o servidor escreveu.

   E QUEM MEDE O TEXTO É O SERVIDOR (Fase 6c, achados A1 e A2 do revisor de
   acabamento da 6b). Até aqui o corpo saía do trilho multiplicado por 0,21 —
   um fator tirado de UMA string semeada, "53%/47%". A folha não sabe medir
   texto, e o painel passou a criar canais: com "12.345.678" no campo, o valor
   pedia 135px num trilho de 124px a 1440 e, com `nowrap`, pintava por cima do
   canal vizinho. Agora o servidor escreve `--largura-max` no `<ol>` — quanto
   o valor MAIS LARGO da régua ocupa, em múltiplos do corpo da letra, somado
   caractere a caractere por `App\Support\Mesa::largura` com uma tabela de
   pesos MEDIDA no navegador (dígito 0,587; ponto e vírgula 0,282; barra
   0,267; por-cento 0,948). Contar caracteres não serviria: "73%" gasta 0,707
   por caractere e "12.147" gasta 0,536.

   O 0,95 é a folga: o valor ocupa no máximo 95% do trilho, e nunca encosta no
   vizinho. UMA medida para a régua inteira, e não uma por trilho, para que
   dois números da mesma régua não saiam em tamanhos diferentes (A2).

   A GARANTIA, agora dita com a sua condição: nenhum valor sai do seu trilho
   enquanto o corpo calculado ficar acima do chão de 1,05rem. Com oito canais
   a 1440 (trilho de 124px) isso vale até `--largura-max` ≈ 7,0, que é o que
   doze dígitos gastam — e é por isso que `CanalRequest` recusa valor com mais
   de doze caracteres. Abaixo do chão manda a legibilidade, não a geometria.

   O `min()` guarda o que já estava certo: onde o trilho é largo o bastante, a
   medida antiga (`clamp(1.45rem, 2vw, 1.8rem)`) é a menor das duas e continua
   mandando — é o caso da régua de NOVE canais a 1440, porque cinco colunas dão
   225px de trilho. Com OITO canais a 1440 o trilho é de 124px e os valores de
   hoje dão `--largura-max` 4,511: o número sai a 26,1px, o mesmo que o fator
   antigo dava, o que prova que nada se perdeu na troca. O `max()` põe o chão
   de legibilidade. A declaração de cima fica como rede para o motor sem
   unidade de contêiner: ali o valor volta a ser o de sempre. */
.fader__valor {
  font-size: clamp(1.45rem, 2vw, 1.8rem);
  font-size: max(
    1.05rem,
    min(
      clamp(1.45rem, 2vw, 1.8rem),
      calc(
        (100cqw - (var(--colunas, 8) - 1) * var(--e3)) * 0.95
        / var(--colunas, 8) / var(--largura-max, 4.6)
      )
    )
  );
  white-space: nowrap;
  font-variation-settings: 'wdth' 100, 'wght' 790;
  letter-spacing: -0.035em;
  line-height: 0.98;
  color: var(--frente);
}
.fader__rotulo {
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--frente-2);
  font-variation-settings: 'wdth' 94, 'wght' 480;
  text-wrap: pretty;
}
.mesa__pe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e2) var(--e4);
  padding-top: var(--e3);
  border-top: 1px solid var(--linha);
}
.mesa__pe .tec {
  margin-right: auto;
}
.mesa__link {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--frente-2);
  padding-block: 0.7rem;
}
.mesa__link:hover,
.mesa__link:focus-visible {
  color: var(--frente);
}

/* ---------- 12. Blocos de conteúdo ---------- */
.duo {
  display: grid;
  gap: var(--e6);
  align-items: start;
}
.bloco-titulo {
  display: grid;
  gap: var(--e3);
  margin-bottom: var(--e5);
}
.regra {
  height: 1px;
  background: var(--linha);
  border: 0;
  margin-block: var(--e6);
}

/* citação / manifesto interno */
.fala {
  border: 0;
  margin: 0;
  padding: 0;
  max-width: 24ch;
  font-size: clamp(1.7rem, 3.4vw, 2.8rem);
  font-variation-settings: 'wdth' 106, 'wght' 700;
  line-height: 1.06;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.fala cite {
  display: block;
  margin-top: var(--e3);
  font-style: normal;
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--frente-3);
}

/* ---------- 12b. O bloco vazio na grade (Fase 6b, item 5) ----------
   Um texto esvaziado pelo painel some da página com o elemento que o
   embrulhava (a diretiva `@bloco` das sete páginas). Quando o que sumiu era
   uma das duas colunas de um `.duo` — a coluna de texto ao lado do retrato
   do fundador, a fala ao lado do parágrafo —, a que ficou ocupa a largura
   inteira em vez de dividir a grade com um vão em branco. `:has(> :only-child)`
   diz exatamente isso: "a grade que ficou com um filho só". Onde `:has` não
   existe (Firefox anterior a 121), a coluna que sobrou continua na metade
   dela — um vão, não uma quebra. Abaixo de 56rem o `.duo` já é uma coluna. */
@media (min-width: 56rem) {
  .duo:has(> :only-child),
  .duo--largo:has(> :only-child) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- 13. Acervo ---------- */
/* Mosaico de linhas iguais: a cena ocupa módulos inteiros da grade,
   nunca frações — nenhuma cena deixa buraco atrás de si.

   O `dense` SAIU (Fase 6d, caça a bugs, rodada 3). Ele fechava buraco
   PUXANDO uma cena de baixo para cima, e com isso a ordem da TELA deixava
   de ser a ordem do documento — enquanto a lente e o Tab continuavam
   andando pela do documento. Medido a 390, com duas colunas: a segunda
   fotografia do HTML é larga, não cabia na sobra da primeira fileira, e o
   navegador subia a terceira para o buraco. Na tela via-se 1ª e 3ª lado a
   lado; abrir a primeira e apertar "Próxima fotografia" pulava a vizinha e
   caía na larga de baixo, com o contador dizendo "2 de 20" para a foto que
   é a 3ª da leitura. É a ordem significativa da página trocada por um
   buraco a menos, e o buraco é o mal menor.

   A 390 não sobra nem buraco: ali nenhuma cena ocupa duas colunas (ver a
   regra do estreito), então a grade é regular e fecha sempre. */
.acervo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: clamp(8.5rem, 21vw, 13.5rem);
  grid-auto-flow: row;
  gap: var(--e1);
}
/* teaser da home: bloco regular, sem variação de módulo */
.acervo--regular > .cena {
  grid-row: span 2;
  grid-column: span 1;
}
.cena {
  position: relative;
  margin: 0;
  background: var(--camada);
  overflow: hidden;
}
/* Todo módulo tem a mesma altura; a variação é só de largura.
   Assim a grade fecha sempre, sem cena deixando buraco atrás de si. */
.acervo > .cena {
  grid-row: span 2;
  grid-column: span 1;
}
.acervo > .cena--larga {
  grid-column: span 2;
}
.acervo > .cena--alta img {
  object-position: 50% 28%;
}
/* o teaser da home ignora a variação de largura: bloco regular */
.acervo--regular > .cena--larga {
  grid-column: span 1;
}
.cena img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.86) saturate(0.96);
  transition: filter 0.5s var(--fader), transform 0.7s var(--fader);
}
.cena:hover img,
.cena:focus-within img {
  filter: brightness(1.06) saturate(1.12);
  transform: scale(1.03);
}
/* A ficha não depende de mouse: ela fica. A página promete os campos
   "à vista de todo mundo" e é assim que a promessa se cumpre. */
.cena__ficha {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: var(--e4) var(--e2) var(--e2);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.55rem;
  /* faixa de altura fixa: todas as fichas fecham na mesma linha de base,
     senão o pé do mosaico fica serrilhado. */
  min-height: 2.9rem;
  align-content: end;
  font-family: var(--face-tec);
  font-size: 0.66rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  /* A FICHA NÃO TROCA DE TEMA: ela mora sobre a fotografia, e a fotografia
     é a mesma nos dois. Escurecer o pé da foto é o que a torna legível — no
     papel também, porque ali o fundo continua sendo a foto, não a folha. */
  color: var(--luz-2);
  background: linear-gradient(
    to top,
    rgba(11, 10, 12, 0.93) 0%,
    rgba(11, 10, 12, 0.72) 46%,
    transparent 100%
  );
}
/* A ETIQUETA DE ARQUIVO ESCREVE SOBRE A FOLHA, E NÃO SOBRE A FOTO (Fase 6d,
   caça a bugs, rodada 2). A tinta era `--luz` — o branco de quem escreve por
   cima de uma fotografia —, e este <span> é `position: static`: ele cai na
   faixa da <figure> ABAIXO da imagem, sobre o fundo da página. No escuro
   passava por acidente; no tema claro dava 1,17:1 contra o papel e a etiqueta
   simplesmente desaparecia. `--frente-2` é a tinta secundária de cada tema, e
   é a que este texto sempre quis: ele é aparato de catálogo, não legenda de
   cena. */
/* E PARA ESCREVER SOBRE A FOLHA ELA PRECISA ESTAR FORA DA CHAPA (Fase 6d,
   caça a bugs, rodada 4). A regra acima descrevia o lugar certo e a etiqueta
   estava no lugar errado: dentro da `<figure class="cena">`, que recorta
   (`overflow: hidden`, o zoom da fotografia) e tem altura travada pela
   proporção — o span caía inteiro abaixo da borda e nunca era pintado. A
   `.prancha` empilha as duas coisas que sempre foram duas: a chapa e o número
   de catálogo dela. */
.prancha {
  display: grid;
  gap: var(--e2);
}
.cena__num {
  color: var(--frente-2);
  font-weight: 700;
}
.a-completar {
  color: var(--gel-162);
  border-bottom: 1px dashed color-mix(in srgb, var(--gel-162) 55%, transparent);
}
/* Sobre papel a L162 dá 1,3:1 e a marca sumiria: a tinta escreve e a gelatina
   de ação vira o tracejado (3,0:1) — a marca continua sendo a marca, e continua
   sendo gelatina.

   A EXCEÇÃO DA FICHA DA CENA SAIU (Fase 6b, item 11). Havia aqui uma segunda
   regra, para `.cena__ficha .a-completar`, porque na legenda do acervo o fundo
   não é a folha — é a fotografia com o degradê preto por baixo — e ali a L162
   continuava certa nos dois temas. A página do Acervo deixou de marcar campo em
   branco, então não há mais marca dentro de ficha nenhuma, e uma regra para um
   seletor que não existe é uma armadilha para quem vier depois.

   A CLASSE FICA, e é usada: o número da pendência na tela de início do painel
   (`painel/inicio.blade.php`) é o que ela veste hoje — e era ele que ficava
   ilegível quando a regra estava presa a `.corpo`. */
html[data-tema='claro'] .a-completar {
  color: var(--frente);
  border-bottom-color: var(--realce-marca);
}

/* ---------- 14. Ficha técnica / dados (luz de serviço) ---------- */
.ficha {
  display: grid;
  grid-template-columns: minmax(11rem, 16rem) 1fr;
  border-top: 1px solid var(--linha);
}
.ficha > dt,
.ficha > dd {
  padding: 0.82rem var(--e3) 0.82rem 0;
  border-bottom: 1px solid var(--linha);
}
.ficha > dt {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--frente-3);
  padding-left: 0;
}
.ficha > dd {
  font-variant-numeric: tabular-nums;
  color: var(--frente);
}
.ficha > dd b {
  font-variation-settings: 'wdth' 100, 'wght' 700;
}

/* ---------- 15. Comunicados ---------- */
.busca {
  display: flex;
  gap: var(--e2);
  align-items: center;
  border-bottom: 2px solid var(--linha-forte);
  padding-bottom: var(--e2);
  max-width: 32rem;
}
.busca__rotulo {
  flex: 0 0 auto;
  color: var(--frente-2);
}
.busca input {
  flex: 1;
  background: none;
  border: 0;
  padding: 0.35rem 0;
  font-size: 1.05rem;
}
.busca input::placeholder {
  color: var(--frente-3);
  opacity: 1;
}
.busca input:focus {
  outline: none;
}
.busca:focus-within {
  border-bottom-color: var(--gel-106);
}
/* O RETORNO DA BUSCA (Fase 6d, caça a bugs, rodada 3): a região viva que diz
   quantos comunicados sobraram. Nasce vazia e só ocupa altura quando tem o
   que dizer — `min-height` seria uma faixa de nada abaixo do campo em toda
   visita, e `display:none` a tiraria da árvore de acessibilidade, que é
   justamente onde ela precisa estar para ser anunciada. */
.busca__resultado {
  margin: var(--e2) 0 0;
  color: var(--frente-2);
}
.busca__resultado:empty {
  margin: 0;
}
.avisos {
  display: grid;
  border-top: 1px solid var(--linha);
}
.aviso {
  display: grid;
  gap: var(--e2);
  padding-block: var(--e5);
  border-bottom: 1px solid var(--linha);
  grid-template-columns: 1fr;
}
.aviso__data {
  display: flex;
  gap: var(--e2);
  align-items: baseline;
  flex-wrap: wrap;
}
/* o tipo do comunicado: no palco é a L162; sobre papel a gelatina sai do
   texto e a ênfase volta a ser densidade de tinta — o tipo em tinta cheia ao
   lado da data em terciário. */
.aviso__tipo {
  color: var(--quente-texto);
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
}
.aviso__acao {
  margin-top: var(--e2);
  /* Vários botões (29/10/2026): lado a lado enquanto couberem, e um por
     linha no celular. O primeiro é cheio e os demais vazados — a classe
     decide; aqui só o respiro entre eles. */
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
}
/* A lista dentro de um comunicado (Fase 6): o texto passou a ser HTML limpo
   e pode enumerar — documentos a apresentar, etapas, prazos. O `ul, ol` da
   base zera marcador e recuo para o site inteiro; aqui os dois voltam, com o
   recuo e o respiro da escada, porque uma lista sem marcador é um parágrafo
   picotado. `.corpo` chega pelo Texto::html, que o põe em cada bloco de
   primeiro nível. */
/* A LISTA ANINHADA CAI NA MESMA REGRA (Fase 6d, caça a bugs, rodada 5).
   `Texto::html` põe `.corpo` só no bloco de PRIMEIRO NÍVEL, e estas regras
   pediam a classe: a sublista — que o editor mostra com marcador e recuo,
   porque lá o seletor é de descendente — caía na base do site
   (`ul, ol { padding: 0; list-style: none }`) e saía publicada sem bolinha e
   sem recuo, com os subitens idênticos aos de cima. A hierarquia que a pessoa
   montou com o Tab desaparecia entre o editor e a página. Alcançando também
   `.corpo ul` e `.corpo ol`, o marcador vai até o fundo da lista. */
.aviso ul.corpo,
.aviso ol.corpo,
.aviso .corpo ul,
.aviso .corpo ol {
  padding-left: 1.4em;
  margin-top: var(--e2);
}
.aviso ul.corpo,
.aviso .corpo ul {
  list-style: disc;
}
.aviso ol.corpo,
.aviso .corpo ol {
  list-style: decimal;
}
.aviso .corpo li + li {
  margin-top: var(--e1);
}
/* Comunicado vencido continua legível — é registro, não ruído. Recua um
   passo em intensidade, e o selo diz por quê. */
.aviso--encerrado .secao,
.aviso--encerrado .corpo {
  color: var(--frente-2);
}
.aviso--encerrado .aviso__tipo {
  color: var(--frente-3);
}
.selo-encerrado {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  color: var(--frente-2);
}
.vazio {
  padding: var(--e7) 0;
  display: grid;
  gap: var(--e2);
  justify-items: start;
  border-bottom: 1px solid var(--linha);
}

/* tira do último comunicado, presente em toda página */
/* A TIRA — L119 misturada com a segunda camada. No palco é uma superfície
   MAIS CLARA que o preto; sobre papel é uma superfície mais ESCURA que a
   folha. Nos dois casos ela se afasta do fundo, e nos dois casos o terciário
   se afasta dela: sobe para #b2a595 no palco, desce para o secundário no
   papel (medido: #5f5a51 daria 3,9:1 ali). */
.tira {
  background: color-mix(in srgb, var(--gel-119) var(--tira-carga), var(--camada));
  border-block: 1px solid var(--linha-forte);
  --frente-3: var(--luz-3-campo);
  --luz-3: var(--luz-3-campo);
}
html[data-tema='claro'] .tira {
  --frente-3: var(--frente-2);
  --luz-3: var(--frente-2);
}
/* O TIPO ("CONVOCAÇÃO", "EDITAL") é o único texto colorido da tira: ele
   separa a natureza do aviso do título do aviso, e por isso sobe da escada
   de tinta. Quem faz esse serviço é --realce-texto, nunca --realce cru: no
   palco os dois são a mesma L764 (5,4:1 sobre a tira) e nada muda; sobre
   papel a gelatina crua cai para 1,9:1 nesta faixa e o tipo some, enquanto
   --realce-texto passa para a tinta e o tipo continua o mais escuro da
   linha. É a regra do bloco de tokens lá em cima — --realce só PREENCHE. */
.tira__tipo {
  color: var(--realce-texto);
}
.tira__i {
  max-width: 78rem;
  margin-inline: auto;
  padding: var(--e3) var(--margem);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e1) var(--e3);
  align-items: baseline;
}
.tira__i a {
  margin-left: auto;
  padding-block: 0.7rem;
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--frente);
}

/* ---------- 16. Formulário ---------- */
.form {
  display: grid;
  gap: var(--e4);
  max-width: 36rem;
}
/* no desktop o formulário abre em duas colunas: fica mais largo e mais
   curto, e some o campo morto que sobrava ao lado dele. */
@media (min-width: 56rem) {
  .form {
    max-width: none;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--e5);
  }
  .campo--largo,
  .form > p,
  .form > div:last-child {
    grid-column: 1 / -1;
  }
  .campo textarea {
    min-height: 11rem;
  }
}
.campo {
  display: grid;
  gap: 0.4rem;
}
.campo > label > span {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--frente-2);
}
.campo input,
.campo textarea {
  background: var(--campo);
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  padding: 0.78rem 0.85rem;
  transition: border-color 0.2s var(--fader), background 0.2s var(--fader);
}
.campo input::placeholder,
.campo textarea::placeholder {
  color: var(--frente-3);
  opacity: 1;
}
/* O foco tem cor própria: âmbar L162. Contra o vermelho do erro a
   diferença é de matiz e de espessura, nunca só de espessura. */
.campo input:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--foco-borda);
  background: var(--campo-foco);
  box-shadow: var(--foco-halo);
}
.campo textarea {
  min-height: 8.5rem;
  resize: vertical;
}
/* O erro é a borda grossa vermelha e nunca é apagado pelo foco: num campo
   errado E focado a borda continua vermelha e o foco se anuncia pelo anel
   externo, para que os dois estados sejam lidos ao mesmo tempo. */
.campo--erro input,
.campo--erro textarea {
  border-color: var(--gel-106-tinta);
  border-width: 2px;
}
.campo--erro input:focus,
.campo--erro textarea:focus {
  border-color: var(--gel-106-tinta);
  outline: 2px solid var(--foco-anel);
  outline-offset: 2px;
  box-shadow: var(--foco-halo);
}
.erro {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--gel-106-tinta);
}
.form__aviso {
  padding: var(--e3);
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  background: color-mix(in srgb, var(--gel-162) 16%, transparent);
}

/* ---------- 17. Contato / dados ---------- */
.contatos {
  display: grid;
  gap: var(--e5);
}
.contato-item {
  display: grid;
  gap: 0.3rem;
  padding-top: var(--e3);
  border-top: 1px solid var(--linha);
}
.contato-item a {
  font-size: 1.05rem;
  display: inline-block;
  padding-block: 0.45rem;
  text-decoration-color: var(--linha-forte);
}
.contato-item a:hover {
  text-decoration-color: currentColor;
}

/* ---------- 18. Documentos ---------- */
.docs {
  display: grid;
  gap: 1px;
  background: var(--linha);
  border: 1px solid var(--linha);
}
.doc {
  background: var(--fundo);
  padding: var(--e3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
}
.doc__nome {
  font-variation-settings: 'wdth' 100, 'wght' 620;
}
.doc__acoes {
  margin-left: auto;
  display: flex;
  gap: var(--e1);
}
.doc__acoes a {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--linha-forte);
  border-radius: 2px;
  text-decoration: none;
  transition: background 0.2s var(--fader), color 0.2s var(--fader);
}
.doc__acoes a:hover,
.doc__acoes a:focus-visible {
  background: var(--frente);
  color: var(--fundo);
}

/* ---------- 19. Rodapé ---------- */
.rodape {
  border-top: 1px solid var(--linha);
  padding: var(--e7) var(--margem) var(--e5);
}
.rodape__i {
  max-width: 78rem;
  margin-inline: auto;
  display: grid;
  gap: var(--e6);
}
.rodape__grade {
  display: grid;
  gap: var(--e5);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
/* A COLUNA NÃO É UM PISO. Uma faixa de grade tem largura mínima automática
   igual ao conteúdo indivisível dela, e o endereço da secretaria
   (`secretaria@gruponosdomorro.com.br`, 33 caracteres sem um único ponto de
   quebra) é indivisível. Entre ~600 e ~700px, onde o `auto-fit` cai para duas
   colunas de ~300px, o e-mail estourava a própria coluna e atravessava por
   cima da coluna das redes — texto sobre texto, no rodapé de todas as sete
   páginas. `min-width: 0` deixa a caixa encolher até a faixa, e é a quebra
   abaixo que faz o texto caber nela. */
.rodape__grade > * {
  min-width: 0;
}
/* `anywhere` e não `break-word`: só `anywhere` entra na conta do tamanho
   mínimo do conteúdo, que é justamente o número que a faixa da grade lê. Com
   `break-word` a linha quebraria, mas a coluna continuaria pedindo a largura
   do endereço inteiro. Vale para link e endereço do rodapé, os dois únicos
   lugares do site com palavra longa sem espaço. */
.rodape a,
.rodape p {
  overflow-wrap: anywhere;
}
.rodape h2 {
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--frente-3);
  font-weight: 500;
  margin-bottom: var(--e2);
}
/* alvo de toque: todo link do rodapé tem ao menos 44px de altura */
.rodape li a,
.rodape p a {
  display: inline-block;
  padding-block: 0.62rem;
}
.rodape a {
  text-decoration-color: transparent;
  transition: text-decoration-color 0.2s var(--fader);
}
.rodape a:hover,
.rodape a:focus-visible {
  text-decoration-color: currentColor;
}
.rodape__base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2) var(--e4);
  align-items: center;
  padding-top: var(--e4);
  border-top: 1px solid var(--linha);
  color: var(--frente-3);
}

/* ---------- 18a. Destaques de imprensa ----------
   Matéria recente em veículo grande sai da fila e ganha corpo. Sem caixa — o
   que separa um do outro é o fio e o ar.

   O CRÉDITO VEM DEPOIS DA MANCHETE (correção do revisor de acabamento da Fase
   6c, F6). Até aqui o nome do veículo subia ACIMA do título, em mono caixa
   alta: era a posição do kicker, e o piso de ofício a bane sem resgate — o
   título carrega o próprio peso. Pior, a lista irmã desta mesma página (o
   clipping) sempre pôs o mesmo dado embaixo, ao lado da data: as duas listas
   liam de jeitos diferentes o mesmo fato. Agora leem igual, e o veículo não
   perde nada — continua em mono, na cor da gelatina âmbar e em peso 700, que é
   o que o distingue da data ao lado dele. */
.destaques {
  display: grid;
  gap: var(--e5);
  margin-top: var(--e5);
}
.destaque {
  display: grid;
  gap: 0.4rem;
  padding-top: var(--e3);
  border-top: 2px solid var(--fio-quente);
}
/* O PÉ DO DESTAQUE: veículo e data na mesma linha, com o mesmo desenho do pé
   do clipping (`.clipe__pe`) — mesma quebra, mesma linha de base, mesmo
   respiro. Duas listas, uma leitura. */
.destaque__pe {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  align-items: baseline;
}
.destaque__veiculo {
  color: var(--quente-texto);
  font-weight: 700;
}
.destaque__titulo {
  font-size: clamp(1.35rem, 2vw, 1.85rem);
  font-variation-settings: 'wdth' 100, 'wght' 720;
  line-height: 1.14;
  letter-spacing: -0.022em;
  text-wrap: pretty;
  max-width: 34ch;
}
.destaque__titulo a {
  text-decoration-color: transparent;
  transition: color 0.2s var(--fader), text-decoration-color 0.2s var(--fader);
}
.destaque__titulo a:hover,
.destaque__titulo a:focus-visible {
  color: var(--quente-texto);
  text-decoration-color: currentColor;
}
@media (min-width: 56rem) {
  .destaques {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--e6) var(--e5);
  }
}

/* ---------- 18b. Clipping de imprensa ----------
   Uma lista de recortes, não cartões: cada manchete é uma linha, e a régua
   separa uma da outra.

   SEM A COLUNA DE NUMERAÇÃO (correção do revisor de acabamento da Fase 6c,
   F7). A margem trazia 01 / 02 / 03 em mono terciário, numerando por índice
   uma lista que se ordena por data — e a data já está sob cada manchete.
   Número de secção só se paga quando a sequência carrega informação que o
   leitor precisa; este não carregava, e a coluna estreita vira ar. A ordem
   continua sendo informação, e continua dita pelo <ol>. */
.clipping {
  border-top: 1px solid var(--linha);
}
.clipe {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding-block: var(--e4);
  border-bottom: 1px solid var(--linha);
  align-items: baseline;
}
.clipe__titulo {
  font-size: clamp(1.12rem, 1.3vw, 1.35rem);
  font-variation-settings: 'wdth' 100, 'wght' 640;
  line-height: 1.24;
  letter-spacing: -0.014em;
  text-wrap: pretty;
}
.clipe__titulo a {
  text-decoration-color: var(--linha-forte);
  text-underline-offset: 0.22em;
  transition: color 0.2s var(--fader), text-decoration-color 0.2s var(--fader);
}
.clipe__titulo a:hover,
.clipe__titulo a:focus-visible {
  color: var(--quente-texto);
  text-decoration-color: currentColor;
}
.clipe__pe {
  margin-top: 0.45rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  align-items: baseline;
}
.clipe__veiculo {
  color: var(--frente-2);
}

/* ---------- 19b. Peças de página ---------- */
.ato--entrada {
  padding-top: var(--e7);
}
.prosa {
  margin-top: var(--e5);
  display: grid;
  gap: var(--e3);
  max-width: var(--medida);
}
.prosa .corpo {
  max-width: none;
}
.nomes {
  margin-top: var(--e4);
  border-top: 1px solid var(--linha);
}
.nomes li {
  display: flex;
  gap: var(--e3);
  align-items: baseline;
  padding-block: var(--e2);
  border-bottom: 1px solid var(--linha);
  margin-top: 0;
}
.retrato img {
  object-position: 50% 22%;
}
/* a diretoria está no terço inferior do quadro; o céu não precisa de metade */
.retrato-diretoria img {
  object-position: 50% 78%;
}
.ficha--larga > dt {
  color: var(--frente-2);
}
.ficha--impactos {
  grid-template-columns: minmax(12rem, 20rem) 1fr;
  column-gap: var(--e5);
}
.ficha--impactos > dt {
  display: grid;
  gap: 0.15rem;
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--face);
  font-size: inherit;
  color: var(--frente);
  padding-block: var(--e3);
}
.ficha--impactos > dd {
  padding-block: var(--e3);
  color: var(--frente-2);
}
.impacto__valor {
  font-size: clamp(1.6rem, 2.5vw, 2.15rem);
  font-variation-settings: 'wdth' 100, 'wght' 790;
  letter-spacing: -0.035em;
  line-height: 1;
}
.impacto__rotulo {
  font-size: 0.86rem;
  line-height: 1.3;
  color: var(--frente-2);
  font-variation-settings: 'wdth' 94, 'wght' 500;
}
.doc__pendente {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--gel-106-tinta);
}
code {
  font-family: var(--face-tec);
  font-size: 0.9em;
  padding: 0.1em 0.35em;
  background: color-mix(in srgb, var(--frente) 9%, transparent);
  border-radius: 2px;
}

/* ---------- 20. Utilidades ---------- */
.pula {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--realce);
  color: var(--breu);
  padding: 0.75rem 1.1rem;
  font-family: var(--face-tec);
  font-size: var(--t-tec);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.pula:focus {
  left: var(--margem);
  top: 0.5rem;
}
.so-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.oculto {
  display: none !important;
}

/* ---------- 21. Responsivo ---------- */
@media (min-width: 56rem) {
  /* No desktop as três peças se sobrepõem numa célula só: a foto sangra
     a largura inteira e o texto vive dentro dela, na poça de luz. */
  .abertura {
    grid-template-rows: minmax(0, 1fr) auto;
    min-height: min(calc(100svh - 4.5rem), 52rem);
  }
  .abertura__palco,
  .abertura__texto,
  .abertura__rodape {
    grid-row: 1;
    grid-column: 1;
  }
  /* absoluta: com height:100% em fluxo a porcentagem resolve em círculo
     e a foto volta ao tamanho intrínseco, estourando a dobra. */
  .abertura__palco > img {
    position: absolute;
    inset: 0;
    height: 100%;
  }
  /* A foto sangra as duas colunas; o texto vive na coluna da direita,
     onde a vinheta já baixou o palco e a poça devolve a luz. */
  .abertura {
    grid-template-columns: minmax(0, 1fr) min(30rem, 42%);
    grid-template-rows: minmax(0, 1fr) auto auto;
  }
  .abertura__palco {
    grid-column: 1 / -1;
    grid-row: 1 / 3;
  }
  .abertura__texto {
    grid-column: 2;
    grid-row: 1;
    align-self: end;
    padding: var(--e6) var(--margem) var(--e2) 0;
  }
  .abertura__rodape {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    padding: 0 var(--margem) var(--e6) 0;
  }
  .abertura__poca {
    grid-column: 2;
    grid-row: 1 / 3;
    margin: -20% -22% -16% -42%;
  }
  /* a coxia: do meio para a direita o palco cai, e é sobre esse escuro
     que o texto se apoia. As crianças ficam inteiras à esquerda. */
  .abertura__vinheta::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to right,
      transparent 30%,
      rgb(var(--vinheta) / 0.5) 56%,
      rgb(var(--vinheta) / 0.86) 78%,
      rgb(var(--vinheta) / 0.93) 100%
    );
  }
  .mesa {
    grid-column: 1 / -1;
    grid-row: 3;
  }
  /* UMA COLUNA POR CANAL, COM PISO DE LARGURA (Fase 6b, correção do QA ao
     vivo, rodada 3). A régua era de oito colunas escritas, e o painel passou
     a criar e apagar canais — até doze, hoje. `grid-auto-flow: column` com
     `1fr` sem piso (a versão de antes desta correção) dividia a largura por
     canal igualmente entre TODOS os canais, sem olhar para o que cada um
     escreve: com nove entrava o valor "53%/47%" do CH 05 numa coluna de uns
     108px, e ele transbordava sobre o CH 06 — medido ao vivo, "53%/47%50.376"
     numa linha só, rótulos encostados. `minmax(7rem, 1fr)` dá a cada fader o
     mesmo piso que ele já tinha com oito (a régua de oito sai IDÊNTICA, é a
     prova), e é o `auto-fit` que decide quantas colunas cabem na largura de
     verdade — não quantos canais existem. Quando não cabem todas na mesma
     largura (dez, onze, doze), o grid abre uma SEGUNDA LINHA DE FADERS por
     conta própria: as que sobram descem, ainda com o piso de 7rem, em vez de
     espremer todo mundo. A subgrade de cada fader (quatro linhas de base)
     continua valendo dentro de cada linha de faders — é o motivo de manter
     `grid-auto-flow: row` (o padrão) em vez de `column`: o fluxo por
     coluna força tudo numa fileira só e foi o que quebrou com nove.

     E AS FILEIRAS SE EQUILIBRAM, EM VEZ DE LARGAR O RESTO (correção do revisor
     de acabamento da Fase 6b, rodada de design, F3). O `auto-fit` enchia a
     largura de trilhos e deixava o que sobrasse órfão: com NOVE canais, o CH
     09 descia sozinho para a segunda fileira, encostado à esquerda, com sete
     faixas vazias à direita — e a régua deixava de ser régua, que é justamente
     o que a subgrade existe para impedir. A conta agora é de fileiras: quantas
     fileiras a contagem pede com no máximo oito por fileira, e os canais
     divididos igualmente entre elas — nove viram 5 + 4, doze viram 6 + 6,
     dezessete viram 6 + 6 + 5. Nenhuma fileira fica com um canal solto.

     QUEM CONTA É O SERVIDOR, e não a folha: a página escreve `--colunas` no
     `<ol class="faders">` porque a contagem é DADO (a lista de canais do
     painel), não largura de tela. O piso de 7rem sai com ele — com fileiras
     equilibradas cada fader fica mais largo do que o `auto-fit` lhe dava, e um
     piso em pixels numa contagem de colunas fixa não faria a régua quebrar
     linha: faria ela transbordar para fora da mesa. Com oito canais as
     colunas saem IDÊNTICAS às de sempre, que é a prova de que nada se perdeu.

     E O PISO DE 7rem NÃO VOLTOU: QUEM ENCOLHE É O NÚMERO (correção do revisor
     de acabamento, rodada 2, R2). Tirar o piso devolveu, em telas estreitas, o
     transbordo que ele evitava: a 1000px os oito canais ficam em trilhos de
     97px e o "53%/47%" do CH 05 pede 105px. Repor o `auto-fit` só nessa faixa
     não resolve — a 1000px oito trilhos de 7rem pedem 1.005px e só há 889, de
     modo que a fileira quebraria outra vez e o oitavo canal desceria sozinho,
     que é o defeito que esta correção veio consertar. A saída está em
     `.fader__valor`: o valor passa a ser medido pelo trilho que recebeu, com
     `100cqw` e esta mesma contagem de colunas. E o transbordo era mais largo
     do que parecia — a 1440, com oito canais, os trilhos têm 124px e o velho
     corpo de 2vw já punha 130px dentro deles.

     A GARANTIA, CORRIGIDA NA FASE 6c (achado A1): esta frase dizia "agora
     nenhum valor sai do seu trilho em nenhuma largura", e o código não dava
     isso — o corpo saía de um fator fixo tirado de uma string semeada, e um
     valor mais longo transbordava do mesmo jeito. Com o `--largura-max` que o
     servidor mede, a garantia passa a valer, e com a condição dita: nenhum
     valor sai do seu trilho enquanto o corpo calculado ficar acima do chão de
     1,05rem — o que `CanalRequest` assegura recusando valor com mais de doze
     caracteres. O porquê inteiro está na secção do `.fader__valor`. */
  .faders {
    grid-template-columns: repeat(var(--colunas, 8), minmax(0, 1fr));
    row-gap: var(--e4);
  }
  /* sem subgrade cada fader é uma célula só: a grade fica com uma linha,
     senão quatro faders se empilhariam por coluna */
  @supports not (grid-template-rows: subgrid) {
    .faders {
      grid-template-rows: none;
    }
  }
  .acervo {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .duo {
    grid-template-columns: 1.05fr 1fr;
    gap: var(--e7);
  }
  .duo--largo {
    grid-template-columns: 1fr 1.25fr;
  }
  .contatos {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--e4);
  }
  .aviso {
    grid-template-columns: 12rem 1fr;
    gap: var(--e4);
  }
  .aviso__data {
    display: grid;
    gap: 0.35rem;
    align-content: start;
  }
}
@media (max-width: 55.99rem) {
  /* no celular a dobra é curta: foto, manifesto e os oito canais
     precisam caber juntos, então a mesa aperta o passo. */
  .abertura__palco > img {
    height: 26svh;
    min-height: 12rem;
  }
  .abertura__texto {
    padding-top: var(--e3);
  }
  .abertura__rodape {
    padding-block: var(--e3) var(--e4);
  }
  .mesa__i {
    padding: var(--e2) var(--margem) var(--e4);
    gap: var(--e3);
  }
  /* a mesa vira o que ela é: uma fileira de canais que se percorre
     com o dedo. Nenhum rótulo é cortado e os oito continuam presentes. */
  .faders {
    display: flex;
    align-items: stretch;
    gap: var(--e3);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    padding-bottom: var(--e1);
  }
  /* na fileira rolante o alinhamento vem de cima: id, trilho e valor
     na mesma linha de base; só o rótulo varia de altura, abaixo deles. */
  .fader {
    flex: 0 0 7rem;
    scroll-snap-align: start;
    grid-row: auto;
    grid-template-rows: auto auto auto 1fr;
    align-content: start;
  }
  /* nenhum valor quebra em duas linhas: a régua perderia a linha de base */
  .fader__valor {
    font-size: 1.35rem;
    white-space: nowrap;
  }
  .fader__total {
    display: inline;
  }
  .fader__trilho {
    height: 1.85rem;
  }
  .menu {
    position: fixed;
    inset: 4.5rem 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--fundo);
    border-bottom: 1px solid var(--linha-forte);
    padding: var(--e2) var(--margem) var(--e4);
    transform: translateY(-120%);
    visibility: hidden;
    transition: transform 0.42s var(--fader), visibility 0.42s;
  }
  .menu[data-aberto='sim'] {
    transform: none;
    visibility: visible;
  }
  .menu a {
    padding-block: 0.95rem;
    border-bottom: 1px solid var(--linha);
    font-size: 0.95rem;
  }
  .menu a::after {
    display: none;
  }
  /* No painel do celular não há sublinhado animado, e a página atual era
     marcada só por COR. Sobre papel a L764 não escreve (2,5:1), então a marca
     passa a ser o traço de 2px — que é a mesma peça que a régua de entradas
     do painel usa para dizer «você está aqui», e que agora vale nos dois
     temas: cor mais traço no palco, traço mais tinta cheia no papel. */
  .menu a[aria-current='page'] {
    color: var(--realce-texto);
    border-bottom-color: var(--realce-marca);
    border-bottom-width: 2px;
  }
  .menu__botao {
    display: block;
  }
  /* no painel do celular o interruptor é mais uma linha da régua: a barra a
     390px já carrega marca, «Menu» e nada mais — um controle com rótulo por
     extenso ali empurraria a marca para fora da tela (medido). */
  .luz-servico {
    display: flex;
    justify-content: flex-start;
    gap: 0.7rem;
    margin-top: var(--e2);
    padding: 0.85rem 0.72rem;
    font-size: 0.72rem;
  }
  .ficha {
    grid-template-columns: 1fr;
  }
  .ficha > dt {
    border-bottom: 0;
    padding-bottom: 0.2rem;
  }
  .ficha > dd {
    padding-top: 0.2rem;
  }
  /* NO ESTREITO NENHUMA CENA OCUPA DUAS COLUNAS (Fase 6d, caça a bugs,
     rodada 3). Com duas colunas só, "larga" é a fileira INTEIRA: a cena
     nunca cabe ao lado de outra, e a fileira anterior fica com meia sobra.
     Era daí que vinha o embaralhamento do mosaico — e, sem `dense`, viria um
     buraco de meia fileira a cada foto larga. A variação de largura é efeito
     de tela grande; no celular o mosaico é regular, como o teaser da home
     (`.acervo--regular`) já é em toda largura. */
  .acervo > .cena--larga {
    grid-column: span 1;
  }
  .ato {
    padding-block: var(--e7);
  }
  .feixe {
    filter: blur(16px);
  }
}
/* telas curtas (Android de 740px e afins): a abertura aperta mais um passo
   para que a mesa inteira continue caindo dentro da primeira dobra. */
@media (max-width: 55.99rem) and (max-height: 47rem) {
  .abertura__palco > img {
    height: 19svh;
    min-height: 8.5rem;
  }
  .abertura .manifesto {
    font-size: 2.1rem;
  }
  .abertura__rodape {
    padding-block: var(--e2) var(--e3);
  }
  .mesa__i {
    gap: var(--e2);
  }
}

/* ---------- 22. A deixa: como a luz entra ---------- */
html[data-deixa='pronto'] .ato,
html[data-deixa='pronto'] .abertura,
html[data-deixa='pronto'] .mesa {
  --deixa: 0;
  transition: --deixa 1.15s var(--fader);
}
html[data-deixa='pronto'] .ato[data-acesa],
html[data-deixa='pronto'] .abertura[data-acesa],
html[data-deixa='pronto'] .mesa[data-acesa] {
  --deixa: 1;
}
html.sem-transicao .ato,
html.sem-transicao .abertura,
html.sem-transicao .mesa {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  html[data-deixa='pronto'] .ato,
  html[data-deixa='pronto'] .abertura,
  html[data-deixa='pronto'] .mesa {
    --deixa: 1;
    transition: none;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- 23. A lente: a fotografia inteira (Fase 6b, item 14) ----------

   O SITE E O PAINEL VESTEM A MESMA LENTE, e por isso ela mora aqui e não em
   painel.css: luz.css é o sistema, e é ele que os dois carregam. O painel só
   acrescenta o que é dele — o cursor da miniatura, que lá é um controle de
   lista (painel.css, secção 30).

   O GESTO É APAGAR A SALA. Não há cartão, não há sombra, não há moldura: o
   que separa a fotografia do resto é o breu (ou, de dia, a folha) fechando em
   volta dela. `--lente-breu` é o único token novo, e ele existe nos dois temas
   pelo mesmo motivo que todos os outros — nenhuma peça daqui sabe em qual
   está.

   `contain` E NÃO `cover`: esta é a única superfície do sistema em que a foto
   não é cortada. O mosaico corta porque ali a foto é módulo de uma grade; aqui
   ela é a obra, e ver a cena inteira é a razão de a lente existir.

   `100dvh` E NÃO `100vh`: no celular, a barra do navegador come a diferença, e
   com `vh` a legenda ficava debaixo dela. */
dialog.lente {
  position: fixed;
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--lente-breu);
  color: var(--frente);
  overflow: hidden;
}
dialog.lente::backdrop {
  background: var(--lente-breu);
}
/* A PÁGINA DE TRÁS NÃO ROLA enquanto a lente está aberta. Um `<dialog>` modal
   trava o FOCO, não a rolagem: sem isto a roda do mouse sobre a fotografia
   arrasta o mosaico atrás dela, e ao fechar a pessoa não está mais onde
   estava. `:has` em vez de uma classe posta por JavaScript, para que abrir e
   fechar continue sendo uma coisa só (`showModal`/`close`). */
html:has(dialog.lente[open]) {
  overflow: hidden;
  /* e a calha da lente recebe o fundo, não o véu de 60% do painel: a lente
     não escurece o palco, ela o APAGA. `--lente-breu` é o próprio `--fundo`
     com 94% de alpha (96% no papel), e sobre o `--fundo` da página ele assenta
     de volta em `--fundo` exato nos dois temas — medido, 11,10,12 no palco e
     244,241,234 no papel. Sem esta linha a calha sairia cinza no papel,
     ao lado de uma lente quase branca. */
  background: var(--fundo);
}
/* a entrada: um quadro de luz subindo, e nada mais */
dialog.lente[open] {
  animation: lente-acende 0.18s var(--fader);
}
@keyframes lente-acende {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.lente__quadro {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: var(--e3);
  height: 100%;
  margin: 0;
  /* o respiro de cima é maior porque é lá que fica o botão de fechar */
  padding: var(--e6) var(--margem) var(--e4);
}
/* A FOTOGRAFIA NUNCA É AMPLIADA ALÉM DO QUE ELA TEM (Fase 6d, caça a bugs,
   rodada 2). A regra era `width: 100%; height: 100%; object-fit: contain`, sem
   teto no tamanho natural: cinco fotografias do acervo têm a derivada de 1600
   MENOR que 820 — são cópias de um original pequeno, a menor com 486×366 —, e
   a lente as esticava a 1296px de largura, 2,7 vezes, logo abaixo da frase que
   promete "Ver a fotografia inteira". Com `max-` em vez de `width`/`height`, a
   imagem enche o espaço quando tem pixels para isso e para no seu tamanho
   quando não tem: inteira, e nítida.

   E A CAIXA PASSA A SER A IMAGEM. Com `object-fit: contain` a caixa do <img>
   ocupava a célula inteira e o que estava ao lado da fotografia — breu, aos
   olhos de quem vê — ainda era o <img>: clicar ali não fechava a lente. Agora
   a caixa tem o tamanho do que está pintado, e tudo o que sobra pertence ao
   quadro, que é quem fecha (ver lente.js). */
.lente__foto {
  display: block;
  place-self: center;
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
}
/* ENTRE O `close` E A PRÓXIMA ABERTURA a imagem fica sem `src` (lente.js o
   remove, para não guardar a derivada de 1600 pelo resto da visita). Uma
   `<img>` sem endereço desenha um retângulo de nada; esta regra o apaga. A
   caixa nunca é vista assim — o diálogo está fechado —, mas o navegador a
   monta do mesmo jeito, e é o que ele monta que vale. */
.lente__foto:not([src]) {
  visibility: hidden;
}

.lente__legenda {
  /* DUAS FILEIRAS (ver o comentário do componente): a frase em cima, o
     aparato técnico embaixo. */
  display: grid;
  justify-items: center;
  gap: var(--e1);
  margin: 0;
  text-align: center;
}
.lente__medida {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e1) var(--e3);
}
.lente__alt {
  max-width: var(--medida);
  color: var(--frente);
  font-size: 0.95rem;
  line-height: 1.45;
}
.lente__ficha,
.lente__conta {
  color: var(--frente-2);
}

/* OS TRÊS CONTROLES: fio, canto vivo, fundo da camada. Eles flutuam SOBRE a
   fotografia — uma foto em pé numa tela deitada preenche a altura toda —, e
   por isso precisam de fundo próprio: sem ele, a seta branca sobre uma cena
   clara sumiria. É a mesma peça do resto do sistema, e não um botão de
   lightbox genérico. */
.lente__botao {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--linha-forte);
  background: var(--camada);
  color: var(--frente);
  cursor: pointer;
  transition: border-color 0.2s var(--fader), color 0.2s var(--fader);
}
.lente__botao:hover {
  border-color: var(--realce-marca);
  color: var(--realce-texto);
}
.lente__botao:focus-visible {
  outline: 2px solid var(--foco-anel);
  outline-offset: var(--foco-afast);
  box-shadow: var(--foco-halo);
}
.lente__fechar {
  top: var(--e3);
  right: var(--e3);
}
.lente__anda {
  top: 50%;
  transform: translateY(-50%);
}
.lente__anda--antes {
  left: var(--e3);
}
.lente__anda--depois {
  right: var(--e3);
}

/* O GATILHO É UM BOTÃO QUE NÃO PARECE BOTÃO, e não pode parecer: ele nasce
   por JavaScript em volta de uma fotografia que já estava desenhada. Tudo o
   que o navegador põe num `<button>` — borda, fundo, fonte, alinhamento — é
   zerado; o que sobra é o cursor de lupa e o anel de foco, que são as duas
   únicas coisas que precisam mudar quando a imagem passa a ser clicável. */
.lente__gatilho {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: zoom-in;
}
.lente__gatilho:focus-visible {
  outline: 2px solid var(--foco-anel);
  /* para dentro: a moldura da cena tem `overflow: hidden` e um anel para fora
     seria cortado pela própria figura */
  outline-offset: -3px;
}
/* dentro do mosaico o gatilho ocupa o módulo inteiro, senão a foto perde a
   altura que a grade lhe deu */
.cena > .lente__gatilho {
  height: 100%;
}

@media (max-width: 44.99rem) {
  .lente__quadro {
    padding: var(--e6) var(--e2) var(--e3);
  }
  .lente__botao {
    width: 2.5rem;
    height: 2.5rem;
  }
  .lente__anda--antes {
    left: var(--e0);
  }
  .lente__anda--depois {
    right: var(--e0);
  }
}

/* ---------- 24. A troca de tema é um interruptor, não um entardecer ----------
   (correção do revisor de acabamento da Fase 6c, segunda passada, R1.)

   O interruptor da luz de serviço troca UM atributo na raiz, e a folha inteira
   muda de tinta no mesmo quadro — menos os poucos elementos que declaram
   `transition: color`, que atravessam 0,24s de meio-tom. O rótulo de um botão
   vazado, indo de #FCF8F1 (palco) a #0F1413 (papel), passa por um cinza de
   ~#6A6B68 no meio do caminho: contra o papel ele dá 4,7:1 por um quinto de
   segundo, e o botão parece pintado de outra cor enquanto a página inteira já
   virou. Foi o que uma captura pegou, e foi lida como defeito da folha.

   Um interruptor não tem meio termo: ou a luz de serviço está acesa ou não
   está. As transições existem para GESTOS — o dedo sobre o botão, o foco que
   chega —, não para uma decisão de sala que muda tudo de uma vez. Durante o
   quadro da troca, então, ninguém transiciona; a página seguinte volta a ter
   os seus gestos. O mesmo par de `requestAnimationFrame` de deixa.js apaga a
   marca, e sem JavaScript a marca nunca aparece (nem o interruptor). */
html.trocando-tema *,
html.trocando-tema *::before,
html.trocando-tema *::after {
  transition: none !important;
}

/* =====================================================================
   APARÊNCIA DOS TEXTOS (29/10/2026) — o que o painel ajusta por bloco.
   `App\Support\Aparencia::embrulhar` imprime `<span class="tx">` com as
   variáveis abaixo só quando há ajuste; sem ajuste, nada disto entra na
   página. Cada variável tem `inherit` como reserva, então um span com só a
   cor definida não mexe em mais nada.
   ===================================================================== */
.tx {
  color: var(--tx-cor, inherit);
  font-size: var(--tx-tam, inherit);
  font-weight: var(--tx-peso, inherit);
  font-style: var(--tx-fonte, inherit);
  text-transform: var(--tx-caixa, inherit);
}
.tx--bloco {
  display: block;
  text-align: var(--tx-alinha, inherit);
}
/* A cor escolhida vale também para a ênfase dentro do bloco, que na folha
   base tem cor própria (a da marca): quem pintou o título de azul não quer
   metade dele laranja. */
.tx em,
.tx strong {
  color: inherit;
}

/* AS ANIMAÇÕES DE ENTRADA só começam escondidas quando o JavaScript está de
   pé (`html[data-deixa='pronto']`, o mesmo portão das deixas de luz) e o
   deixa.js vai marcar `data-anim-feita` quando o bloco entrar na tela. Sem
   JS, o texto está simplesmente lá. */
html[data-deixa='pronto'] .tx[data-anim='aparecer']:not([data-anim-feita]),
html[data-deixa='pronto'] .tx[data-anim='subir']:not([data-anim-feita]),
html[data-deixa='pronto'] .tx[data-anim='deslizar']:not([data-anim-feita]),
html[data-deixa='pronto'] .tx[data-anim='crescer']:not([data-anim-feita]) {
  opacity: 0;
}
.tx[data-anim='aparecer'][data-anim-feita] { animation: tx-aparecer 0.9s var(--fader) both; }
.tx[data-anim='subir'][data-anim-feita] { animation: tx-subir 0.9s var(--fader) both; }
.tx[data-anim='deslizar'][data-anim-feita] { animation: tx-deslizar 0.9s var(--fader) both; }
.tx[data-anim='crescer'][data-anim-feita] { animation: tx-crescer 0.9s var(--fader) both; }
/* o sublinhado que se desenha: um gradiente de fundo que cresce da esquerda */
.tx[data-anim='sublinhar'] {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 0.08em;
  padding-bottom: 0.06em;
}
.tx[data-anim='sublinhar'][data-anim-feita] { animation: tx-sublinhar 1.1s var(--fader) 0.2s both; }
/* as contínuas não dependem do observador */
.tx[data-anim='brilhar'] { animation: tx-brilhar 2.6s ease-in-out infinite; }
.tx[data-anim='pulsar'] { display: inline-block; animation: tx-pulsar 2.4s ease-in-out infinite; }
.tx--bloco[data-anim='pulsar'] { display: block; }

@keyframes tx-aparecer { from { opacity: 0; } to { opacity: 1; } }
@keyframes tx-subir { from { opacity: 0; transform: translateY(0.6em); } to { opacity: 1; transform: none; } }
@keyframes tx-deslizar { from { opacity: 0; transform: translateX(-1.2em); } to { opacity: 1; transform: none; } }
@keyframes tx-crescer { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: none; } }
@keyframes tx-sublinhar { from { background-size: 0% 0.08em; } to { background-size: 100% 0.08em; } }
@keyframes tx-brilhar {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  50% { text-shadow: 0 0 0.45em color-mix(in srgb, currentColor 70%, transparent); }
}
@keyframes tx-pulsar { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.035); } }
/* transform num inline não faz nada: as que movem viram inline-block */
.tx[data-anim='subir'],
.tx[data-anim='deslizar'],
.tx[data-anim='crescer'] { display: inline-block; }
.tx--bloco[data-anim] { display: block; }

@media (prefers-reduced-motion: reduce) {
  .tx[data-anim] {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .tx[data-anim='sublinhar'] { background-size: 100% 0.08em; }
}

/* =====================================================================
   VÍDEO NA ABERTURA (29/10/2026): toma o lugar da foto no mesmo palco. A
   foto continua embaixo como cartaz — aparece enquanto o vídeo carrega e
   fica para quem pediu menos movimento (deixa.js pausa o vídeo).
   ===================================================================== */
.abertura__palco > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 40%;
  filter: brightness(calc(0.6 + var(--deixa) * 0.4))
    contrast(calc(1.02 + var(--deixa) * 0.08))
    saturate(calc(0.8 + var(--deixa) * 0.32));
}
/* no celular o palco tem a altura da foto (34svh); a foto segue no fluxo e
   o vídeo cobre o retângulo dela */
.abertura__palco:has(> video) {
  position: relative;
}
@media (prefers-reduced-motion: reduce) {
  .abertura__palco > video {
    display: none;
  }
}

/* =====================================================================
   "TÁ ROLANDO" (29/10/2026): cartões com a mídia no alto.
   ===================================================================== */
.rolando {
  display: grid;
  gap: var(--e7);
}
.rolando__item {
  display: grid;
  gap: var(--e3);
  max-width: var(--medida);
}
.rolando__midia {
  position: relative;
  width: 100%;
  aspect-ratio: var(--proporcao, 16 / 9);
  background: var(--camada);
  overflow: hidden;
  border-radius: 2px;
}
.rolando__midia > video,
.rolando__midia > iframe,
.rolando__midia > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
  background: var(--camada);
}
.rolando__midia--embed > iframe {
  object-fit: unset;
}
.rolando__cabeca {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e1) var(--e3);
}
.rolando__acao {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
}
@media (min-width: 56rem) {
  .rolando {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--e7) var(--e5);
  }
  .rolando__item--larga {
    grid-column: 1 / -1;
  }
}
