/* ============================================================================
   CHAZON — a pele.

   Noite profunda e uma bruma azul que respira. A cor quente (--brasa) é a
   ÚNICA da paleta e está reservada ao que custa: renúncia, conflito com
   âncora, área largada, conselho contrariado. Se ela aparecesse num botão
   comum perderia o peso exatamente onde ele importa.

   Duas regras de tipografia que valem a leitura:

   1. A SERIFA É RESERVADA AO QUE É DITO. As declarações dela e a voz do
      Chazon são em serifa; tudo que a interface fala — rótulo, contagem,
      botão — é sem serifa. Dá para saber de quem é a frase antes de ler.

   2. A BRUMA É A ÚNICA COISA QUE SE MOVE. Cada tela tem sua posição e sua
      temperatura de fumaça, e trocar de menu desloca em vez de cortar. Como
      nada mais anima, a transição sozinha já dá sensação de lugar.
   ========================================================================== */

:root {
  --noite:      #060B15;
  --noite-2:    #0C1524;
  --vidro:      rgba(255, 255, 255, .055);
  --vidro-alto: rgba(255, 255, 255, .085);
  --borda:      rgba(255, 255, 255, .10);
  --borda-viva: rgba(168, 199, 222, .30);
  --texto:      #EFEBE3;
  --calmo:      #98A5B8;   /* neutro puxado para o azul da bruma */
  --fraco:      #7A8699;   /* clareado 26/08: #66738A dava 3,5:1 no vidro */
  --luz:        #A8C7DE;
  --luz-forte:  #CDE4F5;
  --brasa:      #D98E6A;

  --raio:    18px;
  --raio-g:  26px;
  --sombra:  0 10px 34px rgba(0, 0, 0, .38);

  /* AS SUPERFÍCIES DE TOQUE, tokenizadas (26/08).
     O tema Prático provou que "vidro claro sobre noite" estava escrito na
     unha em vinte lugares: botão branco translúcido some no papel branco, e
     campo preto-24% vira uma mancha suja. Tokenizar é o que faz um tema novo
     custar dez linhas em vez de uma caçada — e toda tela futura nascer certa
     nos dois. Os valores escuros abaixo são EXATAMENTE os de antes. */
  --toque:       rgba(255, 255, 255, .07);   /* fundo de botão */
  --toque-alto:  rgba(255, 255, 255, .12);   /* :hover */
  --toque-vivo:  rgba(255, 255, 255, .16);   /* :active */
  --toque-fraco: rgba(255, 255, 255, .06);   /* o hover do sutil */
  --campo:       rgba(0, 0, 0, .24);         /* input e textarea */
  --separador:   rgba(255, 255, 255, .06);   /* a linha entre itens */
  --afundado:    rgba(0, 0, 0, .16);         /* cartão dentro de cartão */
  --fosso:       rgba(0, 0, 0, .30);         /* o trilho do seletor de chaves */
  --fade:        6, 11, 21;                  /* o fundo dos degradês (RGB) */
  --tracejado:   rgba(255, 255, 255, .32);   /* a tinta do que vem do aparelho */
  --capsula:     rgba(12, 20, 34, .82);      /* a caixa de escrever do chat */
  --capsula-viva: rgba(14, 24, 40, .92);
  /* O botão principal é o único par fundo+texto do app — e o texto dele
     estava pintado na unha. No claro o par inverte (tinta escura, letra
     branca): claro sobre claro dava 3:1 no botão que mais importa. */
  --principal-fundo: var(--luz);
  --principal-texto: #0B1120;

  --display: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
  --ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  /**
   * A altura da barra de baixo, num lugar só.
   *
   * Ela é alta porque a esfera é grande e sobe acima da barra. Tudo que precisa
   * sentar em cima dela — o campo da conversa embutida, o aviso — mede daqui,
   * senão o dia em que a esfera crescer um pixel a conta se perde em três
   * arquivos diferentes.
   */
  --barra: calc(116px + env(safe-area-inset-bottom));
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; min-height: 100%; }

/**
 * A PÁGINA NÃO BORRACHA (27/08, do teste no aparelho).
 *
 * O iOS deixa a página passar do fim e voltar — e num app isso não é charme,
 * é defeito: a landing, que é centralizada na altura da janela, balançava
 * para cima e para baixo enquanto o dedo puxava; e a barra de baixo, que é
 * `position: fixed`, subia junto ao chegar no fim do rolo (fixo no iOS é
 * preso ao viewport de LAYOUT, e o visual desliza por cima dele no
 * elástico). Os dois sintomas, uma causa.
 *
 * `overscroll-behavior-y: none` corta o elástico na raiz. Precisa estar no
 * `html` também: só no `body` o gesto sobe a cadeia e o documento estica
 * assim mesmo.
 */
html { overscroll-behavior-y: none; }

body {
  font-family: var(--ui);
  color: var(--texto);
  background: var(--noite);
  -webkit-font-smoothing: antialiased;
  line-height: 1.55;
  overflow-x: hidden;
  overscroll-behavior-y: none;
}

/* ============================================================== a bruma ===

   A bruma era três elipses sólidas com `filter: blur(52px)`. Blur desse
   tamanho FALHA no WebView do iOS quando a memória aperta: o filtro é
   descartado e a elipse aparece crua, com borda dura — "retângulos marcando"
   o fundo, que foi exatamente o defeito relatado.

   Gradiente radial não tem esse modo de falha: o fade faz parte da própria
   imagem de fundo. Não existe estado em que ele renderize sem fade. A cor de
   cada tela vem por variável (`--cor-bruma`), registrada com @property para a
   transição de cor continuar suave onde houver suporte — e onde não houver, a
   cor troca sem animar, que é degradação aceitável. */

@property --cor-bruma {
  syntax: '<color>';
  inherits: false;
  initial-value: transparent;
}

#bruma {
  position: fixed; inset: -25%; z-index: 0; pointer-events: none;
}
#bruma i {
  position: absolute; display: block; opacity: .6;
  /* O miolo segura a cor até ~1/4 do raio e aí desfaz — é o perfil que a elipse
     borrada tinha: núcleo denso, borda em pluma. Sem o degrau do meio o
     gradiente linear deixava a bruma anêmica. */
  background: radial-gradient(closest-side, var(--cor-bruma) 0%, var(--cor-bruma) 24%, transparent 100%);
  transition: transform 1.1s cubic-bezier(.32,.72,0,1), opacity 1.1s ease, --cor-bruma 1.1s ease;
}
#bruma .b1 { width: 68%; height: 40%; left: -6%;  top: 0;    --cor-bruma: #1E4F7E; }
#bruma .b2 { width: 55%; height: 34%; right: -8%; top: 26%;  --cor-bruma: #2B6C9C; }
#bruma .b3 { width: 72%; height: 38%; left: 8%;   bottom: 2%; --cor-bruma: #14304F; }

body[data-em="ia"]         #bruma .b1 { transform: translate(6%, 14%) scale(1.18); --cor-bruma: #2F72A6; }
body[data-em="ia"]         #bruma .b2 { transform: translate(-10%, 6%) scale(1.1); opacity: .72; }
body[data-em="definicoes"] #bruma .b1 { transform: translate(-4%, 30%) scale(1.05); --cor-bruma: #1B4368; }
body[data-em="definicoes"] #bruma .b3 { transform: translate(0, -12%) scale(1.14); }
body[data-em="conversa"]   #bruma .b1 { transform: translate(4%, 8%) scale(1.22); --cor-bruma: #34799F; }
body[data-em="conversa"]   #bruma .b3 { opacity: .3; }
body[data-em="agenda"]     #bruma .b2 { transform: translate(-24%, -14%) scale(1.25); --cor-bruma: #24597F; }
body[data-em="agenda"]     #bruma .b3 { transform: translate(-6%, 8%) scale(.92); opacity: .4; }
body[data-em="saber"]      #bruma .b1 { transform: translate(14%, -6%) scale(.95); }
body[data-em="saber"]      #bruma .b3 { transform: translate(-10%, -18%) scale(1.2); --cor-bruma: #3A4E6B; }
body[data-em="ideias"]     #bruma .b2 { transform: translate(4%, 22%) scale(1.3); --cor-bruma: #43507C; }
body[data-em="ideias"]     #bruma .b3 { transform: translate(12%, 4%) scale(1.05); --cor-bruma: #2A3C63; }
/* A Semana: o rito. A bruma desce e assenta — fim de semana, não meio dele. */
body[data-em="semana"]     #bruma .b1 { transform: translate(-8%, 22%) scale(1.12); --cor-bruma: #1D5A73; }
body[data-em="semana"]     #bruma .b3 { transform: translate(6%, -8%) scale(1.18); --cor-bruma: #274B6E; }

@media (prefers-reduced-motion: reduce) {
  #bruma i { transition: none; }
}

/* ============================================================ estrutura === */

/**
 * `100dvh`, NUNCA `100vh`.
 *
 * No iOS, `vh` mede a tela COM a barra do navegador retraída — uma altura que
 * quase nunca existe. Um `min-height: 100vh` mais o padding do rodapé faz toda
 * tela do app nascer mais alta que a janela, e a página ganha uma rolagem
 * fantasma: dá para arrastar para baixo e encontrar vazio, em telas que nem
 * conteúdo suficiente têm. `dvh` mede a altura de verdade, agora.
 */
#app {
  position: relative; z-index: 1;
  max-width: 720px; margin: 0 auto;
  /* O TOPO É RESERVADO. Sem isto, a primeira coisa da tela nascia debaixo do
     relógio e da ilha dinâmica — a chave "Conversar / O que ele sabe" ficava
     ilegível, com o horário escrito por cima dela. */
  padding: env(safe-area-inset-top) 20px calc(112px + env(safe-area-inset-bottom));
  min-height: 100dvh;
}

.topo { padding: 40px 0 22px; }
.topo h1 {
  font-family: var(--display); font-size: 32px; font-weight: 400;
  letter-spacing: -.018em; margin: 0; text-wrap: balance;
}
.topo p { margin: 8px 0 0; color: var(--calmo); font-size: 14.5px; max-width: 52ch; }
.topo .saud { color: var(--fraco); font-size: 13px; margin: 0 0 6px; }

/* ============================================================== cartões === */

/**
 * Vidro SEM backdrop-filter, de propósito.
 *
 * O blur de fundo aqui recortava a bruma dentro dos limites do cartão — o
 * `saturate(130%)` deixava o azul mais vivo dentro do que fora, e a diferença
 * marcava um retângulo. Sobre um fundo que já é gradiente suave, o backdrop
 * não acrescenta nada: o vidro é a translucidez do próprio fundo + a borda.
 */
.cartao {
  background: var(--vidro); border: 1px solid var(--borda);
  border-radius: var(--raio-g); padding: 20px; margin-bottom: 12px;
}
.cartao h2 { font-family: var(--display); font-size: 19px; font-weight: 400; margin: 0 0 4px; }
.cartao h3 {
  font-size: 11px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  color: var(--fraco); margin: 0 0 12px;
}
.cartao > p:last-child { margin-bottom: 0; }

.cartao-luz   { border-color: var(--borda-viva); background: linear-gradient(180deg, rgba(168,199,222,.10), var(--vidro)); }
.cartao-brasa { border-color: rgba(217,142,106,.34); background: linear-gradient(180deg, rgba(217,142,106,.09), var(--vidro)); }

/* ========================================================== tipografia === */

.declaracao {
  font-family: var(--display); font-size: 21px; line-height: 1.42;
  margin: 0; white-space: pre-wrap;
}
.vazio { color: var(--fraco); font-style: italic; margin: 0; }
.calmo { color: var(--calmo); }
.fraco { color: var(--fraco); font-size: 13px; }

/**
 * Link dentro de texto corrido. O azul e o sublinhado do navegador atravessam a
 * pele inteira — e o único lugar onde isso aparece é o rodapé da landing, que é
 * a primeira coisa que alguém vê.
 */
p a, .fraco a, li a[href^="/"] {
  color: var(--luz); text-decoration: underline;
  text-decoration-color: rgba(168,199,222,.35); text-underline-offset: 3px;
}
p a:hover, .fraco a:hover { text-decoration-color: var(--luz); }
.brasa { color: var(--brasa); }
.secao { font-size: 12.5px; color: var(--fraco); margin: 26px 0 10px; }

/* ============================================================ controles === */

button, .botao {
  font: inherit; font-size: 15px; border-radius: 12px;
  border: 1px solid var(--borda); background: var(--toque);
  color: var(--texto); padding: 11px 18px; cursor: pointer; min-height: 44px;
  transition: background .15s ease, border-color .15s ease;
}
button:hover { background: var(--toque-alto); }
button:active { background: var(--toque-vivo); }
button:focus-visible, a:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible, details:focus-visible {
  outline: 2px solid var(--luz); outline-offset: 2px;
}

.principal { background: var(--principal-fundo); border-color: var(--principal-fundo); color: var(--principal-texto); font-weight: 600; }
.principal:hover { background: var(--luz-forte); border-color: var(--luz-forte); }

.sutil { background: transparent; border-color: transparent; color: var(--calmo); padding: 8px 12px; }
.sutil:hover { background: var(--toque-fraco); color: var(--texto); }

/* Discreto é a APARÊNCIA, não o alvo de toque: com fundo transparente,
   manter os 44px de altura não muda nada do que se vê. */
.corrigir {
  font-size: 12.5px; letter-spacing: .02em; color: var(--fraco);
  padding: 6px 10px; min-height: 44px;
}
.corrigir:hover { color: var(--calmo); }

a.botao { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }

input[type="text"], input[type="email"], input[type="password"],
input[type="time"], input[type="number"], textarea, select {
  font: inherit; font-size: 16px;  /* < 16px faz o iOS dar zoom no foco */
  width: 100%; color: var(--texto);
  background: var(--campo); border: 1px solid var(--borda);
  border-radius: 12px; padding: 12px 14px; resize: vertical;
}
textarea { min-height: 96px; line-height: 1.5; }
input::placeholder, textarea::placeholder { color: var(--fraco); }

label { display: block; font-size: 14px; color: var(--calmo); margin: 0 0 7px; }
.campo { margin-bottom: 18px; }
.campo:last-child { margin-bottom: 0; }

.linha { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.linha-fim { justify-content: flex-end; }
.entre { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }

/* ============================================================== listas === */

.lista { list-style: none; margin: 0; padding: 0; }
.item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 0; border-bottom: 1px solid var(--separador);
}
.item:last-child { border-bottom: none; }
.item-corpo { flex: 1; min-width: 0; }
.item-titulo { margin: 0; font-size: 15px; }
.item-sub { margin: 3px 0 0; font-size: 12.5px; color: var(--fraco); }
.feito .item-titulo { text-decoration: line-through; color: var(--fraco); }

/**
 * O alvo é 44px; o desenho é 24px.
 *
 * Este é o gesto mais repetido do app — marcar uma ação feita — e ele tinha
 * `min-height: 0` num círculo de 24px, bem abaixo do que o dedo acerta. O
 * `::before` estica a área tocável sem tocar no visual, que é a mesma receita
 * já usada em `.corrigir`.
 */
.marca::before {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}
.marca {
  position: relative;
  width: 24px; height: 24px; flex: 0 0 24px; margin-top: 2px;
  border-radius: 8px; border: 1.5px solid var(--fraco);
  background: transparent; padding: 0; min-height: 0; cursor: pointer;
}
.marca[aria-pressed="true"] { background: var(--luz); border-color: var(--luz); }

.etiqueta {
  display: inline-block; font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; font-weight: 700; padding: 4px 10px;
  border-radius: 999px; border: 1px solid var(--borda); color: var(--calmo);
}
.etiqueta-luz   { border-color: var(--borda-viva); color: var(--luz); }
.etiqueta-brasa { border-color: rgba(217,142,106,.42); color: var(--brasa); }

/* ============================================================== âncora ===
   Uma coisa ancorada não se discute: a barra sólida e o cadeado dizem isso
   antes de qualquer texto. */

.ancorado { border-left: 2px solid var(--luz); padding-left: 14px; }
.cadeado {
  display: inline-flex; align-items: center; gap: 5px; color: var(--luz);
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
}
.cadeado svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2; }
.motivo-ancora { margin: 12px 0 0; font-size: 12.5px; color: var(--fraco); }

/* ============================================================== chaves === */

.chave {
  display: flex; gap: 4px; padding: 4px; margin-bottom: 20px;
  background: var(--fosso); border: 1px solid var(--borda); border-radius: 14px;
}
/* Os seletores pegam `a` também: as chaves da esfera são LINKS (a navegação é
   por hash), e mirar só em `button` deixava as duas iguais — nunca dava para
   saber em qual das duas você está. */
.chave button, .chave a {
  flex: 1; font-size: 13.5px; font-weight: 600; padding: 9px 6px;
  border: 0; border-radius: 11px; background: none; color: var(--fraco);
  min-height: 42px; transition: background .18s, color .18s;
  display: flex; align-items: center; justify-content: center;
  text-decoration: none; text-align: center;
}
/* `aria-current` cobre os seletores que são NAVEGAÇÃO (a Agenda) — a11y
   verdadeira em vez de tablist de mentira, e o realce continua o mesmo. */
.chave [aria-selected="true"],
.chave [aria-current="page"] { background: var(--vidro-alto); color: var(--texto); }

/* ========================================================== navegação ===
   A conversa é o mecanismo do produto, então ela não é uma aba entre cinco:
   é o centro, levantada acima da barra, e a única coisa que respira. */

/* Só o gradiente, sem backdrop-filter: o blur tem um retângulo de limites, e
   a borda de cima dele aparecia como um degrau sobre a bruma. O fade do
   gradiente é o que faz o conteúdo mergulhar na barra em vez de bater nela. */
.nav {
  position: fixed; z-index: 20; left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-around;
  padding: 26px 12px calc(18px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(var(--fade), 0), rgba(var(--fade), .94) 52%);
}
.nav a {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-decoration: none; color: var(--fraco); font-size: 10px;
  letter-spacing: .03em; padding: 6px 4px; min-width: 56px; min-height: 48px;
  transition: color .2s;
}
.nav a[aria-current="page"] { color: var(--luz); }

/* Menu que ainda não abriu: presente e apagado. Ver dá vontade; tocar explica
   como abrir. A transição é o momento de "acordar" — ele acende no lugar. */
.nav a.adormecido { opacity: .32; transition: opacity .6s ease; }
.nav svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.nav .esfera-link { min-width: 74px; margin-bottom: 2px; gap: 3px; }
.esfera {
  width: 56px; height: 56px; border-radius: 50%; position: relative; overflow: hidden;
  background: radial-gradient(circle at 34% 28%, #D6ECFB 0%, #7FB4DC 34%, #2E6B9E 62%, #143A5E 100%);
  box-shadow: 0 0 26px rgba(126,176,212,.42), 0 6px 18px rgba(0,0,0,.45), inset 0 -7px 16px rgba(0,0,0,.34);
  animation: respira 5.2s ease-in-out infinite;
}
.esfera::before, .esfera::after { content: ''; position: absolute; border-radius: 50%; filter: blur(9px); }
.esfera::before { width: 76%; height: 76%; left: -14%; top: 8%; background: rgba(214,236,251,.62); animation: gira 9s linear infinite; }
.esfera::after  { width: 62%; height: 62%; right: -10%; bottom: -6%; background: rgba(20,58,94,.85); animation: gira 13s linear infinite reverse; }
@keyframes respira { 0%,100% { transform: scale(1); } 50% { transform: scale(1.045); } }
@keyframes gira { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .esfera, .esfera::before, .esfera::after { animation: none; } }

.nav .esfera-link[aria-current="page"] .esfera {
  box-shadow: 0 0 38px rgba(126,176,212,.68), 0 6px 18px rgba(0,0,0,.45), inset 0 -7px 16px rgba(0,0,0,.34);
}

/* ============================================================= landing === */

/* A landing CABE NUMA TELA. `100dvh` e não `100vh`: no iOS o `vh` conta a
   barra do navegador como se ela não existisse, e a página nascia mais alta
   que a tela — daí a rolagem que não deveria existir. O espaço entre a marca
   e o botão é o que sobra, não uma medida fixa. */
.landing {
  /* `#app` reserva 112px no rodapé para a barra de menu — que a landing e a
     promessa não têm. Sem descontar, a tela nasce mais alta que a janela e o
     botão de entrar cai abaixo da dobra: era a rolagem gigante da porta. */
  min-height: calc(var(--janela-util, 100dvh) - 112px - env(safe-area-inset-bottom));
  display: flex; flex-direction: column;
  justify-content: center; gap: 40px;
  padding: calc(28px + env(safe-area-inset-top)) 0 0;
}
.landing-marca { display: flex; flex-direction: column; }
/* O hebraico alinha com o nome logo abaixo. `dir="rtl"` acerta a ordem dos
   glifos e, de brinde, joga o bloco para a direita — que aqui desalinha a
   assinatura de duas linhas. */
.landing .hebraico { text-align: left; }
.landing .hebraico {
  font-size: 48px; color: var(--luz); margin: 0; opacity: .95;
  text-shadow: 0 0 34px rgba(120, 170, 215, .4);
}
.landing .marca-nome { font-family: var(--display); font-size: 52px; font-weight: 400; letter-spacing: -.02em; margin: 10px 0 0; }
.landing .promessa { font-family: var(--display); font-size: 25px; line-height: 1.4; margin: 22px 0 0; max-width: 20ch; }

/* =============================================================== pilha ===
   A tela que abre o app: um card de cada vez.

   O baralho é literal — os dois cards seguintes aparecem atrás, encolhidos e
   apagados. Isso não é enfeite: é o que faz a pessoa saber que existe um fim,
   e "quanto falta" é a informação que decide se ela continua ou fecha o app.

   A serifa continua reservada ao que É DITO. O texto do card é do Chazon,
   então é serifa; o "por quê" embaixo é a interface explicando, então não é. */

.topo-pilha { padding-bottom: 10px; }

/* A folga embaixo é onde os cards de trás aparecem. Menor do que o degrau
   deles, e a contagem passa por cima da pilha. */
.baralho { position: relative; padding-bottom: 40px; }

/* Quase opaco, de propósito: era o backdrop-filter que escondia o texto do
   card de trás vazando pela frente — sem ele, quem esconde é a tinta. */
.card-pilha {
  position: relative; z-index: 3;
  background: linear-gradient(168deg, rgba(26,41,66,.985), rgba(13,20,35,.99));
  border: 1px solid var(--borda-viva); border-radius: var(--raio-g);
  padding: 26px 22px 22px; box-shadow: var(--sombra);
}

/* Os de trás ocupam a MESMA caixa do de cima (top e bottom presos) e encolhem
   a partir da base. É isso que faz a borda deles aparecer embaixo em vez de
   sumir atrás: um card mais curto, ancorado pelo topo, ficaria invisível — e a
   pilha perderia justamente o que ela comunica, que é "ainda tem mais". */
.card-pilha[data-fundo="1"],
.card-pilha[data-fundo="2"] {
  position: absolute; left: 0; right: 0; top: 0; bottom: 40px; pointer-events: none;
  transform-origin: 50% 100%; overflow: hidden;
}
.card-pilha[data-fundo="1"] { z-index: 2; transform: translateY(11px) scale(.965); opacity: .45; }
.card-pilha[data-fundo="2"] { z-index: 1; transform: translateY(21px) scale(.93);  opacity: .2; }

.card-pergunta { border-color: rgba(168,199,222,.42); }
.card-grave    { border-color: rgba(217,142,106,.42); }

/* O gesto. `pan-y` deixa a rolagem vertical passar e reserva o horizontal
   para o card — sem isso, no iOS o navegador rouba o arrasto e o gesto some
   justamente no aparelho onde ele é a interface principal. */
.card-pilha[data-fundo="0"] { touch-action: pan-y; }
.card-pilha.arrastando { cursor: grabbing; user-select: none; }

/* As duas etiquetas do gesto. Aparecem conforme o card anda, e são a prova de
   que o movimento vai fazer alguma coisa — arrastar sem retorno visual é o
   mesmo que arrastar no escuro.

   Elas ocupam o LUGAR da etiqueta do card, que sai de cena enquanto o dedo
   está na tela: durante a decisão, o rótulo que importa é o da decisão, e
   empilhar os dois numa tela de 375px vira sopa de letra. */
.dica {
  position: absolute; top: 20px; z-index: 2; opacity: 0;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 999px; border: 1px solid currentColor;
  pointer-events: none; max-width: 60%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dica-sim { left: 20px;  color: var(--luz-forte); transform: rotate(-6deg); }
.dica-nao { right: 20px; color: var(--brasa);     transform: rotate(6deg); }
.dica:empty { display: none; }

.card-pilha .etiqueta-card { transition: opacity .14s ease; }
.card-pilha.arrastando .etiqueta-card { opacity: 0; }

.etiqueta-card {
  margin: 0 0 12px; font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fraco);
}
.card-grave .etiqueta-card { color: var(--brasa); }

.card-pilha .declaracao { margin: 0; font-size: 21px; line-height: 1.45; }
/* Sem escopo: o mesmo par pergunta + "para que serve" aparece no card e no
   diálogo de "apareceu alguma coisa", e é a mesma coisa nos dois lugares. */
.porque {
  margin: 12px 0 0; color: var(--calmo); font-size: 13.5px; line-height: 1.5;
}
.card-pilha .destino {
  margin: 14px 0 0; color: var(--luz); font-size: 12.5px;
  letter-spacing: .02em;
}

/* As escolhas: a maior parte do tanque enche com um toque. */
.escolhas { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.chip {
  font: inherit; font-size: 14px; cursor: pointer;
  background: var(--vidro); color: var(--texto);
  border: 1px solid var(--borda); border-radius: 999px;
  padding: 9px 15px; min-height: 40px; transition: background .16s, border-color .16s;
}
.chip:hover:not(:disabled) { background: var(--vidro-alto); border-color: var(--borda-viva); }
.chip:disabled { opacity: .4; }

.decisao { display: flex; gap: 10px; margin-top: 18px; }
.decisao button { flex: 1; min-height: 46px; }

.contador {
  margin: 18px 0 0; text-align: center;
  color: var(--fraco); font-size: 12px; letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
}

/* =============================================================== grade ===
   A semana marcada. Duas coisas carregam esta tela: a barra de carga, que dá o
   formato da semana antes de qualquer leitura, e o horário como controle — ele
   parece um botão porque é um. */

.custo-semana {
  font-variant-numeric: tabular-nums; color: var(--luz);
  font-size: 13px; letter-spacing: .02em;
}


.lista-grade .item { gap: 14px; }
.hora {
  flex: none; font: inherit; font-size: 15px; cursor: ns-resize;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
  background: var(--vidro); color: var(--luz);
  border: 1px solid var(--borda); border-radius: 10px;
  padding: 7px 9px; min-width: 62px; min-height: 40px;
  touch-action: pan-x;   /* o vertical é do ajuste, não da rolagem */
  transition: background .16s, border-color .16s, color .16s;
}
.hora:hover { background: var(--vidro-alto); }
.hora-viva {
  background: rgba(168,199,222,.16); border-color: var(--borda-viva);
  color: var(--luz-forte);
}

.rotulo-bloco {
  margin: 20px 0 10px; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fraco);
}
.chip-escolhido {
  background: rgba(168,199,222,.18); border-color: var(--borda-viva); color: var(--luz-forte);
}
/* Os SETE dias cabem numa linha em 375px. Com `min-width: 42px` o sábado caía
   sozinho na segunda fila e a semana deixava de se ler como semana: eles
   dividem a largura em vez de exigi-la, e o mínimo cai para o alvo de toque. */
.chip-dia {
  flex: 1 1 0; min-width: 40px; max-width: 56px;
  padding-left: 0; padding-right: 0; text-align: center;
}
[data-quando] .escolhas:first-of-type { flex-wrap: nowrap; gap: 5px; }

/* ====================================================== a esfera / chave ===
   A conversa é uma tela onde se FICA, então a chave dela é discreta e fica no
   topo, sem título por cima: o título seria o nome do app repetido. */

.chave-topo { margin: 8px 0 18px; }

/* Os cards que a conversa propôs, prontos para ela podar. */
.card-proposto {
  border: 1px solid var(--borda); border-radius: 14px; padding: 12px;
  margin-bottom: 10px; background: var(--afundado);
}
.card-proposto .entre { margin-bottom: 10px; gap: 10px; }
.card-proposto textarea { min-height: 62px; }
.card-proposto .item-sub { margin: 8px 0 0; }
.card-proposto select { flex: 0 0 auto; width: auto; }

.marcar {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: 13px; color: var(--calmo); min-height: 32px;
}
.marcar input { width: 18px; height: 18px; accent-color: var(--luz); margin: 0; }

/* ============================================================== ideias ===
   Cada coisa guardada carrega o próximo movimento. O empurrão é VOZ DO CHAZON,
   então é serifa; os movimentos são interface, então são chips. */

.empurrao {
  margin: 14px 0 0; color: var(--luz); font-family: var(--display);
  font-size: 16px; line-height: 1.45;
}
.cartao-brasa .empurrao { color: var(--brasa); }

.movimentos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.chip-nao { color: var(--calmo); }
.chip-nao:hover:not(:disabled) { border-color: rgba(217,142,106,.45); color: var(--brasa); }

/* ============================================================== semana ===
   O rito do Norte, na pele do Chazon. Regra herdada e inegociável: NADA
   VERMELHO — a célula fraca é presença baixa (opacidade), nunca acusação. */

.sem-aneis { display: flex; justify-content: space-around; gap: 8px; }
.sem-anel { display: flex; flex-direction: column; align-items: center; gap: 6px; color: var(--luz); }
.sem-anel svg { width: 56px; height: 56px; }
.sem-anel span { font-size: 11.5px; color: var(--calmo); }

.sem-chama { margin: 16px 0 0; font-size: 13px; color: var(--brasa); }

/* A carta é voz do Chazon: serifa, como o empurrão e a proposta. */
.sem-carta {
  margin: 14px 0 0; color: var(--luz); font-family: var(--display);
  font-size: 16px; line-height: 1.55; white-space: pre-wrap;
}

.sem-linha { width: 100%; height: 72px; color: var(--luz); display: block; }

.sem-tabela-rolagem { overflow-x: auto; margin-top: 14px; }
.sem-tabela { border-collapse: collapse; font-size: 11.5px; min-width: 100%; }
.sem-tabela th {
  font-weight: 400; color: var(--fraco); text-align: left; padding: 4px 8px;
  white-space: nowrap;
}
.sem-tabela td { padding: 4px 8px; color: var(--calmo); white-space: nowrap; }
.sem-celula { color: var(--luz-forte); font-variant-numeric: tabular-nums; }

#rito label { margin-top: 14px; }
#rito label:first-of-type { margin-top: 0; }

/* ============================================================== aviso === */

/**
 * O AVISO PRECISA VENCER O BACKDROP DO <dialog>.
 *
 * `z-index` não alcança a camada de topo do navegador, onde o `showModal()`
 * põe o diálogo e o escurecido dele. O aviso "o motivo é obrigatório" nascia
 * ATRÁS — e como o diálogo continuava aberto, o botão Confirmar parecia
 * simplesmente morto: tocava e não acontecia nada visível.
 *
 * `position: fixed` num elemento com `popover` sobe para a mesma camada. Onde
 * `popover` não existir, o z-index alto continua valendo para o resto do app.
 */
.aviso {
  position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom));
  transform: translateX(-50%); z-index: 40;
  margin: 0;
  display: flex; align-items: center; gap: 14px;
  background: rgba(20,28,46,.96); border: 1px solid var(--borda); color: var(--texto);
  padding: 12px 18px; border-radius: 12px; font-size: 14px;
  box-shadow: var(--sombra); max-width: calc(100vw - 40px);
}
.aviso-erro { border-color: rgba(217,142,106,.5); }
.aviso-acao {
  flex: none; font: inherit; font-size: 13px; cursor: pointer;
  background: none; border: none; color: var(--luz);
  padding: 4px 2px; min-height: 32px; text-decoration: underline;
  text-underline-offset: 3px;
}

/* ============================================================= diálogo === */

dialog, .dlg-renuncia {
  border: 1px solid var(--borda); border-radius: var(--raio-g);
  background: #141D31; color: var(--texto); padding: 24px;
  max-width: 460px; width: calc(100vw - 40px); box-shadow: var(--sombra);
}
dialog::backdrop { background: rgba(5,8,16,.72); backdrop-filter: blur(3px); }
dialog h2 { font-family: var(--display); font-weight: 400; font-size: 21px; margin: 0 0 8px; }

/* =========================================================== a conversa === */

/**
 * A CONVERSA É UMA COLUNA DE ALTURA FIXA — e quem rola é a transcrição.
 *
 * Esta é a correção do bug que resistiu a três tentativas de conserto por
 * rolagem. No iOS, quando a PÁGINA é mais alta que a tela e um campo recebe
 * foco, o Safari desloca o viewport VISUAL para revelar o campo — e esse
 * deslocamento não é rolagem: `window.scrollTo` não o alcança, e nenhuma
 * conta de scroll desfaz. A pergunta subia para trás da barra de status e a
 * pessoa não conseguia ver o que o Chazon perguntou e o que ela escrevia ao
 * mesmo tempo.
 *
 * A saída é a arquitetura dos apps de chat de verdade: a página NÃO ROLA. A
 * conversa ocupa exatamente a altura do viewport visível (`100dvh`), a
 * transcrição fica no meio com `overflow-y: auto` — é ela quem rola — e o
 * form é irmão dela, no fim da coluna. Sem página rolável, o Safari não tem
 * o que empurrar; e como o form é irmão e não algo por cima, ele crescer
 * apenas encolhe a transcrição. Os dois ficam à vista, sempre.
 */
/* A COLUNA OCUPA O QUE SOBRA — não uma altura que ela chuta.
   `height: 100dvh` na conversa estava errado porque ela NÃO começa no topo da
   tela: dentro da esfera há as abas por cima, e a coluna terminava essa mesma
   altura abaixo — o form ia parar fora da tela. A cadeia abaixo faz a página
   inteira ser uma coluna de altura da tela, e cada nível repassar o que sobra
   para o de baixo. Ninguém precisa saber onde começa. */
#app:has(.onboarding-chat) {
  display: flex; flex-direction: column;
  /* A janela útil medida pelo vigia (`teclado.js`). `100dvh` é só o palpite
     do primeiro quadro, antes da primeira medição chegar. */
  height: var(--janela-util, 100dvh); padding-bottom: 0;
  /* A coluna DESLIZA junto com o teclado (~250ms no iOS) em vez de saltar de
     uma altura para a outra no quadro em que a medição chega. A regra global
     de prefers-reduced-motion desliga isto para quem pediu. */
  transition: height .24s cubic-bezier(.3, .9, .35, 1);
  /* O `min-height: 100dvh` do #app vence qualquer `height` MENOR — com o
     teclado aberto, a página continuava com a altura da tela inteira e o
     campo ia parar embaixo do teclado. Aqui quem manda é a altura. */
  min-height: 0;
}
#app:has(.onboarding-chat) > #conteudo,
#painel-chazon:has(.onboarding-chat) {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
}
/* O topo-chat é altura fixa; o painel abaixo dele fica com o resto. Sem esta
   linha o painel não recebe altura nenhuma e a conversa não sabe onde acaba. */
#conteudo:has(.topo-chat) { display: flex; flex-direction: column; }
#conteudo:has(.topo-chat) .topo-chat { flex: 0 0 auto; }

.onboarding-chat {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0; height: auto;
  padding: 20px 0 0;
}
.chat-rolagem {
  flex: 1 1 0; min-height: 0; overflow-y: auto;
  /* SEM âncora de rolagem: quem gere o carretel é o código da tela. Com ela
     ligada, o Chrome "estabilizava" a vista no fim durante o render da folha
     — e a pessoa caía nos botões de confirmar sem ter visto o que confirmava. */
  overflow-anchor: none;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.onboarding-chat .chat-mensagens { padding-bottom: 8px; }
/* O form e o painel de gravação são o último item da COLUNA — nunca flutuaram
   desde que a conversa virou coluna de altura fixa. O bloco `position: fixed`
   que eles carregavam lá em cima existe só para quem os usasse fora dela, e
   ninguém usa; estas regras são as que valem. */
.onboarding-chat .chat-form,
.onboarding-chat .gravando {
  position: static; transform: none; width: auto; max-width: none;
  /* `max`, não soma: a área segura JÁ é a folga do indicador de início —
     somar 6px a ela empurrava a caixa para longe do polegar. Sem área segura
     (desktop, Android), os 6px seguram o mínimo. */
  padding: 6px 0 max(6px, env(safe-area-inset-bottom));
  background: none;
}
/* A proposta mora DENTRO do carretel: rola junto, sem teto próprio. Dois
   rolos na mesma coluna brigam — e quem perdia era a folha do setup. */

/**
 * Embutida na esfera, a coluna RESERVA a faixa da barra dentro de si.
 *
 * Descontar a barra da altura por aritmética era frágil: `--barra`, o
 * `env(safe-area-inset-bottom)` e o gradiente da barra entram na conta de
 * jeitos diferentes conforme o navegador, e sobrava microfone por baixo do
 * menu. Reservar por padding é um conceito só e não depende de acertar a
 * soma: a coluna ocupa a altura visível inteira, e o padding garante que o
 * último item dela (o form) termine acima da barra.
 */
/* A conversa embutida guardava o rodapé para a barra de cinco menus. Agora o
   Chazon é tela cheia e não tem barra: o espaço volta para a conversa. */
.chat-embutido { padding-bottom: 0; }
.chat-topo {
  display: flex; gap: 14px; align-items: center;
  padding: 4px 0 26px; border-bottom: 1px solid var(--borda);
}
.chat-topo > div { flex: 1; min-width: 0; }
.chat-topo .hebraico { color: var(--luz); font-size: 23px; margin: 0; opacity: .8; }
.chat-topo h1 { font-family: var(--display); font-size: 24px; font-weight: 400; margin: 0; }
.chat-topo p { color: var(--fraco); font-size: 13px; margin: 2px 0 0; }
.chat-topo #pular-por-agora { flex: 0 0 auto; font-size: 13.5px; white-space: nowrap; }

/* ─────────────────────────────────────────────────────── as bolhas ──────
   Pedido do André (06/08): "uma coisa mais chat conversa" — um lado para
   cada voz, cores diferentes, como o WhatsApp mas na identidade daqui. A
   fala do Chazon perdeu o formato editorial (texto solto, serifa grande) e
   virou bolha como a dela: à esquerda, em vidro; a dela à direita, no azul
   da luz. O rótulo VOCÊ/CHAZON saiu da tela — lado e cor já dizem quem fala
   — mas continua no DOM para o leitor de tela, que não vê lado nenhum. */
/* O ar em volta era generoso demais para uma tela de conversa: 28px em cima
   e embaixo mais 10px entre bolhas somavam quase uma bolha inteira de espaço
   perdido. Aqui o ritmo é de chat — junto, mas não colado. */
.chat-mensagens { display: flex; flex-direction: column; gap: 7px; padding: 10px 0; }
.fala {
  max-width: 85%; padding: 9px 13px;
  border-radius: 17px; border: 1px solid var(--borda);
}
.fala p { margin: 0; white-space: pre-wrap; font-size: 14.5px; line-height: 1.5; }
.fala .fala-autor {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.fala-chazon {
  align-self: flex-start;
  background: var(--vidro);
  border-bottom-left-radius: 6px;
}
/* A serifa fica, menor: é a voz dele, e a bolha continua sendo do Chazon. */
/* A serifa fica — é a voz dele —, mas NO MESMO CORPO da fala dela. Ela era
   17px contra 15,5px: a diferença que fazia a tela parecer um livro em vez de
   uma conversa, e que custava uma linha a cada duas bolhas. */
.fala-chazon p { font-family: var(--display); font-size: 15px; line-height: 1.5; }
.fala-pessoa {
  align-self: flex-end;
  background: rgba(168, 199, 222, .16);
  border-color: var(--borda-viva);
  border-bottom-right-radius: 6px;
  color: var(--luz-forte);
}

/* ──────────────────────────────────────────── a chegada das bolhas ──────
   Ela BROTA da origem — o rabinho aponta para quem falou, e é dali que a
   bolha nasce (transform-origin no canto do rabinho: o que aparece emerge de
   onde veio). Duas curvas de propósito: a bolha DELA carrega o impulso do
   envio e passa um fio do alvo antes de assentar; a do Chazon chega
   amortecida, sem ricochete — ninguém a arremessou.

   E só as DUAS ÚLTIMAS animam. O redesenho reconstrói a transcrição inteira
   a cada volta, e antes disso TODAS as bolhas repetiam a animação de chegada
   — a conversa inteira piscava a cada mensagem. As duas últimas são as que
   podem ter acabado de nascer; o resto já estava lá. */
.fala-chazon { transform-origin: 14px 100%; }
.fala-pessoa { transform-origin: calc(100% - 14px) 100%; }
.chat-mensagens .fala:nth-last-child(-n+2) {
  animation: brotar .38s cubic-bezier(.22, .9, .32, 1) both;
}
.chat-mensagens .fala-pessoa:nth-last-child(-n+2) {
  animation-timing-function: cubic-bezier(.3, 1.28, .36, 1);
}
@keyframes brotar {
  from { opacity: 0; transform: translateY(12px) scale(.94); }
}

/* "Pensando" são três pontos respirando, não uma palavra parada: movimento
   diz "estou trabalhando" mais rápido do que qualquer texto. */
.pensando { display: inline-flex; gap: 6px; padding: 8px 2px 2px; }
.pensando i {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--luz); opacity: .3;
  animation: ponto 1.15s ease-in-out infinite;
}
.pensando i:nth-child(2) { animation-delay: .16s; }
.pensando i:nth-child(3) { animation-delay: .32s; }
@keyframes ponto {
  0%, 100% { opacity: .25; transform: translateY(0); }
  40% { opacity: .9; transform: translateY(-3px); }
}

/* O modo conversa ligado acende o botão — é o único jeito de saber, de
   relance, por que o microfone reabre sozinho. */
.redondo[aria-pressed="true"] {
  background: rgba(168,199,222,.2); color: var(--luz-forte);
  border-color: var(--borda-viva);
}

/* O campo mergulha no fundo por um fade, não por uma caixa: fundo quase opaco
   com borda reta era um retângulo duro cortando a bruma — o defeito relatado. */
.chat-form {
  position: fixed; left: 50%; bottom: 0; z-index: 30;
  /* A folga do teclado entra aqui: no iOS o fixo é preso ao viewport de
     layout, e sem isto a caixa fica escondida embaixo do teclado. */
  transform: translate(-50%, calc(-1 * var(--teclado, 0px)));
  /* COLUNA: a barra de escrita em cima, o rodapé (Modo voz) embaixo. Em
     linha, o rodapé virava um irmão da cápsula e roubava a largura dela —
     "Modo voz" acabava espremido ao lado do microfone. */
  width: min(720px, 100%); display: flex; flex-direction: column; gap: 0;
  padding: 30px 20px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(var(--fade), 0), rgba(var(--fade), .95) 30px);
}
/* `display: flex` acima vence o atributo `hidden`, e sem isto o campo
   continuava aparecendo depois da proposta — deixando a pessoa digitar numa
   conversa encerrada, que o servidor recusa. */
.chat-form[hidden] { display: none; }
.chat-form textarea {
  /* Nasce com UMA linha e cresce conforme ela escreve (o JS mede a cada
     tecla). Um campo alto e vazio pesa na tela; um que cresce acompanha. */
  min-height: 22px; max-height: 160px; resize: none; overflow-y: auto;
}
.chat-form button { flex: 0 0 auto; }

/* ------------------------------------------------- falar e fotografar ---
   O campo deixou de ser uma linha com um botão: agora ele tem três saídas —
   escrever, falar, mostrar. Elas ficam embaixo do texto e não ao lado dele
   porque numa tela de 375px três botões na horizontal espremem o campo até ele
   caber uma palavra. */

/* ───────────────────────────────── a barra de escrita (desenho WhatsApp) ──
   Uma LINHA: a cápsula com o texto e a câmera dentro, e fora dela o botão da
   vez — microfone quando vazio, seta quando há o que enviar. O botão troca no
   mesmo lugar, então o polegar não precisa procurar. */
/* O botão da vez alinha pelo FIM da cápsula, não pelo centro dela.
   Com `center`, uma cápsula crescida (quatro linhas de texto) deixaria o
   microfone flutuando no meio; com `flex-end` ele acompanha a base, como no
   WhatsApp. O desalinhamento que se via era outro: a cápsula tem borda de 1px
   e o botão não tinha nenhuma — 2px de diferença de altura. Resolvido com a
   borda transparente no botão da vez, logo abaixo. */
.entrada { flex: 1; display: flex; align-items: flex-end; gap: 8px; min-width: 0; }
.acao-vez { border: 1px solid transparent; }

.capsula {
  flex: 1; min-width: 0;
  display: flex; align-items: flex-end; gap: 6px;
  padding: 6px 6px 6px 16px;
  /* Pílula completa: os cantos são metade da altura de uma linha, como no
     WhatsApp. Crescendo para várias linhas, o raio fica — canto grande é o
     que segura a forma. */
  border-radius: 27px;
  /* Mais presente que o vidro comum: sobre a bruma escura, um cartão de vidro
     translúcido desaparecia — e uma caixa de escrever que não se vê é uma
     caixa que não existe. Fundo próprio e borda viva dão a ela o peso de
     entrada principal do app. */
  background: var(--capsula);
  border: 1px solid var(--borda-viva);
  box-shadow: 0 2px 14px rgba(0, 0, 0, .28);
  transition: border-color .16s, background .16s;
}
.capsula:focus-within { background: var(--capsula-viva); }
.capsula:focus-within { border-color: var(--borda-viva); }
.capsula textarea {
  flex: 1; min-width: 0; border: 0; background: none; padding: 8px 0;
  border-radius: 0; box-shadow: none;
}
.capsula textarea:focus { outline: none; box-shadow: none; border: 0; }

/* A câmera mora DENTRO da cápsula: anexar é parte de compor a mensagem. */
.na-capsula {
  /* 44×44 de ALVO com 20px de ícone: o toque cumpre a regra da Apple e o
     desenho continua leve. Com 34px de altura declarada, o mínimo global de 44
     esticava só a altura e o halo do modo voz saía oval. */
  flex: 0 0 auto; width: 44px; height: 44px; min-width: 44px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: none; color: var(--fraco); cursor: pointer;
  transition: color .16s;
}
.na-capsula:hover { color: var(--luz); }
.na-capsula svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}

/**
 * A ESFERA DENTRO DA CÁPSULA.
 *
 * A mesma esfera da barra de baixo, do tamanho de um ícone. Ela não ganha
 * fundo nem borda: é um objeto, não um botão com desenho dentro — e a
 * respiração dela já diz que está viva. Acesa (modo voz ligado), o halo em
 * volta acende junto.
 */
.esfera-botao { padding: 0; }
.esfera-mini {
  width: 24px; height: 24px; display: block;
  box-shadow: 0 0 10px rgba(126,176,212,.45), inset 0 -2px 5px rgba(0,0,0,.34);
}
.esfera-botao.aceso::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 36px; height: 36px; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: rgba(168,199,222,.22); z-index: -1;
}
/* Gravando, ela pulsa — é a esfera respirando mais fundo. */
.esfera-botao.pensando .esfera-mini { animation: respira .9s ease-in-out infinite; }

/* O botão da vez, sempre no mesmo canto. */
.acao-vez { flex: 0 0 auto; }
.acao-vez[hidden] { display: none; }

/* O modo voz é um ÍCONE dentro da cápsula, aceso quando ligado. Nada ocupa a
   linha de baixo: a barra de escrita é uma linha só, e ponto. */
.na-capsula.aceso { color: var(--luz-forte); }
.na-capsula.aceso::after {
  content: ''; position: absolute; inset: 2px;
  border-radius: 50%; background: rgba(168,199,222,.2);
  z-index: -1;
}
/* O halo é um disco de tamanho fixo no centro — `inset` sobre um botão que o
   flex pode esticar devolvia elipse. */
.na-capsula.aceso::after {
  inset: auto; width: 34px; height: 34px;
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
}
.na-capsula { position: relative; isolation: isolate; }

/* 44px, não 42: o `min-height: 44px` de todo botão VENCE um `height` menor, e
   o resultado era uma elipse — largura 42, altura 44. Igualar os dois devolve
   o círculo e, de brinde, acerta o alvo de toque da regra da Apple. */
.redondo {
  width: 44px; height: 44px; min-width: 44px; padding: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--vidro); color: var(--calmo);
  border: 1px solid var(--borda);
  transition: background .16s, color .16s, border-color .16s;
}
.redondo:hover:not(:disabled) { background: var(--vidro-alto); color: var(--luz); border-color: var(--borda-viva); }
.redondo:disabled { opacity: .5; }
.redondo svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.redondo.pensando, .na-capsula.pensando {
  animation: respira 1.1s ease-in-out infinite; color: var(--luz);
}

/* A gravação toma o lugar do campo: enquanto ela fala, não há mais nada a
   fazer ali, e um campo de texto ao lado só ofereceria uma distração. */
.gravando {
  position: fixed; left: 50%; bottom: var(--barra); z-index: 30;
  transform: translate(-50%, calc(-1 * var(--teclado, 0px)));
  width: min(720px, 100%); display: flex; align-items: center; gap: 12px;
  padding: 34px 20px 16px;
  background: linear-gradient(180deg, rgba(var(--fade), 0), rgba(var(--fade), .96) 32px);
  font-variant-numeric: tabular-nums;
}
.gravando[hidden] { display: none; }
.gravando .principal { margin-left: auto; }
.gravando .ouvindo { white-space: nowrap; }
.gravando .sutil { flex: 0 0 auto; }

/* O pulso responde ao som de verdade (`--nivel` vem do medidor). É o que diz
   "o microfone pegou" antes de a pessoa terminar a primeira frase. */
.pulso {
  width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto;
  background: var(--brasa);
  transform: scale(var(--nivel, 1));
  box-shadow: 0 0 12px rgba(217,142,106,.6);
  transition: transform .08s linear;
}
@media (prefers-reduced-motion: reduce) { .pulso { transform: none; } }

/**
 * A CONVERSA EMBUTIDA, dentro da esfera.
 *
 * Aqui a barra de navegação continua de pé, então o campo senta EM CIMA dela em
 * vez de cobri-la. Cobrir seria pior do que parece: a pessoa entra para falar,
 * termina, e não acha o caminho de volta — num app cuja tela principal é
 * justamente esta.
 */
.chat-embutido .chat-mensagens { padding-top: 4px; }

.sintese-onboarding { border-top: 1px solid var(--borda); padding: 30px 0 20px; }
.sintese-onboarding > h2 { font-family: var(--display); font-size: 28px; font-weight: 400; margin: 10px 0 6px; }
.sintese-area { padding: 18px; border-radius: var(--raio); background: var(--vidro); margin-bottom: 12px; }
.sintese-area h3 { color: var(--luz); font-size: 12px; text-transform: uppercase; letter-spacing: .09em; margin: 0 0 12px; }

.nota-proposta {
  margin: 18px 0 22px; padding: 14px 16px;
  border-left: 2px solid var(--borda-viva); background: rgba(168,199,222,.05);
  border-radius: 0 12px 12px 0;
}
.nota-proposta h3 {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fraco); margin: 0 0 6px; font-weight: 700;
}
.nota-proposta p { margin: 0; color: var(--calmo); font-size: 14.5px; white-space: pre-wrap; }

.acoes-proposta { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }

/* ================================================== editor de sistemas === */

.sistema {
  border: 1px solid var(--borda); border-radius: 14px; padding: 12px;
  margin-bottom: 10px; background: var(--afundado);
}
.sistema > input[type="text"] { margin-bottom: 10px; }
.sistema-ritmo { display: flex; gap: 8px; align-items: center; }
.sistema-ritmo select { flex: 1 1 auto; min-width: 0; }
.sistema-min { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.sistema-min input { width: 62px; text-align: center; padding-left: 6px; padding-right: 6px; }
.sistema-min span { color: var(--fraco); font-size: 13px; }
.sistema-ritmo [data-tirar-sistema] { flex: 0 0 auto; padding: 8px 10px; }

/* Os ajustes da grade reusam a caixa do sistema: é a mesma ideia de linha com
   controles ao lado, e duas caixas parecidas com regras próprias divergem. */
.ajuste {
  border: 1px solid var(--borda); border-radius: 14px; padding: 12px;
  margin-bottom: 10px; background: var(--afundado);
}
.ajuste .item-titulo { margin: 0 0 2px; }
.ajuste .item-sub { margin: 0 0 10px; }
.ajuste .sistema-min input { width: 76px; }

.custo { font-variant-numeric: tabular-nums; color: var(--calmo); }

/* ============================================================== outros === */

.parecer { margin-top: 8px; font-size: 13px; }
.parecer summary { cursor: pointer; color: var(--fraco); list-style: none; }
.parecer summary::-webkit-details-marker { display: none; }
.parecer summary::before { content: '▸ '; }
.parecer[open] summary::before { content: '▾ '; }
.parecer summary:hover { color: var(--calmo); }
.parecer p {
  margin: 8px 0 0; padding-left: 12px; border-left: 2px solid var(--borda);
  color: var(--calmo); white-space: pre-wrap;
}

.bloco-area { margin-bottom: 18px; }
.bloco-area:last-of-type { margin-bottom: 0; }
.bloco-area h3 { margin-bottom: 6px; }

.tempo { display: grid; grid-template-columns: 46px 1fr; gap: 0 12px; }
.tempo .hora { font-size: 11.5px; color: var(--fraco); font-variant-numeric: tabular-nums; padding-top: 12px; }
.tempo .bloco { border-left: 2px solid var(--borda); padding: 12px 0 12px 14px; }
.tempo .bloco.meu { border-left-color: var(--luz); }
.tempo .bloco.risco { border-left-color: var(--brasa); }
.tempo .bloco p { margin: 0; font-size: 14px; }

/* =============================================== acessibilidade e móvel === */

.so-leitor {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (max-width: 520px) {
  .fala { max-width: 94%; }
  .chat-form { padding-left: 12px; padding-right: 12px; }
  /* Só os botões de TEXTO ganham respiro lateral. Aplicado a todos, ele
     somava 28px à caixa de conteúdo dos ícones redondos e os achatava. */
  .chat-form button:not(.redondo):not(.na-capsula) {
    padding-left: 14px; padding-right: 14px;
  }

  /* O título da pauta briga com a saída e quebra em duas linhas; alinhar
     pelo topo e encolher resolve, e pautas futuras têm nomes mais longos. */
  .chat-topo { align-items: flex-start; gap: 10px; }
  .chat-topo .hebraico { font-size: 19px; margin-top: 2px; }
  .chat-topo h1 { font-size: 20px; }
  .chat-topo #pular-por-agora { margin-top: -4px; }

  .nav a { min-width: 50px; font-size: 9.5px; }
  .topo h1 { font-size: 28px; }

  /* Quando a conversa termina em DECISÃO e não em confirmação, as opções são
     três e nenhuma é a recomendada pela interface — o parecer é que recomenda.
     `order` em vez de `column-reverse`: reverter inverteria as decisões, e é a
     ordem do DOM que o leitor de tela segue. */
  .acoes-varias { flex-direction: column; align-items: stretch; }
  .acoes-varias button { width: 100%; }
  .acoes-varias #continuar-conversa { order: 1; margin-top: 4px; }

  .sistema-ritmo { flex-wrap: wrap; }
  .sistema-ritmo select { flex: 1 1 100%; }
}

/* ==========================================================================
   VALOR NO MINUTO 1

   Três peças que existem para encurtar o caminho entre abrir o app e receber
   alguma coisa de volta: a pergunta antes do login, o convite para falar em
   vez de digitar, e a espera que diz o próprio nome depois de quatro segundos.
   ========================================================================== */

/* A porta da landing: a marca acima, a maçaneta aqui — sem rolagem no meio. */
.landing-porta { display: flex; flex-direction: column; gap: 16px; }
.landing-porta .principal { width: 100%; padding: 16px 0; font-size: 16px; }
.landing-porta .fraco { margin: 0; max-width: 40ch; }

/* O microfone convidado — pulso lento, uma conversa só. Ele chama sem gritar:
   um anel que respira, e não uma cor nova que o app inteiro teria que honrar. */
.redondo.convite { position: relative; color: var(--luz); }
.redondo.convite::after {
  content: ''; position: absolute; inset: -3px;
  border-radius: 50%; border: 1px solid var(--luz);
  opacity: .5; animation: convite 2.6s ease-out infinite;
  pointer-events: none;
}
@keyframes convite {
  0%   { transform: scale(1);    opacity: .55; }
  70%  { transform: scale(1.35); opacity: 0; }
  100% { transform: scale(1.35); opacity: 0; }
}


/* A espera com nome. Entra por baixo dos pontinhos, sem empurrar a bolha. */
.espera-longa {
  margin: 8px 0 0; font-size: 13px; line-height: 1.45;
  animation: surgir .4s ease-out both;
}
@keyframes surgir { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; } }

/* A colheita: o que ela contou de passagem, com a evidência colada.
   Sem cartão próprio — é informação dela, não proposta do Chazon, e um cartão
   a mais na folha de confirmação daria a ela o peso errado. */
.colhido { padding: 10px 0; border-bottom: 1px solid var(--borda); }
.colhido:last-child { border-bottom: 0; }
.colhido .item-sub { margin: 6px 0 0 26px; font-style: italic; }

/* A evidência: o que aconteceu, colado no que foi marcado.
   Frase, nunca porcentagem — nota convida a se justificar, observação convida
   a olhar. E sem sequência: "12 dias seguidos" transforma o objetivo em não
   quebrar a série, e o dia da quebra é o dia em que a pessoa larga. */
.evidencia { margin: 4px 0 0; font-size: 12.5px; color: var(--calmo); }
.evidencia.nao-pegou { color: var(--brasa); }

/* O que ele aprendeu observando — dito com menos peso que o que ela escreveu.
   A declaração dela é a fonte; isto é leitura dele, e a hierarquia tipográfica
   tem que dizer isso sem precisar de um aviso. */
.declaracao.aprendi { font-size: 18px; line-height: 1.45; margin: 0 0 12px; }
.declaracao.aprendi:last-of-type { margin-bottom: 0; }

/* A leitura do mês: cinco a oito frases, uma por linha. É o texto mais longo
   que a pilha mostra, e o cartão cresce para caber — cortar seria entregar
   meia leitura depois de cobrar a espera inteira. */
.declaracao.leitura-mes {
  font-size: 17px; line-height: 1.55; white-space: pre-line;
  max-height: 46vh; overflow-y: auto;
}

/* Texto já escrito, mostrado num diálogo: as quebras são do texto, não do
   layout. Sem isto a carta da semana vira um parágrafo só. */
.dlg-texto .pre { white-space: pre-wrap; max-height: 46vh; overflow-y: auto; }

/* =========================================================== o onboarding ===
   Os passos do começo. A primeira conversa é o onboarding, e onboarding tem
   três promessas a fazer de cara: onde você está, quanto falta, e que isto
   acaba. O passo do momento acende; o feito fica marcado. */
.passos {
  display: flex; gap: 6px; align-items: center;
  padding: 0 20px 14px; max-width: 720px; margin: 0 auto;
}
.passo {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--fraco); white-space: nowrap;
}
.passo i {
  font-style: normal; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: 11px;
  background: var(--vidro); border: 1px solid var(--borda);
  transition: background .25s, color .25s, border-color .25s;
}
.passo:not(:last-child)::after {
  content: ''; width: 18px; height: 1px; background: var(--borda);
  margin-left: 6px;
}
.passo-atual { color: var(--luz-forte); }
.passo-atual i { background: rgba(168,199,222,.22); border-color: var(--borda-viva); color: var(--luz-forte); }
.passo-feito { color: var(--calmo); }
.passo-feito i { background: rgba(168,199,222,.12); border-color: var(--borda-viva); }

@media (max-width: 520px) {
  .passos { padding-left: 14px; padding-right: 14px; }
  .passo { font-size: 11px; }
  .passo:not(:last-child)::after { width: 10px; }
}

/* A pílula do Modo voz. Texto, não ícone: dois ícones de som lado a lado é
   adivinhação, e modo que fica ligado merece nome. Ligada, ela acende — e o
   estado escrito embaixo do campo fica visível enquanto o modo durar. */




/* ========================================================== o teclado ===
   Enquanto o teclado está aberto: a nav se recolhe (metade da tela é dele,
   e um menu flutuando em cima do teclado não serve para nada ali), e o
   chat embutido desce para o lugar dela. Quem devolve tudo é o teclado
   fechando — a variável zera e as transições trazem de volta. */
body.teclado-aberto .nav { transform: translateY(120%); pointer-events: none; }
.nav { transition: transform .22s ease; }

/**
 * Com o teclado aberto, a coluna da conversa passa a medir a JANELA ÚTIL.
 *
 * `100dvh` já desconta a barra do navegador, mas não o teclado — e é o
 * teclado que come metade da tela. A variável `--teclado` (do vigia) entra
 * na conta, a coluna encolhe, e a transcrição encolhe com ela: a pergunta
 * fica em cima, o campo embaixo, e os dois à vista. A barra de menu sai, e o
 * espaço dela volta para a conversa.
 */
/* Com o teclado aberto, a página encolhe para a janela útil e a barra sai de
   cena — o espaço dela volta para a conversa. A cadeia repassa o resto. */
/* Nada aqui sobre altura: `--janela-util` já vale com teclado aberto ou
   fechado. A subtração que existia neste ponto era o bug — ver teclado.js. */

/**
 * ESCREVENDO, A BARRA DE CIMA SAI DE CENA.
 *
 * As duas chaves e o voltar são navegação — e ninguém navega no meio de uma
 * frase. Com o teclado aberto, a tela útil já é metade da tela: são quase
 * quarenta pixels de moldura tirando lugar de uma linha e meia de conversa,
 * exatamente no momento em que a conversa é tudo o que importa.
 *
 * A barra volta sozinha assim que o teclado fecha, e o gesto de arrastar da
 * borda do Safari continua voltando a tela — ninguém fica preso.
 */
body.teclado-aberto .topo-chat {
  height: 0; opacity: 0; margin: 0; padding: 0; pointer-events: none;
}

/**
 * COM O TECLADO ABERTO, A CAIXA ENCOSTA NELE.
 *
 * O respiro de baixo existe por causa do indicador de início do iPhone. Com o
 * teclado na tela, o indicador não está mais lá — o teclado ocupa aquele
 * espaço —, e alguns iOS continuam relatando a área segura mesmo assim.
 * Resultado: uma faixa de trinta e poucos pixels entre a caixa e as teclas,
 * que não protege nada e come área de leitura.
 */
body.teclado-aberto .onboarding-chat .chat-form,
body.teclado-aberto .onboarding-chat .gravando {
  padding-bottom: 4px;
}
body.teclado-aberto .chat-embutido { padding-bottom: 0; }

/**
 * R2 — TELAS ROLÁVEIS COMUNS (Áreas, Jornadas, Caminho…): o teclado abre e a
 * página ganha o espaço dele como padding. Com espaço real de rolagem, o
 * scroll-into-view do Safari acontece por ROLAGEM DO CORPO — que é previsível
 * e reversível — em vez do deslocamento de viewport que não se controla. O
 * vigia completa centralizando o campo focado (ver teclado.js).
 */
body.teclado-aberto #app:not(:has(.onboarding-chat)) {
  padding-bottom: calc(112px + var(--teclado, 0px));
}

/**
 * R3 — DIÁLOGOS: ancorados no topo enquanto o teclado está aberto, com teto
 * de altura na janela útil. Centrado (o padrão do <dialog>), metade dele —
 * junto com os botões — afundava atrás do teclado.
 */
body.teclado-aberto dialog[open] {
  margin-top: max(14px, env(safe-area-inset-top));
  margin-bottom: auto;
  /* A margem do topo entra na conta: sem ela, o diálogo empurrado para baixo
     do notch tinha o fundo caindo atrás do teclado. */
  max-height: calc(
    100dvh - var(--teclado, 0px) - max(14px, env(safe-area-inset-top)) - 14px
  );
  overflow-y: auto;
}


/* ======================================================= o hero do começo ===
   A primeira conversa é a primeira tela que a pessoa vê com a conta feita — e
   ela abria com a cara de qualquer chat. Aqui a marca ganha o tamanho de
   marca, tudo centra, e os passos ficam por baixo: uma abertura, não uma aba.
   O DOM é o mesmo do cabeçalho comum; só a classe muda. */
.topo-onboarding {
  flex-direction: column; align-items: center; text-align: center;
  gap: 10px; position: relative; padding: 40px 0 24px;
}
.topo-onboarding .hebraico {
  font-size: 54px; line-height: 1; opacity: 1; margin: 0;
  /* A marca respira como a bruma: um brilho leve, nunca um logotipo chapado. */
  text-shadow: 0 0 34px rgba(120, 170, 215, .45);
}
.topo-onboarding h1 { font-size: 30px; }
.topo-onboarding p { max-width: 36ch; margin: 6px auto 0; font-size: 14px; }
.topo-onboarding #pular-por-agora {
  position: absolute; top: 8px; right: 0; margin: 0;
}
/* Os passos centram junto do hero. Fora do onboarding, seguem à esquerda. */
.topo-onboarding + .passos { justify-content: center; padding-top: 16px; }

@media (max-width: 520px) {
  .topo-onboarding { align-items: center; padding-top: 46px; }
  .topo-onboarding .hebraico { font-size: 46px; margin-top: 0; }
  .topo-onboarding h1 { font-size: 26px; }
  .topo-onboarding #pular-por-agora { margin-top: 0; }
}

/* ======================================================== a apresentação ===
   ATENÇÃO ao nome: `.promessa` JÁ EXISTE e é a frase da landing. Chamar estas
   telas de `.promessa` fazia o `min-height: 100dvh` daqui esticar aquela frase
   até a altura da tela inteira e empurrar o botão de entrar para fora da dobra
   — era a "rolagem gigante" da porta.

   As três telas antes da primeira conversa. Uma ideia por tela, a arte feita
   da linguagem do próprio app, e o pé fixo com os pontos e o botão. O trilho
   desliza; no celular, o dedo folheia. */
.apresentacao {
  /* Mesmo desconto da landing: o `#app` guarda 112px para a barra de menu, que
     aqui não existe. Sem isso, cada tela de apresentação nasce mais alta que a
     janela e ganha uma rolagem que não leva a lugar nenhum. */
  min-height: calc(var(--janela-util, 100dvh) - 112px - env(safe-area-inset-bottom));
  display: flex; flex-direction: column;
  overflow: hidden; position: relative;
  padding: calc(14px + env(safe-area-inset-top)) 0 0;
}
#apresentacao-pular { position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 16px; z-index: 2; }

.apresentacao-trilho {
  flex: 1; display: flex; transition: transform .38s cubic-bezier(.3,.9,.3,1);
}
.apresentacao-tela {
  flex: 0 0 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 0 30px; gap: 8px;
}
.apresentacao-tela h1 {
  font-family: var(--display); font-weight: 400;
  font-size: 29px; line-height: 1.25; margin: 26px 0 0; max-width: 17ch;
  text-wrap: balance;
}
.apresentacao-tela > p { color: var(--calmo); font-size: 15px; line-height: 1.65; max-width: 34ch; margin: 10px 0 0; }

.apresentacao-pe {
  display: flex; flex-direction: column; align-items: center; gap: 22px;
  padding: 10px 30px 0;
}
.apresentacao-pe .principal { width: min(340px, 100%); padding: 15px 0; font-size: 16px; }
.pontos { display: flex; gap: 2px; }
/* O alvo de toque continua nos 44px (o min-height global de botão está certo);
   o PONTO é só o ::before de 8px no meio dele. Sem isso, o mínimo esticava o
   círculo num bastão. */
.ponto {
  width: 24px; min-height: 44px; padding: 0; border: 0;
  background: none; cursor: pointer; position: relative;
}
.ponto::before {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 8px; height: 8px; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: rgba(168,199,222,.22);
  transition: background .25s, transform .25s;
}
.ponto-atual::before { background: var(--luz-forte); transform: translate(-50%, -50%) scale(1.3); }

/* --- as artes: o app desenhado com o próprio app --- */

.arte-esfera { display: grid; place-items: center; padding: 8px 0 4px; }
.esfera-grande {
  width: 132px; height: 132px; display: block;
  box-shadow: 0 0 70px rgba(126,176,212,.55), 0 14px 40px rgba(0,0,0,.5),
              inset 0 -14px 30px rgba(0,0,0,.34);
}

.arte-fala { display: flex; flex-direction: column; gap: 12px; width: min(320px, 88%); }
.bolha-arte {
  padding: 13px 16px; border-radius: 18px; font-size: 14.5px; line-height: 1.5;
  text-align: left; border: 1px solid var(--borda); background: var(--vidro);
}
.bolha-pessoa { align-self: flex-end; border-bottom-right-radius: 6px; color: var(--luz-forte);
  background: rgba(168,199,222,.13); max-width: 82%; }
.bolha-chazon { align-self: flex-start; border-bottom-left-radius: 6px; color: var(--calmo); max-width: 88%; }

.arte-cards { position: relative; width: min(300px, 84%); height: 168px; }
.card-arte {
  position: absolute; inset: 0; border-radius: 20px;
  border: 1px solid var(--borda); background: var(--vidro);
}
.card-arte.fundo-2 { transform: translateY(18px) scale(.9); opacity: .35; }
.card-arte.fundo-1 { transform: translateY(9px) scale(.95); opacity: .6; }
.card-arte.frente {
  background: linear-gradient(180deg, rgba(168,199,222,.10), var(--vidro));
  border-color: var(--borda-viva); transform: rotate(-1.6deg);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 18px; text-align: left;
}
.card-arte.frente p { margin: 0; font-family: var(--display); font-size: 16.5px; line-height: 1.45; }
.card-arte .gesto { display: flex; justify-content: space-between; align-items: center; }
.card-arte .gesto span { font-size: 13px; color: var(--fraco); padding: 8px 16px; border-radius: 999px; }
.card-arte .gesto .sim {
  color: var(--principal-texto); background: var(--luz-forte); font-weight: 600;
}

@media (max-width: 520px) {
  .apresentacao-tela h1 { font-size: 25px; }
  .esfera-grande { width: 112px; height: 112px; }
}

/* ============================================================== a abertura ===
   A esfera é o app: ela é o centro da barra, é o que a promessa mostra
   primeiro, e é o que aparece enquanto tudo carrega. Aqui ela ganha uma órbita
   — o brilho interno gira mais rápido e um anel corre em volta —, para o
   carregamento parecer trabalho acontecendo e não uma tela parada.

   Mora no HTML, não no JS: uma tela de carregamento desenhada por JavaScript
   só aparece depois de o JavaScript carregar, que é o tempo que ela existe
   para cobrir. */
.abrindo {
  min-height: 100dvh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 22px;
  animation: abrindo-entra .5s ease-out both;
}
@keyframes abrindo-entra { from { opacity: 0; } to { opacity: 1; } }

.esfera-abrindo {
  width: 96px; height: 96px; display: block; position: relative;
  box-shadow: 0 0 54px rgba(126,176,212,.5), 0 10px 30px rgba(0,0,0,.5),
              inset 0 -11px 24px rgba(0,0,0,.34);
  animation: respira 3.4s ease-in-out infinite;
}
/* O brilho de dentro acelera: é o que dá a sensação de "pensando". */
.esfera-abrindo::before { animation-duration: 3.4s; }
.esfera-abrindo::after  { animation-duration: 4.6s; }

/* O anel que corre em volta. `overflow: hidden` da esfera cortaria um filho,
   então ele é um irmão desenhado por cima, com o mesmo centro. */
.abrindo .esfera-abrindo + .hebraico { position: relative; }
.abrindo::before {
  content: ''; position: absolute; width: 128px; height: 128px;
  margin-top: -80px; border-radius: 50%;
  border: 1px solid transparent; border-top-color: rgba(168,199,222,.75);
  border-right-color: rgba(168,199,222,.25);
  animation: orbita 1.15s linear infinite;
}
@keyframes orbita { to { transform: rotate(360deg); } }

.abrindo .hebraico {
  font-size: 30px; color: var(--luz); margin: 0; opacity: .9;
  text-shadow: 0 0 26px rgba(120,170,215,.4);
}
.abrindo-nota {
  margin: -12px 0 0; font-size: 13px; color: var(--fraco);
  animation: pulsa-nota 2s ease-in-out infinite;
}
@keyframes pulsa-nota { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .abrindo::before, .esfera-abrindo, .abrindo-nota { animation: none; }
}

/* O enviar redondo: a seta do chat. `.principal` vence o vidro do `.redondo`
   na cor de fundo; aqui só o ícone e o hover que o par não cobre. */
.redondo.enviar { background: var(--principal-fundo); border-color: var(--principal-fundo); color: var(--principal-texto); }
.redondo.enviar:hover:not(:disabled) { background: var(--luz-forte); border-color: var(--luz-forte); color: var(--principal-texto); }
.redondo.enviar svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}

/* ═══════════════════════════════════ o hero recolhe para o teclado ═══════
   O hero do onboarding (marca grande, título, subtítulo, passos) ocupa quase
   a tela inteira — é o que ele deve fazer na CHEGADA. Mas ele continuava do
   mesmo tamanho quando o teclado subia, e aí não sobrava altura para a
   pergunta e o campo ao mesmo tempo: a página voltava a ser rolável e o
   Safari empurrava tudo para cima. Era o bug que sobrevivia na esfera
   corrigida.

   Escrevendo, o hero encolhe para uma assinatura: marca pequena, título em
   uma linha, subtítulo fora. Ele já fez o trabalho dele — agora a tela é da
   conversa. Recolhe também quando a conversa engrena (ver `.conversa-andando`
   em conversa.js): a partir da segunda fala, o hero é enfeite ocupando o
   lugar do que importa. */
.topo-onboarding,
.topo-onboarding .hebraico,
.topo-onboarding h1,
.topo-onboarding p,
.passos { transition: all .28s cubic-bezier(.3, .9, .35, 1); }

body.teclado-aberto .topo-onboarding,
.conversa-andando .topo-onboarding {
  flex-direction: row; align-items: center; gap: 12px;
  padding: 6px 0 10px; text-align: left;
}
body.teclado-aberto .topo-onboarding .hebraico,
.conversa-andando .topo-onboarding .hebraico {
  font-size: 22px; text-shadow: none;
}
body.teclado-aberto .topo-onboarding h1,
.conversa-andando .topo-onboarding h1 { font-size: 17px; }
body.teclado-aberto .topo-onboarding p,
.conversa-andando .topo-onboarding p,
body.teclado-aberto .topo-onboarding #pular-por-agora,
.conversa-andando .topo-onboarding #pular-por-agora {
  /* O subtítulo e a saída somem do fluxo: altura zero, sem deixar buraco. */
  height: 0; opacity: 0; overflow: hidden; margin: 0; pointer-events: none;
}
body.teclado-aberto .passos,
.conversa-andando .passos { padding-bottom: 8px; font-size: 11px; }
body.teclado-aberto .passos .passo i,
.conversa-andando .passos .passo i { width: 17px; height: 17px; font-size: 10px; }

@media (prefers-reduced-motion: reduce) {
  .topo-onboarding, .topo-onboarding *, .passos { transition: none; }
}

/* ═════════════════════════════════ o topo do Chazon (tela cheia) ═════════
   Entrar no Chazon é entrar numa conversa: a barra de cinco menus sai, e o
   voltar traz de volta — o desenho do WhatsApp, que o André pediu. A chave
   "Conversar / O que ele sabe" fica ao lado do voltar, e não mais sozinha
   ocupando a largura toda. */
.topo-chat {
  display: flex; align-items: center; gap: 10px;
  /* Baixo: ele é a moldura da conversa, não um cabeçalho. O respiro de baixo
     vem do fade, que faz a primeira bolha emergir em vez de bater numa linha. */
  padding: 0 0 3px;
  /* Ele SOME e VOLTA deslizando (ver a regra do teclado, mais abaixo). */
  transition: height .22s cubic-bezier(.3,.9,.35,1), opacity .16s ease,
              margin .22s cubic-bezier(.3,.9,.35,1);
  overflow: hidden;
}
/**
 * O FADE É UMA MÁSCARA, NÃO UMA COR.
 *
 * Pintar um gradiente de `--noite` por cima parecia o caminho — e desenhava um
 * retângulo escuro sobre a bruma, que é justamente o defeito que este projeto
 * já tinha combatido em outro lugar. A bruma se move e muda de cor; nenhuma
 * cor fixa acompanha.
 *
 * A máscara apaga o CONTEÚDO em vez de cobri-lo: a conversa some ao passar sob
 * a chave, e o fundo continua sendo o fundo. É o mesmo efeito de borda de
 * rolagem que o iOS usa.
 */
.chat-rolagem {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10px);
  mask-image: linear-gradient(180deg, transparent 0, #000 10px);
}
.topo-chat .chave-topo { flex: 1; margin: 0; }
.topo-chat .redondo { flex: 0 0 auto; }

/* A chave da conversa é menor que a das telas de conteúdo: aqui ela divide a
   linha com o voltar, e o assunto da tela é o que está EMBAIXO dela. */
/* 34px de altura: a mesma de um seletor segmentado do iOS. A regra dos 44px
   vale para alvos pequenos; estes ocupam meia largura da tela cada, e ninguém
   erra o toque neles. */
/* O voltar tinha 44px contra 34 da chave — ele sozinho definia a altura da
   barra, e os 10px de diferença eram ar puro. Alvo de toque continua honesto:
   ele ganha área invisível pelo ::before. */
.topo-chat .redondo {
  width: 34px; height: 34px; min-width: 34px; min-height: 34px;
  position: relative;
}
.topo-chat .redondo::before {
  content: ''; position: absolute; inset: -5px; border-radius: 50%;
}
.topo-chat .chave { padding: 2px; border-radius: 11px; }
.topo-chat .chave button, .topo-chat .chave a {
  font-size: 12.5px; padding: 6px; min-height: 34px; border-radius: 9px;
}
.topo-chat .redondo svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* Sem barra de menus, o rodapé reservado para ela também sai. */
/**
 * A ÁREA SEGURA DE BAIXO TEM UM DONO SÓ — e é o form.
 *
 * Ela estava contada DUAS vezes: aqui no `#app` e de novo no `padding` do
 * form. No desktop somava 16px e ninguém via; no iPhone, onde a área segura
 * vale 34px, viravam quase 70px de vazio embaixo da caixa de escrever.
 *
 * Quem fica por último na coluna é o form, então é ele quem reserva o espaço
 * do indicador de início. Aqui, zero.
 */
#app:has(.topo-chat) { padding-bottom: 0; }

/* ═══════════════════════════════════════════ a barra de rolagem ══════════
   Ela some. No iPhone a barra do sistema já é um fio que aparece ao rolar e
   se apaga sozinho; no desktop, a barra clara do navegador cortava a bruma
   com uma faixa vertical — e a conversa, que é uma coluna que rola por
   dentro, ganhava uma cicatriz na borda direita.

   `scrollbar-width: none` cobre Firefox e o Chrome novo; o pseudo-elemento
   cobre o WebKit. A rolagem continua inteira: só o desenho dela sai. */
.chat-rolagem,
#chat-proposta,
.dlg-texto,
body {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.chat-rolagem::-webkit-scrollbar,
#chat-proposta::-webkit-scrollbar,
.dlg-texto::-webkit-scrollbar,
body::-webkit-scrollbar {
  width: 0;
  height: 0;
  background: transparent;
}

/* ==================================================== AUDITORIA DE LAYOUT ===
   Consertos que saíram de uma varredura tela a tela em 375px — a largura em
   que o app é realmente usado. Aditivo no fim do arquivo, pela mesma razão de
   sempre: some sem desfazer nada acima.
   ========================================================================== */

/**
 * A LINHA DE AÇÃO DESCE EM VEZ DE ESPREMER O TEXTO.
 *
 * `.item` é `display:flex`, e um `.linha` de botões dentro dele nunca encolhe
 * (`min-width:auto` é o padrão de item flex). Quem cedia era sempre o texto: em
 * Tarefas, "Escrever 20 minutos" ficava com 32% da largura e virava uma coluna
 * de duas palavras por linha, com o subtítulo em quatro. O conteúdo perdendo
 * espaço para os controles é a inversão exata da prioridade.
 *
 * Abaixo de 420px — quer dizer, em todo celular — o texto toma a linha inteira
 * e os botões descem para a sua, alinhados à direita. Nenhuma marcação muda.
 */
@media (max-width: 420px) {
  .item:has(> .linha) { flex-wrap: wrap; }
  .item:has(> .linha) > .item-corpo { flex: 1 1 100%; }
  .item > .linha { width: 100%; justify-content: flex-end; margin-top: 2px; }
}

/**
 * O par "título + botão" pode virar duas linhas, mas o botão não se parte.
 *
 * `.entre` é space-between sem quebra: em 375px, "Apareceu alguma coisa" ao
 * lado de "Contar pra ele" espremia o botão até ele quebrar no meio do próprio
 * rótulo — duas linhas dentro de uma cápsula, que lê como defeito.
 */
.entre { flex-wrap: wrap; }
.entre > .botao { white-space: nowrap; }

/**
 * QUARENTA E QUATRO É O PISO, e o ✕ de remover estava com 37 de largura.
 *
 * Ele é o único botão destrutivo da lista e o mais fácil de errar — errar aqui
 * apaga uma tarefa. Os outros alvos pequenos do app (a caixa de marcar, o
 * "corrigir") já esticam a área tocável por `::before`; este não tinha nada.
 */
[data-apagar] { min-width: 44px; }

/* O chip parava em 42px por conta do padding — dois pixels abaixo do piso. */
.chip { min-height: 44px; }

/* ======================================================= AS TRÊS PORTAS ===
   A landing passou a ter Apple, Google e e-mail. A ordem não é estética: a
   diretriz 4.8 exige o Sign in with Apple em pé de igualdade com os outros
   logins sociais — não menor, não escondido, não atrás de "mais opções".
   ========================================================================== */

.landing-porta .botao-porta,
.landing-porta .botao-apple {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 50px; font-size: 15px; margin-bottom: 10px;
}

/* O botão da Apple é preto com texto branco nos dois temas — é a única marca
   do app cuja aparência é ditada por quem a licencia. */
.botao-apple { background: #000; color: #fff; border: 1px solid #000; }
.botao-apple:hover:not(:disabled) { background: #1a1a1a; }
.botao-apple .marca-porta { fill: #fff; }

.marca-porta { width: 18px; height: 18px; flex: 0 0 18px; }

/**
 * `[hidden]` PERDE PARA `display` — e é por isso que o formulário nascia aberto.
 *
 * O atributo `hidden` é só `display: none` vindo da folha do navegador, e
 * qualquer `display` declarado por nós vence. A regra do formulário precisa,
 * portanto, excluir o estado escondido; a alternativa preguiçosa
 * (`display: none !important`) esconderia o problema em vez de resolvê-lo.
 */
#porta-email:not([hidden]) { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
#porta-email input { width: 100%; }
#porta-email button[type="submit"] { min-height: 50px; }

/* A linha do aceite é a única do app que precisa ser lida antes de um toque —
   por isso ela não usa o cinza mais apagado. */
.landing-porta .aceite { color: var(--calmo); margin-top: 14px; }
.landing-porta .aceite a { color: var(--luz); }

/* ==================================================== SINALIZAR A RESPOSTA ===
   Um caminho para dizer "isto que ele falou saiu errado". Discreto de propósito:
   ele mora na bolha, não compete com a leitura, e só aparece nas falas dele.
   ========================================================================== */

.fala-chazon { position: relative; }

.sinalizar {
  position: absolute; top: 2px; right: 4px;
  width: 28px; height: 28px; min-height: 28px; padding: 0;
  line-height: 1; font-size: 15px; letter-spacing: .06em;
  background: transparent; border: none; color: var(--fraco);
  opacity: .45; transition: opacity .15s ease, color .15s ease;
}
.sinalizar:hover:not(:disabled) { opacity: 1; color: var(--calmo); }
.sinalizar:disabled { opacity: .2; }

/* O alvo é 44px; o desenho é 28. Mesma receita da caixa de marcar e do voltar. */
.sinalizar::before {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}

/* ========================================================== O FIO ETERNO ===
   As mensagens antigas, acima da janela viva. Um pouco mais apagadas — são
   passado — e a linha de aplicação é registro, não fala: sem bolha.
   ========================================================================== */

.fio-antigo { opacity: .74; }

.fio-aplicacao {
  text-align: center; font-size: 12.5px; color: var(--fraco);
  margin: 10px 0; letter-spacing: .02em;
}

/* ================================================= A GALERIA DE PERSONAS ===
   O ícone do cérebro é decoração ao lado do nome — sem tamanho declarado, um
   SVG inline cresce até o natural e engole o cartão inteiro (bug pego no
   arranjo). O traço herda a cor do texto.
   ========================================================================== */

.persona-icone {
  width: 22px; height: 22px; flex: none;
  color: var(--calmo, currentColor);
}

/* ============================================================ A AGENDA v2 ===
   Quatro olhares (25/08): o dia em pé + ticker, a corrida, a semana deitada.
   As regras de tinta: nada vermelho; horas SEMPRE tabulares; alvo de toque
   nunca abaixo de 44px; poucas cores, todas com dono (o fio da área).
   ========================================================================== */

:root {
  --ag-salvia: #9DB89D;
  --ag-lilas:  #B4A6CE;
}

.ag-seletor { margin-top: 16px; }
.ag-seletor a { min-height: 44px; }

/* ------------------------------------------------------------- o ticker -- */

.tk-confronto {
  text-align: center; font-size: 12.5px; color: var(--calmo);
  margin: 2px 0 10px; letter-spacing: .01em;
}
.tk-confronto b { color: var(--calmo); font-weight: 600; }

.tk-fita { display: flex; gap: 4px; margin: 0 0 14px; }
.tk-dia {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center;
  padding: 7px 2px 8px; border-radius: 12px; border: 1px solid transparent;
  text-decoration: none; min-height: 44px;
}
.tk-hoje { background: var(--vidro-alto); border-color: var(--borda); }
.tk-letra { font-size: 10px; color: var(--calmo); text-transform: uppercase; letter-spacing: .08em; }
.tk-n {
  font-family: var(--display); font-size: 17px; color: var(--texto);
  line-height: 1.25; font-variant-numeric: tabular-nums;
}
.tk-pills { position: relative; width: 100%; height: 26px; margin-top: 2px; }
.tk-pills i {
  position: absolute; left: 24%; right: 24%; height: 3.5px; border-radius: 2px;
  background: var(--luz); opacity: .85;
}
.tk-brasa {
  position: absolute; right: 12%; bottom: 0; width: 5px; height: 5px;
  border-radius: 50%; background: var(--brasa);
}
.tk-min { font-size: 10px; color: var(--calmo); margin-top: 2px; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------- a prateleira -- */

.prateleira { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 14px; }
.chip-acao { border-style: solid; }
.chip-acao.assentada { opacity: .55; }
.chip-acao.assentando { transition: opacity .35s ease, transform .35s ease; transform: translateY(1px); }
.chip-pendente b { color: var(--brasa); font-weight: 500; }

/* ------------------------------------------------------------ o dia em pé */

.tl { padding: 14px 14px 16px; }
.tl-linha { display: flex; gap: 10px; align-items: stretch; }
.tl-hora {
  flex: none; width: 48px; min-height: 44px; align-self: flex-start; padding-top: 9px;
  background: none; border: 0; color: var(--calmo); text-align: right;
  font-family: var(--ui); font-size: 12px; font-variant-numeric: tabular-nums;
  cursor: grab; touch-action: none; border-radius: 10px;
}
.tl-hora.hora-viva { color: var(--luz-forte); background: var(--vidro); cursor: grabbing; }
.tl-bloco {
  position: relative; flex: 1; text-align: left; border-radius: 14px;
  background: var(--vidro-alto); border: 1px solid var(--borda);
  padding: 9px 12px 8px 14px; margin: 2px 0; color: var(--texto);
  display: flex; flex-direction: column; justify-content: flex-start; gap: 1px;
  font-family: var(--ui);
}
.tl-fio { position: absolute; left: 0; top: 9px; bottom: 9px; width: 2.5px; border-radius: 2px; }
.tl-texto { font-size: 14px; }
.tl-sub { font-size: 11.5px; color: var(--calmo); }
.tl-evid { font-size: 11.5px; color: var(--calmo); margin-top: 3px; }
.tl-evid.brasa { color: var(--brasa); }

.tl-vao { min-height: 4px; }
.tl-dobra {
  display: block; width: calc(100% - 58px); margin: 6px 0 6px 58px;
  min-height: 44px; background: none; color: var(--calmo); font-size: 11.5px;
  border: 0; border-top: 1px dashed var(--borda); border-bottom: 1px dashed var(--borda);
  border-radius: 0;
}
.tl-dobra:hover { color: var(--calmo); }

.tl-agora { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
.tl-agora span {
  font-family: var(--display); color: var(--brasa); font-size: 12.5px;
  font-variant-numeric: tabular-nums; width: 48px; text-align: right; flex: none;
}
.tl-agora i {
  flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--brasa), rgba(217, 142, 106, .08));
}

/* -------------------------------------------------------------- a corrida */

.ag-corrida { padding: 6px 16px 16px; }
.cr-cab {
  display: flex; align-items: baseline; gap: 9px; margin: 16px 0 4px;
  min-height: 44px; text-decoration: none;
}
.cr-n {
  font-family: var(--display); font-size: 26px; color: var(--texto);
  font-variant-numeric: tabular-nums;
}
.cr-nome { font-size: 11px; color: var(--calmo); text-transform: uppercase; letter-spacing: .1em; }
.cr-item {
  display: flex; gap: 12px; width: 100%; text-align: left; background: none;
  border: 0; border-bottom: 1px solid var(--separador);
  padding: 9px 0; min-height: 44px; color: var(--texto); font-family: var(--ui);
  border-radius: 0;
}
.cr-item:last-of-type { border-bottom: 0; }
.cr-hora {
  flex: none; width: 44px; text-align: right; color: var(--calmo);
  font-size: 12.5px; font-variant-numeric: tabular-nums; padding-top: 2px;
}
.cr-corpo { position: relative; flex: 1; padding-left: 10px; }
.cr-fio { position: absolute; left: 0; top: 3px; bottom: 3px; width: 2.5px; border-radius: 2px; }
.cr-texto { display: block; font-size: 14px; }
.cr-sub { display: block; font-size: 11.5px; color: var(--calmo); margin-top: 1px; }
.cr-livres {
  display: block; width: 100%; background: none; border: 0; min-height: 44px;
  border-top: 1px dashed var(--borda); border-bottom: 1px dashed var(--borda);
  color: var(--calmo); font-size: 11.5px; font-style: italic; margin: 10px 0;
  border-radius: 0;
}
.cr-rodape { font-size: 12px; color: var(--calmo); margin: 14px 0 0; }
.cr-rodape.brasa { color: var(--brasa); }


/* -------------------------------------------- o botão de visão e o menu -- */

/* Os controles ficam NO CANTO, sempre.
   `.entre` ganhou `flex-wrap: wrap` lá embaixo para o par "título + botão"
   das LISTAS poder virar duas linhas sem partir o rótulo do botão. No TOPO
   isso tem o efeito oposto do desejado: com um título longo ("Agosto de
   2026"), a dupla de controles descia para o meio da tela — justamente o
   botão que o André pediu no canto. Aqui quem cede é o título, que quebra o
   próprio texto; os botões não se movem. */
.topo .entre { flex-wrap: nowrap; }
.topo .entre > div:first-child { min-width: 0; }
.topo .entre > .linha { flex: none; align-self: flex-start; }

.ag-visao { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
.ag-visao svg { opacity: .7; }

.dlg-visoes .lista { margin-top: 4px; }
.ag-visao-opcao {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; text-align: left; background: none; border: 0;
  padding: 10px 12px; border-radius: 12px; min-height: 44px;
}
.ag-visao-opcao[aria-current="page"] { background: var(--vidro-alto); }
.ag-visao-opcao[aria-current="page"] .item-titulo { color: var(--luz-forte); }

/* ---------------------------------------------------------------- o mês -- */

.mes { padding: 14px 12px 16px; }
.mes-cabeca { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
/* Sem `capitalize`: ele maiúscula o "de" de "agosto de 2026" também. Quem
   sabe capitalizar um nome de mês é quem o escreve, no JS. */
.mes-nome { font-family: var(--display); font-size: 15px; color: var(--texto); }
button.mes-nome { font-family: var(--ui); font-size: 13px; }
.mes-semana, .mes-grade { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.mes-semana span {
  text-align: center; font-size: 9.5px; color: var(--calmo);
  text-transform: uppercase; letter-spacing: .06em; padding-bottom: 5px;
}
.mes-vazio { aspect-ratio: 1; }
.mes-dia {
  aspect-ratio: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; padding: 0; border: 1px solid transparent;
  background: none; border-radius: 11px; min-height: 40px;
}
.mes-n {
  font-family: var(--display); font-size: 14.5px; color: var(--calmo);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.mes-hoje .mes-n { color: var(--brasa); font-weight: 600; }
.mes-aberto { background: var(--vidro-alto); border-color: var(--borda); }
.mes-aberto .mes-n { color: var(--texto); }

/* A altura é fixa para os números não dançarem entre linhas com e sem marca. */
.mes-marcas { display: flex; align-items: center; justify-content: center; gap: 2.5px; height: 5px; }
.mes-ponto { width: 4px; height: 4px; border-radius: 50%; background: var(--luz); opacity: .8; }
/* O rastro: uma barrinha cuja força é o que aconteceu naquele dia. Nunca
   vermelho, nunca zero visível — dia sem nada simplesmente não acende. */
.mes-rastro { width: 16px; height: 3.5px; border-radius: 2px; background: var(--brasa); }
.mes-legenda { font-size: 10.5px; color: var(--calmo); margin: 14px 4px 0; line-height: 1.45; }

/* ------------------------------------------------- a agenda do aparelho -- */

.tl-conectar { padding: 14px 16px; margin-bottom: 14px; }
.tl-evento {
  background: transparent; border: 1px dashed var(--tracejado);
  color: var(--calmo);
}
.tl-hora-parada { cursor: default; touch-action: auto; display: block; }
.chip-evento { border-style: dashed; color: var(--calmo); }
.cr-evento { opacity: .85; }
.cr-selo-agenda {
  font-size: 10px; border: 1px dashed var(--tracejado);
  border-radius: 6px; padding: 1px 6px; margin-left: 6px;
  color: var(--calmo); vertical-align: 1px;
}
.tk-evk { opacity: .45; }

/* ============================================================ TEMA PRÁTICO ===
   A opção que o André pediu (26/08): "um layout mais funcional, sem esse
   azul — mais prático, mais limpo". Papel claro, cartões brancos e chatos,
   sem bruma, sem vidro; a brasa continua sendo a única cor quente,
   escurecida para valer no branco. Liga por body[data-tema="pratico"].

   O BLOCO É SÓ DE TOKENS, e é assim que ele tem que continuar. Cada regra
   por componente aqui embaixo é uma dívida: significa que algum lugar do app
   pintou cor na unha em vez de ler um token — conserte LÁ, não aqui.
   ========================================================================== */

body[data-tema="pratico"] {
  --noite:      #F4F5F7;
  --noite-2:    #ECEEF1;
  --vidro:      #FFFFFF;
  --vidro-alto: #EDF0F4;
  --borda:      rgba(20, 30, 46, .10);
  --borda-viva: rgba(20, 30, 46, .24);
  --texto:      #1B2432;
  --calmo:      #46536A;
  --fraco:      #5C6779;   /* 4,7:1 no pior fundo (o trilho das chaves) */
  --luz:        #51617A;
  --luz-forte:  #2C3A50;
  --brasa:      #9C5229;   /* a mesma brasa, escurecida para valer no branco */
  --sombra:     0 2px 10px rgba(20, 30, 46, .07);

  /* As superfícies de toque, no claro: tinta escura sobre papel, nunca o
     contrário — vidro branco translúcido em papel branco é um botão que
     desaparece. */
  --toque:       rgba(20, 30, 46, .05);
  --toque-alto:  rgba(20, 30, 46, .09);
  --toque-vivo:  rgba(20, 30, 46, .13);
  --toque-fraco: rgba(20, 30, 46, .04);
  --campo:       #FFFFFF;
  --separador:   rgba(20, 30, 46, .08);
  --afundado:    rgba(20, 30, 46, .035);
  --fosso:       rgba(20, 30, 46, .06);
  --fade:        244, 245, 247;
  --tracejado:   rgba(20, 30, 46, .34);
  --capsula:     #FFFFFF;
  --capsula-viva: #FFFFFF;
  --principal-fundo: #2C3A50;
  --principal-texto: #FFFFFF;
}

/* A bruma é a alma do tema escuro — no prático ela simplesmente não existe. */
body[data-tema="pratico"] #bruma { display: none; }

/* O cartão ganha SOMBRA no lugar da borda de vidro: é o que separa papel de
   papel. Único componente que muda de natureza entre os temas. */
body[data-tema="pratico"] .cartao {
  background: #FFFFFF;
  box-shadow: var(--sombra);
}

/* O bloco da timeline é um cartão dentro do cartão: no papel ele precisa da
   mesma sombra fina para não virar um retângulo chapado sobre outro. */
body[data-tema="pratico"] .tl-bloco { box-shadow: 0 1px 4px rgba(20, 30, 46, .06); }

/* A esfera é a marca, e ela brilha: no papel claro o halo azul vira sujeira.
   Ela mantém o corpo e perde o brilho — presença sem neon. */
body[data-tema="pratico"] .esfera,
body[data-tema="pratico"] .nav .esfera-link[aria-current="page"] .esfera {
  box-shadow: 0 2px 10px rgba(20, 30, 46, .18), inset 0 -3px 8px rgba(20, 30, 46, .12);
}
body[data-tema="pratico"] .esfera-mini {
  box-shadow: 0 1px 5px rgba(20, 30, 46, .16), inset 0 -2px 5px rgba(20, 30, 46, .12);
}
body[data-tema="pratico"] .esfera-grande,
body[data-tema="pratico"] .esfera-abrindo {
  box-shadow: 0 8px 26px rgba(20, 30, 46, .16), inset 0 -12px 26px rgba(20, 30, 46, .10);
}
body[data-tema="pratico"] .capsula { box-shadow: 0 1px 6px rgba(20, 30, 46, .07); }
