/* ============================================================
   tryzen — reset + base mobile
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

/* ============================================================
   A troca de tema com o circulo
   ------------------------------------------------------------
   O par em CSS do `revelarEmCirculo()` do js/tema.js, que e o
   AnimatedThemeToggler do MagicUI portado. Sao duas regras, e as duas
   so valem ENQUANTO a troca acontece (`data-vt-tema="ativo"`), pra
   nenhuma outra view transition do futuro herdar isso sem querer.

   `animation: none` desliga o cruzado que o navegador faz sozinho
   entre as duas fotos: quem revela aqui e o recorte, e o cruzado por
   cima dele lava o efeito. `mix-blend-mode: normal` pelo mesmo
   motivo — o padrao mistura as duas camadas, e o tema novo apareceria
   desbotado em cima do velho.

   O `clip-path` aqui e o circulo FECHADO. Ele segura a tela nova
   escondida no quadro entre a foto e o comeco da animacao; o
   `animate()` do JS assume dali e abre o circulo.
   ============================================================ */
:root[data-vt-tema="ativo"]::view-transition-old(root),
:root[data-vt-tema="ativo"]::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

:root[data-vt-tema="ativo"]::view-transition-new(root) {
  clip-path: var(--vt-corte);
}

:root[data-vt-tema="ativo"]::view-transition-group(root) {
  animation-duration: var(--vt-dur);
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* `pan-x pan-y` = rola pra tudo que e lado, mas NAO amplia: mata a
     pinca e o toque duplo na pagina inteira. E o par do `user-scalable=no`
     do viewport (index.html) no lado do Chrome/Android, onde o gesto
     nasce no elemento e nao no documento.
     Nao vira `none`: `none` mataria tambem a rolagem. E nao impede o
     `touch-action: none` da previa do mapa (css/screens.css), que e mais
     restritivo e continua valendo no elemento dele. */
  touch-action: pan-x pan-y;
}

/* ---------- na CONVERSA a pagina nao rola; quem rola e a tela ----------
   Pedido do dono (22/09/2026): "tem como abaixar e quebra a logica de
   CSS do site (...) no chat da pra ficar movimentando pra cima e pra
   baixo".

   Nao era conteudo sobrando: no chat a pagina tem exatamente a altura
   da janela (medido). O que se mexia era a BORRACHA do navegador — o
   elastico do fim da rolagem. E ele mexe so no conteudo: a tab bar e o
   campo sao `fixed` e `sticky`, ficam parados, e o que se ve e a tela
   descolando das duas barras.

   O `overscroll-behavior` do `body` (logo abaixo) resolve isso no
   Chrome do Android e NAO resolve no Safari: no iPhone a regra so vale
   dentro de um elemento que rola, nunca pra pagina. Enquanto quem
   rolasse fosse o documento, o gesto continuaria existindo. Entao na
   conversa o documento para de rolar, e quem rola passa a ser o
   `#view`, que e um elemento — e ai a regra vale nos dois.

   ---------- por que SO na conversa ----------
   Por um dia isto valeu pro app inteiro, e o dono viu telas cortadas
   embaixo. Travar a pagina tem um preco que so aparece no celular: a
   barra de endereco recolhe quando a pagina rola, e devolve uns 60px
   de altura. Numa pagina que nao rola ela fica pra sempre, e a tela
   inteira passa a viver com esses 60px a menos. Numa conversa isso nao
   custa nada (a lista rola por dentro); nas outras telas custa o pe da
   tela. Decisao dele, 22/09/2026: "poderia deixar isso so na parte de
   chat, o restante estava tudo certo".

   ---------- quem liga e a propria tela ----------
   A chave e o `.screen--travada` na marcacao (hoje so
   js/screens/chat.js). Nao ha classe no `body` nem lista de rotas no
   router: a tela que precisa pede, e o `:has` responde. Quem tem `:has`
   e quem entende `dvh` sao praticamente os mesmos navegadores; o que
   nao tem simplesmente rola a pagina, que e o que ele fazia ontem.

   ⚠️ QUEM MEXER EM ROLAGEM: `scrollY`, `scrollTo()` e
   `document.body.scrollHeight` valem numa tela e nao valem na outra.
   Use js/rolagem.js, que pergunta quem rola antes de cada gesto.      */
html:has(.screen--travada),
html:has(.screen--travada) body { height: 100%; overflow: hidden; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  /* Numero de largura fixa em todo o app. A Inter substituiu a mono nos dados
     (pace, tempo, splits, ranking) e, proporcional, faria a coluna dancar a
     cada digito. Herda pra tudo: aqui numero e dado, nao texto corrido. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior-y: none;
  /* Vale pros PAINEIS, que leem este arquivo e continuam rolando a
     pagina: tabela larga nao pode empurrar o painel pro lado. No app o
     `overflow: hidden` la de cima ja cobre os dois eixos. */
  overflow-x: hidden;
}

/* comportamento de app: sem selecao acidental, sem flash de toque */
body, .tabbar, .btn, .icon-btn, .row, .opt, .chip {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
input, textarea, [contenteditable] { -webkit-user-select: text; user-select: text; }

/* O `hidden` do HTML tem que vencer o display de qualquer componente.
   A regra do navegador e `[hidden] { display: none }` com especificidade
   0-1-0: ela perde pra QUALQUER classe — `.btn { display: flex }`,
   `.chip { display: grid }`, `.tabbar { display: flex }` — e o elemento
   fica na tela com o atributo ligado, que e um jeito silencioso de
   quebrar. Uma regra pra todos, aqui, em vez de um `.x[hidden]` por
   componente (a tab bar ja precisava do dela). */
[hidden] { display: none !important; }

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

a { color: inherit; text-decoration: none; }

input, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  outline: none;
  width: 100%;
  border-radius: 0;      /* mata o arredondamento nativo do iOS */
  -webkit-appearance: none;
  appearance: none;
}
input::placeholder, textarea::placeholder { color: var(--text-3); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- a abertura ----------
   O logo que cobre o app enquanto a primeira tela e montada. A marcacao
   esta no index.html (o porque esta la); aqui esta o desenho, e em
   js/abertura.js a hora de sair.

   PARADA de proposito (27/09/2026, pedido do dono): a abertura animada
   segurava a tela por 0,8 s, ou 1,6 s na primeira vez do dia, mesmo com
   o app pronto atras dela. Agora ela so cobre o tempo que o app leva de
   verdade pra pintar, e sai assim que ele pinta. Marca parada nao pede
   tempo minimo: nao ha animacao pela metade pra esperar terminar. */

.abertura {
  position: fixed;
  inset: 0;
  /* acima de tudo: tab bar (40), folhas (80/85), toast (90/95) */
  z-index: 100;
  display: grid;
  place-items: center;
  background: var(--bg);
}

/* a saida: um fade curto, so pra troca nao ser um corte seco */
.abertura--sai {
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s linear;
}

/* As medidas sao as do arquivo da marca, na mesma conta do `logotipo()`
   (js/ui.js): com o corredor em 54px, a palavra tem 0.8404 disso (45.4)
   e o vao entre os dois 0.3009 (16.2). Alinha pela BASE porque o
   corredor e um desenho em pe. */
.abertura__marca {
  display: flex;
  align-items: flex-end;
  gap: 16.2px;
  line-height: 0;      /* SVG e imagem sao inline: mata a entrelinha */
}

.abertura__glifo {
  flex: none;
  width: 38px;
  height: 54px;
}

/* O nome e o arquivo da marca usado como MASCARA, e nao como imagem:
   assim o desenho e um so (assets/marca/nome.svg) e a cor sai do tema,
   preto no claro e branco no escuro. Imagem nenhuma herda cor. */
.abertura__nome {
  flex: none;
  width: 161.5px;                       /* 45.4 x 3.5584, a razao do nome */
  height: 45.4px;
}
/* Fundo pintado so onde a mascara existe: sem ela, `--text` viraria um
   retangulo preto no meio da abertura. */
@supports ((-webkit-mask-image: url(a.svg)) or (mask-image: url(a.svg))) {
  .abertura__nome {
    background: var(--text);
    -webkit-mask: url(../assets/marca/nome.svg) no-repeat center / contain;
    mask: url(../assets/marca/nome.svg) no-repeat center / contain;
  }
}

/* ---------- o recado de quando a tela nao veio ----------
   Entra no lugar da marca, dentro da propria cortina (js/abertura.js).
   Mora AQUI, e nao no components.css, pelo mesmo motivo da abertura:
   esta folha e a que o app tem quando nada mais deu certo, e o recado
   precisa estar desenhado justamente nessa hora. O botao e o `.btn
   .btn--primary` de sempre, porque ha uma identidade so no app. */
.abertura__socorro {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 0 32px;
  max-width: 360px;
  text-align: center;
}
.abertura__socorro-t {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}
.abertura__socorro-p {
  font-size: 15px;
  line-height: 1.45;
  color: var(--text-2);
}
.abertura__socorro .btn { margin-top: 12px; }

@media (prefers-reduced-motion: reduce) {
  .abertura--sai { transition: none; }
}

/* ---------- estrutura do app ---------- */

#app {
  min-height: 100vh;   /* fallback: iOS < 15.4 nao entende dvh */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
/* Na conversa a altura e FECHADA, e nao minima: e dela que sai a altura
   do `#view`, e um `min-height` deixaria a altura em aberto — o `#view`
   cresceria com o conteudo em vez de rolar por dentro. */
body:has(.screen--travada) #app {
  height: 100vh;
  height: 100dvh;
}

#view {
  flex: 1;
  position: relative;
  min-height: 0;
  /* a tela entra deslizando pela direita: recorta a sobra para
     nao gerar rolagem horizontal durante a transicao */
  overflow-x: clip;
}

/* ---------- o rolador da conversa ----------
   `overscroll-behavior-y: none` aqui e o que mata a borracha nos dois
   navegadores: num elemento que rola, o Safari respeita (ver o bloco no
   alto do arquivo).

   A barra nao e desenhada, como em toda faixa que rola no app (os
   chips, as abas, a roda): no celular ela ja era invisivel e, no
   computador, uma barra clara DENTRO da moldura de 430px seria uma peca
   que o app nunca teve — antes ela morava na beira da janela, fora
   dele.

   O `overflow-x: clip` de cima vira `hidden` sozinho aqui (regra do
   CSS: um eixo que rola nao convive com `clip` no outro), e recorta
   igual. */
body:has(.screen--travada) #view {
  overflow-y: auto;
  overscroll-behavior-y: none;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
body:has(.screen--travada) #view::-webkit-scrollbar { display: none; }

/* ---------- a faixa da barra de status (12/10/2026) ----------
   Pedido do dono: no app das lojas, a parte de cima (hora, bateria,
   notificacoes) estava transparente, e o conteudo passava por tras dela
   ao rolar. O app e edge-to-edge (`viewport-fit=cover`), e do Android 15
   em diante o sistema nao pinta mais essa barra: quem pinta e o app. A
   tela ja reservava o espaco (`--safe-top` no `.screen`), mas reservar
   nao e pintar: a pagina rola, e o texto subia pra baixo do relogio.

   E a mesma solucao da faixa de baixo (`.tabbar::after`, em
   css/components.css): os `--safe-top` do alto sao opacos e da cor do
   fundo do tema, presos na janela. Onde nao ha barra do sistema pra
   reservar (o site no navegador), a altura e zero e a faixa nao existe.

   Fica acima do conteudo e da tab bar (40) e abaixo de tudo que cobre a
   tela inteira de proposito: as folhas e o convite (80), o aviso (90) e
   a abertura (100) escurecem ou pintam ate o topo por conta propria. */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--safe-top);
  background: var(--bg);
  z-index: 45;
  pointer-events: none;
}

/* cada tela e uma "screen": rola sozinha, respeita safe-areas */
/* `100dvh` vale nos dois modos: na conversa o `#view` tem exatamente
   essa altura, e em toda outra tela e a janela que manda, como sempre. */
.screen {
  display: flex;
  flex-direction: column;
  min-height: 100vh;   /* fallback */
  min-height: 100dvh;
  padding-top: calc(var(--safe-top) + 20px);
  padding-bottom: var(--safe-bottom);
}
.screen--tabbed {
  padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom));
}

/* corpo rolavel da tela.
   O padding-bottom e a "margem de seguranca" do fim da lista: sem ele o
   ultimo item encosta na tab bar (ou no rodape) e a tela parece cortada. */
.body {
  flex: 1;
  padding: 0 var(--pad) var(--gap-md);
  min-height: 0;
}
.body--flush { padding: 0 0 var(--gap-md); }

/* rodape fixo no fim da tela (botao Continuar etc.)

   ---------- o respiro entre os botoes mora AQUI ----------
   Era cada tela que escrevia `mt-sm` no segundo botao a mao, e bastava
   um botao condicional entrar na frente pra pilha aparecer colada: na
   tela do treino, "Divulgar este treino" e "Registrar outro treino" sao
   os dois `btn--outline`, e sem folga as duas bordas arredondadas se
   encaixam uma na outra como se fossem uma peca so.

   Com o rodape virando coluna flex, o espaco passa a ser do CONTAINER:
   quem entra ganha folga por existir, e nenhuma tela precisa lembrar.
   O `gap` tambem ignora quem esta com `hidden` (a tela de correr esconde
   tres botoes e mostra um), coisa que margem no irmao seguinte nao faz.

   O `mt-sm` que ja estava escrito nas telas e zerado logo abaixo: os
   dois se somariam e abririam 20px onde sempre foram 10. */
.footer {
  display: flex;
  flex-direction: column;
  gap: var(--gap-sm);
  padding: var(--gap-md) var(--pad) calc(var(--gap-md) + 4px);
  background: linear-gradient(to top, var(--bg) 62%, transparent);
}
.footer > .mt-sm { margin-top: 0; }

/* ---------- tipografia ---------- */

.display {
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
  font-weight: 600;
}
.h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
  font-weight: 600;
}
.h2 {
  font-size: var(--fs-h2);
  line-height: 1.08;
  letter-spacing: var(--tr-tight);
  font-weight: 600;
}
.h3 {
  font-size: var(--fs-h3);
  line-height: 1.25;
  letter-spacing: -.015em;
  font-weight: 600;
}
.lg   { font-size: var(--fs-lg); line-height: 1.4; }
.body-t { font-size: var(--fs-body); line-height: var(--lh-body); }
.sm   { font-size: var(--fs-sm); line-height: 1.45; }
.xs   { font-size: var(--fs-xs); line-height: 1.4; }

.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tr-mono);
  font-weight: 400;
}
.mono-sm { font-family: var(--font-mono); font-size: var(--fs-mono-sm); letter-spacing: var(--tr-mono); }

/* cores utilitarias
   As de estado pedem sempre a variante -texto. A viva e clara demais pra
   carregar letra: no claro o verde da 2,2:1 sobre branco e o amarelo
   1,4:1 — os dois reprovam. Quem le e a -texto (>= 4,5:1). */
.c-1 { color: var(--text); }
.c-2 { color: var(--text-2); }
.c-accent { color: var(--certo-texto); }   /* esta certo */
/* Em titulo, o mesmo verde pode ser mais vivo: texto grande fecha em 3:1,
   nao em 4,5:1. Sem isto o tema claro ficava com um verde-garrafa no
   titulo enquanto o escuro usava o verde da marca — o mesmo texto com
   duas personalidades. So vale de .h2 pra cima (>= 27px); em .h3 (21px)
   ainda e texto miudo pra regra, e o verde fechado continua valendo. */
.display .c-accent, .h1 .c-accent, .h2 .c-accent,
.display.c-accent,  .h1.c-accent,  .h2.c-accent { color: var(--certo-titulo); }
.c-warn   { color: var(--acao-texto); }    /* precisa de voce agora */
.c-3      { color: var(--text-3); }        /* ja foi / incompleto */
.c-danger { color: var(--risco-texto); }   /* destrutivo */

.w-500 { font-weight: 500; }
.w-600 { font-weight: 600; }
.italic { font-style: italic; }

/* espacadores */
.mt-xs  { margin-top: var(--gap-xs); }
.mt-sm  { margin-top: var(--gap-sm); }
.mt     { margin-top: var(--gap); }
.mt-md  { margin-top: var(--gap-md); }
.mt-lg  { margin-top: var(--gap-lg); }
.mt-xl  { margin-top: var(--gap-xl); }
.mt-2xl { margin-top: var(--gap-2xl); }
.grow   { flex: 1; }

/* Fora da vista, dentro do DOM. Existe pro input de arquivo do cartao
   de divulgar: `display:none` faz alguns navegadores recusarem o
   `.click()` que abre o seletor, e `visibility:hidden` idem. Tirar do
   fluxo com 1px transparente e o unico jeito que funciona em todos, e
   ainda deixa o campo acessivel pra quem navega por teclado. */
.fora-da-tela {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Regua fina: a divisoria da identidade visual.
   Ela so funciona com vao dos DOIS lados. O de cima vem do .mt-* que a
   marcacao poe nela; o de baixo e este piso — por isso margin-bottom
   sozinho, e nao o atalho `margin`, que zeraria o .mt-* de cima. */
.rule {
  height: 1px;
  background: var(--border);
  border: 0;
  margin-top: 0;
  margin-bottom: var(--gap-md);
}

/* ============================================================
   OS IDIOMAS (27/09/2026)
   ------------------------------------------------------------
   O `lang` do <html> vem do js/i18n.js (e do script inline do
   index.html, antes do primeiro quadro). Daqui pra baixo, so o que
   muda de verdade quando a lingua muda:

   · CJK: a Figtree e a Inter so tem alfabeto latino. Elas continuam
     primeiro na fila (numero, "km" e nome proprio seguem na letra do
     app) e o ideograma cai na fonte do SISTEMA de cada lingua. O `lang`
     certo e o que faz o navegador escolher o desenho japones, coreano
     ou chines do mesmo caractere.
   · CJK nao leva o espaco negativo dos titulos (os ideogramas encostam
     uns nos outros) e pede entrelinha maior.
   · Coreano quebra linha entre palavras, nao no meio delas (keep-all);
     japones segue as regras de pontuacao (strict).
   · Alemao e frances tem palavra longa: titulo e texto hifenizam em vez
     de estourar a largura.
   ============================================================ */
:root:lang(zh) {
  --font:      'Figtree', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Noto Sans SC', sans-serif;
  --font-mono: 'Inter', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Noto Sans SC', sans-serif;
}
:root:lang(ja) {
  --font:      'Figtree', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Meiryo', 'Noto Sans CJK JP', 'Noto Sans JP', sans-serif;
  --font-mono: 'Inter', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Meiryo', 'Noto Sans CJK JP', 'Noto Sans JP', sans-serif;
}
:root:lang(ko) {
  --font:      'Figtree', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR', 'Noto Sans KR', sans-serif;
  --font-mono: 'Inter', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR', 'Noto Sans KR', sans-serif;
}
:root:lang(zh), :root:lang(ja), :root:lang(ko) {
  --tr-tight: 0;
  --tr-mono:  0;
  --lh-tight: 1.25;
  --lh-snug:  1.35;
  --lh-body:  1.7;
}
:lang(ko) body { word-break: keep-all; }
:lang(ja) body { line-break: strict; }
:lang(de) :is(h1, h2, h3, .h1, .h2, .body-t, .card__title, .row__title, .row__sub),
:lang(fr) :is(h1, h2, h3, .h1, .h2, .body-t, .card__title, .row__title, .row__sub) {
  hyphens: auto;
  overflow-wrap: break-word;
}
/* titulos em japones quebram por frase, nao no meio da palavra
   ("し/ますか"); navegador sem suporte ignora e segue como antes */
:lang(ja) :is(h1, h2, h3, .h1, .h2, .h3) { word-break: auto-phrase; }

/* ---------- a lista de TODO select no tema escuro (16/10/2026) ----------
   A lista aberta e desenhada pelo sistema e nao le as cores do app: no
   escuro ela saia branca com letra clara (o print do dono, no filtro
   "Prazo" do Workspace). O Coach ja avisava o tema so no select com
   .field__input; agora vale pra todo select do produto, nos dois jeitos
   de chegar no escuro (escolhido ou automatico). */
:root[data-tema="escuro"] select { color-scheme: dark; }
:root[data-tema="claro"] select { color-scheme: light; }
@media (prefers-color-scheme: dark) { :root:not([data-tema="claro"]) select { color-scheme: dark; } }
select option { background: var(--surface); color: var(--text); }
