/* ---------- Tokens: claro (base) ---------- */
:root{
  --ground:#EDEEEA; --surface:#FFFFFF; --surface-2:#F5F6F2; --sunken:#E4E7E0;
  --ink:#14181A; --ink-2:#3D464A; --muted:#66716D; --line:#D5D9D1; --line-2:#C2C8BD;
  --accent:#1F6F5C; --accent-ink:#FFFFFF; --accent-soft:#DCEBE5;
  --copper:#A9551F; --copper-soft:#F2E3D6;
  --rest:#215C86; --rest-soft:#DCE8F2;
  --ring:#1C7ED6; --ring-go:#0CA678;
  --warn:#8A6410; --warn-soft:#F5EBD2;
  --danger:#94301F; --danger-soft:#F5DCD6;
  --shadow:0 1px 2px rgba(20,24,26,.06), 0 6px 18px rgba(20,24,26,.05);
  --r:10px; --r-s:6px;
  /* System stacks: the strict CSP blocks external fonts, and a self-hosted
     app should not need a CDN to render. */
  --f-display:-apple-system,'Segoe UI Variable Display','Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --f-body:-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --f-mono:ui-monospace,'SF Mono',SFMono-Regular,Menlo,Consolas,monospace;
  color-scheme:light;   /* faz o range e o select nativos acompanharem o tema */
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ground:#0E1210; --surface:#161B18; --surface-2:#1B211D; --sunken:#0A0E0C;
    --ink:#E8EBE6; --ink-2:#BCC4BE; --muted:#8B968F; --line:#28302B; --line-2:#374039;
    --accent:#4FB39A; --accent-ink:#07130F; --accent-soft:#152A24;
    --copper:#D98E52; --copper-soft:#2B1E13;
    --rest:#6FB6E3; --rest-soft:#12232E;
    --ring:#4DABF7; --ring-go:#20C997;
    --warn:#D6B057; --warn-soft:#2A2313;
    --danger:#E08373; --danger-soft:#2E1713;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --ground:#0E1210; --surface:#161B18; --surface-2:#1B211D; --sunken:#0A0E0C;
  --ink:#E8EBE6; --ink-2:#BCC4BE; --muted:#8B968F; --line:#28302B; --line-2:#374039;
  --accent:#4FB39A; --accent-ink:#07130F; --accent-soft:#152A24;
  --copper:#D98E52; --copper-soft:#2B1E13;
  --rest:#6FB6E3; --rest-soft:#12232E;
  --ring:#4DABF7; --ring-go:#20C997;
  --warn:#D6B057; --warn-soft:#2A2313;
  --danger:#E08373; --danger-soft:#2E1713;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
  color-scheme:dark;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:var(--f-body); font-size:15px; line-height:1.55;
  -webkit-tap-highlight-color:transparent;
  overflow-wrap:break-word;
}
h1,h2,h3,h4{font-family:var(--f-display); font-weight:700; text-wrap:balance; margin:0; letter-spacing:-.015em}
button,input,select,textarea{font:inherit; color:inherit}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:4px}
@media (prefers-reduced-motion: reduce){*{animation:none!important; transition:none!important}}

.wrap{max-width:1120px; margin:0 auto; padding:0 20px}

/* ---------- Cabeçalho ---------- */
header{border-bottom:1px solid var(--line); background:var(--surface); position:sticky; top:0; z-index:20}
.hbar{display:flex; align-items:center; gap:18px; height:60px}
.brand{display:flex; align-items:baseline; gap:9px; font-family:var(--f-display); font-weight:700; font-size:18px; letter-spacing:-.02em}
.brand em{font-style:normal; color:var(--accent)}
.brand small{font-family:var(--f-mono); font-size:10.5px; font-weight:500; color:var(--muted); letter-spacing:.08em; text-transform:uppercase}
nav.tabs{display:flex; gap:2px; margin-left:auto}
.tab{
  background:none; border:0; padding:7px 13px; border-radius:var(--r-s); cursor:pointer;
  font-size:13.5px; font-weight:500; color:var(--muted);
}
.tab:hover{background:var(--surface-2); color:var(--ink)}
.tab[aria-selected="true"]{background:var(--accent-soft); color:var(--accent); font-weight:600}
.icon-btn{background:none; border:1px solid var(--line); border-radius:var(--r-s); width:32px; height:32px; cursor:pointer; color:var(--muted); font-size:14px}
.icon-btn:hover{border-color:var(--line-2); color:var(--ink)}

/* ---------- Blocos ---------- */
main{padding:26px 0 70px}
.panel{background:var(--surface); border:1px solid var(--line); border-radius:var(--r); box-shadow:var(--shadow)}
.panel + .panel{margin-top:16px}
.panel-h{padding:14px 18px; border-bottom:1px solid var(--line); display:flex; align-items:center; gap:12px; flex-wrap:wrap}
.panel-h h2{font-size:15px}
/* The header's badges travel together. */
.ph-meta{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.panel-b{padding:18px}
.eyebrow{font-family:var(--f-mono); font-size:10.5px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
.sub{color:var(--muted); font-size:13.5px; margin:5px 0 0}
.hidden{display:none!important}

/* ---------- Controles ---------- */
.btn{
  background:var(--accent); color:var(--accent-ink); border:0; border-radius:var(--r-s);
  padding:9px 16px; font-size:13.5px; font-weight:600; cursor:pointer;
}
.btn:hover{filter:brightness(1.08)}
.btn.ghost{background:none; color:var(--ink-2); border:1px solid var(--line)}
.btn.ghost:hover{border-color:var(--line-2); background:var(--surface-2); filter:none}
.btn.sm{padding:5px 11px; font-size:12.5px}
/* The button that erases something looks like it. */
.btn.danger{background:var(--danger); color:#fff}
.btn:disabled{opacity:.45; cursor:not-allowed}
.field{display:flex; flex-direction:column; gap:5px}
.weekpick{display:grid; grid-template-columns:repeat(7,1fr); gap:5px}
.weekpick .wd{
  display:grid; place-items:center; padding:9px 0; cursor:pointer;
  border:1px solid var(--line); border-radius:var(--r-s);
  background:var(--surface); font-family:var(--f-mono); font-size:12px;
  font-weight:600; color:var(--muted); text-transform:uppercase;
}
.weekpick .wd.on{
  border-color:var(--accent); background:var(--accent-soft); color:var(--accent);
}
.weekpick .wd.never{
  border-color:var(--danger); background:var(--danger-soft); color:var(--danger);
}
.weekpick .wd.never span{text-decoration:line-through}
.weekpick .wd small{font-size:9.5px; font-weight:500; letter-spacing:.03em; opacity:.85; white-space:nowrap}
@media (max-width:720px){.weekpick .wd{padding:10px 0; font-size:13px}}

/* Orange is the colour of what runs past the clock: the sets the fortnight
   owes but the hour does not hold, the minutes they add, the day the plan
   borrowed. One colour, one meaning, everywhere it appears. */
.over{color:var(--copper); font-family:var(--f-mono); font-weight:600}
.day.extra{border-color:var(--copper); border-style:dashed}
.day-extra{font-size:11px; color:var(--copper); line-height:1.3}
.setrow.optional .lbl{color:var(--copper); font-weight:700}
.setrow.optional input{border-style:dashed; border-color:var(--copper)}
.optdivider{
  display:flex; flex-direction:column; gap:1px; margin-top:6px; padding:7px 0 3px;
  border-top:1px dashed var(--copper); color:var(--copper);
}
.optdivider b{font-family:var(--f-mono); font-size:10.5px; letter-spacing:.07em; text-transform:uppercase}
.optdivider span{font-size:11.5px; color:var(--muted)}
.field label{font-size:12.5px; font-weight:600; color:var(--ink-2)}
.field .hint{font-size:11.5px; color:var(--muted); font-weight:400}
input[type="number"],input[type="text"],select,textarea{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-s);
  padding:8px 10px; font-size:14px; width:100%;
}
input[type="number"]{font-family:var(--f-mono)}

/* A native <select> keeps the engine's own metrics: Chromium ignores the
   author padding and min-height above, which left the exercise swap control
   as a 23px tap target. Turning the appearance off hands the box back to
   this stylesheet - it matters, because that control is used standing up,
   one-handed, between sets. The chevron is inlined so the strict CSP does
   not have to allow an external image. */
select{
  appearance:none; -webkit-appearance:none;
  background-color:var(--surface);
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%237c867f' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 11px center;
  background-size:11px 8px;
  padding-right:32px;
}
select::-ms-expand{display:none}
textarea{font-family:var(--f-mono); font-size:12px; line-height:1.5}
.grid{display:grid; gap:14px}
.g2{grid-template-columns:repeat(2,1fr)} .g3{grid-template-columns:repeat(3,1fr)} .g4{grid-template-columns:repeat(4,1fr)}
@media (max-width:760px){.g3,.g4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.g2,.g3,.g4{grid-template-columns:1fr}}

/* ---------- Chips e badges ---------- */
.chip{
  display:inline-flex; align-items:center; gap:5px; padding:2px 8px; border-radius:100px;
  font-family:var(--f-mono); font-size:11px; font-weight:600; letter-spacing:.02em;
  background:var(--sunken); color:var(--ink-2); border:1px solid var(--line);
}
.chip.acc{background:var(--accent-soft); color:var(--accent); border-color:transparent}
.chip.cop{background:var(--copper-soft); color:var(--copper); border-color:transparent}
.chip.wrn{background:var(--warn-soft); color:var(--warn); border-color:transparent}
.chip.dgr{background:var(--danger-soft); color:var(--danger); border-color:transparent}

/* ---------- Semana ---------- */
.week{display:grid; grid-template-columns:repeat(7,1fr); gap:8px}

/* Weeks as sections: what ended is a summary line until asked, the
   current one is open, the one ahead sits collapsed to plan by. */
.wk{grid-column:1/-1; display:grid; grid-template-columns:subgrid; gap:8px}
.wk-h{
  grid-column:1/-1; display:flex; align-items:baseline; gap:10px;
  padding:4px 2px; cursor:default;
}
details.wk > .wk-h{cursor:pointer; list-style:none}
details.wk > .wk-h::-webkit-details-marker{display:none}
details.wk > .wk-h::after{
  content:"▸"; margin-left:auto; color:var(--muted); font-size:12px;
  transition:transform .15s ease;
}
details.wk[open] > .wk-h::after{transform:rotate(90deg)}
details.wk > .wk-h + *{margin-top:0}
.wk-h h3{
  font-family:var(--f-mono); font-size:11.5px; font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; color:var(--ink-2);
}
.wk-range{color:var(--muted); font-weight:400; letter-spacing:.04em}
.wk-sum{font-size:12.5px; color:var(--muted)}
section.wk .wk-sum{margin-left:auto}
details.wk > .wk-h .wk-sum{margin-left:0}
details.wk:not([open]){border:1px dashed var(--line); border-radius:var(--r); padding:2px 10px}

@media (max-width:900px){.week{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.week{grid-template-columns:1fr}}
.day{
  border:1px solid var(--line); border-radius:var(--r); background:var(--surface-2);
  padding:11px; min-height:112px; display:flex; flex-direction:column; gap:7px;
}
.day.rest{background:var(--sunken); border-style:dashed}
.day.rest h4{color:var(--muted); font-weight:600}
/* Amber and not red: a session that did not happen wants attention, not
   an alarm. The stripes are what carry it when the card is glanced at
   rather than read, and they survive a colourblind reader. */
.day.rest.missed{
  border-style:solid; border-color:var(--warn);
  background:
    repeating-linear-gradient(-45deg,
      var(--warn-soft) 0 7px, transparent 7px 14px),
    var(--sunken);
}
.day.rest.missed h4{color:var(--warn)}
/* A training day the window has not reached: agenda, not prescription.
   Accent-tinted and dashed, with nothing to press. */
.day.rest.expected{border-color:var(--accent); border-style:dashed; background:var(--surface)}
.day.rest.expected h4{color:var(--accent)}
.day.today{border-color:var(--accent); box-shadow:0 0 0 1px var(--accent)}
/* Behind today. Still readable, plainly over: the strip carries the week
   you are measured on as well as the one you are planning, and the eye has
   to be able to tell them apart at a glance. */
.day.past{opacity:.62}
.day.past:hover{opacity:1}
.day.done{background:var(--accent-soft); border-color:transparent}
.day-top{display:flex; align-items:baseline; justify-content:space-between; gap:6px}
.day-name{font-family:var(--f-mono); font-size:10.5px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--muted)}
.day-num{font-family:var(--f-mono); font-size:11px; color:var(--muted)}
.day h4{font-size:13.5px; line-height:1.3; display:flex; flex-wrap:wrap; align-items:baseline; gap:0 8px}
.day-foco{font-size:11.5px; color:var(--muted); font-weight:400}
.day .meta{font-family:var(--f-mono); font-size:11px; color:var(--muted); margin-top:auto}
.day button{margin-top:auto}

/* ---------- Tabelas ---------- */
.tbl-wrap{overflow-x:auto}
table{border-collapse:collapse; width:100%; font-size:13px}
th{
  text-align:left; font-family:var(--f-mono); font-size:10.5px; font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
  padding:7px 10px; border-bottom:1px solid var(--line-2); white-space:nowrap;
}
td{padding:8px 10px; border-bottom:1px solid var(--line); vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
td.num,th.num{font-family:var(--f-mono); font-variant-numeric:tabular-nums; text-align:right}

/* ---------- Barra de volume ---------- */
.vbar{position:relative; height:7px; background:var(--sunken); border-radius:100px; overflow:hidden; min-width:110px}
.vbar span{position:absolute; inset:0 auto 0 0; background:var(--accent); border-radius:100px}
.vbar span.over{background:var(--copper)}
.vbar span.under{background:var(--warn)}

/* ---------- Exercícios ---------- */
.ex{border:1px solid var(--line); border-radius:var(--r); margin-bottom:12px; overflow:hidden; background:var(--surface)}
.ex-h{padding:12px 14px; background:var(--surface-2); border-bottom:1px solid var(--line); display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap}
.ex-h .n{width:23px; height:23px; border-radius:5px; background:var(--ink); color:var(--ground); display:grid; place-items:center; font-family:var(--f-mono); font-size:11.5px; font-weight:600; flex:none}
.ex-h h4{font-size:14.5px}
.alias{font-size:12px; color:var(--muted); margin-top:2px}
.ex-h .tags{display:flex; gap:5px; flex-wrap:wrap; margin-top:5px}
.ex-b{padding:12px 14px}
.presc{display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin-bottom:12px}
@media (max-width:640px){.presc{grid-template-columns:repeat(2,1fr)}}
.presc div{background:var(--sunken); border-radius:var(--r-s); padding:8px 10px}
.presc dt{font-family:var(--f-mono); font-size:10px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--muted)}
.presc dd{margin:2px 0 0; font-family:var(--f-mono); font-size:14px; font-weight:600}
.cue{font-size:12.5px; color:var(--ink-2); border-left:2px solid var(--accent); padding:2px 0 2px 11px; margin:0 0 6px}
.cue.warn{border-left-color:var(--copper); color:var(--copper)}
.cue.tec{border-left-color:var(--line-2); color:var(--ink)}   /* execução: vem do exercício, não do papel */
.troca{display:block; margin:12px 0 0; font-family:var(--f-mono); font-size:10px; font-weight:600;
       letter-spacing:.08em; text-transform:uppercase; color:var(--muted)}
.troca select{margin-top:4px; font-family:var(--f-body); font-size:13px; letter-spacing:0; text-transform:none}
.sets{display:flex; flex-direction:column; gap:6px; margin-top:11px}
.setrow{display:grid; grid-template-columns:34px 1fr 1fr 1fr 30px; gap:7px; align-items:center}
.setrow .lbl{font-family:var(--f-mono); font-size:11px; color:var(--muted); text-align:center}
.setrow input{padding:6px 8px; font-size:13px; text-align:center}
.setrow .ok{font-size:15px; text-align:center; color:var(--muted)}
.setrow.filled .ok{color:var(--accent)}
.sethead{display:grid; grid-template-columns:34px 1fr 1fr 1fr 30px; gap:7px}
.sethead span{font-family:var(--f-mono); font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); text-align:center}

/* ---------- Notas do motor ---------- */
.note{display:flex; gap:10px; padding:11px 13px; border-radius:var(--r-s); background:var(--sunken); font-size:13px; align-items:flex-start}
.note + .note{margin-top:8px}
.note .k{font-family:var(--f-mono); font-size:10px; font-weight:600; letter-spacing:.07em; text-transform:uppercase; padding:2px 7px; border-radius:100px; flex:none; margin-top:1px}
.note.up .k{background:var(--accent-soft); color:var(--accent)}
.note.down .k{background:var(--warn-soft); color:var(--warn)}
.note.hold .k{background:var(--sunken); color:var(--muted); border:1px solid var(--line)}
.note.alert .k{background:var(--danger-soft); color:var(--danger)}
.note b{font-weight:600}
.note .src{display:block; color:var(--muted); font-size:11.5px; margin-top:3px}
.det{margin-top:5px}
.det summary{cursor:pointer; color:var(--accent); font-weight:600; font-size:12.5px; list-style:none}
.det summary::-webkit-details-marker{display:none}
.det summary::after{content:" ⌄"}
.det[open] summary::after{content:" ⌃"}
.det p{color:var(--muted); font-size:12.5px; margin:5px 0 0}
ul.warmup{margin:6px 0 0; padding-left:18px; color:var(--ink-2); font-size:13.5px}
ul.warmup li{margin-top:3px}
@media (max-width:720px){ul.warmup{font-size:15px}}

/* ---------- Prontidão ---------- */
.slider{display:grid; grid-template-columns:1fr 42px; gap:11px; align-items:center}
input[type="range"]{width:100%; accent-color:var(--accent)}
/* The check-in dials: one track, red on the left and green on the right,
   lit up to where the thumb is. The colour says which way is better
   before the label does. */
.mood input[type="range"]{-webkit-appearance:none; appearance:none; background:transparent; --p:50%}
.mood input[type="range"]::-webkit-slider-runnable-track{
  height:8px; border-radius:4px;
  background:linear-gradient(to right, transparent var(--p), var(--line) var(--p)),
             linear-gradient(to right, #d64541, #e6a800 50%, #2e9e5b)}
.mood input[type="range"]::-moz-range-track{
  height:8px; border-radius:4px;
  background:linear-gradient(to right, transparent var(--p), var(--line) var(--p)),
             linear-gradient(to right, #d64541, #e6a800 50%, #2e9e5b)}
.mood input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:22px; height:22px; margin-top:-7px;
  border-radius:50%; background:var(--card); border:2px solid var(--ink);
  box-shadow:0 1px 3px rgba(0,0,0,.3)}
.mood input[type="range"]::-moz-range-thumb{
  width:22px; height:22px; border-radius:50%; background:var(--card);
  border:2px solid var(--ink); box-shadow:0 1px 3px rgba(0,0,0,.3)}
.slider output{font-family:var(--f-mono); font-size:14px; font-weight:600; text-align:right}
.score{font-family:var(--f-mono); font-size:34px; font-weight:600; letter-spacing:-.02em; line-height:1}

/* ---------- Estatísticas ---------- */
.stat{background:var(--surface-2); border:1px solid var(--line); border-radius:var(--r); padding:13px 15px}
.stat dt{font-family:var(--f-mono); font-size:10px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--muted)}
.stat dd{margin:5px 0 0; font-family:var(--f-mono); font-size:25px; font-weight:600; letter-spacing:-.02em; line-height:1}
.stat .d{font-size:11.5px; color:var(--muted); font-family:var(--f-body); margin-top:4px}

footer{border-top:1px solid var(--line); padding:20px 0 34px; color:var(--muted); font-size:12px}
footer code{font-family:var(--f-mono); font-size:11px}
.empty{text-align:center; padding:36px 18px; color:var(--muted); font-size:13.5px}

/* =====================================================================
   Toque e celular
   O app é usado de pé, entre séries, com uma mão e a tela suada.
   Alvos de toque de 44 px e campos de 16 px (abaixo disso o iOS dá
   zoom sozinho ao focar o campo e desloca a tela).
   ===================================================================== */
@media (pointer: coarse){
  .btn{min-height:44px; padding:11px 18px}
  .btn.sm{min-height:40px; padding:9px 15px}
  .tab{min-height:44px}
  .icon-btn{width:44px; height:44px; font-size:16px}
  input[type="number"],input[type="text"],select,textarea{font-size:16px; min-height:44px}
  .setrow input{font-size:16px; min-height:46px; padding:8px 4px}
  input[type="range"]{height:40px}
  .day button{min-height:44px}
}

@media (max-width:720px){
  /* Escala tipográfica para presbiopia. O usuário-alvo tem 45+ e lê de pé,
     com o braço estendido, sob luz de academia. Nada abaixo de 13 px, e o
     que se lê durante a série (nome do exercício, prescrição, campos) bem
     acima disso. iOS não infla texto por conta própria aqui porque
     -webkit-text-size-adjust está travado em 100%. */
  body{font-size:17px; line-height:1.5; padding-bottom:calc(72px + env(safe-area-inset-bottom))}
  .wrap{padding:0 14px}
  main{padding:14px 0 8px}

  .panel-h h2{font-size:19px}
  .eyebrow{font-size:13px}
  .sub{font-size:15px}
  /* Selo em cima, texto em largura total: lado a lado o selo é fixo e
     espreme o texto numa coluna que quebra em cinco linhas. */
  .note{padding:12px 14px; font-size:15px; flex-direction:column; gap:6px}
  .note .k{font-size:13px; align-self:flex-start; margin-top:0}
  .note .src{font-size:13.5px}
  .cue{font-size:15px; padding-left:12px}
  .btn{font-size:15.5px}
  .btn.sm{font-size:14.5px}
  .field label{font-size:14px}
  .field .hint{font-size:13px}
  .empty{font-size:15px}
  footer{font-size:13.5px; padding:18px 0 24px}
  footer code{font-size:13px}

  /* Cabeçalho enxuto; a navegação desce para o alcance do polegar */
  .hbar{height:56px; gap:10px}
  .brand{font-size:19px}
  .brand small{display:none}
  #theme{margin-left:auto}
  nav.tabs{
    position:fixed; left:0; right:0; bottom:0; z-index:30; margin:0;
    display:grid; grid-template-columns:repeat(4,1fr); gap:4px;
    background:var(--surface); border-top:1px solid var(--line);
    padding:6px 8px calc(6px + env(safe-area-inset-bottom));
  }
  .tab{border-radius:8px; font-size:13.5px; font-weight:600; padding:8px 2px}

  .panel{border-radius:12px}
  .panel + .panel{margin-top:12px}
  .panel-h{padding:13px 14px; gap:8px}
  .panel-b{padding:14px}
  .panel-h .btn{margin-left:0 !important; width:100%}
  #voltar{display:none}   /* a aba "Semana" no rodapé já faz isso; dois caminhos confundem */

  /* No cabeçalho, os selos viram uma linha de texto corrida: seis pílulas
     legíveis ocupariam três linhas antes de aparecer qualquer conteúdo.
     A linha ocupa a largura toda e fica abaixo do título — como item
     flexível ela partia junto com ele e o primeiro selo sobrava ao lado.
     Sendo texto corrido, a quebra acontece entre palavras e não entre
     caixas, que é o que faz tudo alinhar à mesma margem. */
  .chip{font-size:13px; padding:3px 9px}
  .ph-meta{display:block; flex-basis:100%; line-height:1.75; margin-top:2px}
  /* Quebra entre selos, nunca dentro de um: "12 séries/músculo" partido
     ao meio lê-se como duas informações. */
  .panel-h .chip{
    display:inline; background:none; border:0; padding:0;
    font-weight:600; white-space:nowrap;
  }
  /* O separador quebra, o selo não: sem isto o espaço do "·" fica
     dentro da região nowrap e a linha inteira perde onde partir. */
  .panel-h .chip::after{
    content:" · "; color:var(--line-2); font-weight:400; white-space:normal;
  }
  .panel-h .chip:last-child::after{content:""}

  /* Semana: um cartão por linha, dias de descanso reduzidos a uma tira */
  .week{grid-template-columns:1fr; gap:7px}
  .wk{grid-template-columns:1fr}
  .day{min-height:0; padding:14px}
  .day-name{font-size:13px}
  .day-num{font-size:13px}
  .day h4{font-size:17px}
  .day-foco{font-size:14px}
  .day .meta{font-size:13.5px}
  .day .btn{width:100%}
  .day.rest{flex-direction:row; align-items:center; gap:10px; padding:11px 14px}
  .day.rest .day-top{flex:none; gap:8px}
  .day.rest h4{font-size:14px; margin-left:auto; color:var(--muted)}
  .day.rest .meta{display:none}

  /* Exercício: o seletor de troca vira largura total abaixo do título */
  .ex-h{padding:13px 12px; gap:10px}
  .ex-h .n{width:26px; height:26px; font-size:13px}
  .ex-h h4{font-size:18px; line-height:1.25}
  .alias{font-size:14px; margin-top:3px}
  .ex-h > div{min-width:0}
  .troca{font-size:12px; letter-spacing:.06em}
  .troca select{font-size:16px}
  .ex-b{padding:12px}
  .presc{grid-template-columns:repeat(2,1fr); gap:8px}
  .presc dt{font-size:13px; letter-spacing:.06em}
  .presc dd{font-size:17px}
  .setrow,.sethead{grid-template-columns:26px 1fr 1fr 1fr 24px; gap:6px}
  .sethead span{font-size:13px; letter-spacing:.05em}
  .setrow .lbl{font-size:14px}
  .det summary,.det p{font-size:14px}
  .setrow .ok{font-size:17px}
  .sets{gap:9px}

  .grid.g4{grid-template-columns:repeat(2,1fr)}
  .stat{padding:12px 13px}
  .stat dt{font-size:13px}
  .stat dd{font-size:26px}
  .stat .d{font-size:13px}
  .slider output{font-size:16px}
  table{font-size:14px}
  th{font-size:13px; letter-spacing:.05em; padding:8px}
  td{padding:9px 8px}
  .vbar{min-width:60px}
}

@media (max-width:380px){
  body{font-size:16px}
  .panel-h h2{font-size:18px}
  .ex-h h4{font-size:17px}
  .setrow,.sethead{grid-template-columns:22px 1fr 1fr 1fr 20px; gap:4px}
  .setrow input{padding:8px 2px}
  .sethead span{font-size:12px; letter-spacing:0}
  .presc dt{font-size:12px}
  .presc dd{font-size:15px}
  .tab{font-size:13px}
}

/* =====================================================================
   Added for the server-backed client: sign-in, roles and async state.
   Everything above this line came from the single-file prototype.
   ===================================================================== */

/* ---------- Sign in / invite ---------- */
.gate{min-height:100dvh; display:grid; place-items:center; padding:24px 16px}
.gate-card{width:100%; max-width:420px}
.gate-brand{font-family:var(--f-display); font-weight:700; font-size:30px; letter-spacing:-.02em; text-align:center; margin-bottom:4px}
.gate-brand em{font-style:normal; color:var(--accent)}
.gate-sub{text-align:center; color:var(--muted); font-size:13.5px; margin-bottom:22px}
.gate form{display:flex; flex-direction:column; gap:14px}
.gate .btn{width:100%; justify-content:center}
.gate .alt{text-align:center; margin-top:14px}
.gate .alt button{background:none; border:0; color:var(--accent); font-weight:600; cursor:pointer; font-size:13.5px; padding:8px}
.form-error{background:var(--danger-soft); color:var(--danger); border-radius:var(--r-s); padding:10px 12px; font-size:13.5px}
.field.invalid input,.field.invalid select{border-color:var(--danger); outline-color:var(--danger)}
.field-error{color:var(--danger); font-size:12.5px; margin-top:4px}
.form-ok{background:var(--accent-soft); color:var(--accent); border-radius:var(--r-s); padding:10px 12px; font-size:13.5px}

/* ---------- Header extras ---------- */
.who{display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--muted)}
.who b{color:var(--ink); font-weight:600}
.rolechip{font-family:var(--f-mono); font-size:10px; font-weight:600; letter-spacing:.08em;
          text-transform:uppercase; padding:2px 7px; border-radius:100px;
          background:var(--surface-2); border:1px solid var(--line); color:var(--muted)}
.rolechip.trainer{background:var(--copper-soft); color:var(--copper); border-color:transparent}
.rolechip.admin{background:var(--danger-soft); color:var(--danger); border-color:transparent}

/* ---------- Async feedback ---------- */
.saving{position:fixed; left:50%; transform:translateX(-50%); bottom:88px; z-index:60;
        background:var(--ink); color:var(--ground); font-size:12.5px; font-weight:600;
        padding:7px 14px; border-radius:100px; box-shadow:var(--shadow);
        opacity:0; transition:opacity .18s; pointer-events:none}
.saving.on{opacity:.95}
.saving.err{background:var(--danger); color:#fff}
.skeleton{color:var(--muted); text-align:center; padding:40px 16px; font-size:13.5px}

/* ---------- Viewing another athlete ---------- */
.impersonate{background:var(--copper-soft); color:var(--copper); border-radius:var(--r);
             padding:10px 14px; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
             font-size:13.5px; margin-bottom:14px}
.impersonate .btn{margin-left:auto}

/* ---------- Suggested load ---------- */
.suggest{display:inline-flex; align-items:baseline; gap:6px; margin-top:4px;
         font-family:var(--f-mono); font-size:11.5px; color:var(--accent)}
.suggest span{color:var(--muted)}

/* ---------- Tables in admin/clients ---------- */
.tbl-actions{display:flex; gap:6px; flex-wrap:wrap}
.code-box{font-family:var(--f-mono); font-size:15px; font-weight:600; letter-spacing:.06em;
          background:var(--sunken); border-radius:var(--r-s); padding:11px 13px; word-break:break-all}

@media (max-width:720px){
  .who b{display:none}
  .gate-brand{font-size:28px}
  .saving{bottom:96px; font-size:14px}
}

/* ---------- Session clock ---------- */
/* Lives in the header so it is visible from every tab: someone resting
   between sets is often looking at the dashboard, not at the session. */
.timer{
  display:flex; align-items:baseline; gap:7px;
  font-family:var(--f-mono); font-variant-numeric:tabular-nums;
  background:var(--accent-soft); color:var(--accent);
  border-radius:100px; padding:4px 12px; font-weight:600; font-size:14px;
}
.timer small{font-family:var(--f-body); font-size:10.5px; font-weight:500; opacity:.75; letter-spacing:.04em}
.timer.idle{background:var(--warn-soft); color:var(--warn)}

/* ---------- Time-based sets ---------- */
/* A plank has no kilos and no repetitions. The row loses the columns it has
   no answer for instead of asking for them. */
.setrow.hold{grid-template-columns:34px 1fr 30px}
.sethead.hold{grid-template-columns:34px 1fr 30px}
.setrow.loadhold{grid-template-columns:34px 1fr 1fr 30px}
.sethead.loadhold{grid-template-columns:34px 1fr 1fr 30px}
.chip.iso{background:var(--warn-soft); color:var(--warn); border-color:transparent}

@media (max-width:720px){
  .timer{font-size:16px; padding:5px 13px}
  .timer small{display:none}
  .setrow.hold,.sethead.hold{grid-template-columns:26px 1fr 24px}
  .setrow.loadhold,.sethead.loadhold{grid-template-columns:26px 1fr 1fr 24px}
}
@media (max-width:380px){
  .setrow.hold,.sethead.hold{grid-template-columns:22px 1fr 20px}
  .setrow.loadhold,.sethead.loadhold{grid-template-columns:22px 1fr 1fr 20px}
}

/* A finished day gets a tick next to its name: on a phone the colour alone
   is easy to miss in gym lighting, and some users cannot rely on it. */
.day h4 .tick{color:var(--accent); font-weight:700}
.day.done h4 .tick{color:var(--accent)}

/* ---------- Trend column ---------- */
.trend{font-family:var(--f-mono); font-size:11.5px; color:var(--muted); white-space:nowrap}
.trend.up{color:var(--accent)}
.trend.down{color:var(--warn)}
.hintlet{font-family:var(--f-body); font-size:11px; color:var(--muted)}
/* The plan's own numbers are an audit trail, not a call to action. */
.det.audit{margin-top:16px; border-top:1px solid var(--line); padding-top:12px}
.det.audit table{margin-top:8px}
@media (max-width:720px){
  .trend{font-size:13px}
  .hintlet{font-size:12.5px; display:block}
}

/* ---------- Last time ---------- */
/* The ghost has to read as "this is not your number yet". Italic plus the
   muted colour does that without a legend; the input itself stays empty. */
.setrow input.ghost::placeholder{color:var(--muted); font-style:italic; opacity:.85}
.setrow.hasghost input{border-style:dashed}
.lastline{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin:10px 0 2px; font-family:var(--f-mono); font-size:11.5px; color:var(--muted);
}
.lastline > span:first-child{
  text-transform:uppercase; letter-spacing:.08em; font-weight:600;
}
.lastline b{color:var(--ink-2); font-weight:600}
.lastline .btn{margin-left:auto}

@media (max-width:720px){ .lastline{font-size:13.5px} }

/* =====================================================================
   Session card: one thing at a time

   Measured on an iPhone 14 (664 px of viewport): half the exercise cards
   were taller than the screen, and the technique cues alone accounted for
   170–237 px of that — more than the set rows they were pushing off. The
   card now leads with what is touched between sets and folds the rest.
   ===================================================================== */

/* ---------- The one control on the right of every row ---------- */
.mark{
  display:grid; place-items:center; text-align:center;
  font-size:15px; line-height:1; color:var(--muted);
  background:none; border:0; padding:0; font-family:inherit;
}
.mark.done{color:var(--accent)}
button.mark.confirm{
  color:var(--accent); cursor:pointer;
  /* It has to read as pressable, not as a status dot. */
  border:1px solid var(--accent-soft); border-radius:100px;
}
button.mark.confirm:hover{background:var(--accent-soft)}
button.mark.confirm:active{transform:scale(.92)}

/* ---------- How-to disclosure ---------- */

/* ---------- Progress and folding ---------- */
.ex-h{cursor:default}
.ex .progress{
  font-family:var(--f-mono); font-size:11.5px; font-weight:600;
  color:var(--muted); flex:none; align-self:flex-start;
}
.ex.complete .progress{color:var(--accent)}
.ex.complete .n{background:var(--accent); color:var(--accent-ink)}
/* ---------- One card at a time ----------
   `proximity` and not `mandatory`: a card with five sets and a long alias
   can still overflow, and mandatory snapping fights the user when it does.
   `scroll-snap-stop: always` is what gives one drag per card. Scoped to the
   session by a class on the root, so the other tabs scroll normally. */
:root.snap{scroll-snap-type:y proximity}
:root.snap .ex{scroll-snap-align:start; scroll-snap-stop:always}
/* Without a snap point at the bottom, the end of the page sits within
   proximity of the last card's snap point and the scroll gets pulled back
   up, hiding the two buttons that end a session. Aligned to the end
   rather than the start because that position is always reachable: it is
   where the panel's bottom meets the bottom of the screen. */
:root.snap .panel.finish{scroll-snap-align:end}
/* "end" means the bottom of the scrollport, and on a phone the bottom of
   the scrollport is behind the fixed tab bar. Without this the panel
   lands underneath it and the buttons cannot be pressed. */
:root.snap{scroll-padding-bottom:16px}

@media (pointer: coarse){
  .mark{min-height:46px; min-width:30px; font-size:19px}
  button.mark.confirm{font-size:20px}
}

@media (max-width:720px){
  .ex .progress{font-size:14px}
  :root.snap .ex{scroll-margin-top:60px}
  :root.snap{scroll-padding-bottom:calc(72px + env(safe-area-inset-bottom))}
}

/* =====================================================================
   Session card on a phone, second pass

   The first pass folded the cues away and then undid the gain: the chips
   wrapped onto three lines and the header became a 180 px band, the four
   prescription boxes cost another 134, and a sticky header inside a card
   with `overflow:hidden` left a white gap above itself and covered the
   content below. Seen on a real iPhone, not measured.
   ===================================================================== */

/* One line instead of four boxes; the boxes stay where there is room. */
.prescline{display:none}
.prescline b{font-family:var(--f-mono); font-weight:600; color:var(--ink)}
.prescline .sep{color:var(--line-2); margin:0 2px}

/* Native spinners are useless with a thumb and they eat the width the
   placeholder needs — "carga" was rendering as "carg⌃⌄". */
input[type="number"]{appearance:textfield; -moz-appearance:textfield}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}

@media (max-width:720px){
  .prescline{
    display:block; font-size:14px; color:var(--muted);
    padding:2px 0 10px; line-height:1.7;
  }
  .prescline b{font-size:15px}
  .presc{display:none}

  /* Header: name and progress. Everything else moved into the disclosure.
     The badge aligns with the title's line, not with the middle of a block
     that is two lines tall. */
  .ex-h{padding:12px; gap:9px; align-items:flex-start}
  .ex-h .n{margin-top:1px}
  .ex-h .progress{margin-top:3px}
  .ex-h h4{font-size:17px; line-height:1.25}
  .ex-h .tags{margin-top:6px}
}

/* =====================================================================
   "How to perform" sheet

   The bordered row it replaces was the shape of a combo box: it promised a
   dropdown and delivered prose, and cost 44 px on every card. An icon
   promises help, and a sheet has the room a picture or a clip of the
   movement will need.
   ===================================================================== */
.ex-h .info{
  flex:none; width:26px; height:26px; border-radius:100px;
  border:1px solid var(--line-2); background:none; cursor:pointer;
  color:var(--muted); font-family:var(--f-display); font-weight:700;
  font-size:13px; line-height:1; display:grid; place-items:center;
}
.ex-h .info:hover{border-color:var(--accent); color:var(--accent)}

dialog.sheet{
  border:0; padding:0; background:var(--surface); color:var(--ink);
  border-radius:var(--r); box-shadow:var(--shadow);
  width:min(520px, calc(100vw - 32px)); max-height:82dvh; overflow:auto;
}
dialog.sheet::backdrop{background:rgba(0,0,0,.45)}
dialog.sheet .sheet-h{
  display:flex; align-items:center; gap:12px;
  padding:14px 16px; border-bottom:1px solid var(--line);
  position:sticky; top:0; background:var(--surface); z-index:1;
}
dialog.sheet .sheet-h h3{font-family:var(--f-display); font-size:17px; flex:1; min-width:0}
dialog.sheet .sheet-b{padding:14px 16px 18px}
dialog.sheet .alias{margin:0 0 10px; font-size:13px; color:var(--muted)}
dialog.sheet .tags{display:flex; gap:5px; flex-wrap:wrap; margin-bottom:14px}
dialog.sheet .cue{margin-bottom:10px}
dialog.sheet .cue:last-child{margin-bottom:0}

/* A sheet of choices: one row per action, each with the consequence
   spelled out under it. Destructive rows say so in red rather than
   hiding behind a neutral label. */
dialog.sheet .acts{display:flex; flex-direction:column; gap:2px}
dialog.sheet .act{
  display:block; width:100%; text-align:left; background:none; cursor:pointer;
  border:0; border-radius:10px; padding:12px 12px; color:var(--ink);
  font-family:inherit; font-size:15px; font-weight:600;
}
dialog.sheet .act:hover{background:var(--line)}
dialog.sheet .act .hint{
  display:block; margin-top:3px; font-size:13px; font-weight:400;
  color:var(--muted); white-space:normal;
}
dialog.sheet .act.danger{color:var(--danger)}
dialog.sheet .act.danger .hint{color:var(--muted)}
dialog.sheet .confirm-b p{margin:0 0 18px; font-size:15px; line-height:1.5}
dialog.sheet .confirm-b .row{display:flex; gap:9px; justify-content:flex-end}
dialog.sheet .confirm-b .row .btn{flex:1}

/* The field to beat. Progressive overload is the second priority in the
   whole project (docs/12, nível 0) and this is all it needs on screen:
   the number, where the thumb already is, in the colour that means go. */
/* Verde, e ainda assim fantasma: mesma inclinação e mesmo peso do
   placeholder comum, só a cor muda. Preencher o campo e engrossar a fonte
   fazia a sugestão parecer um valor já digitado — e um número que ninguém
   levantou não pode se parecer com um que foi levantado. */
.setrow input.ghost.up{border-color:var(--accent)}
.setrow input.ghost.up::placeholder{color:var(--accent); opacity:.85}

.finish-acts{display:flex; gap:9px; margin-top:16px; flex-wrap:wrap}

/* The square sibling of the wide button on a finished day. */
.day .day-acts{display:flex; gap:6px; align-items:stretch}
.day .day-acts .btn{flex:1; min-width:0}
.day .kebab{
  flex:none; width:34px; border-radius:10px; cursor:pointer;
  border:1px solid var(--line-2); background:none; color:var(--muted);
  font-size:16px; line-height:1; letter-spacing:1px;
}
.day .kebab:hover{border-color:var(--accent); color:var(--accent)}

@media (max-width:720px){
  /* From the bottom, because that is where the thumb is. */
  dialog.sheet{
    width:100%; max-width:100%; top:auto; bottom:0;
    border-radius:14px 14px 0 0; max-height:88dvh;
    padding-bottom:env(safe-area-inset-bottom);
  }
  .ex-h .info{width:34px; height:34px; font-size:15px}
  /* Square, and a target a thumb can actually hit. */
  .day .kebab{width:48px; font-size:18px}
  /* Stacked and full width: two half-width buttons of different lengths
     on one line read as an accident. */
  .finish-acts{flex-direction:column}
  .finish-acts .btn{width:100%; padding:12px 16px; font-size:15px}
  dialog.sheet .sheet-h h3{font-size:19px}
  dialog.sheet .cue{font-size:15px}
}
@media (pointer: coarse){ .ex-h .info{min-height:34px} }

/* =====================================================================
   Rest timer

   Between sets the phone is on a bench and nobody is looking at it, so
   the signal is the whole edge of the screen: a border that shrinks as
   the rest runs out. It reads from arm's length and it is in the way of
   nothing, because the overlay takes no pointer events at all.

   Rest is a window and not a moment - the prescription gives a range per
   exercise - so the border also says which part of the range you are in:
   blue while it is still early, accent once the minimum has passed and
   you are cleared to lift.
   ===================================================================== */
#restring{
  position:fixed; z-index:60; pointer-events:none;
  /* --vv-top/--vv-bottom are where the visual viewport ends when the
     keyboard is up (app.js, trackVisualViewport); zero otherwise. */
  top:calc(env(safe-area-inset-top) + var(--vv-top, 0px)); right:env(safe-area-inset-right);
  bottom:calc(env(safe-area-inset-bottom) + var(--vv-bottom, 0px)); left:env(safe-area-inset-left);
}
#restring svg{width:100%; height:100%; display:block; overflow:visible}
/* The band is drawn as concentric strokes rather than one thick one: SVG
   has no gradient perpendicular to a stroke, and a linear one cannot
   follow four sides and four corners. Six rings of falling opacity read
   as a single band that fades inward, and they cost no filter. */
#restring path{
  fill:none; stroke:var(--ring);
  /* The dash starts at the top-left corner and unwinds clockwise. */
  transition:stroke .35s ease;
}
#restring.go path{stroke:var(--ring-go)}
#restring.hidden, #rest.hidden{display:none}

/* Bottom left, not bottom right. The right edge of the session is where
   every control already lives - the set marks, the info icons, the swap
   selector - and a floating button there covers one of them at some
   scroll position. The left edge holds only the set numbers. */
#rest{
  position:fixed; z-index:61; left:16px; bottom:calc(20px + var(--vv-bottom, 0px));
  display:flex; align-items:center; gap:6px;
}
#rest .rest-go{
  width:56px; height:56px; border-radius:100px; cursor:pointer;
  border:0; background:var(--rest); color:#fff;
  font-size:22px; line-height:1; display:grid; place-items:center;
  box-shadow:var(--shadow);
}
#rest .rest-go.running{background:var(--rest)}
#rest.go .rest-go.running{background:var(--accent)}
#rest .rest-t{
  font-family:var(--f-mono); font-size:16px; font-weight:600; color:#fff;
  /* Tabular figures, or the circle twitches every second. */
  font-variant-numeric:tabular-nums;
}
#rest .rest-acts{
  display:flex; align-items:center; gap:4px; padding:4px;
  background:var(--surface); border:1px solid var(--line);
  border-radius:100px; box-shadow:var(--shadow);
}
#rest .rest-acts button{
  width:40px; height:40px; border-radius:100px; cursor:pointer;
  border:0; background:none; color:var(--ink-2); font-size:16px;
  display:grid; place-items:center;
}
#rest .rest-acts button:hover{background:var(--line)}

@media (max-width:720px){
  /* Clear of the fixed tab bar as well. */
  /* With the keyboard up the tab bar is behind it, so the button only
     needs to clear the keyboard: whichever of the two is higher. */
  #rest{bottom:max(calc(72px + env(safe-area-inset-bottom) + 12px), calc(var(--vv-bottom, 0px) + 12px)); left:12px}
  /* 60 px and not more: at 64 the circle grazed the load field by 2 px. */
  #rest .rest-go{width:60px; height:60px; font-size:25px}
  #rest .rest-t{font-size:18px}
  #rest .rest-acts button{width:46px; height:46px; font-size:18px}
}
