/* Concix Design System v3.0

   ARQUIVO COMPLETO. Substitui nada e apaga nada: entra AO LADO da v2.9, que
   continua servida ate a ultima tela repontar.

   QUANTAS TELAS SAO E QUAIS, ESTE ARQUIVO NAO DIZ. Quem diz e o
   VERSAO_VIGENTE.md deste mesmo diretorio — e o PORTAO 1 aponta para la
   quando reprova. Lista de consumidor dentro do proprio pacote envelhece
   sem ninguem perceber; num lugar so, nao.

   O CORPO DA v2.9 ESTA ABAIXO, PALAVRA POR PALAVRA. Nenhuma regra dela foi
   alterada, reordenada ou removida — o diff contra a v2.9 e so acrescimo,
   e acrescimo se confere lendo. O que vence, vence por especificidade e
   por ordem, e esta escrito onde isso acontece.

   COM UMA EXCECAO, E ELA MUDA A APARENCIA DE QUEM JA ESTA NO AR: a
   --cx-rail-width e SOBRESCRITA na parte nova, de 60 para 72px. A barra
   recolhida estava 12px estreita demais e nenhum icone caia no centro dela.
   A sobrescrita esta declarada embaixo, com a conta e o motivo, em vez de
   editada aqui em cima — assim o corpo da v2.9 continua conferivel palavra
   por palavra e a mudanca aparece onde ela e explicada. Decisao do Jimmy,
   09/09, sabendo do custo.

   A v3.0 FOI EDITADA NO LUGAR EM 07/10, E ISSO E DECISAO, NAO DESCUIDO.
   Lapidacao da barra e do andar, pedida pelo Jimmy com print das telas:
   itens do andar longe demais, grupo e item pouco distintos, a barra que
   ficava aberta depois de fechar o andar e o filete duplo do item ativo.
   Os quatro defeitos moram neste arquivo, e 23 telas o carregam. Abrir
   uma v3.1 obrigaria cada dono a repontar a sua, com os portoes que exigem
   "v3.0" mudando junto — semanas de telas com aparencias diferentes, como
   foi a saida da v2.9, terminada no mesmo dia. O Jimmy escolheu corrigir
   aqui. O CSS e servido com cache curto (src/assets.ts, 300s), entao a
   correcao alcanca todas as telas sem troca de endereco.
   CONSEQUENCIA: "v3.0" deixou de nomear um conteudo fixo. O sha256 que o
   VERSAO_VIGENTE.md guardava e o de antes desta edicao. O que mudou esta
   todo no fim do arquivo, sob "LAPIDACAO DE 07/10", menos UMA troca que
   nao cabia la: o :focus-within da barra virou :has(:focus-visible) nas
   proprias regras, porque estado de foco nao se desfaz por sobrescrita.
   O motivo esta escrito na secao.

   POR QUE 3.0. Escolha do Jimmy, e o que a sustenta e o tamanho do que
   entra: andares na barra, uma escada de escopo que nao existia, o par de
   marcas, e uma regra de botao que muda o que ja esta na tela. Isso e
   mudanca de maior, nao a decima correcao da v2.

   A DIFERENCA DELIBERADA EM RELACAO AO ARQUIVO DO PACOTE continua aqui: o
   `@import "./concix-fonts.css"`. O pacote nao distribui as faces; quem as
   serve e o produto, de /painel/assets/fonts.

   O QUE A v3.0 ACRESCENTA, e de onde veio — tudo no FIM do arquivo, depois
   do corpo da v2.9, sob o cabecalho "PARTE NOVA DA v3.0":
     1. [hidden] tem de esconder — AVISO_DESIGN_008, promovido do
        painel.css do reservas, com o raciocinio junto.
     2. Tokens novos — lotacao, andar, par de marcas, paleta de grafico.
     3. A BARRA EM ANDARES — decisao do Jimmy em 08/09, AVISO_NUCLEO_030.
     4. As QUATRO FAIXAS de escopo — AVISO_NUCLEO_024 e 032.
     5. O PAR DE MARCAS — AVISO_NUCLEO_030, com a implementacao do nucleo
        (AVISO_DESIGN_015), que ficou melhor que a especificacao.
     6. O INTERRUPTOR COM LUZ — AVISO_DESIGN_006, promovido do reservas.
     7. A VARIANTE DE ACAO — a regra que fecha a colisao do laranja,
        AVISO_RESERVAS_026.
     8. ETIQUETA DE ESTADO NAO SE DISTINGUE POR COR — AVISO_DESIGN_018,
        medido pelo reservas e reproduzido aqui antes de virar regra.
     9. O NOME DO MODULO NO TOPO DA BARRA — pedido do Jimmy em 09/09.
        Monograma quando recolhida, nome inteiro quando aberta, e o
        monograma e o estado principal porque a barra vive recolhida.
    10. A --cx-rail-width CORRIGIDA de 60 para 72px, que e a unica coisa
        neste arquivo que muda tela que ja esta no ar.

   SETE CORRECOES QUE SO APARECERAM AO LER O ARQUIVO, AO ABRIR NO NAVEGADOR
   OU PORQUE OUTRO PROJETO FOI MEDIR. Ficam escritas porque o erro foi de
   metodo — afirmar o que estava a uma medicao de distancia — e nao de
   digitacao:

   a) NAO EXISTE `--cx-rail-aberta`, e nunca existiu. A barra recolhida e
      `--cx-rail-width`; a ABERTA e `--cx-sidebar-width` (248px), e a
      propria v2.9 diz isso no comentario do token. O 216px de um rascunho
      anterior era numero inventado. Toda a conta da fase 1 usa
      `--cx-sidebar-width`.

   b) A .cx-rail E UM BALAO FLUTUANTE, nao uma coluna colada na borda:
      `left: var(--cx-space-4)`, `top: calc(--cx-header-height +
      --cx-space-16)`, `border-radius: var(--cx-radius-xl)`. O andar se
      alinha A ELA — mesma origem, mesmo topo, mesmo raio — e nao ao canto
      da janela. Encaixa sem numero magico: as duas caixas partem do mesmo
      `left`, entao deslocar o andar pela largura da barra encosta um no
      outro exatamente. Medido: fase 1, a barra termina em 264 e o andar
      comeca em 264; fase 2, 76 e 76.

   c) NAO EXISTE `--cx-shadow-nivel`. A sombra de elemento levantado deste
      pacote e `--cx-shadow-interactive-hover`.

   d) A BARRA DEITADA NO RODAPE NAO TEM --cx-rail-width DE ALTURA. Tem uma
      borda a mais. O andar estreito parava 3px POR DENTRO dela. Virou
      conta derivada, --cx-rail-rodape-altura, explicada onde e declarada.

   e) O SUBTITULO DA FAIXA "DA INSTALACAO" NAO PODE SER CHAMPANHE. A faixa
      inverte e o champanhe nao: no tema escuro ela vira marfim, e
      champanhe sobre marfim e o mesmo 2,05:1 que a v2.7 ja reprovou no
      item ativo. O champanhe ficou no filete, onde e assinatura; o texto
      segue a inversao.

   As duas ultimas vieram de fora, no mesmo dia, e ficam registradas com o
   credito de quem mediu:

   f) O MOTIVO DE NAO IMPORTAR A FAMILIA DE SUPERFICIE ESTAVA INVERTIDO.
      Eu tinha escrito que ela era a nossa "com outro nome". O reservas foi
      ler os dois arquivos e comparar par a par: nenhum dos seis bate, e a
      divergencia e sistematica — a deles e quente, a nossa e fria. A
      decisao continua a mesma, o motivo e o oposto, e o motivo e o que
      sobrevive. AVISO_DESIGN_017, e a correcao esta escrita onde o token
      mora.

   g) O ANDAR COBRE A FAIXA DE ESCOPO DO PAINEL. A faixa e sticky no
      z-index 5 e o andar entra no 45, por cima dela — some a declaracao de
      escopo exatamente enquanto se navega entre escopos. Nao se resolve
      pela pilha: quem sai do caminho e o conteudo. Entra o par
      .cx-com-andar / .cx-desvia-do-andar, e quem escolhe o alvo e a tela.
      COLISAO 3 do AVISO_DESIGN_020.

   h) NENHUM ICONE DA BARRA RECOLHIDA ESTAVA NO CENTRO DELA, e nunca esteve
      desde a v2.6. Sao 6px para a direita, em todos. A conta da
      --cx-rail-width e "um controle mais o respiro dos dois lados" e
      esqueceu duas bordas: a da barra e a do item. O certo e um controle
      mais duas vezes (borda + respiro + borda), que da 72 e nao 60.
      Apareceu porque o bloco do modulo desenha as bordas da barra e os 6px
      ficaram visiveis; antes disso ninguem tinha por onde ver.
      E a SEGUNDA conta deste pacote a esquecer a borda em dois dias — a
      outra e a (d), aqui em cima. Nao e coincidencia: e o que acontece
      quando a conta se escreve olhando o desenho em vez de somar as
      parcelas.
   ==================================================================== */

/* Concix Design System v2.9

   O QUE A v2.9 MUDA — e o raciocinio e do Jimmy, nao meu:

   A BARRA LATERAL PASSA A USAR O TEAL DA CASA, o mesmo do botao Confirmar.
   O argumento que me convenceu: num ERP grande a barra esta em TODA tela, o
   tempo todo; o botao de confirmar aparece de vez em quando. Quem esta
   sempre presente e que deve carregar a cor da casa — e a cor que ja deu
   certo e agradou nao precisa ser reinventada para virar navegacao. O estado,
   que e ocasional, e que se ajusta.

   Isso inverte o que a v2.8 fez, e a v2.8 e que estava errada de premissa:
   ela protegia a paleta de estado como se ela fosse o centro do sistema.
   Numa tela de reservas ela quase e; num ERP inteiro, nao.

   E O CONFIRMAR ANDA UM POUCO PARA O VERDE — 14 graus de matiz. Isso resolve
   a colisao e, de quebra, conserta uma fraqueza que ja existia: success
   (169) e present (170) estavam a UM GRAU um do outro. Confirmar e presente
   eram praticamente a mesma cor, e ninguem tinha reparado. Agora sao 15
   graus, que e o suficiente para distinguir dois estados que aparecem lado a
   lado na mesma agenda.

   A NAVEGACAO NAO E ALIAS DE SUCCESS, e sim valores proprios que hoje
   coincidem com o teal original. Se um dia o confirmar mudar de novo, a
   barra nao muda junto — cor da casa e cor de estado sao decisoes
   diferentes, mesmo quando o hexadecimal nasce igual.

   Concix Design System v2.8

   O QUE A v2.8 MUDA EM RELACAO A v2.7 — pedido do Jimmy em 22/08, poucas
   horas depois. A v2.7 nunca chegou a tela nenhuma: nenhuma pagina apontou
   para ela, entao a troca nao muda nada por baixo de ninguem.

   1. UMA COR SO PARA A NAVEGACAO, nao cinco. A familia ametista de cinco
      passos saiu. Fica um verde folha unico para todos os icones da barra.
      Cinco tons pediam do leitor uma distincao que ele nao faz: quem
      identifica a secao e o icone e o nome, nao o passo da rampa.

   2. O VERDE E DE FOLHA, NAO DE TEAL — e isso importa. #3FAD98 (confirmar)
      e #69CCBB (chegou) estao os DOIS na matiz 169-170. Um "verde claro"
      naquela faixa nao colidiria com o confirmar, como se temia: colidiria
      com o PRESENTE. A navegacao foi para a matiz 122, a uns 48 graus de
      distancia — le como verde, nao le como estado de reserva.

   3. O ICONE EM REPOUSO USA A TINTA ESCURA da familia, nao a clara. Verde
      claro sobre marfim da menos de 2:1 e some. A cor clara e o
      PREENCHIMENTO do hover, com grafite por cima. Continua sendo "a cor
      sai do simbolo e toma o botao" — o que muda e qual tom faz cada papel.

   4. O AMETISTA DO BOTAO PRIMARIO FOI SUAVIZADO (menos saturado) e, no tema
      escuro, deixou de precisar da borda de muleta: #8851B8 passa 3:1 contra
      a pagina E contra o cartao sozinho.

   Concix Design System v2.7

   O QUE A v2.7 MUDA — decisao do Jimmy em 22/08, e ela vale para TODAS as telas:

   1. COR DE BASE NAO VESTE BOTAO. A doutrina dizia "o dourado e o preto
      trabalham na base, nao nas partes ativas". Faltava a consequencia: se a
      base e o que e estatico, pintar um botao com a cor da base faz ele
      PARECER estatico. O botao primario era grafite — a acao mais importante
      da tela vestida com a cor de "nao me clique". Agora ele e ametista.

   2. FAMILIA PROPRIA DE NAVEGACAO. Os icones da barra ganham cor, mas NAO a
      paleta de estado: verde e confirmar, vermelho e recusar, laranja e nao
      veio. Um icone de Relatorios em vermelho seria lido como erro pela mesma
      equipe que aprendeu isso. A navegacao ganha uma familia so dela —
      ametista virando magenta, cinco passos — que nao colide com estado
      nenhum. A barra le como uma progressao, nao como salada de frutas.

   3. A COR SAI DO SIMBOLO E TOMA O BOTAO. Em repouso o icone e colorido e o
      botao e base. No hover (ou no toque) a MESMA cor vira o preenchimento e
      o conteudo vira marfim. Mesmo hexadecimal, papel diferente.

   4. TOQUE NAO TEM HOVER. A expansao por hover passa a ser condicionada a
      @media (hover: hover). Em tablet o icone navega no primeiro toque e o
      botao "manter aberta" continua disponivel — nada de dois toques para
      tudo, e nada de atraso, que faz sistema parecer lento.

   5. CARTAO EXPANSIVEL (cx-card--expansivel), sobre <details>/<summary>
      nativo: abre no toque e no teclado, funciona antes do JS carregar.

   CONTRASTE: os 23 pares novos foram conferidos. Dois reprovaram e estao
   corrigidos onde ocorrem — o primario do tema escuro ganhou borda clara, e o
   item ativo ganhou barra indicadora, porque champanhe sobre marfim da 2,05:1
   e a WCAG 1.4.11 pede 3:1 para identificar ESTADO de componente.

   Concix Design System v2.6

   NOTA SOBRE A PROCEDENCIA: o cabecalho da v2.5 dizia "gerado por
   qa/build_tokens_css.py, nao edite". Esse gerador NAO existe no pacote — o
   arquivo sempre foi mantido a mao. A v2.6 assume isso: o JSON continua sendo
   a fonte da VERDADE dos valores, e o CSS e mantido em paralelo, com o
   qa/token_lint.py conferindo que os dois nao divergem.

   O QUE A v2.6 ACRESCENTA A v2.5 — um unico componente:
   · cx-rail — navegacao vertical flutuante. Recolhida mostra so icones;
     ao passar o mouse (ou receber foco pelo teclado) expande com os nomes,
     POR CIMA do conteudo — nada reflui atras dela. Em tela estreita vira
     barra inferior, porque balao flutuante em 375px come a tela toda.
   · --cx-rail-width, derivada de --cx-control: a largura recolhida e a
     altura de um controle mais o respiro dos dois lados. Nao e literal.

   A cor obedece a doutrina: a barra e BASE — marfim, filete e grafite. O
   champanhe marca o item ativo, que e estado, nao enfeite. Nenhuma familia
   semantica entra aqui: verde, vermelho e laranja pertencem a acao e ao
   estado da reserva, nunca a navegacao.

   Tudo o mais e identico a v2.5.

   O que a v2.5 consolidou, em relacao a v2.3:

   · paleta semantica PASTEL, derivada do tom #63C1BB e fechada em #3FAD98,
     #FB3C04, #FF9646, #69CCBB e #3C55D1;
   · cada familia em QUATRO papeis — surface, tint, ink, indicator — porque um
     valor unico nao serve ao mesmo tempo de fundo de botao e de cor de texto;
   · sete estados de reserva, nao cinco: no_show e recusada entraram;
   · botoes semanticos: o botao veste a cor do estado que ele cria;
   · brilho (--cx-gloss) e filete de marca (--cx-hairline);
   · --cx-page passou ao branco gelo da marca (#F6F4EF), nao ao cinza-azulado;
   · componentes novos: cx-select, cx-label, cx-hint, cx-field-error/success/
     warning, cx-scrim, cx-icon com pintura, cx-status--icon e --solid.

   DUAS EXCECOES DE ACESSIBILIDADE, documentadas onde ocorrem:
   · #FB3C04 opaco reprova com grafite (4,41) E com marfim (3,32). Sao os 88%
     de opacidade sobre superficie clara que o tornam legivel. A transparencia
     dele e acessibilidade, nao acabamento.
   · #3C55D1 e o inverso: so passa com texto marfim, e a 88% reprova. E o unico
     opaco e o unico com letra clara. */

/* DIFERENÇA DELIBERADA EM RELAÇÃO AO ARQUIVO DO PACOTE: o @import abaixo.
   O pacote não distribui as faces; quem as serve é o produto, de
   /painel/assets/fonts. Fora esta linha, os dois arquivos são idênticos. */
@import "./concix-fonts.css";


:root {
  color-scheme: light;

  /* marca */
  --cx-graphite: #1F2125;
  --cx-stone: #8A8D91;
  --cx-champagne: #C9B07A;
  /* v2.4.3 - filete de marca. Estrutural, nunca semantico: separa regioes,
     nao comunica estado. Espessura na escala para poder engrossar sem literal. */
  --cx-hairline: var(--cx-champagne);
  --cx-hairline-size: 3px;
  --cx-ivory: #F6F4EF;
  --cx-slate: #2A2F3A;
  --cx-mist: #DAD7D1;
  --cx-sand: #E5D4AB;
  --cx-white: #FFFFFF;

  /* semantica */

  /* v2.4 - familias semanticas em quatro papeis */
  --cx-success-surface: rgba(63,173,126,.88);
  --cx-success-tint: #E4F3EC;
  --cx-success-ink: #1A5A40;
  --cx-success-indicator: #34946B;
  --cx-success-on: var(--cx-graphite);
  --cx-error-surface: rgba(251,60,4,.88);
  --cx-error-tint: #FEECE5;
  --cx-error-ink: #8F2705;
  --cx-error-indicator: #E04A10;
  --cx-error-on: var(--cx-graphite);
  --cx-warning-surface: rgba(255,150,70,.88);
  --cx-warning-tint: #FFF0E1;
  --cx-warning-ink: #7F430E;
  --cx-warning-indicator: #E07B27;
  --cx-warning-on: var(--cx-graphite);
  --cx-present-surface: rgba(105,204,187,.88);
  --cx-present-tint: #E8F7F4;
  --cx-present-ink: #1D5D52;
  --cx-present-indicator: #4FB6A4;
  --cx-present-on: var(--cx-graphite);
  --cx-completed-surface: #3C55D1;
  --cx-completed-tint: #E8ECFB;
  --cx-completed-ink: #26368C;
  --cx-completed-indicator: #3C55D1;
  --cx-completed-on: var(--cx-ivory);
  --cx-requested-surface: rgba(143,176,220,.88);
  --cx-requested-tint: #EDF3FB;
  --cx-requested-ink: #2E4E7C;
  --cx-requested-indicator: #4A6FB3;
  --cx-requested-on: var(--cx-graphite);
  /* alias historicos: apontam para o `ink`, que era o uso majoritario */
  --cx-success: var(--cx-success-ink);
  --cx-error: var(--cx-error-ink);
  --cx-warning: var(--cx-warning-ink);
  --cx-info: var(--cx-requested-ink);
  --cx-on-surface: #1F2125;
  /* v2.4.1 - brilho. Clareia o topo da superficie; como o texto e grafite, o
     contraste so MELHORA. O pior caso continua sendo a base do botao, que e o
     valor verificado na tabela de contraste. */
  --cx-gloss: linear-gradient(180deg, rgba(255,255,255,.24), rgba(255,255,255,0) 60%);

  /* superficie e texto - tema claro */
  --cx-page: #F6F4EF;   /* v2.4.3 - branco gelo da marca, nao o cinza-azulado */
  --cx-panel: #FCFCFD;
  --cx-panel-strong: #FFFFFF;
  --cx-subtle: #F0EEE8;
  --cx-text-primary: #1F2125;
  --cx-text-secondary: #5F636B;
  --cx-text-muted: #6B6F77;
  --cx-border: #DADFE5;
  --cx-border-strong: #BFC5CD;
  --cx-focus: #4A6FB3;
  --cx-text-subtle: #828689;
  --cx-focus-halo: rgba(74,111,179,.16);
  /* v2.3.2 - veu atras de modal. Existia so como literal nos produtos. */
  --cx-scrim: rgba(31,33,37,0.45);

  /* tipografia */
  --cx-font-heading: Manrope, Inter, system-ui, sans-serif;
  --cx-font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --cx-font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;
  --cx-text-h1-size: 48px;
  --cx-text-h1-line: 56px;
  --cx-text-h1-weight: 700;
  --cx-text-h1-tracking: -0.01em;
  --cx-text-h2-size: 32px;
  --cx-text-h2-line: 40px;
  --cx-text-h2-weight: 600;
  --cx-text-h2-tracking: 0;
  --cx-text-h3-size: 24px;
  --cx-text-h3-line: 32px;
  --cx-text-h3-weight: 500;
  --cx-text-h3-tracking: 0;
  --cx-text-body-size: 16px;
  --cx-text-body-line: 24px;
  --cx-text-body-weight: 400;
  --cx-text-body-tracking: 0;
  --cx-text-small-size: 14px;
  --cx-text-small-line: 20px;
  --cx-text-small-weight: 400;
  --cx-text-small-tracking: 0;
  --cx-text-caption-size: 12px;
  --cx-text-caption-line: 16px;
  --cx-text-caption-weight: 400;
  --cx-text-caption-tracking: 0;
  --cx-text-button-size: 14px;
  --cx-text-button-line: 20px;
  --cx-text-button-weight: 600;
  --cx-text-button-tracking: 0.005em;
  --cx-text-technical-size: 13px;
  --cx-text-technical-line: 20px;
  --cx-text-technical-weight: 400;
  --cx-text-technical-tracking: 0;

  /* espacamento */
  --cx-space-1: 4px;
  --cx-space-2: 8px;
  --cx-space-3: 12px;
  --cx-space-4: 16px;
  --cx-space-6: 24px;
  --cx-space-8: 32px;
  --cx-space-12: 48px;
  --cx-space-16: 64px;

  /* raio */
  --cx-radius-sm: 8px;
  --cx-radius-md: 12px;
  --cx-radius-lg: 16px;
  --cx-radius-xl: 24px;
  --cx-radius-pill: 999px;

  /* elevacao */
  --cx-shadow-surface: 0 2px 8px rgba(31,33,37,0.06);
  --cx-shadow-interactive: 0 8px 24px rgba(31,33,37,0.08);
  --cx-shadow-interactive-hover: 0 18px 48px rgba(31,33,37,0.10);

  /* foco */
  --cx-focus-outline: 2px solid #4A6FB3;
  --cx-focus-offset: 2px;
  --cx-focus-ring: 0 0 0 4px rgba(74,111,179,0.16);

  /* controles */
  --cx-control-compact: 36px;
  --cx-control: 44px;
  --cx-control-large: 52px;
  --cx-control-padding-inline: 24px;

  /* layout */
  --cx-content-max-width: 1440px;
  /* v2.3.2 - largura maxima de caixa de formulario (login, definir senha,
     modais). Substitui o calc(var(--cx-space-16) * 7) das excecoes do §10. */
  --cx-form-max-width: 448px;
  --cx-sidebar-width: 248px;
  /* v2.6 - largura da barra RECOLHIDA. Derivada: um controle (44px) mais o
     respiro dos dois lados. O icone mora numa caixa de --cx-control, entao
     ele cai no centro exato sem numero magico. --cx-sidebar-width continua
     sendo a largura EXPANDIDA. */
  --cx-rail-width: calc(var(--cx-control) + var(--cx-space-2) * 2);

  /* v2.7 - FAMILIA DE NAVEGACAO. Ametista virando magenta, cinco passos.
     Deliberadamente FORA da paleta de estado: nenhuma secao pode ser lida
     como confirmada, recusada ou atrasada. Em tema claro o mesmo hex serve
     de tinta do icone em repouso E de preenchimento no hover — o que muda e
     o papel, nao a cor. Todos passam 3:1 como icone sobre o painel e 4.5:1
     com marfim por cima. */
  /* v2.9 - o teal da casa. Valores PROPRIOS, nao alias de --cx-success:
     eles nascem iguais ao teal original de proposito, mas a cor da casa e a
     cor do estado sao decisoes independentes daqui em diante. */
  --cx-nav-ink:     #1A5A4F;                 /* icone em repouso — 7,8:1 sobre o painel */
  --cx-nav-surface: rgba(63,173,152,.88);    /* preenchimento do hover — grafite da 6,6:1 */
  --cx-nav-on:      var(--cx-graphite);

  /* v2.7 - ACAO PRIMARIA. Era o grafite, que e cor de base e por isso lia
     como estatico. Ametista mais fundo que o passo 1 da navegacao: mesma
     familia, mais peso. NAO e o #3C55D1 — aquele azul ja tem dono, e o
     'concluir mesa'. */
  --cx-primary: #684389;
  --cx-primary-on: var(--cx-ivory);
  --cx-primary-border: var(--cx-primary);
  --cx-header-height: 64px;
  --cx-margin-desktop: 64px;
  --cx-margin-tablet: 32px;
  --cx-margin-mobile: 16px;

  /* movimento */
  --cx-motion-fast: 160ms;
  --cx-motion-normal: 220ms;
  --cx-ease: cubic-bezier(0.2,0,0,1);
  --cx-hover-lift: -2px;
  --cx-press-translate: 1px;

  /* icones */
  --cx-icon-size: 20px;
  --cx-icon-size-compact: 16px;
  --cx-icon-size-large: 24px;
  --cx-icon-stroke: 1.75;
  --cx-icon-stroke-active: 2;

  /* v2.4 - estados de reserva: cada um aponta para a familia correspondente */
  --cx-status-requested-bg: var(--cx-requested-tint);
  --cx-status-requested-text: var(--cx-requested-ink);
  --cx-status-requested-indicator: var(--cx-requested-indicator);
  --cx-status-confirmed-bg: var(--cx-success-tint);
  --cx-status-confirmed-text: var(--cx-success-ink);
  --cx-status-confirmed-indicator: var(--cx-success-indicator);
  --cx-status-present-bg: var(--cx-present-tint);
  --cx-status-present-text: var(--cx-present-ink);
  --cx-status-present-indicator: var(--cx-present-indicator);
  --cx-status-completed-bg: var(--cx-completed-tint);
  --cx-status-completed-text: var(--cx-completed-ink);
  --cx-status-completed-indicator: var(--cx-completed-indicator);
  --cx-status-canceled-bg: var(--cx-error-tint);
  --cx-status-canceled-text: var(--cx-error-ink);
  --cx-status-canceled-indicator: var(--cx-error-indicator);
  --cx-status-no-show-bg: var(--cx-warning-tint);
  --cx-status-no-show-text: var(--cx-warning-ink);
  --cx-status-no-show-indicator: var(--cx-warning-indicator);
  --cx-status-refused-bg: var(--cx-error-tint);
  --cx-status-refused-text: var(--cx-error-ink);
  --cx-status-refused-indicator: var(--cx-error-indicator);
  /* v2.3.2 - no_show usa a familia Warning: nao veio e falha do cliente,
     nao decisao da casa. Contraste texto/fundo 7.00:1. */

  /* camada tenant (unicos overrides permitidos) */
  --tenant-accent: #C9B07A;
  --tenant-on-accent: #1F2125;
}

[data-theme="dark"] {
  color-scheme: dark;
  --cx-page: #15171A;
  --cx-panel: #1F2125;
  --cx-panel-strong: #24272C;
  --cx-subtle: #2A2F3A;
  --cx-text-primary: #F6F4EF;
  --cx-text-secondary: #C7C9CD;
  --cx-text-muted: #A4A8AE;
  --cx-border: #3D424B;

  /* v2.7 - navegacao no tema escuro: os mesmos cinco passos, claros o
     bastante para 3:1 sobre o painel escuro. Aqui o conteudo sobre o
     preenchimento e GRAFITE, nao marfim. */
  /* No escuro a tinta e o teal claro (10,9:1 sobre o painel) e o
     preenchimento e o teal cheio, com grafite por cima (5,9:1). */
  --cx-nav-ink:     #B1DDDA;
  --cx-nav-surface: #3FAD98;
  --cx-nav-on:      var(--cx-graphite);

  /* v2.7 - primario escuro. #62319B sumiria na pagina escura. Este passa
     5.06:1 com marfim e 3.23:1 contra a pagina; a borda mais clara garante
     o limite do componente tambem quando ele cai sobre um cartao. */
  --cx-primary: #8851B8;
  --cx-primary-on: var(--cx-ivory);
  /* Suavizado, e agora sem muleta: 3,35:1 contra a pagina e 3,01:1 contra o
     cartao. A borda deixou de ser necessaria e virou a propria cor. */
  --cx-primary-border: var(--cx-primary);
  --cx-border-strong: #565D68;
  --cx-focus: #86A8DF;
  --cx-text-subtle: #868B93;
  --cx-focus-halo: rgba(134,168,223,.18);
  --cx-scrim: rgba(10,11,13,0.62);
  /* No escuro a superficie pode clarear: o fundo da pagina ja e escuro,
     entao o botao precisa SUBIR de luminancia para flutuar. */
  --cx-focus-outline: 2px solid #86A8DF;
  --cx-focus-ring: 0 0 0 4px rgba(134,168,223,0.18);
  --cx-shadow-surface: 0 2px 8px rgba(0,0,0,0.22);
  --cx-shadow-interactive: 0 8px 24px rgba(0,0,0,0.30);
  --cx-shadow-interactive-hover: 0 18px 48px rgba(0,0,0,0.38);

  /* v2.4 - no escuro a superficie clareia levemente e o ink vira a propria
     familia clara; o tint vira o pastel a 18% sobre o painel. */
  --cx-success-ink: #B1DDD0;
  --cx-success-indicator: #63C1A5;
  --cx-error-ink: #E6ACA8;
  --cx-error-indicator: #DE7A72;
  --cx-warning-ink: #EDC9A1;
  --cx-warning-indicator: #E8A458;
  --cx-present-ink: #DCCFB2;
  --cx-present-indicator: #C9B07A;
  --cx-completed-ink: #C0C7CE;
  --cx-completed-indicator: #B4BEC7;
  --cx-requested-ink: #ACC3E1;
  --cx-requested-indicator: #8FB0DC;
  --cx-success-surface: #3FAD7E;
  --cx-success-tint: rgba(63,173,126,0.18);
  --cx-success-on: var(--cx-graphite);
  --cx-error-surface: #FF6A3D;
  --cx-error-tint: rgba(255,106,61,0.18);
  --cx-error-on: var(--cx-graphite);
  --cx-warning-surface: #FF9646;
  --cx-warning-tint: rgba(255,150,70,0.18);
  --cx-warning-on: var(--cx-graphite);
  --cx-present-surface: #69CCBB;
  --cx-present-tint: rgba(105,204,187,0.18);
  --cx-present-on: var(--cx-graphite);
  --cx-completed-surface: #3C55D1;
  --cx-completed-tint: rgba(60,85,209,0.18);
  --cx-completed-on: var(--cx-ivory);
  --cx-requested-surface: #8FB0DC;
  --cx-requested-tint: rgba(143,176,220,0.18);
  --cx-requested-on: var(--cx-graphite);
  /* No escuro nenhuma superficie e translucida: a cor escureceria contra
     o painel e o texto sumiria. E o #FB3C04, que no claro so passa GRACAS
     a transparencia, aqui precisa de um clareado proprio (#FF6A3D, 5,67:1
     com grafite) — opaco ele reprova com os dois textos. */
  --cx-gloss: none;
}

/* ------------------------------------------------------------------
   Camada de componentes.
   Regra: nada aqui pode conter valor literal de cor, raio, sombra,
   espacamento ou fonte. Tudo referencia var(--cx-*).
   ------------------------------------------------------------------ */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--cx-page);
  color: var(--cx-text-primary);
  font-family: var(--cx-font-body);
  font-size: var(--cx-text-body-size);
  line-height: var(--cx-text-body-line);
  -webkit-font-smoothing: antialiased;
}

:focus-visible {
  outline: var(--cx-focus-outline);
  outline-offset: var(--cx-focus-offset);
  box-shadow: var(--cx-focus-ring);
}

/* tipografia */
.cx-h1 { font-family: var(--cx-font-heading); font-size: var(--cx-text-h1-size); line-height: var(--cx-text-h1-line); font-weight: var(--cx-text-h1-weight); letter-spacing: var(--cx-text-h1-tracking); margin: 0; }
.cx-h2 { font-family: var(--cx-font-heading); font-size: var(--cx-text-h2-size); line-height: var(--cx-text-h2-line); font-weight: var(--cx-text-h2-weight); letter-spacing: var(--cx-text-h2-tracking); margin: 0; }
.cx-h3 { font-family: var(--cx-font-heading); font-size: var(--cx-text-h3-size); line-height: var(--cx-text-h3-line); font-weight: var(--cx-text-h3-weight); letter-spacing: var(--cx-text-h3-tracking); margin: 0; }
.cx-body { font-family: var(--cx-font-body); font-size: var(--cx-text-body-size); line-height: var(--cx-text-body-line); font-weight: var(--cx-text-body-weight); }
.cx-small { font-family: var(--cx-font-body); font-size: var(--cx-text-small-size); line-height: var(--cx-text-small-line); font-weight: var(--cx-text-small-weight); }
.cx-caption { font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); font-weight: var(--cx-text-caption-weight); }
.cx-technical { font-family: var(--cx-font-mono); font-size: var(--cx-text-technical-size); line-height: var(--cx-text-technical-line); font-weight: var(--cx-text-technical-weight); }

/* Texto que CARREGA informacao. Passa AA em toda superficie do sistema. */
.cx-text-muted { color: var(--cx-text-muted); }
/* Texto/tracos DECORATIVOS. Nunca use para informacao necessaria. */
.cx-text-subtle { color: var(--cx-text-subtle); }
.cx-text-secondary { color: var(--cx-text-secondary); }

/* superficies */
.cx-surface {
  background: var(--cx-panel);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-lg);
  box-shadow: var(--cx-shadow-surface);
}

.cx-interactive {
  background: var(--cx-panel-strong);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  box-shadow: var(--cx-shadow-interactive);
  transition: transform var(--cx-motion-fast) var(--cx-ease),
              box-shadow var(--cx-motion-fast) var(--cx-ease),
              border-color var(--cx-motion-fast) var(--cx-ease);
}
.cx-interactive:hover { transform: translateY(var(--cx-hover-lift)); box-shadow: var(--cx-shadow-interactive-hover); border-color: var(--cx-border-strong); }
.cx-interactive:active { transform: translateY(var(--cx-press-translate)); box-shadow: var(--cx-shadow-surface); }

/* botoes */
.cx-button {
  min-height: var(--cx-control);
  padding-inline: var(--cx-control-padding-inline);
  border-radius: var(--cx-radius-md);
  border: 1px solid transparent;
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-button-size);
  line-height: var(--cx-text-button-line);
  font-weight: var(--cx-text-button-weight);
  letter-spacing: var(--cx-text-button-tracking);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--cx-space-2);
  cursor: pointer; text-decoration: none;
  transition: transform var(--cx-motion-fast) var(--cx-ease),
              box-shadow var(--cx-motion-fast) var(--cx-ease),
              background var(--cx-motion-fast) var(--cx-ease);
}
.cx-button:hover { transform: translateY(var(--cx-hover-lift)); box-shadow: var(--cx-shadow-interactive-hover); }
.cx-button:active { transform: translateY(var(--cx-press-translate)); }
.cx-button--compact { min-height: var(--cx-control-compact); padding-inline: var(--cx-space-4); }
.cx-button--large { min-height: var(--cx-control-large); }
.cx-button--primary { background: var(--cx-primary); color: var(--cx-primary-on); border-color: var(--cx-primary-border); box-shadow: var(--cx-shadow-interactive); }
.cx-button--accent { background: var(--cx-champagne); color: var(--cx-graphite); box-shadow: var(--cx-shadow-interactive); }
.cx-button--secondary { background: var(--cx-panel-strong); color: var(--cx-text-primary); border-color: var(--cx-border); box-shadow: var(--cx-shadow-interactive); }
.cx-button--tenant { background: var(--tenant-accent); color: var(--tenant-on-accent); box-shadow: var(--cx-shadow-interactive); }

/* v2.3.3 - SOLIDOS SEMANTICOS. Para a acao que faz a coisa acontecer. */
.cx-button--success { background: var(--cx-gloss), var(--cx-success-surface);   color: var(--cx-success-on); box-shadow: var(--cx-shadow-interactive); }
.cx-button--danger  { background: var(--cx-gloss), var(--cx-error-surface);     color: var(--cx-error-on); box-shadow: var(--cx-shadow-interactive); }
.cx-button--warning { background: var(--cx-gloss), var(--cx-warning-surface);   color: var(--cx-warning-on); box-shadow: var(--cx-shadow-interactive); }
.cx-button--present { background: var(--cx-gloss), var(--cx-present-surface);   color: var(--cx-present-on); box-shadow: var(--cx-shadow-interactive); }
.cx-button--neutral { background: var(--cx-gloss), var(--cx-completed-surface); color: var(--cx-completed-on); box-shadow: var(--cx-shadow-interactive); }

/* v2.3.3 - TONAIS SEMANTICOS. Mesma cor, menos peso: para a alternativa que
   convive com a acao principal sem disputar com ela. Reusam exatamente os
   tokens das etiquetas de estado - nenhuma cor nova entra por aqui. */
/* Versao atenuada da mesma familia, para a alternativa que convive com a acao
   principal sem disputar com ela. */
.cx-button--success-soft { background: var(--cx-success-tint);   color: var(--cx-success-ink);   border-color: var(--cx-success-indicator);   box-shadow: var(--cx-shadow-surface); }
.cx-button--danger-soft  { background: var(--cx-error-tint);     color: var(--cx-error-ink);     border-color: var(--cx-error-indicator);     box-shadow: var(--cx-shadow-surface); }
.cx-button--warning-soft { background: var(--cx-warning-tint);   color: var(--cx-warning-ink);   border-color: var(--cx-warning-indicator);   box-shadow: var(--cx-shadow-surface); }
.cx-button--neutral-soft { background: var(--cx-completed-tint); color: var(--cx-completed-ink); border-color: var(--cx-completed-indicator); box-shadow: var(--cx-shadow-surface); }
.cx-button:disabled, .cx-button[aria-disabled="true"] { opacity: .46; cursor: not-allowed; transform: none; box-shadow: none; }

/* campos */
.cx-input {
  min-height: var(--cx-control);
  padding-inline: var(--cx-space-4);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-panel-strong);
  color: var(--cx-text-primary);
  font-family: var(--cx-font-body);
  font-size: var(--cx-text-small-size);
  line-height: var(--cx-text-small-line);
  box-shadow: var(--cx-shadow-interactive);
}
/* placeholder usa text-muted (AA), nunca text-subtle */
.cx-input::placeholder { color: var(--cx-text-muted); opacity: 1; }
.cx-input:hover { border-color: var(--cx-border-strong); }
.cx-input:focus { border-color: var(--cx-focus); }
.cx-label { display: block; font-family: var(--cx-font-body); font-size: var(--cx-text-small-size); line-height: var(--cx-text-small-line); font-weight: 600; color: var(--cx-text-secondary); margin-bottom: var(--cx-space-2); }
.cx-hint { font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); color: var(--cx-text-muted); }
.cx-field-error { font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); color: var(--cx-error); }
/* v2.3.2 - o token --cx-success existia desde a v2.3; faltava a classe. */
.cx-field-success { font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); color: var(--cx-success); }
.cx-field-warning { font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); color: var(--cx-warning); }

/* v2.3.2 - <select> nativo. Herda altura de controle, raio e foco do sistema;
   a seta fica por conta do navegador (nao ha appearance:none aqui, para nao
   perder o comportamento nativo em toque). */
.cx-select {
  min-height: var(--cx-control);
  padding-inline: var(--cx-space-3);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-panel-strong);
  color: var(--cx-text-primary);
  font-family: var(--cx-font-body);
  font-size: var(--cx-text-small-size);
  line-height: var(--cx-text-small-line);
  box-shadow: var(--cx-shadow-interactive);
  cursor: pointer;
}
.cx-select:hover { border-color: var(--cx-border-strong); }
.cx-select:focus { border-color: var(--cx-focus); }
.cx-select--compact { min-height: var(--cx-control-compact); box-shadow: none; }

/* cartoes e navegacao */
.cx-card { background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); box-shadow: var(--cx-shadow-surface); }
.cx-card--interactive { background: var(--cx-panel-strong); box-shadow: var(--cx-shadow-interactive); transition: transform var(--cx-motion-fast) var(--cx-ease), box-shadow var(--cx-motion-fast) var(--cx-ease); }
.cx-card--interactive:hover { transform: translateY(var(--cx-hover-lift)); box-shadow: var(--cx-shadow-interactive-hover); }

.cx-nav-item { min-height: var(--cx-control); border-radius: var(--cx-radius-md); display: flex; align-items: center; gap: var(--cx-space-3); padding-inline: var(--cx-space-4); color: var(--cx-text-secondary); text-decoration: none; }
.cx-nav-item--active { background: var(--cx-panel-strong); color: var(--cx-text-primary); border: 1px solid var(--cx-border); box-shadow: var(--cx-shadow-interactive); }

/* estados de reserva - cor NUNCA sozinha: sempre com texto e icone */
.cx-status { display: inline-flex; align-items: center; gap: var(--cx-space-2); min-height: 28px; padding: var(--cx-space-1) var(--cx-space-3); border-radius: var(--cx-radius-pill); font-family: var(--cx-font-body); font-size: var(--cx-text-caption-size); line-height: var(--cx-text-caption-line); font-weight: 600; }
.cx-status::before { content: ""; width: var(--cx-space-2); height: var(--cx-space-2); border-radius: 50%; background: var(--status-indicator); flex: 0 0 auto; }
.cx-status--requested { --status-indicator: var(--cx-status-requested-indicator); background: var(--cx-status-requested-bg); color: var(--cx-status-requested-text); }
.cx-status--confirmed { --status-indicator: var(--cx-status-confirmed-indicator); background: var(--cx-status-confirmed-bg); color: var(--cx-status-confirmed-text); }
.cx-status--present   { --status-indicator: var(--cx-status-present-indicator);   background: var(--cx-status-present-bg);   color: var(--cx-status-present-text); }
.cx-status--completed { --status-indicator: var(--cx-status-completed-indicator); background: var(--cx-status-completed-bg); color: var(--cx-status-completed-text); }
.cx-status--canceled  { --status-indicator: var(--cx-status-canceled-indicator);  background: var(--cx-status-canceled-bg);  color: var(--cx-status-canceled-text); }
.cx-status--no-show   { --status-indicator: var(--cx-status-no-show-indicator);   background: var(--cx-status-no-show-bg);   color: var(--cx-status-no-show-text); }
.cx-status--refused   { --status-indicator: var(--cx-status-refused-indicator);   background: var(--cx-status-refused-bg);   color: var(--cx-status-refused-text); }
/* v2.3.2 - quando o chip traz o icone Lucide do estado, o ponto indicador sai:
   o icone JA e o indicador nao-cromatico exigido pelo RESERVATION_STATUS_SYSTEM.
   Ponto + icone + texto polui sem acrescentar informacao. */
.cx-status--icon::before { content: none; }
/* v2.4 - etiqueta solida. Por padrao a etiqueta e passiva (tint); esta variante
   existe para listas onde o estado e a informacao principal da linha. */
.cx-status--solid { color: var(--cx-on-surface); }
.cx-status--solid.cx-status--requested { background: var(--cx-requested-surface); color: var(--cx-requested-on); }
.cx-status--solid.cx-status--confirmed { background: var(--cx-success-surface); color: var(--cx-success-on); }
.cx-status--solid.cx-status--present   { background: var(--cx-present-surface); }
.cx-status--solid.cx-status--completed { background: var(--cx-completed-surface); color: var(--cx-completed-on); }
.cx-status--solid.cx-status--canceled  { background: var(--cx-error-surface); }
.cx-status--solid.cx-status--no-show   { background: var(--cx-warning-surface); }
.cx-status--solid.cx-status--refused   { background: var(--cx-error-surface); }

/* acoes flutuantes e modal */
.cx-floating-action {
  width: 72px; height: 72px; min-width: var(--cx-control); min-height: var(--cx-control);
  border-radius: 50%; border: 1px solid var(--cx-border);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cx-panel-strong); color: var(--cx-text-primary);
  box-shadow: var(--cx-shadow-interactive);
  transition: transform var(--cx-motion-fast) var(--cx-ease), box-shadow var(--cx-motion-fast) var(--cx-ease);
}
.cx-floating-action:hover { transform: translateY(var(--cx-hover-lift)); box-shadow: var(--cx-shadow-interactive-hover); }
.cx-floating-action--graphite { background: var(--cx-graphite); color: var(--cx-ivory); border-color: var(--cx-graphite); }
.cx-floating-action--champagne { background: var(--cx-champagne); color: var(--cx-graphite); border-color: var(--cx-champagne); }

.cx-hairline { height: var(--cx-hairline-size); background: var(--cx-hairline); border: 0; border-radius: var(--cx-radius-pill); }

.cx-modal { background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-xl); box-shadow: var(--cx-shadow-interactive-hover); }
/* v2.3.2 - o veu era literal em todo produto que abria modal. */
.cx-scrim { position: fixed; inset: 0; background: var(--cx-scrim); overflow: auto; }

/* icones Lucide */
.cx-icon {
  width: var(--cx-icon-size); height: var(--cx-icon-size);
  stroke-width: var(--cx-icon-stroke); flex: 0 0 auto;
  fill: none; stroke: currentColor;
  stroke-linecap: round; stroke-linejoin: round;
}
.cx-icon--active { stroke-width: var(--cx-icon-stroke-active); }
.cx-icon--compact { width: var(--cx-icon-size-compact); height: var(--cx-icon-size-compact); }
.cx-icon--large { width: var(--cx-icon-size-large); height: var(--cx-icon-size-large); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ============================================================
   cx-rail — NAVEGACAO VERTICAL FLUTUANTE          (novo na v2.6)
   ============================================================

   Um balao vertical fixo na lateral. Recolhido: so icones. Ao passar o
   mouse, ao receber foco pelo teclado (:focus-within) ou com a classe
   .cx-rail--fixa: expande com os nomes.

   Ele expande POR CIMA. O conteudo atras nao se mexe — quem reserva o
   espaco da barra recolhida e a margem da pagina, que nunca muda. Barra
   que empurra conteudo faz a agenda reflowar a cada passada de mouse, e
   numa tela que a equipe olha o dia inteiro isso cansa.

   COR: a barra e base. Marfim, filete e grafite. O champanhe marca o item
   ativo — mesmo tratamento da etiqueta de papel no cabecalho, para quem
   ja conhece a tela reconhecer sem aprender de novo. Nenhuma cor
   semantica entra aqui: verde e vermelho sao da acao, nao do menu.

   MARCACAO ESPERADA:
     <nav class="cx-rail" aria-label="Secoes">
       <button class="cx-rail-item ativa" aria-current="page">
         <span class="cx-rail-icone"><svg class="cx-icon">...</svg></span>
         <span class="cx-rail-rotulo">Reservas</span>
       </button>
       ...
     </nav>
*/

.cx-rail {
  position: fixed;
  left: var(--cx-space-4);
  /* Ancorada abaixo do cabecalho, nao centralizada na vertical. Centralizar
     so fica bem quando a barra e alta o bastante para parecer coluna; com
     meia duzia de itens ela vira uma ilha no meio da tela, longe do titulo
     e longe do rodape. Presa ao topo ela le como continuacao do cabecalho. */
  top: calc(var(--cx-header-height) + var(--cx-space-16));
  z-index: 40;

  display: flex;
  flex-direction: column;
  gap: var(--cx-space-1);

  width: var(--cx-rail-width);
  padding: var(--cx-space-2);

  background: var(--cx-panel);
  border: var(--cx-hairline-size) solid var(--cx-border);
  border-radius: var(--cx-radius-xl);
  box-shadow: var(--cx-shadow-interactive);

  overflow: hidden;
  transition: width var(--cx-motion-normal) var(--cx-ease),
              box-shadow var(--cx-motion-normal) var(--cx-ease);
}

/* v2.7 - a expansao por HOVER so vale onde hover existe de verdade. Em
   tela de toque o :hover "gruda" depois do tap e deixaria a barra aberta
   sem que ninguem tenha pedido. O foco DE TECLADO continua abrindo em
   qualquer dispositivo — quem chega pelo Tab precisa ler os nomes —, e a
   classe --fixa e o caminho explicito do tablet. (07/10: era :focus-within,
   que abria tambem com foco de clique e de script; ver LAPIDACAO DE 07/10,
   no fim do arquivo.) NAO ha atraso em lugar nenhum:
   atraso em resposta de hover faz o sistema parecer lento. */
@media (hover: hover) {
  .cx-rail:hover {
    width: var(--cx-sidebar-width);
    box-shadow: var(--cx-shadow-interactive-hover);
  }
}
.cx-rail:has(:focus-visible),
.cx-rail--fixa {
  width: var(--cx-sidebar-width);
  box-shadow: var(--cx-shadow-interactive-hover);
}

.cx-rail-item {
  display: flex;
  align-items: center;
  gap: var(--cx-space-2);

  width: 100%;
  min-height: var(--cx-control);
  padding: 0 var(--cx-space-2) 0 0;

  border: var(--cx-hairline-size) solid transparent;
  border-radius: var(--cx-radius-md);
  background: none;
  color: var(--cx-text-secondary);

  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-button-size);
  line-height: var(--cx-text-button-line);
  font-weight: var(--cx-text-button-weight);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;

  transition: background var(--cx-motion-fast) var(--cx-ease),
              color var(--cx-motion-fast) var(--cx-ease);
}

/* A caixa do icone tem a largura de um controle. E o que mantem o icone no
   centro exato da barra recolhida sem depender de padding calculado. */
.cx-rail-icone {
  flex: 0 0 var(--cx-control);
  display: grid;
  place-items: center;
}

/* O rotulo nao usa display:none: ele precisa continuar no fluxo para o
   leitor de tela anunciar o nome da secao mesmo com a barra recolhida.
   Some por opacidade, e a barra recorta o excedente com overflow:hidden. */
.cx-rail-rotulo {
  opacity: 0;
  transition: opacity var(--cx-motion-fast) var(--cx-ease);
}
@media (hover: hover) {
  .cx-rail:hover .cx-rail-rotulo { opacity: 1; }
}
.cx-rail:has(:focus-visible) .cx-rail-rotulo,
.cx-rail--fixa .cx-rail-rotulo {
  opacity: 1;
}

/* ---- v2.7: a cor sai do simbolo e toma o botao ----
   Em repouso o botao e base e o ICONE e colorido: e o que diz "isto aqui
   se clica" sem encher a barra de blocos coloridos. No hover a MESMA cor
   vira o preenchimento e o conteudo vira marfim (grafite no tema escuro).
   Mesmo hexadecimal, papel diferente — e por isso a transicao parece uma
   coisa so, nao uma troca de cor.

   v2.8: e UMA cor para todos os itens, nao uma por secao. Quem identifica a
   secao e o icone e o nome — cinco tons de verde pediriam do leitor uma
   distincao que ele nao faz. Consequencia boa: a marcacao encurtou, porque
   nenhum item precisa mais declarar a cor dele. */
.cx-rail-item .cx-icon { color: var(--cx-nav-ink); }

@media (hover: hover) {
  .cx-rail-item:hover {
    background: var(--cx-nav-surface);
    color: var(--cx-nav-on);
  }
  .cx-rail-item:hover .cx-icon { color: var(--cx-nav-on); }
}
/* No toque nao ha hover: o mesmo efeito aparece no instante do toque. */
.cx-rail-item:active {
  background: var(--cx-nav-surface);
  color: var(--cx-nav-on);
}
.cx-rail-item:active .cx-icon { color: var(--cx-nav-on); }

/* Estado, nao enfeite: o champanhe da base marca onde voce esta. Ele NAO
   segue a familia de navegacao de proposito — "voce esta aqui" nao e
   affordance, e a mesma logica da etiqueta de papel no cabecalho.

   A barra indicadora nao e decoracao: champanhe sobre o painel claro da
   2,05:1, e a WCAG 1.4.11 pede 3:1 para identificar ESTADO de componente.
   O grafite (15,7:1) e quem cumpre a regra; o champanhe fica pela marca. */
.cx-rail-item.ativa {
  background: var(--cx-champagne);
  color: var(--cx-graphite);
  box-shadow: inset var(--cx-space-1) 0 0 0 var(--cx-graphite);
}
.cx-rail-item.ativa .cx-icon { color: var(--cx-graphite); }
.cx-rail-item.ativa:hover,
.cx-rail-item.ativa:active {
  background: var(--cx-champagne);
  color: var(--cx-graphite);
}
.cx-rail-item.ativa:hover .cx-icon,
.cx-rail-item.ativa:active .cx-icon { color: var(--cx-graphite); }

[data-theme="dark"] .cx-rail-item.ativa {
  box-shadow: inset var(--cx-space-1) 0 0 0 var(--cx-ivory);
}

/* Separador antes do rodape da barra (fixar, sair). */
.cx-rail-separador {
  height: var(--cx-hairline-size);
  margin: var(--cx-space-2) var(--cx-space-2);
  background: var(--cx-border);
  border: 0;
  flex: 0 0 auto;
}

.cx-rail-espaco { flex: 1 1 auto; min-height: var(--cx-space-2); }

/* Item que so faz sentido em tela larga — o "manter aberta", por exemplo:
   na barra inferior nao ha o que manter aberto. Sai da barra e sai da ordem
   de tabulacao junto, senao o teclado para num botao invisivel. */
.cx-rail-item--so-desktop { display: flex; }

/* ---- Tela estreita: o balao vira barra inferior ----
   Balao flutuante lateral em 375px come um terco da largura util. Embaixo,
   com o polegar por perto, e o lugar certo. Os nomes somem: nao cabem. */
@media (max-width: 900px) {
  .cx-rail {
    left: 0; right: 0; bottom: 0;
    top: auto;
    transform: none;
    width: auto;
    flex-direction: row;
    justify-content: space-around;
    gap: 0;
    padding: var(--cx-space-2);
    border-radius: var(--cx-radius-xl) var(--cx-radius-xl) 0 0;
    border-inline: 0;
    border-bottom: 0;
  }
  .cx-rail:hover,
  .cx-rail:has(:focus-visible),
  .cx-rail--fixa { width: auto; }

  .cx-rail-item { width: auto; padding: 0; justify-content: center; }
  /* Deitada, a barra indicadora do item ativo vai para o TOPO: no rodape,
     uma marca na lateral esquerda do botao nao le como "voce esta aqui". */
  .cx-rail-item.ativa { box-shadow: inset 0 var(--cx-space-1) 0 0 var(--cx-graphite); }
  [data-theme="dark"] .cx-rail-item.ativa { box-shadow: inset 0 var(--cx-space-1) 0 0 var(--cx-ivory); }
  .cx-rail-rotulo,
  .cx-rail-separador,
  .cx-rail-espaco,
  .cx-rail-item--so-desktop { display: none; }
  .cx-rail:hover .cx-rail-rotulo,
  .cx-rail:has(:focus-visible) .cx-rail-rotulo { opacity: 0; }
}

/* ============================================================
   cx-card--expansivel — CARTAO QUE ABRE          (novo na v2.7)
   ============================================================

   Para os baloes da coluna esquerda: fila de espera, avisos, ocupacao por
   ambiente. Recolhido mostra o resumo — os numeros que a pessoa le de
   relance, em pe, no meio do salao. Aberto mostra o detalhe.

   Feito sobre <details>/<summary> NATIVO, de proposito:
   · abre no toque e no teclado sem uma linha de JavaScript;
   · funciona antes do JS carregar, que e quando o maitre abre o painel;
   · o leitor de tela ja sabe anunciar "expandido/recolhido" — nao precisa
     de aria-expanded na mao, e o que se escreve na mao se esquece de
     atualizar.

   MARCACAO ESPERADA:
     <details class="cx-card cx-card--expansivel">
       <summary class="cx-card-resumo">
         <span class="cx-card-titulo">Fila</span>
         <span class="cx-card-numeros">4 grupos · 13 pessoas · 1º há 22 min</span>
       </summary>
       <div class="cx-card-detalhe"> ...lista... </div>
     </details>
*/

.cx-card--expansivel { padding: 0; overflow: hidden; }

.cx-card-resumo {
  display: flex;
  align-items: baseline;
  gap: var(--cx-space-3);
  flex-wrap: wrap;
  padding: var(--cx-space-4);
  cursor: pointer;
  list-style: none;
  min-height: var(--cx-control);
  transition: background var(--cx-motion-fast) var(--cx-ease);
}
/* O triangulo padrao do Safari/Chrome nao segue tipografia nenhuma. */
.cx-card-resumo::-webkit-details-marker { display: none; }
.cx-card-resumo::marker { content: ''; }

@media (hover: hover) {
  .cx-card-resumo:hover { background: var(--cx-subtle); }
}

.cx-card-titulo {
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-small-size);
  line-height: var(--cx-text-small-line);
  font-weight: var(--cx-text-button-weight);
  color: var(--cx-text-primary);
  text-transform: uppercase;
  letter-spacing: .06em;
}

/* Os numeros do resumo sao o conteudo mais lido do cartao — nao sao
   legenda. Corpo, nao caption. */
.cx-card-numeros {
  font-family: var(--cx-font-body);
  font-size: var(--cx-text-body-size);
  line-height: var(--cx-text-body-line);
  color: var(--cx-text-primary);
}

/* A seta e o unico sinal de que o cartao abre: ela precisa existir, e
   precisa girar, senao ninguem descobre que ha detalhe embaixo. */
.cx-card-resumo::after {
  content: '';
  margin-left: auto;
  width: var(--cx-space-2);
  height: var(--cx-space-2);
  border-right: 2px solid var(--cx-text-secondary);
  border-bottom: 2px solid var(--cx-text-secondary);
  transform: rotate(45deg);
  transition: transform var(--cx-motion-fast) var(--cx-ease);
}
.cx-card--expansivel[open] .cx-card-resumo::after { transform: rotate(-135deg); }

.cx-card-detalhe {
  padding: 0 var(--cx-space-4) var(--cx-space-4);
  border-top: var(--cx-hairline-size) solid var(--cx-border);
  padding-top: var(--cx-space-4);
}

/* Cartao de coluna lateral tem altura util pequena. O detalhe rola por
   dentro em vez de empurrar o resto da coluna para fora da tela. */
.cx-card--expansivel .cx-card-detalhe { max-height: calc(var(--cx-space-16) * 5); overflow-y: auto; }

/* Variante estreita — para os baloes que ficam lado a lado numa faixa, tipo
   ocupacao por ambiente. Titulo e numeros empilham SEMPRE, em vez de caber
   numa linha quando o cartao e largo e quebrar quando e estreito: cartao
   irmao que quebra diferente do vizinho le como defeito, nao como layout. */
.cx-card--compacto .cx-card-resumo {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--cx-space-1);
  position: relative;
  padding-right: var(--cx-space-8);
}
.cx-card--compacto .cx-card-resumo::after {
  position: absolute;
  right: var(--cx-space-4);
  top: 50%;
  margin: 0;
  transform: translateY(-70%) rotate(45deg);
}
.cx-card--compacto[open] .cx-card-resumo::after { transform: translateY(-30%) rotate(-135deg); }
/* Os numeros sao o que se le de relance nestes: sobem de corpo. */
.cx-card--compacto .cx-card-numeros {
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-h3-size);
  line-height: var(--cx-text-h3-line);
  font-weight: var(--cx-text-h3-weight);
}


/* ####################################################################
   ####################################################################
   ##                                                                ##
   ##                     PARTE NOVA DA v3.0                         ##
   ##                                                                ##
   ##   Acima desta linha, o corpo da v2.9 palavra por palavra.       ##
   ##   Daqui para baixo, so acrescimo. Nada acima foi tocado.        ##
   ##                                                                ##
   ####################################################################
   #################################################################### */


/* ====================================================================
   v3.0 — 1. `hidden` TEM DE ESCONDER
   Promovido do painel.css do reservas, e o comentario vem junto porque o
   raciocinio e metade do valor.

   O atributo `hidden` do HTML nao e magica: ele vale por uma regra
   `display:none` na folha do NAVEGADOR, que tem a menor precedencia que
   existe. Qualquer `display` declarado por nos ou pelo pacote ganha dela.
   `.cx-button` declara `display:inline-flex` — entao `elemento.hidden =
   true` virava ordem ignorada em silencio: o JavaScript mandava esconder,
   o CSS nao escondia, e o desencontro nao aparecia no codigo, so na tela.

   Custou duas idas ao Jimmy em 07/09, no reservas. Fica no pacote para
   ninguem pagar de novo.

   Se algum dia um elemento precisar aparecer com `hidden` posto — nao
   existe caso legitimo —, tire o atributo, nao esta regra.
   ==================================================================== */
[hidden] { display: none !important; }


/* ====================================================================
   v3.0 — 2. TOKENS NOVOS
   ==================================================================== */
:root {

  /* --- Largura do andar -----------------------------------------------
     O andar tem a largura da barra ABERTA, que e --cx-sidebar-width. NAO
     existe token de "barra aberta" separado, e nao se cria um: o
     comentario do --cx-rail-width, la em cima, ja diz que a expandida e a
     --cx-sidebar-width. Um segundo nome para a mesma medida e a maneira
     mais silenciosa de as duas divergirem na primeira mudanca.

     Este token existe porque o ANDAR pode um dia querer largura propria;
     enquanto nao quiser, ele aponta para a da barra e o alinhamento se
     mantem sozinho. */
  --cx-nivel-largura: var(--cx-sidebar-width);

  /* --- A BARRA RECOLHIDA ESTAVA 12px ESTREITA DEMAIS --------------------
     UNICA SOBRESCRITA DE TOKEN DA v2.9 EM TODO ESTE ARQUIVO, e por isso
     esta declarada aqui, com o motivo junto, em vez de editada la em cima.

     O comentario original diz que --cx-rail-width mantem o icone "no centro
     exato da barra recolhida sem depender de padding calculado". Nao mantem,
     e a conta mostra onde some:

       borda da barra      3
       + respiro           8
       + borda do item     3        <- transparente, mas ocupa
       + meia caixa        22
       = 36 do canto esquerdo ate o centro do icone

     Com a barra em 60, o centro dela cai em 30. Sao 6px de diferenca, para
     a direita, em todos os icones — e a caixa de 44 ainda vaza 9px para
     fora da area util, que o overflow:hidden recorta.

     A conta certa e SIMETRICA, e agora esta escrita como ela e:

       um controle + duas vezes (borda da barra + respiro + borda do item)
       = 44 + 2 x 14 = 72

     A DIFERENCA E VISIVEL: a barra recolhida passa de 60 para 72px em toda
     tela que a usa. Nao e ajuste fino, e mudanca de layout, e foi decidida
     pelo Jimmy em 09/09 sabendo disso — o defeito so apareceu quando o
     bloco do modulo desenhou as bordas da barra e os 6px ficaram visiveis.

     Isso vinha desde a v2.6. E e a segunda vez em dois dias que uma conta
     deste pacote esquece a borda: a primeira foi a altura da barra deitada,
     logo abaixo. */
  --cx-rail-width: calc(var(--cx-control)
                      + (var(--cx-hairline-size) + var(--cx-space-2)
                         + var(--cx-hairline-size)) * 2);

  /* --- Altura da barra deitada ----------------------------------------
     Em tela estreita a .cx-rail vira barra de rodape, e o andar precisa
     parar EM CIMA dela.

     NAO SE DERIVA DA --cx-rail-width, e a versao anterior deste token fazia
     isso. Deitada, a barra tem borda so em CIMA — as laterais e a de baixo
     saem no @media. Entao a conta vertical e propria:

       um controle (o box-sizing:border-box do pacote ja inclui a borda do
       item dentro dele)
       + o respiro de cima e de baixo (--cx-space-2 x 2)
       + a borda de cima da barra (--cx-hairline-size)

     Conferido no navegador: 63px. Quando a --cx-rail-width virou 72, esta
     continuou 63 — que e o motivo de ela precisar da propria conta. */
  --cx-rail-rodape-altura: calc(var(--cx-control)
                              + var(--cx-space-2) * 2
                              + var(--cx-hairline-size));

  /* --- Quanto o conteudo desvia quando um andar abre --------------------
     Resposta a COLISAO 3 do AVISO_DESIGN_020, e o defeito era meu.

     A faixa de escopo da TELA DE RESERVAS e `position: sticky; z-index: 5`,
     grudada no
     topo por pedido do Jimmy: rolando uma lista longa de configuracao, sem a
     faixa grudada a pessoa perde de vista em que casa esta mexendo. O andar
     entra no z-index 45 e vai de --cx-space-4 ate mais 248px — ou seja,
     cobre o filete e o comeco do titulo da faixa EXATAMENTE enquanto a
     pessoa navega entre escopos, que e quando a faixa mais precisa ser lida.

     NAO SE RESOLVE PELA PILHA. Subir a faixa acima do andar so troca de
     vitima: ela passaria a cortar o andar pelo meio. Um dos dois tem de sair
     do caminho do outro, e quem sai e o conteudo — porque o andar e
     transitorio e a faixa fica.

     A conta e A BORDA DIREITA DO ANDAR mais um respiro, e ela se escreve
     inteira porque cada parcela tem dono:

       o respiro da barra ate a janela  (--cx-space-4)
       + a barra recolhida             (--cx-rail-width)
       + o andar                       (--cx-nivel-largura)
       + o respiro ate o conteudo      (--cx-space-4)

     Medido no navegador: 340px com os valores de hoje, e a borda direita do
     andar cai em 324.

     COMO SE APLICA, e a hipotese esta dita para nao virar armadilha: como
     `padding-left` num elemento cuja borda esquerda E a da janela, que e
     como a coluna de conteudo da tela de reservas e construida (ela ja usa
     padding
     para escapar da barra). Tela que recua o proprio invólucro aplica a
     diferenca, nao este valor cru — o andar e `position: fixed`, entao a
     conta dele e da JANELA, nao do pai.

     Nao custa largura de LISTA, que era o ponto do Jimmy: custa
     deslocamento de uma faixa de uma linha, e so enquanto o andar esta
     aberto. */
  --cx-nivel-recuo: calc(var(--cx-space-4)
                       + var(--cx-rail-width)
                       + var(--cx-nivel-largura)
                       + var(--cx-space-4));

  /* --- O nome do modulo na barra ---------------------------------------
     Par PROPRIO, e nao o --cx-escopo-estrutural, ainda que o truque seja o
     mesmo: no claro o grafite, no escuro o marfim. Aquele par significa
     ALCANCE MAXIMO e nada mais, e esta escrito la que ele nao vira
     decoracao em outro lugar sob pena de parar de funcionar onde precisa.
     Mesmo mecanismo, significado diferente, token diferente.

     E o grafite aqui esta no lugar certo pela doutrina de 22/08: cor de
     base nao veste botao PORQUE ela e a cor do que e estatico. Um rotulo
     que nao se clica e o unico lugar do sistema onde ela cabe inteira. */
  --cx-modulo:    var(--cx-graphite);
  --cx-modulo-on: var(--cx-ivory);

  /* --- Escopo estrutural ---------------------------------------------
     UM par de tokens governa os dois degraus de cima da escada de escopo,
     e a inversao esta declarada uma vez so.

     No tema claro o mais estrutural e o grafite; no escuro e o marfim.
     Nao e capricho: no escuro o grafite E o fundo da pagina, e a faixa
     mais grave do sistema desapareceria exatamente onde ela existe para
     gritar. O que carrega o sentido nao e a cor — e o fato de a quarta
     faixa ser A UNICA QUE INVERTE A SUPERFICIE. */
  --cx-escopo-estrutural:    var(--cx-graphite);
  --cx-escopo-estrutural-on: var(--cx-ivory);

  /* --- Chapa da marca de cliente --------------------------------------
     NAO acompanha o tema, e e de proposito. Regra fechada em 08/09:
     MARCA DE CLIENTE VAI SEMPRE SOBRE CHAPA CLARA.

     Ela substitui uma coluna de banco. A alternativa era pedir a cada
     cliente uma variante clara de cada marca — duas colunas novas,
     migration, e um segundo arquivo por marca de cada contratante — para
     um caso que nao acontece: pela hierarquia de 27/08, a marca da casa
     nao vai na tela de reservas, que e a unica superficie escura. */
  --cx-marca-chapa: #FFFFFF;

  /* --- Caixa do par de marcas -----------------------------------------
     200 por 80 nao sao dois numeros: sao um numero e uma PROPORCAO.
     200/80 = 2,5, que e exatamente o limiar entre marca horizontal e
     marca empilhada. A imagem para no eixo que encostar primeiro, entao
     a caixa decide sozinha o eixo limitante — sem tabela de casos, sem
     JavaScript. Implementacao do nucleo, melhor que a especificacao que
     o design tinha escrito.

     E a regua do arquivo minimo E A ALTURA VEZES DOIS, escrita como
     conta e nao como numero: no dia em que a caixa crescer, a regua
     cresce junto, sem ninguem lembrar de nada. */
  --cx-marca-altura:  80px;
  --cx-marca-largura: 200px;
  --cx-marca-minima:  calc(var(--cx-marca-altura) * 2);   /* 160px */

  /* --- Luz do interruptor / relogio de lotacao -------------------------
     Promovidos do painel.css do reservas, medidos no arquivo SERVIDO em
     producao. Pagam duas dividas de uma vez: o interruptor do reservas
     (AVISO_DESIGN_006) e os tres --cx-lotacao-* do relogio do Monitor,
     abertos desde 27/08.

     O Monitor nao esta neste deploy e nao pode ser conferido agora. Se
     ele divergir quando voltar, quem se ajusta e o Monitor: o pacote e a
     fonte, e o servico copia. */
  --cx-lotacao-livre: #28BD87;
  --cx-lotacao-cheio: #DA1B34;

  /* --- Paleta de grafico -----------------------------------------------
     Adotada do reservas, ja validada para daltonismo e contraste.

     Vem so a familia de SERIE. A familia de SUPERFICIE deles — --superficie,
     --papel, --borda e as tres --tinta — fica de fora.

     O MOTIVO ESTAVA INVERTIDO AQUI, e o reservas mediu no AVISO_DESIGN_017.
     Eu tinha escrito que eram --cx-page, --cx-panel, --cx-border e a familia
     --cx-text-* COM OUTRO NOME, e que importar seria redundante. Nenhum dos
     seis pares bate, nem no claro nem no escuro, e a divergencia e
     sistematica: a familia deles e QUENTE (bordas e cinzas puxam para o bege
     e o oliva) e a nossa e FRIA (puxam para o azul).

     A decisao continua a mesma; o motivo e o oposto. Nao sao a mesma coisa
     com dois nomes — sao duas paletas com intencao diferente, e importar
     criaria de fato as duas paletas que a decisao queria evitar.

     Fica escrito assim porque O MOTIVO E O QUE SOBREVIVE: com a frase
     antiga, alguem daqui a tres meses troca --superficie por --cx-page sem
     olhar, porque o documento disse que era a mesma coisa.

     EM QUE SUPERFICIE O GRAFICO SE ASSENTA — resposta ao mesmo aviso:
     em --cx-panel. As series foram escolhidas contra o #fcfcfb do reservas,
     e o --cx-panel claro e #FCFCFD: dois pontos de diferenca num canal so.
     Medido, a troca nao custa nada — no claro os seis contrastes mudam na
     segunda casa decimal; no escuro (deles #1a1a19, nosso #1F2125) a maior
     perda e de 0,4 num valor que continua acima de 3:1.

     Os dois que ficam ABAIXO de 3:1 no escuro, --serie-fraca e --grade, ja
     estavam abaixo na superficie propria deles: e o que se espera de um
     preenchimento fraco e de uma linha de grade, que existem para nao serem
     olhados de frente.

     --grade NAO E BORDA, e por isso nao mora perto de --cx-border nem se
     resolve para ele. #ECE9E4 e linha de grade de grafico: existe para ser
     vista pelo canto do olho e ignorada. Borda de caixa e --cx-border, que e
     outra cor e outro trabalho.

     CUIDADO QUE VEM JUNTO E NAO SE PERDE: promotor e detrator separam mal
     para deuteranopia (dE 6,9, medido pelo validador do reservas). So sao
     legitimos COM codificacao secundaria — rotulo escrito na faixa e nome
     repetido na legenda. Cor sozinha nunca decide aqui. */
  --cx-viz-serie:        #2A78D6;
  --cx-viz-serie-fraca:  #D9E6F8;
  --cx-viz-grade:        #ECE9E4;
  --cx-viz-promotor:     #1BAF7A;
  --cx-viz-neutro:       #B9B2A8;
  --cx-viz-detrator:     #E34948;
}

[data-theme="dark"] {
  --cx-modulo:    var(--cx-ivory);
  --cx-modulo-on: var(--cx-graphite);

  --cx-escopo-estrutural:    var(--cx-ivory);
  --cx-escopo-estrutural-on: var(--cx-graphite);

  /* A chapa da marca NAO inverte. Ver o comentario no :root. */

  --cx-lotacao-livre: #47D19E;
  --cx-lotacao-cheio: #E8354D;

  --cx-viz-serie:        #3987E5;
  --cx-viz-serie-fraca:  #20334A;
  --cx-viz-grade:        #2F2E2C;
  --cx-viz-promotor:     #199E70;
  --cx-viz-neutro:       #7D766C;
  --cx-viz-detrator:     #E66767;
}


/* ====================================================================
   v3.0 — 3. A BARRA EM ANDARES
   Decisao do Jimmy, 08/09. A .cx-rail nao ganha uma coluna ao lado: ela
   ganha ANDARES.

   O DESENHO, e o porque de cada regra:

   - A raiz continua com um nivel visivel, sempre. Nada abaixo altera o
     comportamento de hover que a v2.9 ja tem.
   - So quem tem filhos empilha. Secao sem filhos navega direto, como
     hoje. A pilha so existe na configuracao, entao quem opera durante o
     servico nunca cai nela.
   - A troca tem DUAS FASES: o andar entra encostado na borda direita da
     barra ABERTA, inteiro a vista, e NUNCA por baixo dela; so entao a
     raiz recolhe aos icones e o andar desliza para encostar nela.
   - A raiz NAO some. Fica nos icones e nao expande no hover enquanto o
     andar esta aberto — expandir por cima do filho refaria o problema.
     Ganho: um clique para qualquer outra secao, de qualquer profundidade.
   - Profundidade NAO custa largura. O andar entra por cima do conteudo,
     como a barra ja faz ao expandir. O quarto nivel custa o mesmo que o
     segundo: zero.

   A GEOMETRIA SAI DA BARRA, NAO DA JANELA. A .cx-rail e um balao: mora em
   `left: var(--cx-space-4)`, abaixo do cabecalho, com raio xl. O andar
   parte do MESMO `left` e do MESMO `top`. Por isso desloca-lo pela largura
   da barra encosta os dois exatamente, sem numero magico e sem conta que
   precise ser refeita se a margem mudar.
   ==================================================================== */

/* --- O NOME DO MODULO, no topo da barra ---------------------------------
   Pedido do Jimmy em 09/09: dentro de um modulo, nada na tela dizia em qual
   modulo se estava. A barra mostra as SECOES do modulo e uma saida para o
   anel, sem nenhuma linha entre "onde eu estou" e "por onde eu saio".

   E O AVISO_TODOS_010 DO NUCLEO, DE 10/09, TORNA ISSO MAIS NECESSARIO E NAO
   MENOS: PAINEL passou a ser A TELA DO ANEL, e nenhum modulo e base de
   outro. Se sao oito irmaos alcancados a partir do anel, saber em qual
   deles se esta deixa de ser conforto e vira orientacao — antes, com um
   modulo se chamando "painel", ele era o centro por acidente e a pergunta
   quase nao aparecia.

   NAO E CLICAVEL, e a cor faz esse trabalho sozinha. Pela doutrina de
   22/08, cor de base nao veste botao PORQUE ela e a cor do que e estatico;
   um rotulo que nao se clica e o unico lugar do sistema onde ela cabe
   inteira. Sem hover, sem foco, cursor default.

   O MONOGRAMA E O ESTADO PRINCIPAL, e nao o plano B. A barra passa a maior
   parte do tempo recolhida, e quando um andar abre ela TRAVA nos icones de
   proposito — entao o nome inteiro e a excecao, e o monograma e o que
   responde a pergunta quase sempre. Ele precisa funcionar sozinho.

   QUEM ESCOLHE O MONOGRAMA E A TELA, nao o pacote — mesma divisao do
   .cx-desvia-do-andar. Se dois modulos comecarem com a mesma letra, a letra
   deixa de servir e vira simbolo; isso e problema de quem nomeia os
   modulos, e nao se resolve em CSS.

   A ALTURA E A DE UM CONTROLE nos dois estados, para nada saltar quando a
   barra abre. A caixa do monograma tem a largura de --cx-control, a mesma
   do .cx-rail-icone, e por isso ele cai na coluna dos icones — que, desde a
   correcao da --cx-rail-width acima, e de verdade o centro da barra.
   ------------------------------------------------------------------------ */
.cx-rail-modulo {
  display: flex;
  align-items: center;
  flex: 0 0 var(--cx-control);
  min-height: var(--cx-control);
  width: 100%;
  padding: 0;
  /* A borda transparente e a MESMA do .cx-rail-item, e existe so para
     alinhar: sem ela o monograma fica 3px a esquerda da coluna de icones,
     porque a borda do item empurra o conteudo dele. */
  border: var(--cx-hairline-size) solid transparent;
  border-radius: var(--cx-radius-md);
  background: var(--cx-modulo);
  color: var(--cx-modulo-on);
  overflow: hidden;
  cursor: default;
  user-select: none;
}
.cx-rail-modulo-marca {
  flex: 0 0 var(--cx-control);
  display: grid;
  place-items: center;
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-h3-size);
  font-weight: var(--cx-text-h1-weight);
  line-height: 1;
}
/* Some por opacidade e nao por display, pelo mesmo motivo do
   .cx-rail-rotulo: o leitor de tela precisa continuar anunciando em que
   modulo a pessoa esta, mesmo com a barra recolhida. */
.cx-rail-modulo-nome {
  white-space: nowrap;
  padding-right: var(--cx-space-3);
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-caption-size);
  line-height: var(--cx-text-caption-line);
  font-weight: var(--cx-text-button-weight);
  letter-spacing: .10em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--cx-motion-fast) var(--cx-ease);
}
@media (hover: hover) {
  .cx-rail:hover .cx-rail-modulo-nome { opacity: 1; }
}
.cx-rail:has(:focus-visible) .cx-rail-modulo-nome,
.cx-rail--fixa .cx-rail-modulo-nome,
.cx-rail.cx-rail--forcada .cx-rail-modulo-nome { opacity: 1; }
.cx-rail.cx-rail--travada .cx-rail-modulo-nome,
.cx-rail.cx-rail--travada:hover .cx-rail-modulo-nome,
.cx-rail.cx-rail--travada:has(:focus-visible) .cx-rail-modulo-nome { opacity: 0; }


/* --- A raiz durante a fase 1: aberta a forca ---------------------------
   O clique acontece com o ponteiro em cima, entao o :hover ja segura a
   barra aberta. Esta classe existe para o caso em que ele sai antes de a
   fase 1 terminar — e para tela de toque, onde o hover da v2.9 nao vale,
   porque ele mora dentro de @media (hover: hover). */
.cx-rail.cx-rail--forcada {
  width: var(--cx-sidebar-width);
  box-shadow: var(--cx-shadow-interactive-hover);
}
.cx-rail.cx-rail--forcada .cx-rail-rotulo { opacity: 1; }

/* --- A raiz durante a fase 2: travada nos icones -----------------------
   Precisa vencer TRES regras da v2.9 que expandem a barra: .cx-rail:hover,
   .cx-rail:has(:focus-visible) (ate 07/10, :focus-within) e .cx-rail--fixa. Por isso o seletor duplica a
   classe e repete o estado: .cx-rail.cx-rail--travada:hover tem
   especificidade 0,3,0 e ganha das tres, sem !important — inclusive da
   regra de hover, que esta dentro de um @media mas continua valendo 0,2,0.

   Vence .cx-rail--fixa de proposito: com o andar aberto, a preferencia de
   manter a barra fixa cede ao componente que esta por cima. */
.cx-rail.cx-rail--travada,
.cx-rail.cx-rail--travada:hover,
.cx-rail.cx-rail--travada:has(:focus-visible) {
  width: var(--cx-rail-width);
  box-shadow: var(--cx-shadow-interactive);
}
.cx-rail.cx-rail--travada .cx-rail-rotulo,
.cx-rail.cx-rail--travada:hover .cx-rail-rotulo,
.cx-rail.cx-rail--travada:has(:focus-visible) .cx-rail-rotulo { opacity: 0; }

/* --- Seta de "tem filhos" ---------------------------------------------
   Some junto com o rotulo, pelo mesmo motivo dele: com a barra recolhida
   nao ha onde caber. Nao usa display:none — o leitor de tela precisa
   continuar anunciando que o item abre um andar. */
.cx-rail-seta {
  margin-left: auto;
  opacity: 0;
  transition: opacity var(--cx-motion-fast) var(--cx-ease);
}
@media (hover: hover) {
  .cx-rail:hover .cx-rail-seta { opacity: 1; }
}
.cx-rail:has(:focus-visible) .cx-rail-seta,
.cx-rail--fixa .cx-rail-seta,
.cx-rail.cx-rail--forcada .cx-rail-seta { opacity: 1; }
.cx-rail.cx-rail--travada .cx-rail-seta,
.cx-rail.cx-rail--travada:hover .cx-rail-seta,
.cx-rail.cx-rail--travada:has(:focus-visible) .cx-rail-seta { opacity: 0; }

/* --- O andar ----------------------------------------------------------
   Fica ACIMA da raiz na pilha (z-index 45 contra os 40 da barra). Foi o
   defeito da primeira versao do prototipo: com o andar por baixo, a barra
   aberta comia os primeiros 156px dele.

   Mesma origem, mesmo topo e mesmo raio da barra: e um SEGUNDO BALAO, nao
   uma gaveta colada na janela. A altura maxima desconta o cabecalho, o
   respiro de cima e o respiro de baixo — lista curta faz balao curto, e a
   longa rola por dentro. */
.cx-nivel {
  position: fixed;
  left: var(--cx-space-4);
  top: calc(var(--cx-header-height) + var(--cx-space-16));
  z-index: 45;

  width: var(--cx-nivel-largura);
  max-height: calc(100vh - var(--cx-header-height)
                         - var(--cx-space-16)
                         - var(--cx-space-4));

  display: flex;
  flex-direction: column;
  overflow: hidden;

  background: var(--cx-panel-strong);
  border: var(--cx-hairline-size) solid var(--cx-border);
  border-radius: var(--cx-radius-xl);
  box-shadow: var(--cx-shadow-interactive-hover);

  transform: translateX(calc(-100% - var(--cx-space-4)));
  opacity: 0;
  pointer-events: none;

  transition: transform var(--cx-motion-normal) var(--cx-ease),
              opacity   var(--cx-motion-fast)   var(--cx-ease);
}
/* Fase 1 — encostado na borda direita da barra ABERTA, inteiro a vista.
   O deslocamento e a largura da barra aberta porque as duas caixas partem
   do mesmo `left`. */
.cx-nivel--fase1 {
  transform: translateX(var(--cx-sidebar-width));
  opacity: 1;
  pointer-events: auto;
}
/* Fase 2 — a raiz recolheu aos icones; o andar desliza e encosta nela. */
.cx-nivel--fase2 {
  transform: translateX(var(--cx-rail-width));
  opacity: 1;
  pointer-events: auto;
}

.cx-nivel-topo {
  display: flex;
  align-items: center;
  gap: var(--cx-space-2);
  flex: 0 0 var(--cx-header-height);
  min-height: var(--cx-header-height);
  padding: 0 var(--cx-space-3);
  background: var(--cx-subtle);
  border-bottom: var(--cx-hairline-size) solid var(--cx-border);
}
/* O titulo do andar E o botao de voltar. Um clique, sempre, sem enterrar
   ninguem: o cabecalho diz de onde se veio e leva de volta. */
.cx-nivel-voltar {
  display: grid;
  place-items: center;
  flex: 0 0 var(--cx-control);
  width: var(--cx-control);
  height: var(--cx-control);
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: var(--cx-radius-sm);
  color: var(--cx-text-secondary);
  cursor: pointer;
}
.cx-nivel-voltar:hover {
  background: var(--cx-panel-strong);
  color: var(--cx-text-primary);
}
.cx-nivel-voltar:focus-visible {
  outline: var(--cx-focus-outline);
  outline-offset: var(--cx-focus-offset);
}
.cx-nivel-titulo {
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-body-size);
  font-weight: var(--cx-text-h1-weight);
  letter-spacing: .005em;
}

.cx-nivel-lista {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--cx-space-4) var(--cx-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--cx-space-6);
}

/* --- Grupos dentro do andar -------------------------------------------
   O agrupamento aparece quando ha MAIS DE UM ESCOPO no mesmo andar, nunca
   por obrigacao. Andar de escopo unico nasce sem titulo e sem seletor —
   e o caso do Cadastros do nucleo. */
.cx-nivel-grupo {
  display: flex;
  flex-direction: column;
  gap: var(--cx-space-1);
}
.cx-nivel-grupo-titulo {
  padding: 0 var(--cx-space-3) var(--cx-space-2);
  font-size: var(--cx-text-caption-size);
  line-height: var(--cx-text-caption-line);
  font-weight: var(--cx-text-button-weight);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cx-text-muted);
}

.cx-nivel-item {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--cx-control);
  padding: 0 var(--cx-space-3) 0 var(--cx-space-4);
  border: 0;
  background: transparent;
  border-radius: var(--cx-radius-sm);
  font: inherit;
  font-size: var(--cx-text-small-size);
  line-height: var(--cx-text-small-line);
  color: var(--cx-text-secondary);
  text-align: left;
  cursor: pointer;
}
.cx-nivel-item:hover {
  background: var(--cx-subtle);
  color: var(--cx-text-primary);
}
.cx-nivel-item:focus-visible {
  outline: var(--cx-focus-outline);
  outline-offset: var(--cx-focus-offset);
}
/* O ativo se distingue por PESO e por TINTA, nao so por fundo — quem nao
   separa as duas cores continua vendo qual esta aberto. Doutrina do
   reservas, escrita nas sub-abas de 08/09. */
.cx-nivel-item.ativa {
  background: var(--cx-subtle);
  color: var(--cx-text-primary);
  font-weight: var(--cx-text-button-weight);
}
/* O filete do item ativo carrega O MESMO ESCOPO da faixa do conteudo, para
   o andar e a tela dizerem a mesma coisa sem a pessoa ler as duas. */
.cx-nivel-item.ativa::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: var(--cx-hairline-size);
  border-radius: var(--cx-radius-pill);
  background: var(--cx-nav-ink);
}
.cx-nivel-item[data-escopo="empresa"].ativa::before { background: var(--cx-champagne); }
.cx-nivel-item[data-escopo="conta"].ativa::before,
.cx-nivel-item[data-escopo="instalacao"].ativa::before { background: var(--cx-escopo-estrutural); }

/* --- O que sai do caminho do andar -------------------------------------
   O par de classes que resolve a COLISAO 3. Quem aplica e a TELA, porque o
   elemento que precisa continuar visivel e dela e nao do pacote:

     .cx-com-andar        na raiz da pagina, enquanto um andar esta aberto
     .cx-desvia-do-andar  no elemento que nao pode ser coberto

   Na tela de reservas isso e a faixa `.pn-casa`, que e sticky no topo. Em
   outra tela pode ser outra coisa, ou nada — por isso o pacote entrega o
   gancho e nao escolhe o alvo.

   O deslocamento acompanha o movimento do andar, na mesma duracao: as duas
   coisas sao um gesto so, e se andarem em tempos diferentes le como duas.
   Nao ha esvanecimento em lugar nenhum aqui. */
.cx-desvia-do-andar {
  transition: padding-left var(--cx-motion-normal) var(--cx-ease);
}
.cx-com-andar .cx-desvia-do-andar {
  padding-left: var(--cx-nivel-recuo);
}

/* Captura o clique fora sem escurecer nada: o conteudo continua legivel
   atras, porque o andar e transitorio e nao modal. */
.cx-nivel-veu {
  position: fixed;
  inset: 0;
  z-index: 44;
  background: transparent;
}

@media (prefers-reduced-motion: reduce) {
  /* A troca vira instantanea, NUNCA esvanecimento — degrade de opacidade
     parece falha de impressora. Doutrina do Jimmy. */
  .cx-nivel,
  .cx-desvia-do-andar { transition: none; }
}


/* ====================================================================
   v3.0 — 4. AS QUATRO FAIXAS DE ESCOPO
   Toda tela declara, logo abaixo do titulo, de quem e o que se esta
   editando.

   A ESCADA E POR PESO, NAO POR MATIZ, e sao TRES DEGRAUS E UM MURO:
   casa, empresa e todas as empresas sao recortes do mundo do cliente e
   dividem o mesmo fundo; DA INSTALACAO sai desse mundo — atravessa para
   os outros clientes do Concix — e e a unica que INVERTE A SUPERFICIE.

   O filete anda do verde da casa (a cor do que se opera todo dia) para o
   dourado e para o estrutural. Do local para o abstrato. Nenhuma cor nova,
   e nada emprestado da familia de estado: vermelho ja significa recusada e
   cancelada, e escopo nao e estado.

   A REGRA DA SUPERFICIE: a faixa pertence a superficie que ocupa o
   conteudo. Detalhe que SUBSTITUI a lista troca a faixa; detalhe que
   SOBREPOE — modal, gaveta — nao troca.

   A faixa TROCA junto com o conteudo, nunca transiciona de cor. Pisca o
   que muda sozinho enquanto o resto fica parado; ali muda tudo de uma vez.
   ==================================================================== */
.cx-faixa {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cx-space-3);
  padding: var(--cx-space-4);
  border-radius: var(--cx-radius-sm);
  background: var(--cx-subtle);
  border-left: var(--cx-hairline-size) solid var(--cx-nav-ink);
}
.cx-faixa-titulo {
  font-family: var(--cx-font-heading);
  font-size: var(--cx-text-body-size);
  font-weight: var(--cx-text-h1-weight);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.cx-faixa-sub {
  font-size: var(--cx-text-technical-size);
  line-height: var(--cx-text-technical-line);
  color: var(--cx-text-secondary);
}

.cx-faixa--casa    { border-left-color: var(--cx-nav-ink); }
.cx-faixa--empresa { border-left-color: var(--cx-champagne); }
.cx-faixa--todas   { border-left-color: var(--cx-escopo-estrutural); }

/* O MURO. A unica que inverte, e a inversao vale nos dois temas porque o
   par de tokens ja carrega a troca: claro vira grafite com texto marfim,
   escuro vira marfim com texto grafite. O filete champanhe fica nos dois
   — e a assinatura da base, e as duas cores de base trabalham juntas. */
.cx-faixa--instalacao {
  background: var(--cx-escopo-estrutural);
  color: var(--cx-escopo-estrutural-on);
  border-left-color: var(--cx-champagne);
}
/* O SUBTITULO SEGUE A INVERSAO, nao o champanhe. Escrito depois de ver a
   tela: champanhe sobre grafite (tema claro) le bem, mas a faixa invertida
   do tema ESCURO e marfim — e champanhe sobre marfim e o mesmo 2,05:1 que
   a v2.7 ja tinha reprovado no item ativo. Como a faixa inverte e o
   champanhe nao, um so valor nao serve aos dois lados.

   Entao o champanhe fica onde ele e assinatura e nao texto: no filete. E
   titulo e subtitulo usam os dois a tinta invertida — o que os separa e o
   corpo e a caixa alta do titulo, que ja bastavam. */
.cx-faixa--instalacao .cx-faixa-sub { color: var(--cx-escopo-estrutural-on); }

/* RESERVADO: a faixa cheia significa ALCANCE MAXIMO e nada mais. Se virar
   decoracao em outro lugar, perde o efeito onde precisa funcionar. */


/* ====================================================================
   v3.0 — 5. O PAR DE MARCAS
   Ate duas logos por casa, lado a lado, e a escolha e do cliente
   (decisao do Jimmy, 27/08).
   ==================================================================== */
.cx-marcas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cx-space-6);                 /* 24px */
  padding: var(--cx-space-4);
  border-radius: var(--cx-radius-sm);
  background: var(--cx-marca-chapa);      /* nao acompanha o tema */
}
/* SEM DIVISOR. Decisao do Jimmy em 08/09, CONTRA a recomendacao do
   design — que argumentou que duas marcas coladas leem como uma marca
   composta so, sendo duas empresas diferentes. Ele decidiu que nao, e a
   decisao e dele porque a marca e dele.
   Se alguem propuser um divisor daqui a dois meses, esta linha e a
   resposta. */

.cx-marca {
  display: block;
  width: auto;
  height: auto;
  max-height: var(--cx-marca-altura);
  max-width:  var(--cx-marca-largura);
}
/* Marca 1 e sempre a da esquerda; com uma so, ela e a marca 1 e o
   justify-content:center ja a centraliza — um lado vazio pareceria que
   faltou carregar. Ao remover a marca 1, a marca 2 sobe para o lugar
   dela; isso e do JavaScript de quem monta, nao do CSS. */

/* Sem marca nenhuma: o nome da casa ocupa a altura da caixa. E regra do
   sistema, nao decisao de cada tela — o estado sem marca e o mais comum
   hoje, e telas que resolvem por conta divergem. */
.cx-marcas-nome {
  display: flex;
  align-items: center;
  min-height: var(--cx-marca-altura);
  font-family: var(--cx-font-heading);
  font-weight: var(--cx-text-h1-weight);
  font-size: var(--cx-text-h3-size);
  line-height: var(--cx-text-h3-line);
  color: var(--cx-text-primary);
}


/* ====================================================================
   v3.0 — 6. O INTERRUPTOR COM LUZ
   Promovido do painel.css do reservas. O Jimmy pediu como padrao do
   Concix em 06/09.

   O DESENHO E DELES E NAO MUDA NA PROMOCAO, porque esta certo: a luz
   acende o ICONE e nao o botao — e indicador, nao acao. E o estado nunca
   depende so da cor: quem usa tem de manter `aria-pressed` e a etiqueta
   escrita ao lado.
   ==================================================================== */
.cx-luz .cx-icon {
  color: var(--cx-lotacao-cheio);
  filter: drop-shadow(0 0 3px var(--cx-lotacao-cheio));
}
.cx-luz--on .cx-icon {
  color: var(--cx-lotacao-livre);
  filter: drop-shadow(0 0 4px var(--cx-lotacao-livre));
}
@media (prefers-reduced-motion: no-preference) {
  .cx-luz .cx-icon {
    transition: color var(--cx-motion-fast) var(--cx-ease),
                filter var(--cx-motion-fast) var(--cx-ease);
  }
}


/* ====================================================================
   v3.0 — 7. A VARIANTE DE ACAO — a regra que fecha a colisao do laranja

   Nao ha CSS novo aqui. Ha uma REGRA, e ela e o motivo de este bloco
   existir: a variante warning estava fazendo dois trabalhos diferentes
   sem que ninguem tivesse escrito qual era qual.

     BOTAO QUE CRIA UM ESTADO VESTE A COR DO ESTADO QUE ELE CRIA.
     Confirmar e turquesa porque produz `confirmada`; Nao veio e laranja
     porque produz `no_show`. E a semantica das etiquetas aplicada a acao.
     Doutrina do reservas, escrita no painel.js e promovida aqui.

     BOTAO QUE NAO CRIA ESTADO — acrescentar, salvar, enviar — VESTE A
     ACAO PRINCIPAL DA SUPERFICIE, que e .cx-button--primary.

   SUPERFICIE e nao tela: adicionar e a acao principal de uma LISTA,
   salvar e a acao principal de um EDITOR, e nunca ha duas superficies
   ativas ao mesmo tempo.

   Decisao do Jimmy em 08/09, entre tres saidas: a doutrina do estado
   carrega SIGNIFICADO, porque a cor preve o resultado do clique e cobre
   sete estados; laranja no adicionar carrega PREFERENCIA.

   E o pedido dele de 06/09 nao se perde: o botao de acrescentar continua
   sendo o mais visivel da superficie, por POSICAO — alto e a direita do
   superficie — e por ser o primario. O que ele deixa de fazer e tomar
   emprestada uma cor que ja significa outra coisa.
   ==================================================================== */


/* ====================================================================
   v3.0 — 8. ETIQUETA DE ESTADO NAO SE DISTINGUE POR COR

   Tambem nao ha CSS novo aqui. Ha uma REGRA, e ela sai de uma medicao do
   reservas no AVISO_DESIGN_018 que eu reproduzi antes de escrever:

     .cx-status--confirmed resolve para --cx-success-tint, #E4F3EC.
     .cx-status--present   resolve para --cx-present-tint, #E8F7F4.
     Entre as duas, dE76 = 2,55.

   Dois e meio. Lado a lado na mesma agenda, sao a MESMA COR. A tinta ajuda
   um pouco e nao resolve: #1A5A40 contra #1D5D52 da dE76 9,87. No tema
   escuro a folga e maior — 4,56 nos preenchimentos e 22,10 nas tintas —,
   mas o tema claro e o que a agenda usa o dia inteiro.

   O QUE ISSO QUER DIZER, e e a parte que precisa ficar escrita: as duas
   etiquetas NUNCA foram separadas por cor. Nao passaram a ser quando a
   familia success andou 14 graus na v2.9, e nao deixaram de ser antes. O
   que separa "confirmada" de "presente" na tela e a PALAVRA e o ICONE —
   circle-check contra user-check, com o nome escrito ao lado.

   Esta certo assim, e continua certo. O defeito era isso funcionar por
   sorte de quem desenhou, sem estar escrito em lugar nenhum.

     ENTAO: TODA .cx-status--* CARREGA ICONE E ROTULO ESCRITO. Bolinha de
     cor sozinha nao identifica estado, em nenhuma tela, em nenhum tema.

   E a mesma doutrina que viaja com os tres polos do NPS na paleta de
   grafico, escrita la em cima: promotor e detrator separam mal para
   deuteranopia, e por isso a faixa leva rotulo e a legenda repete o nome.
   Duas familias diferentes, uma regra so — cor nunca decide sozinha.

   Sem esta linha, a primeira tela que usar .cx-status--* so com a cor
   nasce ilegivel, e vai parecer que o defeito e da tela.
   ==================================================================== */


/* ====================================================================
   v3.0 — 9. TELA ESTREITA
   Mesmo breakpoint do bloco da .cx-rail: 900px. Conferido no arquivo,
   nao de memoria — barra e andar desalinhados por 1px de breakpoint sao
   dois componentes brigando em silencio.

   Abaixo dele a barra ja deita no rodape, pelo que a v2.9 faz. O andar
   entao toma a largura inteira ACIMA dela, que e o drill-in natural do
   toque — e as duas fases perdem o sentido, porque nao ha barra lateral
   para o andar encostar.

   A altura da barra deitada esta em --cx-rail-rodape-altura, derivada la
   em cima: --cx-rail-width mais a borda de cima da barra. Por isso o andar
   para EM CIMA dela sem numero solto — e sem encostar 3px por dentro, que
   e o que acontecia quando eu supunha que a altura era a --cx-rail-width
   pelada.
   ==================================================================== */
@media (max-width: 900px) {
  .cx-nivel {
    left: 0;
    right: 0;
    width: auto;
    top: auto;
    bottom: var(--cx-rail-rodape-altura);
    max-height: 70vh;
    border-radius: var(--cx-radius-xl) var(--cx-radius-xl) 0 0;
    border-inline: 0;
    border-bottom: 0;
  }
  .cx-nivel--fase1,
  .cx-nivel--fase2 { transform: translateX(0); }

  /* A raiz e rodape: nao ha o que travar nem forcar. */
  .cx-rail.cx-rail--forcada,
  .cx-rail.cx-rail--travada { width: auto; }

  .cx-nivel-veu { bottom: var(--cx-rail-rodape-altura); }

  /* Nada desvia: o andar toma a largura inteira e nao ha conteudo ao lado
     dele para sair do caminho. */
  .cx-com-andar .cx-desvia-do-andar { padding-left: 0; }

  /* O BLOCO DO MODULO SAI. Deitada no rodape a barra nao tem topo, e o
     monograma virando um sexto botao leria como secao.

     ISTO DEIXA UM BURACO DECLARADO: no toque, a pergunta "em que modulo eu
     estou" fica sem resposta na barra. Ou o cabecalho assume, ou o
     monograma volta como primeiro item da barra deitada. Decisao do Jimmy,
     em aberto em 09/09 — e escrita aqui para nao ser descoberta na tela. */
  .cx-rail-modulo { display: none; }
}


/* ====================================================================
   LAPIDACAO DE 07/10 — a barra e o andar
   Pedido do Jimmy, com print do Observatorio e da IA. Quatro defeitos,
   todos medidos renderizando este arquivo com a marcacao real das telas
   (zip do main de 07/10), nos dois temas, antes e depois.

   1. OS ITENS DO ANDAR LONGE DEMAIS UM DO OUTRO — NO OBSERVATORIO, NAO NA IA.
      O vao de 24px da .cx-nivel-lista foi escrito para separar GRUPOS. Andar
      de escopo unico nasce sem grupo (a regra e essa, AVISO_NUCLEO_050), e
      ai os itens viram filhos diretos da lista e herdam o vao de grupo:
      44 + 24 = 68px de passo, contra 44 + 4 = 48 dentro de um grupo. A
      mesma lista media 68 numa tela e 48 na outra.
      Conserto: a lista passa a ter o vao de ITEM, e o respiro entre grupos
      mora no proprio grupo, que e quem precisa dele. Os dois casos dao 48.

   2. GRUPO E ITEM POUCO DISTINTOS. O titulo do grupo era --cx-text-muted
      (#6B6F77) e o item --cx-text-secondary (#5F636B): seis pontos de
      diferenca, que o olho nao separa. E o recuo era 12 contra 16 — os dois
      praticamente na mesma coluna.
      Conserto por TRES meios, nenhum de cor nova:
        - o titulo sobe para a tinta principal; o item continua secundario;
        - o item DENTRO de grupo recua para --cx-space-6, e o titulo fica em
          --cx-space-3: o item passa a morar visivelmente "debaixo" dele;
        - entre um grupo e o seguinte, um traco de --cx-hairline-size, o
          mesmo peso de toda linha do pacote, sem esvanecimento.
      Andar sem grupo nao muda: nao ha titulo para distinguir.

   3. A BARRA FICAVA ABERTA DEPOIS DE FECHAR O ANDAR, e so recolhia com mais
      um clique fora. O fecharAndar() do trecho de referencia (AVISO_NUCLEO_
      050, item 4) devolve o foco ao item da barra — certo para quem usa
      teclado — e o .cx-rail:focus-within da v2.9 abria a barra para
      QUALQUER foco, inclusive o posto por script depois de um clique.
      Medido: fechar pelo veu ou pelo voltar deixava a barra em 248px; com o
      conserto, 72. Teclado preservado: Tab ate o item abre a barra (248),
      Esc no andar devolve o foco e a barra abre com os nomes, que e o que
      quem navega pelo teclado precisa ver.
      O conserto NAO cabe numa regra nova aqui embaixo: nao ha como uma
      sobrescrita "desligar" um estado de foco sem tambem desligar o hover.
      Por isso o :focus-within foi trocado por :has(:focus-visible) nas
      proprias regras — dez seletores, quatro na parte da v2.9 e seis na
      parte nova. O navegador ja sabe separar foco de teclado de foco de
      clique; o reservas tinha remendado o mesmo defeito no painel.js com
      esse mesmo criterio, e agora o remendo e redundante e inofensivo.
      Conferido no Chromium. O Safari segue a mesma heuristica desde o 15.4,
      mas nao foi medido aqui.

   4. O FILETE DO ITEM ATIVO DA BARRA SAIA DUPLO, como um parentese. Eram
      duas coisas somadas: a sombra interna de 4px acompanhava o raio do
      botao e desenhava uma curva; e o champanhe do fundo vazava por baixo
      da borda transparente de 3px, fazendo uma segunda linha clara do lado
      de fora da escura.
      Conserto: o fundo para na borda (background-clip) e o filete vira
      traco reto, com o mesmo desenho do filete do item ativo do andar —
      peso de --cx-hairline-size, pontas arredondadas, afastado 6px do topo
      e da base. A barra e o andar passam a marcar "voce esta aqui" do
      mesmo jeito. A cor e a mesma de antes: grafite no claro, marfim no
      escuro (15,7:1, e e ela que cumpre a WCAG 1.4.11; o champanhe fica
      pela marca). Deitada no rodape, o traco vai para o topo, como ja ia.
   ==================================================================== */

/* --- 1. O vao da lista e de item; o respiro de grupo mora no grupo ----- */
.cx-nivel-lista { gap: var(--cx-space-1); }

/* --- 2. Grupo e item ----------------------------------------------------- */
.cx-nivel-lista > .cx-nivel-grupo + .cx-nivel-grupo {
  margin-top: var(--cx-space-3);
  padding-top: var(--cx-space-4);
  border-top: var(--cx-hairline-size) solid var(--cx-border);
}
.cx-nivel-grupo-titulo { color: var(--cx-text-primary); }
.cx-nivel-grupo > .cx-nivel-item { padding-left: var(--cx-space-6); }

/* --- 4. O filete do item ativo da barra: reto, e um so ----------------- */
.cx-rail-item { position: relative; }
.cx-rail-item.ativa,
[data-theme="dark"] .cx-rail-item.ativa {
  box-shadow: none;
  background-clip: padding-box;
}
.cx-rail-item.ativa::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: var(--cx-hairline-size);
  border-radius: var(--cx-radius-pill);
  background: var(--cx-graphite);
}
[data-theme="dark"] .cx-rail-item.ativa::before { background: var(--cx-ivory); }

/* Deitada no rodape: o traco no topo do botao, deitado tambem. */
@media (max-width: 900px) {
  .cx-rail-item.ativa,
  [data-theme="dark"] .cx-rail-item.ativa { box-shadow: none; }
  .cx-rail-item.ativa::before {
    top: 0;
    bottom: auto;
    left: 6px;
    right: 6px;
    width: auto;
    height: var(--cx-hairline-size);
  }
}
