/* ==========================================================================
   Aceite — aceite.app.br
   app.css — componentes (mobile-first)
   Requer: assets/css/tokens.css carregado ANTES deste arquivo.
   --------------------------------------------------------------------------
   LISTA COMPLETA DAS CLASSES DEFINIDAS NESTE ARQUIVO (contrato para as telas):

   Layout ....... .container .card .card__title .grid .kpis
   Nav .......... .navbar .brand
   Botoes ....... .btn .btn--primary .btn--ghost .btn--danger .btn--sm
   Badges ....... .badge .badge--rascunho .badge--enviada .badge--vista
                  .badge--aceita .badge--recusada .badge--expirada
                  .badge--cancelada .badge--realizado
   Tabela ....... .table
   Formulario ... .field .label .input .select .textarea
   Modal ........ .modal .modal__panel
   Extras ....... .muted .pill .timeline .timeline__item .toast

   Quebra de layout: container queries onde o componente depende da largura do
   proprio container (card, kpis); media query na tabela (vira cartoes no fone).
   ========================================================================== */

/* --------------------------------------------------------------------------
   HOVER EFFECTS - futuristas e confortaveis
   -------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  /* Efeito #13 Glowing gradient */
  .card:hover {
    box-shadow: 0 0 0 2px var(--brand),
                0 0 20px oklch(85% 0.12 180 / 0.3),
                0 0 40px oklch(85% 0.12 180 / 0.2);
  }

  /* Efeito #4 Animated underline */
  /* Efeito #26 Active button effect */
  .btn:active {
    transform: translateY(1px);
  }

  /* Efeito #27 Glowing primary button */
  .btn--primary:hover {
    box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3),
                0 8px 24px oklch(85% 0.12 180 / 0.3),
                0 0 10px oklch(85% 0.12 180 / 0.2);
  }

  /* Efeito #31 Outline border */
  .badge:hover,
  .pill:hover {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
  }

  /* Efeito timeline item */
  .timeline__item:hover {
    border-left-color: var(--brand);
  }

  .timeline__item:hover::before {
    box-shadow: 0 0 10px oklch(85% 0.12 180 / 0.5);
  }

  /* Efeito table row */
  .table tbody tr:hover {
    background-color: color-mix(in oklch, var(--surface-2) 75%, transparent);
  }

}

@media (prefers-reduced-motion: reduce) {
  /* Disable animations and transitions for reduced motion */
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   0. BASE / RESET
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  background-image: 
    radial-gradient(circle at 10% 20%, color-mix(in oklch, var(--text) 8%, transparent) 0%, transparent 20%),
    radial-gradient(circle at 90% 80%, color-mix(in oklch, var(--text) 6%, transparent) 0%, transparent 20%);
}

h1, h2, h3, h4 {
  margin: 0 0 var(--space-2);
  line-height: 1.2;
}

p {
  margin: 0 0 var(--space-3);
}

a {
  color: var(--brand);
  text-decoration: none;
  transition: color 0.2s ease;
}

/* `.nav__link` fica FORA desta regra de proposito. `a:not(.btn):hover` tem
   especificidade (0,2,1) e ganhava de `.nav__link:hover` e de
   `.nav__link[aria-current="page"]` (as duas 0,2,0): no hover, o rotulo virava
   `var(--brand)` enquanto o FUNDO do item ativo tambem e' `var(--brand)` —
   texto na cor do fundo, o nome sumia. O item de menu tem as regras dele
   logo abaixo, com o par fundo-da-marca + tinta-da-marca. */
a:not(.btn):not(.nav__link):hover {
  color: var(--brand);
}

/* O botao e um <a>: nao pode herdar sublinhado nem troca de cor no hover. */
.btn,
.btn:hover,
.btn:focus-visible {
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   1. LAYOUT
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: 72rem;
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.card {
  container-type: inline-size;
  background: color-mix(in oklch, var(--surface-2) 80%, transparent);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--space-4);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.card__title {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  position: relative;
  padding-bottom: var(--space-2);
}

.card__title::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 5rem;
  height: 2px;
  background: var(--brand);
  border-radius: 2px;
}

.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

@container (min-width: 34rem) {
  .card > .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.kpis {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* 1fr em todas as linhas: os KPIs ficam com a MESMA altura, nao com a altura
     do proprio conteudo. Sem isto, o 1o KPI (3 linhas: rotulo, valor e
     "cadastrados") esticava a 1a linha e os outros 3 (2 linhas) ficavam baixos. */
  grid-auto-rows: 1fr;
  container-type: inline-size;
  align-content: center;
}

/* Sem align-self aqui de proposito: o stretch (padrao do grid) e o que faz o
   card ocupar a linha inteira. Com align-self:center ele voltava a encolher
   para a altura do conteudo e sobrava um degrau entre os KPIs. */

@container (min-width: 40rem) {
  .kpis {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* --------------------------------------------------------------------------
   2. NAV
   -------------------------------------------------------------------------- */
.navbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  background: color-mix(in oklch, var(--surface) 88%, transparent);
  border-bottom: 1px solid var(--border);
}

/* O desfoque do vidro vive aqui, num pseudo-elemento, e NAO no proprio .navbar.
   Motivo: backdrop-filter cria containing block para descendentes position:fixed.
   Com ele no header, o menu hamburguer (.nav-drawer, position:fixed) ficava preso
   dentro do header de 76px em vez de cobrir a tela. Pseudo-elemento nao contem
   ninguem, entao o menu volta a se posicionar pela viewport. */
.navbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   A BARRA DAS SETE TELAS LOGADAS: FUNDO DO APP, OPACO, 1px EMBAIXO
   --------------------------------------------------------------------------
   Queixa do dono no print de 13:31Z (`lembretes.html`, 390px): "Header do
   ACPT/blur come o titulo", "titulo ILEGIVEL / texto branco em cima de texto".
   Medido aqui: rolando 72px o texto da pagina entra na faixa do cabecalho e
   aparece atraves dele. A causa era o FUNDO DA BARRA NUNCA TER VALIDO — o
   `<header>` do nav.js trazia `bg-white/5 border-b border-white/10` do Tailwind,
   e `tailwind.css` e' carregado DEPOIS de `app.css` (linha 84 contra a linha
   10 no lembretes.html), entao a utilidade (0,1,0, mais tarde) vencia o
   `background` e o `border-color` do `.navbar` (0,1,0, mais cedo). Resultado
   medido a 1280x800: fundo `rgba(255,255,255,0.05)` — a barra ficava 13 pontos
   MAIS CLARA que a pagina no tema escuro, uma faixa de cor propria.

   Agora o fundo e' `--bg`, o MESMO do `body` ("fundo igual ao do app", o alvo
   do dono), a borda e' `--border` (1px) e o `::before` com o blur fica desligado
   — com fundo opaco ele nao desenha nada e ainda custa uma camada de composicao
   num elemento `sticky`.

   O `:has(.nav__perfil)` limita a regra as SETE telas logadas: `index.html` e
   `login.html` tambem usam `.navbar`, mas sobre o hero, com as proprias
   utilidades do Tailwind (`bg-white/10`, `bg-white/5`) — e o dono nao pediu
   mexida la'. E' o mesmo recorte que a regra de altura ja' usava. */
.navbar:has(.nav__perfil) {
  background: var(--bg);
  border-bottom-color: var(--border);
}

.navbar:has(.nav__perfil)::before {
  display: none;
}

/* A MARCA NAO ENCOLHE — nem ela, nem o desenho dentro dela.
   (auditoria de telas, build 3545a41)

   A `nowrap` que a entrega do menu de perfil pos no `.container` (secao "A
   BARRA DO DESKTOP NAO QUEBRA LINHA NUNCA", mais abaixo neste arquivo) fez a
   barra parar de quebrar — mas a sobra de largura passou a ser tirada de TODOS
   os itens encolhiveis, e a marca era um deles. Medido a 1280 com o nome de
   quatro palavras: a `.brand__logo` media 87.0x44 onde a arte (540x246 =
   2.195:1) pede 96.6x44 — 9.6px de espremido, e um wordmark espremido nao e'
   "um pouco menor", e' uma marca DISTORCIDA. A 1100 eram 3.2px.

   Por que `flex: 0 0 auto` nos DOIS: o `a.brand` e' filho flex do `.container`
   (e da `.nav-drawer__top` no fone) e a `.brand__logo` e' filho flex do
   `a.brand`. Travar so' o `a` deixaria o `img` encolher por dentro; travar so'
   o `img` deixaria o `a` ceder e a imagem sair do lugar. A marca e' alvo de
   toque e item de identidade: a largura dela nao e' negociavel. Quem cede
   largura na barra e' o NOME do chip, que ja' tem `overflow: hidden` +
   `text-overflow: ellipsis` (drawer.css secao 4). */
.brand {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: var(--space-2);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   3. BOTOES
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 2.75rem;          /* alvo de toque confortavel no fone */
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in oklch, var(--surface-2) 80%, transparent);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.2s ease;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow: var(--shadow);
}

.btn:active {
  transform: translateY(1px);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3),
              0 8px 24px oklch(0% 0 0 / 0.4);
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
  position: relative;
}

.btn--primary:hover {
  background: color-mix(in oklch, var(--brand) 90%, var(--brand-ink));
  border-color: color-mix(in oklch, var(--brand) 90%, var(--brand-ink));
  box-shadow: 0 4px 14px color-mix(in oklch, var(--brand) 28%, transparent);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  color: var(--brand-ink);
}

.btn--ghost {
  background: color-mix(in oklch, var(--surface-2) 55%, transparent);
  border-color: var(--border);
  color: var(--text);
}

.btn--ghost:hover {
  background: oklch(20% 0.012 260 / 0.5);
  border-color: color-mix(in oklch, var(--border) 70%, var(--text));
}

.btn--danger {
  background: var(--danger);
  border-color: var(--danger);
  color: var(--brand-ink);
}

.btn--danger:hover {
  background: color-mix(in oklch, var(--danger) 88%, var(--text));
  border-color: color-mix(in oklch, var(--danger) 88%, var(--text));
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3),
              0 8px 24px oklch(75% 0.18 25 / 0.3),
              0 0 10px oklch(75% 0.18 25 / 0.2);
}

.btn--sm {
  min-height: 2rem;
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
  border-radius: var(--radius-sm);
}

/* --------------------------------------------------------------------------
   4. BADGES — um por status
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.125rem var(--space-2);
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  background: color-mix(in oklch, var(--surface-2) 55%, transparent);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3);
}

.badge--rascunho  { color: var(--st-rascunho); }
.badge--enviada   { color: var(--st-enviada); }
.badge--vista     { color: var(--st-vista); }
.badge--aceita    { color: var(--st-aceita); }
.badge--recusada  { color: var(--st-recusada); }
.badge--expirada  { color: var(--st-expirada); }
.badge--cancelada { color: var(--st-cancelada); }
.badge--realizado { color: var(--st-realizado); }
/* Pedido do cliente (origin=public + proposed): e' o dono de quem ACEITAR ou
   RECUSAR, entao usa o amber de "precisa de acao" (--st-expirada), distinto do
   azul do "Aguardando resposta" da proposta do profissional. */
.badge--pedido    { color: var(--st-expirada); }

/* --------------------------------------------------------------------------
   5. TABELA — responsiva: virar cartoes no fone
   -------------------------------------------------------------------------- */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-md);
  border-radius: var(--radius);
  overflow: hidden;
  background: color-mix(in oklch, var(--surface-2) 80%, transparent);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* O <caption> e' a DESCRICAO da tabela, nao um cabecalho. Tinha fundo escuro
   (--surface a 65%) + borda embaixo e virava uma faixa cheia dentro do cartao —
   no painel, com a tabela vazia, era so' uma barra preta com uma frase. Quem
   identifica coluna e' o <thead>, que ja' tem o fundo proprio logo abaixo. */
.table caption {
  text-align: left;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  padding-bottom: var(--space-2);
}

.table th,
.table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.table thead th {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: color-mix(in oklch, var(--surface) 65%, transparent);
}

.table tbody tr:last-child td {
  border-bottom: 0;
}

/* Valor de celula com duas linhas: nome em cima, sub-linha embaixo, cada uma
   numa linha so'. Sem este wrapper o <td> (que no fone e' um flex) trata o
   texto solto e o <span> como DOIS itens flex e eles ficam lado a lado — ou
   disputam a largura e quebram.

   Era um bloco do <style> de atendimentos.html. Subiu para ca' porque a agenda
   monta a mesma celula Cliente e precisa do mesmo chrome: uma implementacao so'
   para as duas telas. */
.cell {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.cell__main,
.cell__sub {
  display: block;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.cell__sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: 1.5;
  /* A linha do titulo existe SEMPRE, mesmo sem titulo: e' o que faz dois
     atendimentos com o mesmo numero de linhas terem a mesma altura. */
  min-height: 1.5em;
}

/* Botoes de acao de uma linha/cartao. flex-wrap para o botao quebrar de linha
   em vez de estourar o cartao. */
.list-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
  min-width: 0;
}

/* .btn e' display:inline-flex, que vence o [hidden] do navegador. */
.list-actions .btn[hidden] {
  display: none;
}

/* O botao nao encolhe: se nao couber, quebra de linha. */
.list-actions .btn {
  flex: 0 0 auto;
}

@media (max-width: 40rem) {
  /* No fone cada linha vira um cartao; o rotulo da coluna vem de data-label. */
  .table {
    border: none;
    box-shadow: none;
    background: transparent;
    border-radius: 0;
  }

  .table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* No celular SO A LINHA e um card. Antes esta regra aplicava borda+raio+
     fundo+sombra+blur a table, tbody, tr e td AO MESMO TEMPO, o que produzia
     quatro caixas concentricas (borda dentro de borda). */
  /* `table.table` (0,1,1) e nao `.table` (0,1,0): o Tailwind Play CDN injeta
     em runtime um <style> com `.table{display:table}` DEPOIS deste arquivo.
     No empate de especificidade o CDN vencia por ordem, e no celular a tabela
     continuava tabela com o <thead> ja escondido — tabela sem cabecalho.
     O elemento `table` no inicio resolve sem tocar em mais nada. */
  table.table,
  .table tbody {
    display: block;
    width: 100%;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* O <caption> e' display:table-caption: com a tabela em block ele deixa de
     ser filho de tabela, ganha uma caixa anonima de tabela em volta e encolhe
     para a largura do proprio texto (uma palavra por linha). Em block volta a
     ocupar a largura toda, como ja' faz o .table--atendimentos. */
  table.table > caption {
    display: block;
    width: 100%;
  }

  .table tr {
    display: block;
    width: 100%;
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: color-mix(in oklch, var(--surface-2) 80%, transparent);
    box-shadow: var(--shadow);
  }

  .table td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-2) 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  /* Separador como SOMBRA, e nao como `border-bottom`.
     Borda entra na altura da caixa: com `border-bottom` a celula que nao tem
     separador (a ultima) ficava 1px mais baixa que as outras e o cartao fechava
     com altura diferente do vizinho — com os dois no MESMO estado e com o mesmo
     numero de linhas. Medido com pares de mesmo estado a 360/390/430, diferenca
     entre os dois cartoes do par:
       border-bottom -> agenda 4px, app 3px, clientes 4px, super 7px,
                        lembretes 5px
       esta sombra   -> 0,00px em todas as telas
     A sombra nao ocupa espaco no layout, entao a celula sem separador fecha na
     mesma altura das outras. E o hover (mais abaixo) devolve esta mesma sombra,
     em vez de `none`, para o separador nao sumir sob o dedo.

     `align-items: baseline` alinha o rotulo com a primeira linha do valor. Com o
     `normal` (stretch) o rotulo esticava ate' a altura da celula e o texto ficava
     no topo — medido: o ::before de uma celula Cliente de duas linhas ia de
     19,6px para 42,3px de caixa, sem mexer na altura do cartao. */
  .table td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    box-shadow: inset 0 -1px 0 var(--border);
  }

  .table td:last-child {
    box-shadow: none;
  }

  /* A celula de acoes leva a classe .table__acoes (marcada no JS da tela).
     NAO usar td:last-child: a ultima coluna nem sempre e' a de acoes (o
     dashboard termina em "Resposta", o superadmin em "IP") e a reserva de
     altura engordava essas celulas sem motivo.

     Reserva a altura de um botao mais o padding da celula: um cartao SEM acao
     nenhuma (ja' cancelado) tem que ter a mesma grade de um com acao. Sem isto
     o cartao cancelado ficava ~12px mais baixo que o confirmado, e a diferenca
     era so' a ausencia do botao — chrome diferente entre dois cartoes.
     2.75rem e' o alvo de toque: no fone o .btn--sm sobe de 2rem para 2.75rem
     (medido 44px), entao a reserva usa o MESMO numero que o botao real. */
  .table td.table__acoes {
    min-height: calc(2.75rem + var(--space-2) * 2);
    /* `baseline` (o padrao das outras celulas) alinha o ROTULO com a baseline
       do primeiro botao. Um botao de 2.75rem tem baseline propria e o flex-line
       cresce ~12px alem do max(rotulo, botao): medido 60px contra 48px. Com
       `center` a linha e' max(rotulo, botao) + padding, e os dois cartoes
       fecham na mesma altura. */
    align-items: center;
  }

  .table td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text-muted);
  }
}

/* --------------------------------------------------------------------------
   6. FORMULARIO
   -------------------------------------------------------------------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}

.label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text);
}

.input,
.select,
.textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  background: color-mix(in oklch, var(--surface-2) 80%, transparent);
  color: var(--text);
  /* `--border-control`, e nao `--border`: o campo e' o MESMO controle nas 6
     telas (agenda, atendimentos, clientes, config, login, super) e o limite
     dele precisa de 3:1 (WCAG 1.4.11) contra o proprio fundo e contra o cartao,
     que aqui sao quase a mesma cor. O `--border` fica com os 84 consumidores
     que NAO sao controle (separador de tabela, borda de cartao, divisor).
     Medido: tools/qa-campo-borda-cdp.mjs. NAO mexa na geometria daqui (altura,
     padding, raio, fonte) nem nas cores de texto/placeholder/foco: o card e' o
     limiar do controle, e so' ele. */
  border: 1px solid var(--border-control);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--fs-md);
  line-height: 1.4;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--text-muted);
}

.input:disabled,
.select:disabled,
.textarea:disabled {
  background: color-mix(in oklch, var(--surface) 65%, transparent);
  color: var(--text-muted);
  cursor: not-allowed;
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 2px oklch(75% 0.18 25 / 0.2);
}

/* --------------------------------------------------------------------------
   CONTROLE NATIVO DE DATA/HORA (print 07:17)
   O Safari do iPhone desenha input[type=time] com o visual dele — texto
   CENTRADO na caixa e largura minima propria — e ignora o text-align herdado.
   Era dai' que vinha a "pilula gigante com o texto no meio" da agenda, que o
   Chrome de 360/390/430 NAO reproduz (la' o campo sempre saiu alinhado a
   esquerda e dentro do cartao). `appearance:none` tira o desenho nativo, e
   min-width/max-width tiram do navegador o direito de impor tamanho.
   -------------------------------------------------------------------------- */
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  text-align: left;
  box-sizing: border-box;
}

/* O texto do valor e' um pseudo-elemento do WebKit: sem isto ele continua
   centrado mesmo com appearance:none no Safari. */
input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value {
  text-align: left;
  margin: 0;
}

input[type="time"]::-webkit-datetime-edit,
input[type="date"]::-webkit-datetime-edit {
  padding: 0;
}

.textarea {
  min-height: 6rem;
  resize: vertical;
}

.select {
  appearance: none;
  padding-right: var(--space-6);
  /* O chevron vive em --chevron porque data URI nao aceita currentColor:
     a cor tem que vir de um token, senao ele fica invisivel no tema claro. */
  background: color-mix(in oklch, var(--surface-2) 80%, transparent) 
    var(--chevron) no-repeat right 0.75rem center/1em 1em;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Variante de TABELA. O `.select` cheio (2.75rem, largura total) e para
   formulario; dentro de uma celula ele estoura a coluna, empurra o layout e
   nao lembra um dropdown — que era o caso do seletor de plano no super admin. */
.select--sm {
  width: auto;
  min-width: 6rem;
  min-height: 2.25rem;
  padding: var(--space-1) var(--space-5) var(--space-1) var(--space-3);
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  /* O chevron encolhe junto, senao sobra espaco morto a direita. */
  background-position: right 0.6rem center;
  background-size: 0.85em 0.85em;
}

/* Seletor de plano (free/pro). A cor responde "qual plano e esse?" antes de o
   olho ler o texto — free fica neutro, pro fica na cor da marca. */
.select--plan {
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.select--plan[data-plan="free"] {
  color: var(--text-muted);
}

.select--plan[data-plan="pro"] {
  color: var(--brand);
  border-color: color-mix(in oklch, var(--brand) 45%, var(--border));
  background-color: color-mix(in oklch, var(--brand) 12%, transparent);
}

/* --------------------------------------------------------------------------
   7. MODAL
   -------------------------------------------------------------------------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: color-mix(in oklch, var(--surface) 88%, transparent);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.modal[hidden] {
  display: none;
}

.modal__panel {
  container-type: inline-size;
  width: 100%;
  max-height: 90dvh;
  overflow: auto;
  padding: var(--space-5);
  background: color-mix(in oklch, var(--surface-2) 92%, transparent);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

@media (min-width: 40rem) {
  .modal {
    padding: var(--space-4);
  }

  .modal__panel {
    max-width: 34rem;
    border-radius: var(--radius);
  }
}

/* --------------------------------------------------------------------------
   8. EXTRAS
   -------------------------------------------------------------------------- */
.muted {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  /* Como item de grid o padrao e esticar; a pilula deve ter a largura do texto. */
  width: fit-content;
  /* ...mas nunca mais larga que o cartao: um horario com dia escrito por
     extenso empurrava a fileira para fora. */
  max-width: 100%;
  justify-self: start;
  padding: 0.125rem var(--space-2);
  background: color-mix(in oklch, var(--surface-2) 80%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3);
}

.timeline {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--space-4);
  border-left: 2px solid var(--border);
}

.timeline__item {
  position: relative;
  padding: 0 0 var(--space-4) var(--space-4);
}

.timeline__item:last-child {
  padding-bottom: 0;
}

.timeline__item::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-4) - 5px);
  top: 0.4rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 8px var(--brand);
}

.toast {
  position: fixed;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 80;
  padding: var(--space-3) var(--space-4);
  background: color-mix(in oklch, var(--surface-2) 92%, transparent);
  color: var(--text);
  border: 1px solid var(--border);
  border-left: 4px solid var(--brand);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  font-size: var(--fs-md);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.toast[hidden] {
  display: none;
}

/* Focus styles */
*:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Add transitions for smooth effects */
.card {
  transition: transform 180ms cubic-bezier(.2,.7,.2,1), 
              box-shadow 180ms cubic-bezier(.2,.7,.2,1), 
              border-color 180ms ease-out;
}

.btn--primary,
.btn--ghost,
.btn--danger,
.btn--sm {
  transition: transform 140ms ease-out, 
              box-shadow 140ms ease-out;
}

/* Table fix */
.table tbody tr {
  position: relative;
}

/* Add :active rule outside hover media query */
.btn:active {
  transform: translateY(1px);
}

/* --------------------------------------------------------------------------
   HOVER EFFECTS - futuristas e confortaveis
   -------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  /* Efeito #13 Glowing gradient */
  .card:hover {
    box-shadow: 0 0 0 2px var(--brand),
                0 0 20px oklch(85% 0.12 180 / 0.3),
                0 0 40px oklch(85% 0.12 180 / 0.2);
  }

  /* Efeito #4 Animated underline */
  /* Efeito #27 Glowing primary button */
  .btn--primary:hover {
    box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3),
                0 8px 24px oklch(85% 0.12 180 / 0.3),
                0 0 10px oklch(85% 0.12 180 / 0.2);
  }

  /* Efeito #31 Outline border */
  .badge:hover,
  .pill:hover {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
  }

  /* Efeito timeline item */
  .timeline__item:hover {
    transform: translateX(2px);
  }

  .timeline__item:hover::before {
    box-shadow: 0 0 10px oklch(85% 0.12 180 / 0.5);
  }

  /* Efeito table row */
  .table tbody tr:hover {
    background-color: color-mix(in oklch, var(--surface-2) 75%, transparent);
  }

}

@media (prefers-reduced-motion: reduce) {
  /* Disable animations and transitions for reduced motion */
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
/* --------------------------------------------------------------------------
   Icone sol/lua no botao de tema ([data-theme-toggle]).
   Sol = clique para clarear (tema escuro). Lua = clique para escurecer.
   Tres estados: data-theme="dark" / "light" / sem atributo (segue o sistema).
   -------------------------------------------------------------------------- */
.btn[data-theme-toggle]::before {
  content: '';
  display: inline-block;
  width: 1.05em;
  height: 1.05em;
  vertical-align: -0.15em;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  transition: transform 200ms cubic-bezier(.2,.7,.2,1), opacity 200ms ease-out;
}

/* Sol por padrao e no tema escuro; lua no tema claro.

   A TINTA DA LUA NO TEMA CLARO E' `#a5b4fc` -> `#4f46e5` (indigo-300 ->
   indigo-600, a MESMA familia de cor, tres passos mais escura).
   (auditoria de telas, build 3545a41)

   O numero que muda o conserto: o `getComputedStyle` do BOTAO diz
   `color: oklch(0.25 0.02 260)` e nao ha' nada de errado com ele — a tinta do
   icone NAO herda `color`, ela vem do `fill`/`stroke` DESENHADO dentro do
   `<svg>` do data URI. Medido no pixel desenhado (print de verdade + canvas):
   `#a5b4fc` sobre a chapa do botao `#f7f8fa` dava 1.88:1 nas sete telas logadas
   (`#f5f7f9` no index/agendar = 1.86:1, `#f2f4f6` no login = 1.81:1) — bem
   abaixo dos 3:1 que a WCAG 1.4.11 pede para objeto grafico.

   `#4f46e5` MEDIDO sobre as mesmas chapas: 5.92:1 nas sete, 5.86:1 no
   index/agendar, 5.64:1 no login. Nao ha' `var()` possivel aqui: um data URI
   nao interpola custom property, entao a constante vive nestas duas regras —
   este comentario e' o token. O sol do tema escuro (`#fbbf24`) nao foi tocado:
   amber sobre chapa escura ja' passa. */
.btn[data-theme-toggle]::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='4.2'/><path d='M12 2.2v2.2M12 19.6v2.2M2.2 12h2.2M19.6 12h2.2M5.1 5.1l1.6 1.6M17.3 17.3l1.6 1.6M18.9 5.1l-1.6 1.6M6.7 17.3l-1.6 1.6'/></svg>"); }
[data-theme="dark"] .btn[data-theme-toggle]::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='4.2'/><path d='M12 2.2v2.2M12 19.6v2.2M2.2 12h2.2M19.6 12h2.2M5.1 5.1l1.6 1.6M17.3 17.3l1.6 1.6M18.9 5.1l-1.6 1.6M6.7 17.3l-1.6 1.6'/></svg>"); }
[data-theme="light"] .btn[data-theme-toggle]::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234f46e5'><path d='M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z'/></svg>"); }

/* Sem atributo: o CSS cai no @media (prefers-color-scheme) — cobre os dois. */
@media (prefers-color-scheme: dark) {
  .btn[data-theme-toggle]::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linecap='round'><circle cx='12' cy='12' r='4.2'/><path d='M12 2.2v2.2M12 19.6v2.2M2.2 12h2.2M19.6 12h2.2M5.1 5.1l1.6 1.6M17.3 17.3l1.6 1.6M18.9 5.1l-1.6 1.6M6.7 17.3l-1.6 1.6'/></svg>"); }
}
@media (prefers-color-scheme: light) {
  .btn[data-theme-toggle]::before { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234f46e5'><path d='M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z'/></svg>"); }
}

@media (hover: hover) and (pointer: fine) {
  .btn[data-theme-toggle]:hover::before {
    transform: scale(1.08) rotate(18deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn[data-theme-toggle]::before { transition: none; }
  .btn[data-theme-toggle]:hover::before { transform: none; }
}

/* Cards de plano: mesma altura e CTA alinhado no rodape do card.
   Sem isto o card com mais itens empurra o botao para baixo e os dois ficam tortos. */
.card.plan {
  display: flex;
  flex-direction: column;
}
.card.plan > ul {
  flex: 1 1 auto;
  align-content: start;
}
.card.plan > .btn {
  margin-top: auto;
}

/* Barra de destaque da linha (o acento de marca) no hover.
   NAO usar ::before/::after em <tr>: em tabela o pseudo-elemento vira uma
   celula anonima e empurra a linha inteira uma coluna.

   Em modo TABELA (>= 40rem) o `td:first-child` e' a coluna "Quando" e a barra
   fica nela, como sempre ficou.

   Em modo CARTAO (< 40rem) o `td:first-child` NAO e' uma coluna: e' a linha do
   ROTULO "Quando". A barra caia colada no rotulo e torta, porque ela cobre a
   caixa do <td> (que e' flex, com padding) e nao o texto. Medido a 360/390/430
   no cartao cancelado: era o unico elemento de chrome que diferia de um cartao
   para o outro. O acento passa a ser a borda esquerda do CARTAO inteiro.

   As duas formas sao declaradas aqui, uma vez. A tela que estende o modo cartao
   alem dos 40rem (atendimentos.html, ate' 79.99rem) repete SO' estes dois
   seletores dentro do proprio @media, porque o breakpoint e' dela. */
.table tbody tr:hover td:first-child {
  box-shadow: inset 3px 0 0 var(--brand);
}

@media (max-width: 40rem) {
  /* Devolve ao primeiro <td> a sombra de REPOUSO do modo cartao, que agora e' o
     proprio separador. Sem isto o hover apagava o separador da primeira celula
     da linha e ela dava um degrau de 1px ao passar o dedo. */
  .table tbody tr:hover td:first-child {
    box-shadow: inset 0 -1px 0 var(--border);
  }

  .table tbody tr:hover {
    box-shadow: var(--shadow), inset 3px 0 0 var(--brand);
  }
}

/* --------------------------------------------------------------------------
   Hero card glow extra
   -------------------------------------------------------------------------- */
.card.hero {
  position: relative;
  overflow: hidden;
}
.card.hero::before {
  content: '';
  position: absolute;
  top: -50%;
  right: -25%;
  width: 40rem;
  height: 40rem;
  background: radial-gradient(circle, color-mix(in oklch, var(--brand) 6%, transparent) 0%, transparent 65%);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Scroll-reveal animation — very subtle
   -------------------------------------------------------------------------- */
/* O estado inicial invisivel so vale quando ha garantia de que a animacao vai
   rodar (sem preferencia por menos movimento). Se qualquer coisa matar a
   animacao — keyframes ausente, utility sobrescrevendo o shorthand — o
   conteudo aparece; o modo de falha tem que ser visivel, nunca sumir. */
.reveal {
  animation: reveal-fade 600ms cubic-bezier(.2,.7,.2,1) forwards;
}

@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(12px);
  }
}

@keyframes reveal-fade {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Stagger children of reveal sections */
.reveal > *:nth-child(2) { animation-delay: 80ms; }
.reveal > *:nth-child(3) { animation-delay: 160ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   Navbar — ROTULOS DE TEXTO, SEM CAPSULA (card p1-nav-desktop-agrupado).
   --------------------------------------------------------------------------
   O que estava aqui era uma PILULA SEGMENTADA: `.nav__links` com raio 999px,
   borda de 1px e fundo `color-mix(--surface-2 70%)`, cada link com OUTRO raio
   999px por dentro, e o item ativo/hover vestindo o par solido `--brand-ink`
   sobre `--brand`. O dono (13:21Z) leu isso como "pill grosso mint" e "barra
   tipo extensao do Chrome", e reprovou: o alvo dele e' Linear / Vercel / Stripe
   dashboard 2026 — rotulos soltos de 13-14px, peso 500, 20px entre eles, e o
   LUGAR marcado por uma barra de 2px embaixo do rotulo, nao por preenchimento.

   ESTAS REGRAS SERVEM SO' AS SETE TELAS LOGADAS. `index.html` e `login.html`
   carregam este arquivo mas NAO tem nenhum `.nav__link` (o cabecalho deles e'
   logo + botao de tema), entao a cascata aqui nao alcanca o marketing.

   NO FONE este mesmo markup e' o painel do menu, desenhado em `drawer.css`,
   que carrega DEPOIS deste arquivo: as regras de la' sao `.nav-drawer.open
   .nav__link` (0,3,0) e `... [aria-current]` (0,4,0) e vencem estas por
   especificidade, entao o desenho aprovado do fone nao muda. O que o fone NAO
   herda — o `position` e o `::after` da barra de 2px — vive na secao
   "BARRA DO DESKTOP" logo abaixo, atras de uma media query de largura.
   -------------------------------------------------------------------------- */
.nav {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 1.25rem;                 /* 20px — o alvo do dono */
}

.nav__link {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border-radius: 2px;
  color: var(--text-muted);
  font-size: var(--fs-sm);      /* 13px no fone, 14px no desktop */
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  transition: color 160ms ease-out;
}

/* HOVER: so' o ROTULO sobe de `--text-muted` para `--text`. Nada de
   preenchimento — o preenchimento era exatamente o "pill grosso" reprovado. O
   rotulo nunca fica na cor do fundo: as duas cores sao opacas sobre o fundo do
   app, nos dois temas (medido: 7.2:1 / 4.6:1 em repouso, e bem acima disso no
   hover). Esta regra tambem era o conserto do `p1-nav-hover-nome-some` — o
   `a:not(.btn):hover` do topo deste arquivo (0,2,1) pintava o rotulo de
   `var(--brand)` por cima de um fundo `var(--brand)`, rotulo na cor do fundo. */
@media (hover: hover) and (pointer: fine) {
  .nav__link:hover {
    color: var(--text);
  }
}

/* ATIVO: o rotulo em `--text` (o MESMO do hover) e a barra de 2px, que e'
   desenhada na secao de desktop. Aqui so' o texto. */
.nav__link[aria-current="page"] {
  color: var(--text);
}

.nav__link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   BARRA DO DESKTOP — O QUE E' SO' DO DESKTOP (card p1-nav-desktop-agrupado)
   --------------------------------------------------------------------------
   A media query NAO e' opcional: no fone este mesmo markup e' o painel do menu
   e ele tem desenho aprovado pelo dono ("drawer mobile ja' decente — nao
   piora"). `position` e `::after` nao existem em NENHUMA regra do drawer, entao
   soltos fora daqui o sublinhado do item ativo apareceria tambem no menu do
   fone, em cima do icone.
   -------------------------------------------------------------------------- */
@media (min-width: 48.0625rem) {
  /* O alvo de clique fica com 28.4px de altura (rotulo de 14px + 2x0.45rem),
     acima do minimo de 24x24 do WCAG 2.2 — o padding vertical e' o que devolve
     area de toque sem trazer de volta a pastilha de 44px do print. */
  .nav__link {
    position: relative;
    padding-block: 0.45rem;
  }

  /* A BARRA DE 2px — a escolha do dono entre "texto + underline 2px" e "pill
     fina de 28-32px". Fica a BARRA: e' a unica das duas que nao devolve nenhum
     preenchimento para a barra, que era o centro da queixa. 2px de distancia
     do piso da caixa deixa ~3.2px entre o fim do rotulo e a barra. */
  .nav__link::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 2px;
    height: 2px;
    border-radius: 2px;
    background: transparent;
    transition: background-color 160ms ease-out;
  }

  .nav__link[aria-current="page"]::after {
    background: var(--brand);
  }

  /* O hover NAO acende o lugar de outro link: acende uma barra fraca, so' para
     o olho saber onde ela vai nascer. Ativo e hover continuam distinguiveis. */
  @media (hover: hover) and (pointer: fine) {
    .nav__link:hover::after {
      background: color-mix(in oklch, var(--text) 22%, transparent);
    }
  }

  /* OS TRES GRUPOS: [logo] [links] ......... [sino tema avatar Sair]
     O `.container` do nav.js distribui os filhos com `justify-content:
     space-between`, e no desktop so' dois filhos sobram (o hamburguer esta'
     `display:none`): a logo e o `.nav-drawer`, que carrega os links E as acoes
     dentro do painel. Como o painel inteiro ia para a direita, sobrava um vazio
     de ~165px depois da logo e os rotulos flutuavam no meio da barra — heranca
     da capsula, que era larga o bastante para disfarcar isso. Medido a 1280x800:
     antes da capsula sair o painel tinha 995px de 1152 e o vazio era de 16px.

     Aqui o painel passa a ocupar a largura que sobra e quem separa os dois
     grupos e' ele: links a esquerda (ao lado da logo, como nas tres referencias)
     e as acoes na direita. O `gap` de 12px continua sendo o PISO — o
     `space-between` so' distribui o que sobra, entao o ultimo rotulo NUNCA
     encosta no sino (o pedido literal do dono: "gap 12, nunca colado no ultimo
     link"). Nao muda em nada a quebra de linha: o painel ja' e' maior que a
     sobra de espaco a 1031px com os 7 links, e o `.container` quebra por
     `flex-wrap` como sempre. */
  .nav-drawer {
    flex: 1 1 auto;
  }

  .nav-drawer__panel {
    justify-content: space-between;
    gap: var(--space-3);
  }

  /* O SINO E O TEMA DEIXAM DE SER "BOLINHA". O dono nomeou o sino assim (13:21Z:
     "sino bolinha"). Viram botao de icone discreto: sem fundo e sem borda em
     repouso, realce leve no hover. O TAMANHO NAO MUDA (40px) — o painel do sino
     e o `posicionar()` de sino.js medem a partir deste rect. */
  .navbar:has(.nav__perfil) .nav__acoes .btn {
    width: 2.5rem;
    height: 2.5rem;
    min-height: 2.5rem;
    padding: 0;
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--text-muted);
  }

  .navbar:has(.nav__perfil) .nav__acoes .btn:hover {
    background: color-mix(in oklch, var(--surface-2) 70%, transparent);
    border-color: var(--border);
    color: var(--text);
  }

  /* O SAIR — GHOST, E DISCRETO SEM VIRAR "CONTORNO MANCO".
     Tensao do pedido do dono: 13:14Z ele reprovou um "Sair outline manco";
     13:21Z pediu "Sair ghost". Ghost aqui NAO e' contorno vazio de 1px sem
     peso: e' rotulo em `--text` com peso 500, sem fundo e sem borda VISIVEL em
     repouso (a borda continua ocupando 1px, transparente, para o botao nao
     pular de tamanho no hover) e preenchimento leve no hover. O solido de 44px
     com `background: --surface-2` e `weight: 600` era o "Sair chapado".
     O rotulo fica em `--text`: 18.1:1 no escuro e 14.9:1 no claro. */
  .navbar:has(.nav__perfil) .nav__perfil .btn {
    min-height: 2rem;
    padding: 0.3rem 0.6rem;
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--text);
    font-weight: 500;
  }

  .navbar:has(.nav__perfil) .nav__perfil .btn:hover {
    background: color-mix(in oklch, var(--surface-2) 70%, transparent);
    border-color: var(--border);
  }
}

/* Formato normal (pilula). O circulo so vale quando o botao esta VAZIO —
   nas paginas de marketing ele ainda tem o rotulo "Tema claro" e nao pode
   ser espremido em 2.5rem (foi o que quebrou o index). */
.nav__theme {
  border-radius: 999px;
  padding: var(--space-2) var(--space-3);
  flex: 0 0 auto;
}

.nav__theme:empty {
  width: 2.5rem;
  height: 2.5rem;
  min-height: 2.5rem;
  padding: 0;
  justify-content: center;
}

/* A logo e um JPEG de fundo PRETO. No tema claro ela viraria um retangulo preto
   sobre a barra branca. Inverter + girar o matiz troca o preto por branco e
   devolve o ciano do wordmark, entao a logo assenta nos dois temas.
   (Solucao definitiva: pedir o arquivo em PNG transparente ou SVG.) */
[data-theme="light"] .brand img {
  filter: invert(1) hue-rotate(180deg);
}

@media (prefers-color-scheme: light) {
  html:not([data-theme="dark"]) .brand img {
    filter: invert(1) hue-rotate(180deg);
  }
}

/* --------------------------------------------------------------------------
   Logo responsiva. O tamanho tem que vir de CSS (classe), NAO de style inline:
   estilo inline vence media query e foi o que deixou a barra gigante no celular.
   -------------------------------------------------------------------------- */
/* A arte e um wordmark largo (proporcao ~4.7:1) e transparente agora. O
   height antigo (8rem) somado ao padding preto embutido do JPEG deixava o
   logo minusculo dentro de uma caixa preta grande. */
.brand__logo {
  display: block;
  flex: 0 0 auto;               /* a arte nao se espreme: ver o bloco .brand */
  height: 2.75rem;
  width: auto;
  transition: transform 200ms cubic-bezier(.2,.7,.2,1);
}

@media (max-width: 480px) {
  .brand__logo {
    height: 2.25rem;
  }
}

@media (hover: hover) and (pointer: fine) {
  .brand:hover .brand__logo {
    transform: scale(1.03);
  }
}

@media (max-width: 40rem) {
  .brand__logo {
    height: 3.25rem;
    border-radius: 6px;
  }

  /* Uma linha so: a nav segmentada rola na horizontal em vez de quebrar. */
  .nav {
    flex: 1 1 100%;
    gap: var(--space-2);
    flex-wrap: nowrap;
    min-width: 0;
  }

  .nav__links {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .nav__links::-webkit-scrollbar {
    display: none;
  }

  .nav__link {
    padding: 0.35rem 0.7rem;
    font-size: 0.8125rem;
  }

  .nav__theme {
    width: 2.25rem;
    height: 2.25rem;
    min-height: 2.25rem;
  }
}

/* --------------------------------------------------------------------------
   9. DEDO NO FONE — cada regra aqui nasceu de uma medida em 360/390/430px.
   Nao subir estas regras para largura maior: alvo de 44px e regra de dedo, e o
   Safari do iOS amplia a pagina inteira quando o campo focado tem menos de 16px.
   -------------------------------------------------------------------------- */
@media (max-width: 40rem), (pointer: coarse) {
  /* Campo abaixo de 16px = zoom automatico do iOS ao focar. Em 360px o
     --fs-md cai para 15.08px e o --fs-sm para 13.04px. !important porque
     super.html fixa font-size:var(--fs-sm) inline no #search-input. */
  .input,
  .select,
  .textarea {
    font-size: 16px !important;
  }

  /* Alvo de toque: .btn--sm valia 2rem (32px) e o botao de tema 2.5rem (40px),
     os dois menores que o dedo — medidos em agenda.html, super.html,
     clientes.html, atendimentos.html e app.html. */
  .btn--sm,
  .select--sm {
    min-height: 2.75rem;
  }

  /* O hamburguer e declarado no <style> de CADA pagina, que vem DEPOIS deste
     arquivo e vence no empate de especificidade — 36x36px medidos no fone.
     button.hamburger (0,1,1) ganha de .hamburger (0,1,0) sem editar as 8
     paginas que repetem a regra (inclusive atendimentos.html). */
  button.hamburger {
    width: 2.75rem;
    height: 2.75rem;
  }
}

@media (max-width: 40rem) {
  /* Nav do fone: os 6 links da pilula mediam 24px de altura de alvo. */
  .nav__link {
    min-height: 2.75rem;
  }

  /* Cabecalho de 360px: a logo de 3.25rem mede 243.8px e, com o gap de 12px e
     o hamburguer de 44px, a linha pede 299.8px dentro dos 296px uteis do
     container — o hamburguer caia para a 2a linha e a barra sticky ia de 77
     para 133px (16% da tela de 844px cobrindo o topo do conteudo). 2.75rem
     deixa a linha em 262px e a barra em 69px ate 320px. A regra de 480px que
     declarava 2.25rem para este caso nunca valeu: o bloco de 40rem vem depois
     no arquivo e ganhava no empate de especificidade. */
  .brand__logo {
    height: 2.75rem;
  }

  /* Tabela em modo cartao: a celula de acoes carrega 2-3 botoes com
     white-space:nowrap posto inline pelo JS, entao nao encolhe. A tabela ficava
     com 330px minimos dentro de um wrapper de 294px (tela de 360px), o wrapper
     ganhava scroll horizontal e o ultimo botao ("Cancelar") saia de vista. */
  .table td {
    flex-wrap: wrap;
  }

  .table td[style*="nowrap"] {
    white-space: normal !important;
  }
}

/* Alvo de 44px no mouse tambem. O botao de tema vazio (o unico `.nav__theme`
   com `:empty`) media 40x40 no desktop (2.5rem); `.nav__theme:empty` da regra
   de 40rem (2.25rem) nunca valia, porque `:empty` pesa mais. Fora de media
   query e no fim do arquivo, esta regra vence as duas por ordem de leitura e
   vale para os dois ponteiros. Em index/login o mesmo botao tem rotulo
   ("Tema claro") e nao casa com `:empty` — logo nao encolhe. */
.nav__theme:empty {
  width: 2.75rem;
  height: 2.75rem;
  min-height: 2.75rem;
}

/* --------------------------------------------------------------------------
   O BOTAO SAIR — SO' A ALTURA E O ALINHAMENTO. (Historico; o alvo mudou.)
   --------------------------------------------------------------------------
   ATENCAO — ESTA REGRA ENTREGA SO' O FONE. O alvo de 44px com o estilo solido
   era o do ciclo anterior, quando o dono pediu "o Sair do Dashboard e' solido,
   o de Atendimentos e' um outline manco". Naquele ciclo ficou provado que o
   problema NAO era o botao, e sim o chip do avatar que nao aparecia ao lado.
   No ciclo de 13:21Z o dono REVOGOU aquele alvo e pediu "Sair GHOST" — o
   visual novo vive na secao "BARRA DO DESKTOP" acima (`.navbar:has(.nav__perfil)
   .nav__perfil .btn`, 0,4,0, que vence esta) e vale so' no desktop.
   Esta regra continua valendo no FONE, onde o alvo de 44px e' o certo.
   --------------------------------------------------------------------------
   O dono fixou a referencia (13:14Z e 13:27Z): "O header BOM e' o do
   Dashboard (app.html) ... o Sair do Dashboard e' SOLIDO, o de Atendimentos e'
   um outline manco". Pedido literal: alinhar o Sair do pe' do menu com o
   avatar e deixa-lo com 40-44px de altura — **sem trocar o estilo**.

   Eu tinha trocado o estilo (fundo --surface-2 solido + borda reforcada) antes
   desta mensagem chegar; revertido. Medido nas tres paginas servidas
   (1280x800), o Sair e' IDENTICO nas tres: fundo oklch(0.15 0.01 260 / 0.55),
   borda oklch(0.25 0.01 260), 52.4x32px. O que fazia o de Atendimentos "ler
   como contorno solto" nao era o botao — era o CHIP DO AVATAR QUE NAO
   APARECIA ao lado dele (ver o conserto no assets/js/nav.js).

   Entao a unica regra que sobra e' a altura: 32 -> 44px (o alvo dos icones e a
   linha do logo). `.nav__perfil .btn` (0,2,0) ganha de `.btn--sm` (0,1,0), e
   como o botao e' O MESMO elemento na barra do desktop e no pe' do menu (o
   `position:static` do §6 do drawer.css faz os dois lugares serem o mesmo
   markup), uma regra so' vale nos dois. No fone nao muda nada: a regra de
   48rem de `.btn--sm` ja' forcava os mesmos 2.75rem.
   `padding-block` junto porque `.btn--sm` usa 4px: sem ele o rotulo nao fica
   centrado no meio dos 44px. Largura intocada (12px de padding horizontal do
   `.btn--sm`): no pe' do menu a caixa do perfil tem 273px uteis e
   chip 214.2 + 8 + Sair 50.8 fecham exatamente 273 — alargar o Sair cortaria
   o nome ("Diego Mari..."). */
.nav__perfil .btn {
  min-height: 2.75rem;
  padding-block: var(--space-2);
}

/* --------------------------------------------------------------------------
   A ALTURA DA BARRA: 56px — o alvo do dono (13:21Z: "Header 56px")
   --------------------------------------------------------------------------
   A barra media 69px a 1280x800 (medido) e 61px depois do conserto anterior:
   44px de logo + 2x8px de padding do `.navbar`. O que manda na altura e' o
   FILHO MAIS ALTO — e hoje e' a logo (2.75rem = 44px), nao os controles: o
   sino e o tema medem 40x40, o chip 28px e o Sair 32px.

     44 (logo) + 2 x 5.5 (padding) + 1 (border-bottom) = 56px  ← medido

   5.5px e' o valor que FECHA a conta; nao ha' `--space-*` de 5.5. O conteudo
   continua centrado por `align-items:center` (o `.container` do nav.js).

   O `:has(.nav__perfil)` limita a regra as SETE telas do app. index.html e
   login.html tambem usam `.navbar`, mas com outro conteudo (nao tem Sair nem
   chip) e o dono nao pediu mexida la' — ficam com a barra que ja' tinham.
   Especificidade (0,2,0) ganha do `.navbar` (0,1,0) sem precisar de
   `!important`.

   SO' DESKTOP: no fone a barra fica nos 69px que ela ja' tinha (o desenho do
   fone foi aprovado pelo dono — "drawer mobile ja' decente, nao piora") e o
   conserto de la' e' o FUNDO OPACO, que vale nas duas larguras.

   A FOLGA MELHOROU MUITO nesta entrega. Antes, a linha vivia no limite (o
   conteudo terminava a ~1.6px da borda a 1280x800) porque a capsula custava
   ~46px: 3px de padding da capsula + 13.6px de padding por lado em cada link,
   mais 2px entre eles. Com os rotulos soltos e o gap de 20px, o grupo dos 7
   links ficou ~90px mais estreito. Medido com os 7 links (role super) a
   1280x800: a linha fecha com folga, e um nome de tres palavras
   ("Diego Marin Rodrigues Silva") tambem deixa a barra em UMA linha. */
@media (min-width: 48.0625rem) {
  .navbar:has(.nav__perfil) {
    padding-block: 5.5px;
  }
}

/* ==========================================================================
   A BARRA DO DESKTOP NAO QUEBRA LINHA NUNCA (card p1-nav-perfil-menu-nao-config,
   defeito (b): "o nav quebrou linha, o Super caiu para a 2a")
   ==========================================================================
   O DEFEITO, medido: com um nome de 4 palavras no chip ("Diego Marin Rodrigues
   Silva") a barra passa de 56px para 108px a 1280x800 — a logo fica sozinha na
   1a linha e o PAINEL INTEIRO (links + sino + chip + Sair) desce para a 2a. Nao
   e' o nome que estoura: e' o `<div class="container">` do nav.js que tinha
   `flex-wrap: wrap` INLINE, e o `style=` vence qualquer folha de estilo.

   Por que o `wrap` morde: o container e' um flex de 3 filhos (logo, hamburguer
   escondido, `.nav-drawer`), e o `.nav-drawer` e' `flex: 1 1 auto` — ou seja,
   `flex-basis: auto` = o tamanho MAX-CONTENT do painel. A quebra de linha do
   flexbox decide pela caixa hipotetica (max-content), e nao pelo min-content:
   quando o chip carrega um nome longo, o max-content do painel passa da largura
   que sobra na linha e o painel inteiro vai para a 2a. `min-width: 0` em tudo
   quanto e' elo (drawer, painel, meta) NAO resolve — medido, a barra continua
   108px, porque quem decide a quebra nao le' o min-content (o probe esta' em
   `tools/qa-probe-minwidth.js`).

   A BARRA E' UMA LINHA SO' POR DESENHO no desktop (a altura de 56px depende
   disso), entao quem cede e' o NOME do chip: ele ja' tem `overflow: hidden` +
   `text-overflow: ellipsis` em drawer.css secao 4, e passa a ser cortado com
   reticencias em vez de empurrar a barra. `nowrap` no desktop, `wrap` no fone
   (o de sempre — no fone o drawer e' `position: fixed`, nao disputa a linha, e
   a regra existe so' para nao mudar nada la').

   O `:has(.nav__perfil)` mantem `index.html`/`login.html` de fora, como as
   outras regras desta barra. */
.navbar:has(.nav__perfil) > .container {
  flex-wrap: wrap;
}

/* O SEGUNDO ELO, e o que quase passou batido: com o container em `nowrap` a
   sobra de largura passa a ser tirada de DENTRO do painel, e o `.nav__meta`
   (grupo das acoes + grupo do perfil) nasce com `flex-wrap: wrap` na secao 3 do
   drawer.css. A quebra de linha do flexbox acontece ANTES do encolhimento dos
   filhos: o meta quebra assim que perde 1px, em vez de deixar o chip encolher
   com reticencias. Medido a 1280 com o nome de 4 palavras: faltavam 23px e o
   meta virou 2 linhas — barra 96px, pior que os 108px de antes. Com `nowrap` no
   meta, quem cede e' o chip, que ja' tem `overflow:hidden` + ellipsis. */
@media (min-width: 48.0625rem) {
  .navbar:has(.nav__perfil) > .container {
    flex-wrap: nowrap;
  }

  .navbar:has(.nav__perfil) .nav__meta {
    flex-wrap: nowrap;
  }

  /* O TERCEIRO ELO — QUEM CEDE A LARGURA E' O CHIP, E SO' ELE.
     A marca ficou rigida (bloco `.brand`, secao 2) e o `nowrap` acima tira a
     quebra de linha; sem dizer QUEM cede, o que sobra e' o container TRANSBORDAR
     — medido com um nome de sete palavras ("Diego Marin Rodrigues Silva de
     Oliveira Bueno") a 1280: `scrollWidth` 1267 num container de 1152, e o Sair
     terminava em x=1331, fora de uma tela de 1280.

     A regra e' a mesma da entrega do card, so' que declarada em vez de
     esperada: tudo que NAO e' o chip perde o direito de encolher, e o chip —
     que ja' tem `overflow: hidden` + `text-overflow: ellipsis` no
     `#user-badge` (drawer.css secao 4) — fica o unico elo elastico da barra.
     Sem isso o flexbox reparte a sobra entre os encolhiveis proporcionais, e
     quem "cede" acaba sendo quem tem a menor base: a marca. */
  .navbar:has(.nav__perfil) .nav__links,
  .navbar:has(.nav__perfil) .nav__acoes,
  .navbar:has(.nav__perfil) .nav__perfil > .btn {
    flex-shrink: 0;
  }

  /* A CORRENTE ATE' O CHIP PRECISA PODER ENCOLHER: o `min-width` automatico de
     um item de flex e' o tamanho do conteudo, entao sem zerar isso em CADA elo
     (drawer, painel, rodape, bloco de perfil) o chip nunca chega a ser cortado —
     o corte para no ancestral e vira transbordo. */
  .navbar:has(.nav__perfil) .nav-drawer,
  .navbar:has(.nav__perfil) .nav-drawer__panel,
  .navbar:has(.nav__perfil) .nav__meta,
  .navbar:has(.nav__perfil) .nav__perfil {
    min-width: 0;
  }
}

/* ==========================================================================
   10. MENU DO FONE E BARRA DE CIMA — medido, nao chutado (prints 07:22, 07:25)
   Tudo aqui foi escrito a partir de MEDIDA na 105 viva: o painel do menu media
   293px numa tela de 390 (sobrava uma faixa de 98px da pagina do lado, e a
   borda do painel cortava o logotipo do cabecalho no meio — o humano lia "ACE");
   o rodape do menu empilhava nome + tema + Sair no centro, como tres botoes
   orfaos; e no desktop o chip do nome ficava a 8px do botao de tema.
   As regras usam `.nav-drawer.open` (0,3,0) de proposito: o <style> inline de
   cada pagina vem DEPOIS deste arquivo e, no empate, venceria.
   ========================================================================== */

/* O chip do nome, o menu do fone e o painel sairam daqui: agora vivem em
   assets/css/drawer.css, carregado depois deste arquivo pelas 9 paginas que
   tem menu. Motivo: estas regras eram repetidas INLINE em cada HTML e o
   conserto de uma tela voltava nas outras. A nav de desktop (a pilula
   `.nav__links`, `.nav__link`, `.nav__theme`) continua neste arquivo. */

/* Entre o fone e o desktop largo (769 a 1024px) sete links nao cabem numa linha
   so' com o brand — entao a lista QUEBRA linha (o humano pediu "quebra linha ou
   compacta") em vez de estourar o cabecalho ou esconder o ultimo item.

   Medido na 105, antes: a 800px o pill tinha 570px de caixa para 613px de
   conteudo — o fim do setimo link ficava escondido; a 900px sobravam 11px.

   O QUE SAIU DESTE BLOCO (card p1-nav-desktop-agrupado): (a) a regra de `.nav`,
   uma classe que NAO EXISTE MAIS no markup — o header unico do nav.js monta
   `.nav-drawer > .nav-drawer__panel > .nav__links | .nav__meta`, entao aquelas
   quatro linhas nunca mais casaram com nada; (b) o padding de 0.6rem por lado
   no `.nav__link`, que existia para encolher o miolo do pill e agora atrapalha
   — e' exatamente o preenchimento que a estetica nova tirou do rotulo. O
   `border-radius: var(--radius)` tambem saiu: nao ha' mais capsula para
   desarredondar.

   MEDIDO NESTA FAIXA (7 links, tema escuro, 800px de altura):
     900px  -> barra 173px (a lista quebra em 2 linhas e o painel cai abaixo)
     1024px -> barra 117px (2 linhas)
   Nada cortado: o grupo da direita termina dentro da tela nos dois. */
@media (min-width: 48.0625rem) and (max-width: 64rem) {
  .nav__links {
    flex-wrap: wrap;
    justify-content: center;
    max-width: 100%;
    row-gap: var(--space-2);
  }
}

/* O SETIMO LINK (o "Super", que so' existe para `role === 'super'`) NA FAIXA
   DO NOTEBOOK. O dono anterior gastou um commit para ele caber em UMA linha a
   partir de 1031px; esta entrega NAO pode perder isso.

   O que mudou: antes o miolo do pill encolhia (0.85rem -> 0.6rem por lado). Com
   os rotulos soltos nao ha' padding para encolher, entao quem cede e' o GAP:
   20px -> 12px. Conta medida com os 7 rotulos a 14px/500, o chip "Diego Marin"
   (120.8px) e a logo de 44px:

     gap 20px -> grupo dos links 597px, painel 895px  (nao cabe a 1031)
     gap 12px -> grupo dos links 549px, painel 847px  (cabe a partir de 1031)

   Acima de 1280px a linha cabe inteira com os 20px e esta regra nao alcanca.
   Em EXATAMENTE 1024px a barra ainda vai a 2 linhas — igual ao que ja' estava
   publicado antes desta entrega. */
@media (min-width: 64rem) and (max-width: 79.9375rem) {
  .nav__links:has(.nav__link:nth-child(7)) {
    gap: var(--space-3);
  }
}

@media (max-width: 48rem) {
  /* O botao do menu e' o unico caminho para a navegacao no fone: 36x36 medidos
     a 768px (a regra antiga so' valia abaixo de 640px OU com ponteiro grosso).
     Aqui vale pela largura, que e' o que decide se ele aparece. Fica neste
     arquivo de proposito: `button.hamburger` (0,1,1) tem que vencer o
     `.hamburger` (0,1,0) de drawer.css, que agora carrega depois deste. */
  button.hamburger {
    width: 2.75rem;
    height: 2.75rem;
  }
}
