/* MyBody 2.0 — base estrutural. Cores/efeitos vivem SÓ em aurum.css. */
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  background: var(--au-bg);
  color: var(--au-text);
  font-family: "Sora", system-ui, sans-serif;
  font-weight: 300;
}
.hidden { display: none !important; }

.screen {
  min-height: 100dvh;
  max-width: 460px;
  margin: 0 auto;
  /* o fim reserva a tab bar (--au-h-nav) + 36px de respiro */
  padding: calc(env(safe-area-inset-top, 0px) + 18px) 26px calc(var(--au-h-nav) + 36px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
}
/* [fix 2026-08-11] treino minimizado: a barra do treino (fixa, ~46px acima
   da nav) cobria os CTAs de pé de tela — com ela viva, o fim do scroll
   desce o equivalente. */
/* O lado do COACH tem barra própria (#coachNav, menor e no visual pré-v2):
   fica no reserva de antes, senão a barra maior do atleta abriria um vão
   morto no pé das telas dele. */
#coachTodayView, #coachAthletesView, #editorView, #libraryView {
  padding-bottom: calc(104px + env(safe-area-inset-bottom));
}
body.fs-docked .screen {
  padding-bottom: calc(var(--au-h-nav) + 90px + env(safe-area-inset-bottom));
}
/* ── [dono 2026-08-14] A RESERVA ALCANÇAVA SÓ `.screen` ───────────────────
   A regra acima nasceu em 11/08 e resolvia a Home. Mas metade do app não é
   `.screen`: as telas EMPURRADAS (Peso, Capacidades, foco muscular, Goal)
   são `.pushed-screen` — sobreposições `position:fixed` — e a Conta é
   camada. Nelas o CTA nascia debaixo da barra do treino minimizado, e o
   sintoma era o pior possível: o botão APARECE e o toque não funciona.

   Medido com a barra em 710→760: "Registrar peso" 689–744 (clique morto) ·
   "Rodar bateria de teste" 690–744 (clique morto) · "Trocar senha" 715–767
   (clique morto). Home, Histórico, Agenda, Goal, Mobilidade, Fotos, recibo
   e prévia estavam sãos.

   O `!important` é necessário e não é preguiça: as telas empurradas
   declaram o padding INLINE (elas calculam o próprio recuo a partir do
   token da nav), e estilo inline vence folha. É o mesmo motivo do
   `.pushed-screen[style*="padding"]` logo acima nesta folha.

   A conta é a mesma de sempre: altura da nav + a barra (51) + respiro. */
body.fs-docked .pushed-screen,
body.fs-docked .pushed-screen[style*="padding"] {
  padding-bottom: calc(var(--au-h-nav) + 90px + env(safe-area-inset-bottom)) !important;
}
/* CAMADAS (a Conta e quem vier depois): elas não são `.screen` nem
   `.pushed-screen` — abrem em `#modalRoot`, num container sem classe
   nenhuma. Em vez de um seletor frágil por posição no DOM, a camada que
   precisa reservar a faixa da barra se declara com `.au-reserva-dock`.
   Medido antes: "Trocar senha" nascia em 715–767, com a barra em 710–760 —
   visível e com o clique morto. */
body.fs-docked .au-reserva-dock {
  padding-bottom: calc(var(--au-h-nav) + 90px + env(safe-area-inset-bottom)) !important;
}

/* ── [1a Barra mono · aprovada 2026-08-10] tab bar do ATLETA: sólida
   (superfície + linha), itens de TEXTO por luminância, ativo = traço 1px
   rente ao topo do próprio item (sobrepõe a linha da barra). Trocar de
   território NÃO anima (100+×/dia) — único feedback é o press. Ouro nunca
   aparece aqui. A nav do coach (#coachNav) segue no visual pré-v2. ── */
#bottomNav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: stretch;
  /* [dono 2026-08-12] barra maior de novo (variante B do mockup
     mockups/menu-2x.html): 68 → 104px e rótulo 12 → 20px. O 2× literal do
     RÓTULO (24px) não cabe — "AGENDA" mediria 104px numa aba de 86px.
     [dono 2026-08-14 · opção A do mockup tres-ajustes] 104 → 84px e o
     rótulo 20 → 15px: ficou grande demais (12% da tela). Não é volta ao
     original — 84/15 segue acima do iOS (~49pt/~10pt). A altura mora no
     token --au-h-nav (aurum.css), pra nenhuma tela ficar pra trás. */
  height: calc(var(--au-h-nav) + env(safe-area-inset-bottom, 0px));
  padding: 0 0 env(safe-area-inset-bottom, 0px);
  background: var(--au-surface);
  border-top: 1px solid var(--au-line);
  /* acima das telas empurradas (.pushed-screen 210) — antes a aba GOAL
     cobria a propria barra de abas; abaixo de qualquer folha (300+). */
  z-index: 220;
}
.nav-btn {
  background: none; border: none; cursor: pointer;
  font: 400 .75rem "Space Mono", monospace;
  letter-spacing: .22em;
  color: var(--au-muted);
  padding: 10px 8px;
  min-height: 44px;
}
.nav-btn.active { color: var(--au-text); }
/* [2026-08-14] A caixa alta da barra do COACH era o texto LITERAL do
   index.html ("HOJE"). Quando os rótulos passaram a vir do i18n (que guarda
   "Hoje"/"Today", como todas as outras chaves do app), a barra ficaria em
   caixa mista. Sobe pro CSS — que já é onde a barra do atleta faz isso.
   Em português o resultado é byte a byte o mesmo de antes. */
#coachNav .nav-btn { text-transform: uppercase; }
#bottomNav .nav-btn {
  flex: 1;
  min-width: 0;
  font-size: var(--au-fs-m); /* 15 — foi 12, depois 20 */
  /* espaçamento cai de .12 pra .06em: é o que faz "AGENDA" caber nas 4 abas
     em 375px sem virar rolagem horizontal. */
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 0 4px;
  border-top: 1px solid transparent;
  margin-top: -1px;
}
#bottomNav .nav-btn.active { border-top-color: var(--au-text); }
/* telas estreitas (Android de 360, e o teste de 320px): desce um degrau da
   escala. Nunca sai da régua Sora/Space Mono.
   [dono 2026-08-14] Com o rótulo em 15px esta regra tinha se INVERTIDO —
   mandava 17px, ou seja AUMENTAVA a fonte justamente onde falta espaço.
   Passou pra 13, o degrau abaixo do novo padrão. */
@media (max-width: 374px) {
  #bottomNav .nav-btn { font-size: var(--au-fs-xs); /* 13 */ }
}
/* press e reduced-motion vivem na regra global de aurum.css */

/* ── [APPLE VERSION · tela 05] baralho da Home: scroll-snap nativo
   (gesto 1:1 do sistema), sem barra visível; press = feedback 120ms. ── */
.home-deck { scrollbar-width: none; }
.home-deck::-webkit-scrollbar { display: none; }
.home-card { transition: transform var(--au-dur-press) var(--au-ease); }

/* ── Modal (recibo e folhas) — estrutura App2; cores via aurum ─────────
   [apple-design · §7 caminho simétrico] A folha ENTRA subindo e SAI pelo
   MESMO caminho. Antes ela aparecia e sumia por troca de innerHTML (0ms,
   sem caminho nenhum) — num app cuja identidade é luz e halo, isso lia
   como erro de render. Curva de gaveta do projeto, 320ms na entrada e
   280ms na saída (a saída é resposta do sistema: snap). ── */
@keyframes auSheetIn { from { transform: translateY(100%) } to { transform: translateY(0) } }
@keyframes auSheetOut { from { transform: translateY(0) } to { transform: translateY(100%) } }
@keyframes auFadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes auFadeOut { from { opacity: 1 } to { opacity: 0 } }

.modal-backdrop {
  /* acima da tab bar (220): folha sempre cobre a navegacao */
  position: fixed; inset: 0; z-index: 300;
  background: rgba(5, 5, 4, .72);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: flex-end; justify-content: center;
  animation: auFadeIn 200ms linear both;
}
.modal {
  background: var(--au-surface);
  border: 1px solid var(--au-line);
  border-radius: 22px 22px 0 0;
  width: 100%; max-width: 460px;
  max-height: 94dvh;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 16px 22px calc(28px + env(safe-area-inset-bottom));
  box-sizing: border-box;
  animation: auSheetIn var(--au-dur-sheet) var(--au-ease-sheet) both;
  will-change: transform;
}
.modal-backdrop.closing { animation: auFadeOut 200ms linear both }
.modal-backdrop.closing .modal { animation: auSheetOut 280ms var(--au-ease-sheet) both }
@media (prefers-reduced-motion: reduce) {
  .modal-backdrop.closing, .modal-backdrop.closing .modal {
    animation: auFadeOut 160ms linear both !important;
  }
}

/* ── [P9/P10] Camadas do PLAYER: a prévia, o mapa da sessão e a barra
   minimizada apareciam e sumiam por corte seco, enquanto o overlay de
   vídeo — irmão deles, no mesmo arquivo — já entrava e saía animado.
   Mesma régua das folhas: entra e sai pelo MESMO caminho.
   · camada de conteúdo (prévia/mapa): opacidade, 240ms;
   · player cheio ⇄ barra acoplada: deslize vertical, 320ms de gaveta.

   [SEM ZOOM · dono 2026-08-18] A camada nascia em `scale(.96)` e crescia.
   O dono mandou tirar todo efeito de zoom, principalmente nos caminhos que
   se abrem de DENTRO de uma tela — que é exatamente o que esta classe
   anima. Ficou o fade: entra e sai pelo mesmo caminho, sem escala.
   `auLayerIn`/`auLayerOut` MORRERAM (regra 1) — sem a escala eles eram
   `auFadeIn`/`auFadeOut` com outro nome, e nome duplicado é o começo de
   duas verdades. As linhas de reduced-motion da camada saíram junto: elas
   existiam pra CORTAR o deslocamento, e não há mais deslocamento pra
   cortar. As da `.au-sheet-up` ficam — a folha ainda desliza. ── */
.au-layer { animation: auFadeIn 240ms var(--au-ease) both }
.au-layer.closing { animation: auFadeOut 200ms var(--au-ease) both }
.au-sheet-up { animation: auSheetIn var(--au-dur-sheet) var(--au-ease-sheet) both }
.au-sheet-up.closing { animation: auSheetOut 280ms var(--au-ease-sheet) both }
@media (prefers-reduced-motion: reduce) {
  .au-sheet-up { animation: auFadeIn 200ms linear both }
  .au-sheet-up.closing { animation: auFadeOut 160ms linear both }
}
.modal-close-x {
  min-width: 44px; min-height: 44px;
  background: none; border: none; cursor: pointer;
  color: var(--au-muted); font-size: 15px;
  float: right;
}
.modal-actions { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.workout-receipt-danger-btn, .workout-receipt-link-btn, .workout-edit-toggle-btn, .btn-secondary {
  background: none; border: 1px solid rgba(255, 255, 255, .14);
  color: var(--au-text); border-radius: 100px;
  padding: 11px 16px; min-height: 44px;
  font: 400 .875rem "Sora"; cursor: pointer;
}
.workout-receipt-danger-btn { color: var(--au-orange); border-color: rgba(217, 154, 108, .45); }
.workout-edited-badge {
  font: 400 .625rem "Space Mono", monospace; letter-spacing: .14em;
  color: var(--au-gold-dim); text-transform: uppercase;
}
.workout-receipt-meta-row { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.badge.zone { font: 400 .6875rem "Space Mono", monospace; color: var(--au-muted); }
.workout-blocks { list-style: none; font: 400 .9375rem/1.8 "Sora"; color: var(--au-text-soft); }
.workout-section-title { font: 400 .6875rem "Space Mono", monospace; letter-spacing: .18em; color: var(--au-gold-dim); text-transform: uppercase; }
.empty-day { color: var(--au-muted); font: 400 .875rem "Sora"; }

/* recados (mesmos ids/classes do App 1) */
.messages-section { margin-top: 14px; }
.messages-toggle { background: none; border: none; color: var(--au-gold-dim); font: 400 .6875rem "Space Mono", monospace; letter-spacing: .14em; cursor: pointer; min-height: 44px; min-width: 44px; text-transform: uppercase; }
.messages-list { margin-top: 8px; }
.message-row { padding: 8px 0; border-bottom: 1px solid var(--au-line); font: 400 .875rem "Sora"; color: var(--au-text-soft); }
.message-author { font: 400 .6875rem "Space Mono", monospace; letter-spacing: .12em; color: var(--au-muted); display: block; }
.message-form, .message-edit-form { display: flex; gap: 8px; margin-top: 10px; }
.message-form input, .message-edit-input {
  flex: 1; background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .14); border-radius: 100px;
  color: var(--au-text); font: 400 .9375rem "Sora"; padding: 11px 15px; min-height: 44px;
}
.icon-btn { background: none; border: 1px solid rgba(255, 255, 255, .14); border-radius: 50%; min-width: 44px; min-height: 44px; color: var(--au-text); cursor: pointer; }

/* ── [quebra·acessibilidade] Alvos de toque ≥44pt (regra 12) nos controles
   transplantados do manequim/hub que vinham menores do App 1. Só sizing —
   cor/efeito seguem no manikin.css/aurum.css. */
.hub-mode-seg button { min-height: 44px; }
.hub-seg-pill { min-height: 44px; }
.hub-flip-btn { min-height: 44px; }
.attn-tab { min-height: 44px; }

/* [auditoria] Os botoes PT/EN da Conta so tinham min-height e NENHUMA outra
   regra em todo o css/ — renderizavam como <button> nativo (cinza claro do
   sistema) sobre preto, com menos de 44px de largura. Agora seguem o
   segmento do design system: pilula neutra, ativo por luminancia. */
.account-lang-toggle { display: flex; gap: 6px; flex: none; }
.account-lang-btn {
  min-height: 44px; min-width: 62px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 18px; border-radius: 100px;
  border: 1px solid rgba(255, 255, 255, .1);
  background: none; color: var(--au-muted);
  font: 400 .75rem "Space Mono", monospace; letter-spacing: .2em;
  text-transform: uppercase; cursor: pointer;
}
.account-lang-btn.active { border-color: rgba(255, 255, 255, .28); color: var(--au-text); }

/* ── [quebra·agenda coach] A agenda transplantada traz seu PRÓPRIO
   .agenda-wrap (padding 18px + max-width:640px). Dentro do .screen (que
   já tem padding 26px), isso dobrava o padding e o wrap estourava os
   375px do celular — empurrando a barra de abas do coach pra fora da
   tela. Fix: na agenda, o .screen não re-aplica padding horizontal (o
   wrap cuida disso) e o wrap fica capado em 100%. */
#agendaView { padding-left: 0; padding-right: 0; }
.agenda-wrap { max-width: 100%; }

/* ── [FICHA DO ALUNO · F1] ────────────────────────────────────────────
   Mockup aprovado: mockups/ficha-do-aluno.html.

   Vive aqui e NÃO em estilo inline: o DESIGN-CONTRATO proíbe declarar
   fonte ou altura de botão dentro de uma tela, e o coach-athletes.js é um
   transplante cheio desse vício antigo — o markup NOVO não pode piorá-lo.
   Tamanhos saem dos tokens de escala; nenhuma cor crua. */
.ficha-bloco { margin-top: 18px; }
.ficha-bloco .au-k2 { margin-bottom: 4px; }

.ficha-linha {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 9px 0;
  border-bottom: 1px solid var(--au-line);
}
.ficha-rot {
  flex: none;
  font-size: var(--au-fs-xs); font-weight: 300;
  color: var(--au-muted);
}
/* O VALOR é o dado — fica na cor cheia do texto e pode quebrar em duas
   linhas (lista de músculos pedidos é longa); o rótulo nunca encolhe. */
.ficha-val {
  flex: 1; min-width: 0; text-align: right;
  font-size: var(--au-fs-m); font-weight: 300;
  color: var(--au-text); overflow-wrap: anywhere;
}
.ficha-vazia {
  font-size: var(--au-fs-xs); font-weight: 300;
  color: var(--au-faint); line-height: 1.5;
}

/* ── [dono 2026-08-20] AS SESSÕES PRESENCIAIS NA FICHA ────────────────
   Uma linha = UM botão (nada aninhado) que leva pra aba AGENDA no dia
   certo — o mesmo gesto que o bloco do HOJE já faz. Alvo de 44 pela
   regra 7; nenhuma cor crua, nenhum tamanho fora da escala. */
.ficha-sess {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 44px; padding: 4px 2px; text-align: left;
  background: none; border: none; border-bottom: 1px solid var(--au-line);
  cursor: pointer;
}
.ficha-sess .fs-hora {
  flex: none; font-family: 'Space Mono', monospace; font-size: var(--au-fs-m);
  color: var(--au-text); font-variant-numeric: tabular-nums;
}
.ficha-sess .fs-dia {
  flex: 1; min-width: 0; font-size: var(--au-fs-xs); font-weight: 300;
  color: var(--au-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ficha-sess .fs-arw { flex: none; color: var(--au-gold); font-size: var(--au-fs-m); }

/* ── [FICHA · F2] O CADERNO DO COACH ──────────────────────────────────
   Anotação privada sobre o aluno. Moldura TRACEJADA + cadeado + a frase
   "só você vê" — a MESMA linguagem que as fotos de progresso já usam do
   lado do atleta (photos.js), em vez de inventar texto novo pro mesmo
   conceito.

   O tracejado usa `--au-seal-dashed`, o MESMO token do selo do método.
   Cheguei a escrever o valor à mão (o mockup pede .45 contra os .5 do
   token) e o `tests/selo-usa-o-token.js` reprovou — com razão: 0,05 de
   opacidade ninguém enxerga, e mais um tracejado dourado solto no CSS é
   como a marca do método passou a pesar diferente em 9 lugares antes.
   Abrir exceção no guarda pra uma diferença invisível apodrece o guarda.
   Aqui o papel é outro (moldura de bloco, não assinatura), mas a
   gramática visual é a mesma: "isto não é o normal da tela". */
.coach-nota {
  margin-top: 14px; padding: 12px 13px;
  border: var(--au-seal-dashed); border-radius: 12px;
  background: rgba(201, 162, 74, .04);
}
.coach-nota-selo {
  display: flex; align-items: center; gap: 6px;
  font: 400 var(--au-fs-mono-xs) "Space Mono", monospace;
  letter-spacing: .16em; text-transform: uppercase; color: var(--au-gold);
}
.coach-nota-texto {
  margin: 8px 0 0;
  font-size: var(--au-fs-xs); font-weight: 400; line-height: 1.5;
  color: var(--au-text-soft); white-space: pre-wrap; overflow-wrap: anywhere;
}
.coach-nota-vazia { color: var(--au-faint); font-style: italic; }
.coach-nota-campo {
  width: 100%; margin: 8px 0 0; background: none; border: none; resize: none;
  color: var(--au-text-soft); outline: none;
  font-size: var(--au-fs-xl); font-weight: 400; line-height: 1.5;
  font-family: "Sora", sans-serif;
}

/* ── DESLIZAR PRA REMOVER O ROUND [dono 2026-09-06] ────────────────────
   O "Remover" fica ATRÁS do cartão, e o cartão desliza por cima dele. Só
   `transform` anima (régua do AURUM), e a moldura recorta — sem isso o
   botão apareceria pela lateral antes de o dedo chegar nele.

   COBRE, e não vermelho: é a cor de ATENÇÃO desta casa (`--au-orange`), a
   mesma do "Cancelar esta sessão" e do aviso de round pulado. Vermelho
   seria uma cor nova pra um gesto que apaga um round em branco. */
.fs-swipe{ position:relative; overflow:hidden; border-radius:12px }
.fs-swipe-card{
  position:relative; z-index:1;
  transform:translateX(0);
  transition:transform 220ms var(--au-ease-sheet);
  touch-action:pan-y;   /* a rolagem vertical continua da tela */
}
.fs-swipe-card.aberto{ transform:translateX(calc(var(--fs-swipe-w) * -1)) }
.fs-swipe-card.arrastando{ transition:none }

/* ── [dono 2026-09-08] A FAIXA CRESCE COM O DEDO ──────────────────────
   Ele viu no iPhone: "quando deslizado para a esquerda, surge um botão de
   apagar série, mas esse surgimento deve ser melhor do que tem hoje, pois
   o botão já fica todo preenchido, vazando e dando aparência pouco
   profisional".

   Estava: um retângulo de largura FIXA (104px) com borda e raio PRÓPRIOS,
   ligado e desligado de uma vez por `visibility` no primeiro milímetro de
   arrasto. Medido no mockup: com o dedo a 12px o botão já estava inteiro
   na tela, e o canto arredondado dele aparecia por cima do canto da linha
   — o "vazando".

   Agora a tinta ocupa EXATAMENTE o que foi revelado (o JS escreve a
   largura a cada `pointermove`), sem raio próprio: quem arredonda é a
   moldura `.fs-swipe`, que já recorta. Não há como vazar, porque não há
   nada além da faixa. O conteúdo (lixeira + palavra) entra por opacidade
   a partir de ~45% do gesto — ver `fsLigarDeslizeDoRound`.

   O ESTADO ASSENTADO VEM DAQUI, não de uma animação no nó do gesto: o
   `fim()` do arrasto re-renderiza, e o nó em que o gesto escrevia é
   jogado fora. A faixa aberta NASCE com a largura cheia, como o cartão já
   nascia com o `translateX` do `.aberto`. */
.fs-swipe{ --fs-swipe-w:104px }
.fs-swipe-del{
  position:absolute; right:0; top:0; bottom:0; width:0;
  display:flex; align-items:center; justify-content:center;
  border:none; border-radius:0;
  /* a linha que separa a faixa do cartão é SOMBRA INTERNA, não `border`:
     com `width:0` uma borda de 1px ainda ocuparia 1px de caixa, e "fechada
     não tem um pixel" é a régua que substituiu o `visibility` (08/09). */
  box-shadow:inset 1px 0 0 rgba(217,154,108,.28);
  background:rgba(217,154,108,.16); color:var(--au-orange);
  font:400 var(--au-fs-xs) 'Sora',sans-serif; cursor:pointer; padding:0;
  overflow:hidden; white-space:nowrap;
}
.fs-swipe:has(.fs-swipe-card.aberto) .fs-swipe-del{ width:var(--fs-swipe-w) }
.fs-swipe-del-in{
  display:flex; align-items:center; gap:7px;
  opacity:0; transform:scale(.86);
  transition:opacity 90ms linear, transform 160ms var(--au-ease);
}
.fs-swipe:has(.fs-swipe-card.aberto) .fs-swipe-del-in{ opacity:1; transform:none }
.fs-swipe-del:active .fs-swipe-del-in{ transform:scale(.97) }
/* [06/09, achado na FOTO da alternativa E] O "REMOVER" VAZAVA ATRAVÉS DO
   CARTÃO FECHADO — o cartão tem 3% de branco de fundo (translúcido) e o
   botão cobre morava atrás dele, a 104px de largura, lido por cima dos
   números sem ninguém ter deslizado nada.
   [08/09] QUEM GARANTE ISSO AGORA É A LARGURA ZERO: fechada, a faixa não
   tem um pixel. Foi o que liberou a linha a perder o fundo opaco na peça
   das caixas — sem a faixa nova, o "Remover" voltaria a vazar. */
@media (prefers-reduced-motion: reduce){
  .fs-swipe-card{ transition:none }
  .fs-swipe-del-in{ transition:none }
}

/* ── [dono 2026-09-08] A LINHA DO ROUND: CAIXA POR VALOR ───────────────
   Ele mandou o print do Strong: "separa as linhas da mesma forma que esse
   app, mas em vez de ter o 'ultimo', mantenha % body weight". No Strong
   cada valor editável é uma CAIXA; aqui o que dizia "isto se toca" era um
   pontilhado de 1px embaixo do número — pista fina demais para o dedo.

   A linha deixou de ser um cartão fechado: o `.fs-swipe-card` continua
   sendo o nó (é ele que desliza e que carrega o `data-fs-jump`), mas sem
   fundo e sem borda. Quem se destaca são as caixas.

   O "AGORA" NÃO GANHOU RÉGUA. Ela continua no cabeçalho do exercício
   (`.fs-bloco-agora`, decisão de 07/09) — o mockup aprovado desenha assim,
   e "um sinal de ouro por tela" é a régua do dono de 06/09. O round da vez
   se destaca por LUZ: as caixas dele são mais claras. */
/* as colunas da linha e do cabeçalho — UMA fonte pros dois (era uma const
   inline no JS, e inline não pode ser ajustado por media query). A coluna
   do valor é a maior: é ela que carrega "137,5" dentro de uma caixa. */
.fs-grid-linha{
  display:grid; grid-template-columns:26px .75fr 1.3fr .95fr;
  align-items:center; gap:8px;
}
.fs-cx{
  min-height:44px; min-width:44px; padding:0 8px;
  border-radius:10px;
  background:rgba(255,255,255,.045); border:1px solid rgba(255,255,255,.05);
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; transition:transform 120ms var(--au-ease);
}
.fs-cx:active{ transform:scale(.97) }
.fs-band{ font-size:var(--au-fs-s) }
.fs-swipe-card.cur .fs-cx{ background:rgba(255,255,255,.085); border-color:rgba(255,255,255,.12) }
/* telas muito estreitas (iPhone SE de 320): o número do round da vez desce
   pro corpo de 17px como os outros — em 320 a caixa tem 59px e "137,5" a
   20px pede 68. A distinção do "agora" continua sendo o FUNDO da caixa, que
   é o que o mockup aprovado usa. O `!important` é necessário e não é
   preguiça: a fonte da célula é declarada INLINE (a escala vem do JS), e
   inline vence folha — mesmo motivo do `.pushed-screen[style*="padding"]`. */
@media (max-width: 359px){
  .fs-swipe-card.cur .fs-cx{ font-size:var(--au-fs-xl) !important }
  /* e a caixa aperta o recuo: em 320 ela tem ~59px, e 16px de padding
     deixavam 43 úteis pra "137,5". Medido nos quatro casos (carga longa,
     por tempo, inglês e o rótulo do elástico, que é o texto mais largo). */
  .fs-cx{ padding:0 4px }
  .fs-cx span{ font-size:var(--au-fs-xs) }
  .fs-grid-linha{ grid-template-columns:24px .72fr 1.25fr .83fr; gap:6px }
  .fs-band{ font-size:var(--au-fs-mono-l) }
}
/* o número do round: caixinha discreta na coluna de 26px que o grid já
   reserva — é rótulo, não alvo (quem recebe o toque é a linha inteira). */
.fs-rn{
  width:26px; height:26px; border-radius:7px;
  display:grid; place-items:center;
  background:rgba(255,255,255,.05);
  font:600 var(--au-fs-mono) 'Space Mono',monospace; color:var(--au-faint);
}

/* ── [dono 2026-09-08] O DESCANSO SEPARA AS LINHAS ────────────────────
   "Separa as linhas da mesma forma que esse app" — no Strong, o que divide
   uma série da outra é o próprio descanso: um traço atravessando, com o
   tempo no meio.

   A ARMADILHA QUE ESTE DESENHO TINHA QUE EVITAR: em 07/09 ele viu no
   iPhone "a barra de descanso está dividida em duas, e apenas a parte da
   esquerda possui animação" — eu tinha posto o tempo ENTRE dois traços, e
   o preenchimento é um só. Aqui o trilho é UM elemento absoluto que
   atravessa de ponta a ponta, e a pílula do tempo flutua POR CIMA dele com
   fundo opaco. A tinta drena inteira, por trás do número: uma coisa só.

   O trilho vai de `left:12px` (a coluna do R1/R2) até a borda direita do
   ✓ — a largura que o dono aprovou em 14/08 ("aumente a barra de descanso
   até o botão de concluir set"). */
.fs-rest{
  position:relative; display:flex; align-items:center; justify-content:center;
  min-height:44px;
  /* o mesmo recuo do trilho: sem ele a pílula centra no CONTAINER e fica 6px
     à esquerda do centro da barra — medido, e é o tipo de desalinho que só
     aparece quando alguém compara os dois centros */
  padding-left:12px;
}
.fs-rest-trilho{
  position:absolute; left:12px; right:0; height:3px; border-radius:2px;
  background:rgba(255,255,255,.05); overflow:hidden;
}
.fs-rest-fill{ position:absolute; inset:0 auto 0 0; background:var(--au-gold); border-radius:2px }
.fs-rest-pill{
  position:relative; z-index:2;
  background:var(--au-surface);   /* o fundo do player: é ele que faz a tinta passar POR TRÁS */
  /* min-width junto: com um descanso curto ("45s") a pílula caía pra 39px
     de largura — alvo abaixo do mínimo, e o fiscal não pegava porque as
     cenas dele têm tempos longos */
  min-height:44px; min-width:44px; justify-content:center;
  padding:0 12px; display:flex; align-items:center;
  border:none; border-radius:10px; cursor:pointer;
  font:400 var(--au-fs-mono) 'Space Mono',monospace; letter-spacing:.08em;
  color:var(--au-faint);
}
.fs-rest.correndo .fs-rest-trilho{ background:rgba(201,162,74,.20) }
.fs-rest.correndo .fs-rest-pill{ color:var(--au-gold) }

/* a pílula do ±30 s: abre EM CIMA do tempo, no lugar, sem cobrir o treino.
   Ela é IRMÃ do botão do tempo, nunca filha — botão dentro de botão é ARIA
   inválido, e o `textContent` da pílula tem que continuar sendo só o tempo. */
.fs-rest-pop{
  /* centrado sobre a PÍLULA: o `.fs-rest` tem 12px de recuo à esquerda (o
     mesmo do trilho), então um `left:50%` do container nasce 6px fora do
     centro do botão que o abriu — medido */
  position:absolute; z-index:6; left:calc(50% + 6px); bottom:100%;
  transform:translate(-50%,-6px);
  display:flex; align-items:center; gap:2px; padding:4px;
  border-radius:14px; background:var(--au-surface-2);
  border:1px solid rgba(255,255,255,.12);
  box-shadow:0 12px 30px -14px rgba(0,0,0,.9);
}
/* quando a linha está colada no topo da área que rola, a pílula abre PRA
   BAIXO — senão ela nasce fora da vista, e o toque não teria resposta. */
.fs-rest-pop--baixo{ bottom:auto; top:100%; transform:translate(-50%,6px) }
.fs-rest-pop button{
  min-width:44px; min-height:44px; padding:0 12px;
  border:none; background:none; border-radius:10px; cursor:pointer;
  font:400 var(--au-fs-m) 'Sora',sans-serif; color:var(--au-text-soft);
  white-space:nowrap;   /* "− 30 s" em três linhas foi o que a foto pegou */
}
.fs-rest-pop button:active{ background:rgba(255,255,255,.07) }
.fs-rest-pop .fs-rest-pop-val{
  min-width:64px; justify-content:center; display:flex; align-items:center;
  color:var(--au-text); font-family:'Space Mono',monospace;
  border-left:1px solid var(--au-line); border-right:1px solid var(--au-line); border-radius:0;
}

/* ── A RÉGUA DE OURO: "VOCÊ ESTÁ AQUI" [dono 2026-09-06, alternativa E] ──
   O ouro deixou de ser MOLDURA no executor. Antes havia cinco usos na mesma
   tela (relógio, cartão do exercício, linha do round, número do mapa e o
   avatar) e nenhum dizia sozinho "é aqui que você está" — o dono viu no
   iPhone: "as duas seleções em amarelo estão chamando atenção".
   Agora o "agora" é UM sinal, repetido onde ele vale: uma régua vertical de
   3px à esquerda — a mesma linguagem da barra de descanso, que já era 3px
   em ouro. Ela marca o round da vez, a linha do exercício em cena no mapa e
   o chip aceso da supersérie. O resto se destaca por LUZ (fundo mais claro,
   texto branco), nunca por cor.
   `--fs-agora-x` é onde a régua encosta: 0 dentro de um cartão (a moldura
   do deslize recorta), negativo numa linha sem cartão (o mapa). */
.fs-agora{ position:relative }
.fs-agora::before{
  content:""; position:absolute; left:var(--fs-agora-x, 0); top:8px; bottom:8px;
  width:3px; border-radius:3px; background:var(--au-gold); pointer-events:none;
}

/* [dono 2026-09-07 · a lista do treino] A RÉGUA SUBIU PRO BLOCO. Com todos
   os exercícios na tela, o "agora" que importa primeiro é QUAL EXERCÍCIO —
   a régua do bloco responde isso de uma olhada, e a linha da vez continua
   se destacando por LUZ (fundo mais claro e o cartão com borda), sem uma
   segunda régua ao lado da primeira. Ela recua 14px pra fora do texto, no
   vão do padding de 28px da coluna do player. */
.fs-bloco-agora{ position:relative }
.fs-bloco-agora::before{
  /* [foto, 07/09] Ela marca o CABEÇALHO do bloco, não o bloco inteiro: em
     390px um exercício de 4 rounds tem ~900px de altura, e uma régua dessa
     altura vira uma faixa de ouro no lado da tela — o oposto de "~3 usos
     por tela". Do topo do nome ao pé da capa é o que aponta o exercício. */
  content:""; position:absolute; left:-14px; top:16px; height:52px;
  width:3px; border-radius:3px; background:var(--au-gold); pointer-events:none;
}

/* ── O VÍDEO DO EXERCÍCIO NO EXECUTOR [dono 2026-09-06] ────────────────
   "Sem aparecer o botão de play e voltar ou avançar 10 segundos, pois
   esses botões deixam a tela mais escura e fica difícil de ver."

   O `controls` nativo saiu; o que sobra por cima da imagem é UMA camada
   invisível que ouve o toque, um sinal que aparece e some, e uma barra de
   3px. [junção 06/09] A CAIXA COM PROPORÇÃO MORREU junto com ela: a camada
   virou TELA CHEIA (`object-fit:cover`), decisão posterior do dono na outra
   worktree — sem caixa não há proporção a reservar, e o pulo deitado→
   vertical deixou de existir por construção.

   O ALVO DA BARRA TEM 44px de altura — os 3px são só o que se VÊ. É a
   mesma solução do ± do executor, que ganhou 44 com o quadrado menor
   dentro; a régua do contrato é sobre o DEDO, não sobre a tinta. */
.fsv-toque{ position:absolute; inset:0; cursor:pointer; background:none; border:none }
.fsv-sinal{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%) scale(.94);
  min-width:76px; height:76px; padding:0 18px; border-radius:38px;
  background:rgba(11,10,9,.55); color:var(--au-text);
  display:grid; place-items:center; font:400 var(--au-fs-l) 'Sora',sans-serif;
  opacity:0; pointer-events:none;
  transition:opacity 180ms var(--au-ease), transform 180ms var(--au-ease);
}
.fsv-sinal.on{ opacity:1; transform:translate(-50%,-50%) scale(1) }
.fsv-barra{
  position:absolute; left:0; right:0; bottom:0; height:var(--au-h-tap);
  display:flex; align-items:flex-end; padding:0 16px 12px;
  cursor:pointer; touch-action:none;
}
.fsv-barra .fsv-tr{
  flex:1; height:3px; border-radius:2px; background:rgba(255,255,255,.22);
  overflow:hidden; transition:height 120ms var(--au-ease);
}
.fsv-barra.puxando .fsv-tr{ height:5px }
.fsv-barra .fsv-tr i{
  display:block; height:100%; background:var(--au-gold);
  transform:scaleX(0); transform-origin:left center;
}
@media (prefers-reduced-motion: reduce){
  .fsv-sinal{ transition:opacity 120ms linear; transform:translate(-50%,-50%) }
  .fsv-sinal.on{ transform:translate(-50%,-50%) }
}

/* ── A TELA DE PAGAMENTO (19/08/2026 · tela cheia desde 03/09/2026) ────
   Estrutura só; cor e movimento vêm dos tokens do aurum.css, e a entrada
   sobe como as folhas do app de propósito — pagamento que entra diferente
   das demais superfícies parece outro app.

   NÃO HÁ CTA SÓLIDO AQUI, E AGORA NÃO HÁ BOTÃO NENHUM NOSSO. O botão de
   pagar é desenhado pelo STRIPE, dentro do iframe dele — a régua "um fill
   sólido por tela" continua valendo, e quem o gasta é ele. Desde o quadro
   D, o "Cancelar" ghost também saiu: quem fecha é a seta da barra. */
/* AS CAMADAS. A tab bar vive em 220 e os modais em 300 — com o
   `.modal-backdrop` dizendo, por escrito, "acima da tab bar: folha sempre
   cobre a navegação". A folha de pagamento nasceu em 60/61 e ficaria
   ATRÁS da barra de abas: o pagamento com a navegação desenhada por cima.
   Vai pra 320/321, acima também do modal comum — porque ela abre EM CIMA
   da folha de confirmação, que é 300. */
.pg-veu {
  position: fixed; inset: 0; z-index: 320;
  background: rgba(0, 0, 0, .58);
  animation: auFadeIn 260ms var(--au-ease) both;
}
/* ── TELA CHEIA, NÃO MAIS FOLHA (dono 03/09/2026, quadro D) ───────────
   A folha do rodapé morreu junto com o puxador, o kicker, o valor em ouro
   e o "Cancelar" ghost. Motivo medido: o valor aparecia duas vezes (o
   nosso e o do resumo do próprio Stripe), e o formulário dele é LONGO —
   numa folha de 92vh ele rolava dentro de uma tela que também rolava.
   Em tela cheia é uma rolagem só, e a superfície inteira é dele.

   Ela ENTRA subindo, como a folha entrava: é uma apresentação modal, e o
   gesto de "isto veio por cima do que eu estava fazendo" continua certo. */
.pg-tela {
  position: fixed; inset: 0; z-index: 321;
  display: flex; flex-direction: column;
  background: var(--au-bg);
  transform: translateY(100%);
  transition: transform var(--au-dur-sheet) var(--au-ease-sheet);
}
.pg-tela.on { transform: translateY(0); }

/* A BARRA É A ÚNICA CHROME NOSSA: a seta (o Stripe embutido não tem botão
   de sair) e o nome do que se paga. Mono APAGADO, nunca o kicker dourado —
   ouro aqui seria o app assinando uma tela que não é dele. */
.pg-barra {
  flex: none; display: flex; align-items: center; gap: 4px;
  padding: calc(env(safe-area-inset-top, 0px) + 8px) 20px 8px;
  border-bottom: 1px solid var(--au-line-soft);
}
.pg-barra-tit {
  font: 400 var(--au-fs-mono-s) "Space Mono", monospace;
  letter-spacing: .2em; text-transform: uppercase; color: var(--au-muted);
}
/* Uma rolagem só, e ela é a do formulário dele. */
.pg-rolo {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 16px 16px calc(env(safe-area-inset-bottom, 0px) + 24px);
}
/* O que o Stripe não tem como saber: a data da sessão, a renovação do
   plano. Rola junto com o formulário, como o resumo dele faria. */
.pg-ctx { margin: 0 0 14px; font-size: var(--au-fs-xs); color: var(--au-muted); }
/* O iframe do Stripe cresce sozinho; a altura mínima evita o salto de
   layout entre a tela subir e ele terminar de se desenhar. Em tela cheia
   ela subiu de 260 pra 420: o formulário dele tem e-mail, cartão, validade,
   CVC, nome e o botão de pagar — reservar meia folha fazia a chegada dele
   empurrar a tela inteira. */
/* [23/09 · revisão jurídica] A LINHA DOS 14 DIAS, acima dos campos do
   cartão. Ela usa o interruptor canônico (`.au-switch-row`) — nenhum
   desenho novo pra um gesto que o app já tem —, e o que muda aqui é só o
   espaço em volta: a linha da Conta e a das Fotos vivem em listas, esta
   vive sozinha antes de um bloco de terceiro. */
.pg-14d { margin: 0 0 18px; }
.pg-14d .au-switch-row { margin-top: 0; }

.pg-mount { min-height: 420px; }

/* ── A ESPERA DE ~3s (dono 20/08/2026 · refeita 03/09/2026) ───────────
   Enquanto o Stripe não chega, a área reservada precisa DIZER que está
   vindo. A 1ª versão era um esqueleto dos campos — e o dono mediu com o
   dedo: "por alguns segundos não existe nenhum tipo de ação". O esqueleto
   era `--au-line` (7% de branco) pulsando entre 40% e 73% de opacidade:
   sobre a tela cheia preta, invisível. Agora: o anel canônico girando
   (`.au-anel`, aurum.css — só transform) e a frase em texto claro,
   centrados na área que o bloco do Stripe vai ocupar, no mesmo lugar e
   do mesmo tamanho — a troca não empurra nada. */
.pg-mount-esperando { display: flex; flex-direction: column; justify-content: center; }
.pg-espera {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 48px 12px; text-align: center;
}
.pg-espera-tit { font-size: var(--au-fs-l); color: var(--au-text); }
.pg-espera-sub { font-size: var(--au-fs-xs); color: var(--au-muted); }

@media (prefers-reduced-motion: reduce) {
  .pg-tela { transition: opacity 200ms linear; transform: none; opacity: 0; }
  .pg-tela.on { opacity: 1; }
  .pg-veu { animation: none; }
}

/* ═══ A ABA DO CICLO (atleta) — "onde eu estou" ═══════════════════════════
   [dono 2026-09-09 · forma A de mockups/goal-vira-ciclo.html]
   Classes da tela que substituiu as variantes do GOAL. Nenhuma fonte ou
   altura de botão vive inline lá (contrato visual, 11/08): tudo aqui, com os
   tokens da escala. O ouro aparece TRÊS vezes na tela e todas estão neste
   bloco: a semana atual na fita (o "agora"), o PR (mérito) e a porta
   "Trocar". O percentual da carga é NEUTRO de propósito — cobre é a cor de
   atenção/lesão nesta casa, e pintar a carga de cobre seria o app dando um
   diagnóstico que a literatura não sustenta (31/08). */

.gc-k { font: 400 var(--au-fs-mono-s) 'Space Mono', monospace; letter-spacing: .22em;
        text-transform: uppercase; color: var(--au-faint) }

/* a primeira linha: o objetivo */
.gc-obj { display: flex; align-items: flex-start; gap: 12px;
          padding-bottom: 16px; border-bottom: 1px solid var(--au-line) }
.gc-obj-col { flex: 1; min-width: 0 }
.gc-obj-n { font: 300 var(--au-fs-t-s) 'Sora', sans-serif; color: var(--au-text);
            margin-top: 4px; letter-spacing: -.01em }
.gc-obj-d { font: 400 var(--au-fs-xs) 'Sora', sans-serif; color: var(--au-muted); margin-top: 2px }
.gc-obj-ed { flex: none; color: var(--au-gold) }

/* o herói */
.gc-hero-k { margin-top: 22px }
.gc-hero { display: flex; align-items: baseline; gap: 10px; margin-top: 8px; white-space: nowrap }
.gc-hero-n { line-height: 1 }
.gc-hero-u { font: 400 var(--au-fs-m)/1.3 'Sora', sans-serif; color: var(--au-muted) }

/* a FITA das semanas — ALTURA diz o peso da semana (descarga = metade),
   COR diz se já passou. A foto do mockup pediu isto: com a descarga em 4px
   e 7% de branco ela sumia, e a fita parecia ter barras faltando. */
.gc-fita { display: flex; align-items: flex-end; gap: 5px; height: 18px; margin-top: 18px }
.gc-fita i { flex: 1; min-width: 2px; height: 10px; border-radius: 3px; background: rgba(255,255,255,.16) }
.gc-fita i.gc-w-dl { height: 5px }
.gc-fita i.gc-w-done { background: rgba(255,255,255,.34) }
.gc-fita i.gc-w-now { background: var(--au-gold); height: 14px }
.gc-fita-txt { display: flex; justify-content: space-between; gap: 10px; margin-top: 9px;
               font: 400 var(--au-fs-mono-xs) 'Space Mono', monospace; letter-spacing: .16em;
               text-transform: uppercase; color: var(--au-faint) }

/* os blocos */
.gc-card { border-top: 1px solid var(--au-line); margin-top: 22px; padding-top: 16px }
.gc-l { font: 400 var(--au-fs-s)/1.55 'Sora', sans-serif; color: var(--au-muted);
        margin: 4px 0 0; max-width: 300px }
.gc-num { font: 200 var(--au-fs-t-xl)/1.1 'Sora', sans-serif; color: var(--au-text);
          letter-spacing: -.02em; font-variant-numeric: tabular-nums; margin-top: 8px }
.gc-vazio { font: 400 var(--au-fs-s)/1.6 'Sora', sans-serif; color: var(--au-muted);
            margin: 10px 0 0; max-width: 300px }
.gc-nota { font: 400 var(--au-fs-xs)/1.5 'Sora', sans-serif; color: var(--au-faint); margin: 10px 0 0 }

/* as barras da carga sentida */
.gc-barras { display: flex; align-items: flex-end; gap: 8px; height: 66px; margin-top: 14px }
.gc-barras i { flex: 1; border-radius: 3px 3px 0 0; background: rgba(255,255,255,.16) }
.gc-barras i.gc-bar-now { background: var(--au-text-soft) }
.gc-barras-txt { display: flex; gap: 8px; margin-top: 7px }
.gc-barras-txt span { flex: 1; text-align: center; font: 400 var(--au-fs-mono-xs) 'Space Mono', monospace;
                      letter-spacing: .08em; color: var(--au-faint) }
.gc-chip { margin-top: 12px }

/* "o que mudou" */
.gc-mud { display: flex; align-items: center; gap: 11px; min-height: var(--au-h-tap);
          font-size: var(--au-fs-s); color: var(--au-text-soft) }
.gc-mud-t { flex: none; font: 400 var(--au-fs-mono) 'Space Mono', monospace;
            letter-spacing: .14em; color: var(--au-faint) }
.gc-mud-pr { color: var(--au-gold) }
.gc-mud-f { flex: 1; min-width: 0 }
.gc-mud-q { flex: none; margin-left: auto; font-size: var(--au-fs-xs); color: var(--au-muted);
            font-variant-numeric: tabular-nums }
.gc-porta { display: block; width: 100%; text-align: center; margin-top: 6px }
