/* The approved prototype, `prototype-in-gym-screen.html`, is the visual source of truth.
   Colours, type scale and spacing come from it unchanged. The white switcher bar of the
   prototype was scaffolding, so its `--bar` reserve is gone and the card gets that room. */
:root {
  --bg:#0f1115; --card:#171a21; --card2:#1e222b; --line:#2a2f3a;
  --fg:#e8eaed; --muted:#9aa0a8; --go:#4ade80; --rest:#fbbf24; --skip:#f87171;
  --gap:clamp(5px,1.2dvh,13px);
}
* { box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
/* `overscroll-behavior` stops the pull that reloads the page. A thumb that drags the card
   in the gym must never throw the screen away and start it again. */
/* The fonts ship with the shell, so the phone draws them with no network. Four families,
   one job each. Space Grotesk sets the words: the notes, the buttons, the sentences.
   Archivo sets the names: the Exercise, the Routine, the next machine. It is one variable
   file (every weight in one font), and the names take its 800.
   JetBrains Mono Bold sets every number: the weight, the count, the rows and the clock
   of the Rest, so a digit that changes never moves its neighbours. Space Mono sets the
   small labels in capitals, so a label reads as a label and never as a value. `swap`
   shows the system font while a font still loads, and never a blank card. */
@font-face { font-family:"Space Grotesk"; font-weight:400; font-display:swap;
  src:url(/fonts/SpaceGrotesk-Regular.ttf); }
@font-face { font-family:"Space Grotesk"; font-weight:500; font-display:swap;
  src:url(/fonts/SpaceGrotesk-Medium.ttf); }
@font-face { font-family:"Space Grotesk"; font-weight:700; font-display:swap;
  src:url(/fonts/SpaceGrotesk-Bold.ttf); }
@font-face { font-family:"Archivo"; font-weight:100 900; font-stretch:62% 125%;
  font-display:swap; src:url(/fonts/Archivo.ttf); }
@font-face { font-family:"JetBrains Mono"; font-weight:700; font-display:swap;
  src:url(/fonts/JetBrainsMono-Bold.ttf); }
@font-face { font-family:"Space Mono"; font-weight:400; font-display:swap;
  src:url(/fonts/SpaceMono-Regular.ttf); }
html,body { margin:0; background:#06070a; color:var(--fg); overscroll-behavior:none;
  font:16px/1.4 "Space Grotesk",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; }
.a-name, .a-routine b, .a-pick b, .a-top > b { font-family:"Archivo",sans-serif; font-weight:800; }
.a-srow .v, .a-left, .a-chg, .a-win, .a-sum .wt {
  font-family:"JetBrains Mono",monospace; }
.a-lbl, .a-prev, .a-next, .a-head, .muted.small, .a-ring .t span, .a-srow.head,
.a-routine .muted, .a-mant { font-family:"Space Mono",monospace; text-transform:uppercase;
  letter-spacing:.06em; }
/* The screen is one column of a fixed height. Nothing scrolls the page. */
#phone { max-width:430px; height:100dvh; margin:0 auto; background:var(--bg);
  position:relative; overflow:hidden; display:flex; flex-direction:column; }
#app { flex:1; min-height:0; display:flex; flex-direction:column; }
/* A write locks the screen, and a slow one dims it: see `locked` in `app.js`. Each element
   that holds no part of the tapped button dims, and the button stays bright. A dim with no
   button, as after a drag, dims each part of the screen. A long wait says why. */
#app.busy { pointer-events:none; }
#app.dim > :not(:has(.wait), .wait), #app.dim :has(.wait) > :not(:has(.wait), .wait) { opacity:.35; }
#app.slow::after { content:attr(data-wait); position:fixed; z-index:60; left:24px; right:24px;
  top:40%; padding:16px; border-radius:14px; background:var(--card2); text-align:center; }
/* The tutorial. `.a-slot` keeps its room in the card, 16:9 with the margins of the body,
   and `#video` floats over the slot. `hidden` keeps its display rule, so the frame takes
   no room while no Exercise has a video. */
.a-slot { flex:0 0 auto; aspect-ratio:16/9; margin:0; }
/* The player is taller than the box by `--crop` at each end. YouTube letterboxes the video
   in the middle and draws its title bar and its control bar in the black bands, so the box
   clips both bars and keeps the whole image. Tune `--crop` to the height of the bars. */
#video-box { --crop:56px; position:absolute; overflow:hidden; background:#000; }
#video { position:absolute; left:0; top:calc(-1 * var(--crop)); width:100%;
  height:calc(100% + 2 * var(--crop)); border:0; }
/* An Image fits whole in the slot, with black bars at the sides. The full-size view is a sheet,
   so the back button of the phone shuts it. A box with `aspect-ratio` grows to the height of
   its content, so a tall Image would stretch the slot: `overflow:hidden` keeps it 16:9. */
.a-img { background:#000; overflow:hidden; }
.a-img img, .a-full img { display:block; width:100%; height:100%; object-fit:contain; }
.a-sheet.a-full { align-items:center; background:#000; }
.a-pv { display:block; width:100%; aspect-ratio:16/9; object-fit:contain; background:#000;
  border-radius:12px; margin-bottom:8px; }
.a-pv[hidden] { display:none; }
button { font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
.muted { color:var(--muted); }
.notes { color:var(--muted); font-size:14px; }

/* three parts: the head holds still at the top, the body takes the room that is left,
   and the foot keeps the action on the thumb. The body never hides under the foot. */
.a-wrap { flex:1; min-height:0; display:flex; flex-direction:column; }
.a-top { flex:0 0 auto; display:flex; justify-content:space-between; align-items:center;
  padding:12px 16px; border-bottom:1px solid var(--line); }
.a-body { flex:1; min-height:0; overflow-y:auto; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:var(--gap);
  padding:var(--gap) 18px; text-align:center; }
.a-foot { flex:0 0 auto; padding:8px 16px calc(8px + env(safe-area-inset-bottom)); }
.a-lbl { font-size:11px; color:var(--muted); }
.a-sec { margin:12px 0 4px; } /* a label that opens a new part of a sheet */
.a-name { font-size:clamp(19px,3.1dvh,26px); font-weight:700; margin:0; line-height:1.15; }
.a-notes { margin:0; font-size:clamp(12px,1.7dvh,14px); }
.a-w { font:800 clamp(46px,8.6dvh,72px)/1 "JetBrains Mono",monospace; letter-spacing:-2px; }
.a-go { display:block; width:100%; background:var(--go); color:#06210f;
  font-size:clamp(16px,2.2dvh,18px); font-weight:800; padding:clamp(13px,2.1dvh,18px) 12px;
  border-radius:16px; }
.a-go.rest { background:var(--rest); color:#241a00; }
.small { font-size:11px; }

/* the ring of a Hold timer */
.a-ring { --r:clamp(140px,25dvh,200px); position:relative; flex:0 0 auto; margin:0;
  width:var(--r); height:var(--r); }
.a-ring svg { width:100%; height:100%; transform:rotate(-90deg); }
.a-ring .tr { stroke:var(--card2); }
.a-ring .fg { stroke:var(--rest); stroke-linecap:round; }
.a-ring .t { position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; }
.a-ring .t b { font:800 calc(var(--r) * .26)/1 "JetBrains Mono",monospace; color:var(--rest);
  letter-spacing:-2px; }
.a-ring .t span { font-size:clamp(11px,calc(var(--r) * .075),14px); }
.a-add { padding:10px 20px; font-size:15px; border-radius:999px; background:var(--card2); }

/* the result card: what the Exercise just decided */
.a-card { background:var(--card); border-radius:16px; padding:10px 14px; margin:0; width:100%;
  text-align:left; border-left:4px solid var(--line); }
.a-card.up { border-left-color:var(--go); } .a-card.down { border-left-color:var(--skip); }
.a-card.hold { border-left-color:var(--rest); }
.a-res { font-size:17px; margin-top:3px; }
.a-chg { display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  font-size:clamp(19px,2.8dvh,24px); font-weight:800; margin:3px 0 1px; }
.a-chg .ar { color:var(--muted); font-weight:400; }
.a-chg .old { font-size:16px; font-weight:600; color:var(--muted); }

/* the Routine opens the chooser, so the whole head reads as one tap target */
.a-routine { display:flex; align-items:center; gap:6px; padding:0; }

/* One row per set: its number, the weight, the count and the tick. A row with a tick dims,
   and its steppers stay live. A card with no weight has no weight column. */
.a-rows { width:100%; display:flex; flex-direction:column; gap:6px; }
.a-srow { display:grid; grid-template-columns:34px 1fr 1fr 44px; gap:6px; align-items:center; }
.a-rows.nw .a-srow { grid-template-columns:34px 1fr 44px; }
.a-srow.head { font-size:11px; color:var(--muted); }
.a-srow.on > :not(.tick) { opacity:.55; }
.a-srow .no { height:44px; border-radius:9px; background:var(--card2); font-weight:700; }
.a-step { display:flex; align-items:center; justify-content:space-between;
  background:var(--card2); border-radius:12px; }
.a-step button { width:40px; height:44px; font-size:20px; font-weight:700; }
.a-step button:disabled { opacity:.25; }
.a-step .v { flex:1; width:auto; min-width:0; font-size:18px; font-weight:800; text-align:center; }
.a-srow .tick { width:44px; height:44px; border-radius:50%; border:2px solid var(--muted);
  font-size:20px; font-weight:800; }
.a-srow .tick.on { background:var(--go); border-color:var(--go); color:#06210f; }
/* The bar of the Rest at the foot: the time left, −15s, +15s and Skip. No pause. */
.a-rest { display:flex; align-items:center; gap:8px; }
.a-rest > div { flex:1; display:flex; flex-direction:column; }
.a-left { font-size:26px; font-weight:800; color:var(--rest); line-height:1; }
.a-rest .a-add { padding:10px 12px; }
.a-rest .a-go { width:auto; padding:12px 18px; }

.a-sheet { position:fixed; inset:0; background:rgba(0,0,0,.7); z-index:40; display:flex;
  align-items:flex-end; justify-content:center; }
.a-sheet .in { width:min(430px,100vw); background:var(--card); border-radius:20px 20px 0 0;
  padding:10px 0 calc(10px + env(safe-area-inset-bottom));
  max-height:calc(100dvh - 20px); overflow:auto; }
.a-sheet .row, .a-reditor .row { display:block; width:100%; text-align:left; padding:13px 22px; font-size:16px; }
.a-sheet .row:active, .a-reditor .row:active { background:var(--card2); }

/* the pencil opens the Exercise Editor, the three lines open the sheet that lists the Routine,
   and the ✕ leaves the Routine Editor */
.a-dots { padding:2px 8px; color:var(--muted); }
.a-dots svg { display:block; width:22px; height:22px; fill:none; stroke:currentColor;
  stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round; pointer-events:none; }
/* the next Exercise of the Routine, over the thumb button, so a Jump reads as a choice */
.a-next { font-size:11px; color:var(--muted); text-align:center; padding-bottom:7px; }

/* the head of a sheet: its title and the ✕. It sticks, so a long list never scrolls the ✕ away */
.a-head { position:sticky; top:-10px; z-index:1; display:flex; align-items:center;
  justify-content:space-between; margin-top:-10px; padding:10px 8px 6px 22px;
  background:var(--card); font-size:11px; color:var(--muted); }
.a-head button { padding:8px 14px; font-size:22px; line-height:1; color:var(--muted); }
/* one row per Exercise: the wide part jumps and writes nothing, the narrow button skips */
.plan { display:flex; align-items:center; width:100%; }
.plan[hidden] { display:none; }
.a-sheet .plan.here { background:var(--card2); }
.plan .row { flex:1; min-width:0; }
.plan .row:disabled { color:var(--muted); } /* a Routine with no Exercise is no pick */
/* the handle of a row: a drag of it moves the row, so the browser must not scroll the list */
.a-grip { flex:0 0 auto; padding:13px 0 13px 22px; color:var(--muted); touch-action:none;
  user-select:none; -webkit-user-select:none; cursor:grab; }
.a-grip svg { display:block; width:22px; height:22px; fill:none; stroke:currentColor;
  stroke-width:2.5; stroke-linecap:round; pointer-events:none; }
.a-grip + .row { padding-left:10px; }
.plan.drag { background:var(--card2); opacity:.7; }
.a-sheet .st { margin-left:6px; color:var(--muted); }
.a-sheet .st.ok { color:var(--go); } .a-sheet .st.no { color:var(--skip); } .a-sheet .st.wait { color:var(--rest); }
.a-sheet .sk { flex:0 0 auto; padding:13px 22px; font-size:17px; color:var(--skip); }
.a-sheet .sk.on { color:var(--go); }
/* the pencil of a Routine in the chooser, and the list of the Routine Editor that it opens */
.a-sheet .plan .a-dots { padding:13px 22px; }
.a-reditor .a-body { padding:var(--gap) 0; gap:0; }
.a-reditor .a-dots { font-size:22px; line-height:1; }

/* one line of the previous Session, so the target is on the card before the set */
.a-prev { font-size:11px; color:var(--muted); }
/* the Maintain Override: a switch on the card, not a menu item. The thresholds dim while
   it holds, because the reps still count and the weight still does not move. */
.a-mant { flex:0 0 auto; padding:7px 16px; font-size:11px; border-radius:999px;
  background:var(--card2); color:var(--muted); }
.a-mant.on { background:var(--rest); color:#241a00; font-weight:700; }
/* the Finish, at the foot of the sheet that lists the Routine */
.a-fin { display:block; width:100%; text-align:center; margin-top:6px; padding:15px 22px;
  font-size:16px; font-weight:700; color:var(--go); border-top:1px solid var(--line); }
.a-fin:active { background:var(--card2); }
/* the Cancel, under the Finish, in the colour of the Skip: it throws the Session away */
.a-fin.cancel { color:var(--skip); }
/* the welcome: the cards share the body evenly, so four Activities fill the screen with no
   dead room at the top. Each card centres its three parts: the Activity name, the row that
   holds the Routine pill and the last Session, and the Start. The pill has the fill of a
   control and a chevron, so the eye reads it as a chooser before the thumb tries it. */
.a-body.wel { justify-content:stretch; padding:var(--gap) 16px; }
.a-body.wel .a-card { flex:1 0 auto; display:flex; flex-direction:column;
  justify-content:center; gap:clamp(8px,1.4dvh,14px); padding:14px 16px; border-left:0; }
.a-row { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.a-pick { display:inline-flex; align-items:center; gap:8px; padding:8px 14px;
  border-radius:999px; background:var(--card2); border:1px solid var(--line);
  font-size:15px; font-weight:500; white-space:nowrap; }
.a-pick:active { background:var(--line); }
.a-body.wel .a-go { margin:0; }

/* the summary of the Session that just closed: it proves the arithmetic, so the list
   starts at the top of the body and scrolls instead of standing in the middle. */
.a-body.top { justify-content:flex-start; }
.a-sum { display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  padding:4px 0; font-size:15px; }
.a-sum .nm { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.a-sum .wt { flex:0 0 auto; display:flex; align-items:baseline; gap:6px; font-weight:700; }
.a-sum .old { font-size:13px; font-weight:600; color:var(--muted); }
.a-sum .ar { color:var(--muted); font-weight:400; }

.a-win { width:100%; margin-bottom:7px; padding:12px; border-radius:12px; text-align:center;
  background:var(--card2); color:var(--fg); border:2px solid var(--line);
  font-family:inherit; font-size:24px; font-weight:800; }
.a-win:disabled { opacity:.35; }
/* The Exercise Editor: the choice of three, then the fields of that choice, one per line.
   The line under them is the Step line, or the error in the colour of the Skip. */
.a-kind { display:flex; gap:6px; padding:4px 22px 12px; }
.a-kind button { flex:1; padding:10px 4px; border-radius:12px; background:var(--card2);
  border:2px solid var(--line); font-size:13px; font-weight:700; }
.a-kind .on { border-color:var(--go); color:var(--go); }
.a-kind [data-v=other] { border-style:dashed; } /* the + opens a field for a higher count */
.a-form { display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:0 22px 6px; text-align:center; }
.a-form label { width:100%; }
.a-form .a-win { margin:3px 0 0; padding:9px; font-size:20px; }
/* the name and the Notes are text, so they read smaller than a number does */
.a-form .a-txt { font-size:15px; font-weight:600; resize:none; }
/* the Stack: one pill per weight, then the field and the + that add one */
.a-pins { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; }
.a-pins > button:not(.a-add) { padding:7px 12px; border-radius:999px; background:var(--card2);
  border:2px solid var(--line); font-size:14px; font-weight:700; }
.a-form .a-pins .a-win { width:92px; margin:0; }
/* the fields "from" and "to" of the range, side by side */
.a-two { display:flex; gap:8px; } .a-two > label { flex:1; }
.a-line { min-height:1.3em; } .a-line.bad { color:var(--skip); }
/* the field that adds a Routine or an Activity, the + at its end, and the refusal under it */
.a-new { gap:8px; padding:6px 22px; }
.a-new .a-win { flex:1; min-width:0; margin:0; padding:9px 12px; font-size:15px; font-weight:600;
  text-align:left; }
.a-bad { padding:0 22px 6px; color:var(--skip); }
/* the text of a question or of a message */
.a-ask { margin:0; padding:4px 22px 14px; }
.a-fin:disabled { color:var(--muted); }

/* The Hold timers of a Timed Exercise: the Rest ring in the colour of the set, one per
   side, side by side. A paused ring dims, so the eye tells a running clock at once. */
.a-holds { display:flex; justify-content:center; gap:18px; }
.a-holds > div { display:flex; flex-direction:column; align-items:center; gap:6px; }
.a-hold { padding:0; }
.a-ring.hold { --r:clamp(84px,13dvh,120px); }
.a-ring.hold .fg { stroke:var(--go); } .a-ring.hold .t b { color:var(--go); }
.a-hold.paused .a-ring { opacity:.55; }
.a-holds .a-add, .a-top .a-add { padding:6px 14px; font-size:13px; }
/* "Change Profile" and the language share the right end of the head of the welcome. */
.a-top > span { display:flex; gap:6px; }
/* The password form of the Picker takes the width of the column, as each field does. */
.a-login { width:100%; }
/* The Save of the Exercise Editor stays at the foot of the screen at each scroll. The sheet
   then has no padding at its foot, because the rows would show through that gap. */
.a-sheet .in:has(.a-stick) { padding-bottom:0; }
.a-stick { position:sticky; bottom:0; background:var(--card);
  padding-bottom:calc(15px + env(safe-area-inset-bottom)); }
.a-kind button:disabled { opacity:.4; }
/* the field of a count of sets above 4, in the place of the + */
.a-kind .a-win { flex:1; min-width:0; margin:0; padding:8px 4px; font-size:16px;
  border:2px solid var(--go); }
