/* train.css — the Train tab only (REVAMP-DESIGN §2.3, WP8).
 *
 * Every class here starts with train- or set-, so this file can never reach
 * into another tab's markup. The face and the logger are built from the kit
 * (ui.exerciseRow, ui.dock, ui.chip; base.css draws them); this file lays the
 * tab's own parts around them. Colour comes from the base.css tokens only:
 * the accent is the person (done sets, the live set, the rest ring), greys are
 * everything else, and red is only ever past a limit — nothing here is one.
 *
 * The set grid is the one piece of dense tabular UI in the app: four tracks,
 * tabular figures, 44px targets, and it must not overflow a 320 phone.
 */

/* ---------------------------------------------------------------- the face */

.train-session { display: grid; gap: 0; min-width: 0; }
.train-session-host { display: grid; min-width: 0; }

/* The progress: a meter with one solid segment per exercise's done sets, and
 * one line under it (§2.3 item 3). No box: it sits on the ground. */
.train-progress { margin: 2px 0 6px; }
.train-progress[hidden] { display: none; }
.train-meter { position: relative; height: 12px; }
/* The session as its own shape (§1's grammar, tab_train.js paintSessionMeter):
 * a group per exercise, as wide as its share of the sets, 6px apart; inside
 * it a segment per set, 2px apart. Planned is an outline in --edge, done is
 * solid in the person's mark, and the live exercise's next set is ringed in
 * accent ink — so the bar says where you are, not only how far. */
.train-meter-track {
  position: absolute;
  inset: 0;
  display: flex;
  gap: 6px;
}
.train-meter-ex {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  gap: 2px;
}
.train-meter-ex > i {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 3px;
  transition: background-color .14s var(--ease), box-shadow .14s var(--ease);
}
.train-meter-plan { box-shadow: inset 0 0 0 1.5px var(--edge); }
.train-meter-plan.train-meter-next { box-shadow: inset 0 0 0 2px var(--accent-ink); }
.train-meter-seg { background: var(--accent-mark); }
.train-progress-line {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 12px;
  margin-top: 8px;
  font: var(--t-cap);
  color: var(--ink-2);
}
.train-progress-saved:empty { display: none; }

/* The exercise rows. The row itself is ui.exerciseRow; each sits in its
 * block with the logger's body parked hidden beside it. */
.train-lists { display: grid; min-width: 0; }
.train-ex-list { display: grid; min-width: 0; }
.train-ex-list[hidden] { display: none; }
.train-ex { min-width: 0; }
.train-ex + .train-ex { border-top: 1px solid var(--line); }
.train-ex-row { min-width: 0; }

/* The marks a row may carry under its line: the finisher, the superset, an
 * unconfirmed machine. Words at the caption size, never a colour alone. */
.train-ex-marks {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  min-width: 0;
}
.train-ss-mark,
.train-confirm {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--surface-2);
  font: var(--t-cap);
  color: var(--ink-2);
  white-space: nowrap;
}
/* The finisher is a line of the prescription, not a control: words on the
 * row's own ground, the method in ink-2 and which set in the same voice —
 * never a filled pill that reads as a button (the row is the button). */
.train-fin {
  display: inline;
  font: 450 var(--t-cap-size)/1.35 var(--font);
  color: var(--ink-2);
  text-wrap: pretty;
}
.train-fin-scope { font-style: normal; font-weight: 450; color: var(--ink-2); }
.train-ss-mark[data-ss-state="on"] {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--accent-ink);
  color: var(--ink);
}
.train-ss-mark[data-ss-state="solo"] { background: transparent; box-shadow: inset 0 0 0 1px var(--edge); }
/* Unverified, never an error: a dashed outline in grey, and the words. */
.train-confirm { background: transparent; border: 1px dashed var(--ink-3); }

/* Inside a superset the rest points at the next station; its row is washed
 * the way a selected row is, so the walk is visible at a glance. */
.train-ex-next > .train-ex-row {
  margin: 0 calc(-1 * var(--s-3));
  padding: 0 var(--s-3);
  border-radius: var(--r-field);
  background: var(--accent-wash-bg);
}

.train-hint {
  margin: 14px 0 0;
  font: var(--t-sub);
  color: var(--ink-2);
  text-wrap: pretty;
}
.train-ex-none { margin: 4px 0; font: var(--t-body); color: var(--ink-2); text-wrap: pretty; }

/* The name and duration live with Finish (the summary sheet borrows them). */
.train-meta { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 10px; }
.train-meta[hidden] { display: none; }

.train-rows { min-width: 0; }

/* --------------------------------------------------------------- the dock
 *
 * ui.dock is sticky at the foot of the face (base.css), so it holds its
 * place in the flow and never covers a row; it is there only once the
 * session has begun. Its clock is the way into the Rest sheet. */

.train-dock[hidden] { display: none; }
.train-dock-rest {
  min-height: var(--tap);
  margin: -2px -6px;
  padding: 2px 6px;
  border-radius: var(--r-field);
  cursor: pointer;
}
.train-dock-rest:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.train-timer-next { white-space: nowrap; }

/* The Rest sheet: its length, the sound, whether a tick starts it, and Start
 * rest, or +15 s and Stop while one runs. */
.train-rest-sheet { display: grid; gap: var(--s-4); }
.train-rest-now { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.train-rest-clock { font: 600 44px/1 var(--font); font-stretch: 85%; letter-spacing: -.01em; }
.train-rest-say { font: var(--t-sub); color: var(--ink-2); }
.train-rest-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.train-timer-opts { min-width: 0; }
.train-timer-mute,
.train-timer-auto { min-width: var(--tap); }
/* The two toggles are chips with one constant name each; their state is
 * aria-pressed, shown by the chip's own pressed look and check (base.css
 * `.chip.is-done`), never by a label that changes. */

/* ------------------------------------------------------- the rest day face */

/* The day's mark on a soft disc, what comes next as the headline, why in one
 * line, Train anyway: centred in a stage of its own, the rows under it. */
.train-rest[data-rest] {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  padding: var(--s-8) var(--s-4) var(--s-6);
  text-align: center;
}
.train-rest-mark {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  margin-bottom: var(--s-2);
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--ink-2);
}
.train-rest-mark svg { width: 28px; height: 28px; }
.train-rest-head { margin: 0; font: 600 var(--t-head-size)/1.25 var(--font); color: var(--ink); text-wrap: balance; }
.train-rest-why { max-width: 34ch; margin: 0; font: var(--t-sub); color: var(--ink-2); text-wrap: balance; }
.train-rest-anyway { margin-top: var(--s-3); }

/* -------------------------------------------------------------- the logger
 *
 * The exercise's own screen (§2.3 "The set logger"): the strip, the set
 * rows, the chips, the words behind the numbers, next time, the 1-rep max.
 * The body is built once, parked hidden in its block, and MOVED here. */

.train-ex-screen { display: grid; min-width: 0; }
/* On a phone the dock travels into the logger. A short logger (three sets, no
 * history yet) would leave it floating half way down the glass with the rest
 * blank under it; the screen takes the height the chrome leaves (its header
 * about 140px, the tab bar under it) and the dock sits at its foot. A taller
 * logger grows past it, and the dock's own sticky foot takes over. */
.train-ex-screen:has(> .train-dock:not([hidden])) {
  min-height: calc(100dvh - 140px - var(--tabbar-h)
                   - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  grid-template-rows: auto 1fr;
}
.train-ex-screen > .train-dock { align-self: end; }
.train-ex-body { display: grid; min-width: 0; }
.train-ex-body[hidden] { display: none; }

/* Target · Effective · Last time, hairlines between (§2.3). */
.train-strip {
  display: flex;
  align-items: stretch;
  min-width: 0;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.train-strip-cell {
  display: grid;
  align-content: start;
  gap: 2px;
  min-width: 0;
  padding: 0 12px;
}
.train-strip-cell:first-child { padding-left: 0; }
.train-strip-cell + .train-strip-cell { border-left: 1px solid var(--line); }
.train-strip-k { font: var(--t-cap); color: var(--ink-2); }
.train-strip-v { font: 600 var(--t-row-size)/1.25 var(--font); text-wrap: balance; }

/* ----------------------------------------------------------- the set grid
 *
 * Four tracks: the set's number (a button: its sheet), the load, the reps,
 * the tick. The two boxes share what is left; the tick is the 48px target.
 * The tracks are the kit's (base.css `.setrow`) and the mockup's
 * (phone-setlogger-*.png): 22px for the number, so the boxes keep every
 * pixel the live set's steppers need at 320. */

.set-grid { display: grid; min-width: 0; }
.set-head,
.set-row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) minmax(0, 1fr) 48px;
  align-items: center;
  column-gap: var(--s-2);
}
.set-head {
  padding: 10px 0 8px;
  border-bottom: 1px solid var(--line);
  font: var(--t-cap);
  color: var(--ink-2);
  text-align: center;
}
.set-head-n,
.set-head-check { visibility: hidden; }

.set-row { min-height: 64px; padding: 8px 0; }
.set-row + .set-row { border-top: 1px solid var(--line); }

/* The set's number. A 22px track, a 44px target: the hit area reaches past
 * the track into the 8px gap on its right (to the load box's edge, never
 * over it) and 14px into the row's left gutter, where there is nothing else
 * to hit. */
.set-n {
  position: relative;
  width: 22px;
  height: var(--tap);
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--r-field);
  background: none;
  font: 600 var(--t-body-size)/1 var(--font);
  color: var(--ink-2);
}
button.set-n { cursor: pointer; }
button.set-n::before { content: ""; position: absolute; inset: 0 -8px 0 -14px; }
.set-row[data-state="live"] .set-n { color: var(--accent-ink); }
.set-row[data-warm="true"] .set-n { visibility: hidden; }

/* A box: a quiet ground for a done set, an outline in ink-3 for a ghost, the
 * accent-ink outline and the steppers for the live one. */
.set-cell {
  height: 48px;
  min-width: 0;
  display: flex;
  align-items: center;
  border-radius: var(--r-field);
  background: var(--quiet-bg);
  box-shadow: var(--lift), inset 0 0 0 1px var(--line);
}
.set-row[data-state="ghost"] .set-cell { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
.set-row[data-state="live"] .set-cell { background: transparent; box-shadow: inset 0 0 0 2px var(--accent-ink); }

.set-step {
  flex: none;
  width: 34px;
  height: 48px;
  display: none;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--r-field);
  background: none;
  color: var(--ink-2);
  cursor: pointer;
  touch-action: manipulation;
}
.set-row[data-state="live"] .set-step { display: grid; }
.set-step:hover { color: var(--ink); }

/* The number and its unit, printed by the pill from `data-unit`. Beside
 * each other in a box ("55 lb"); stacked in the live stepper, where the
 * steppers take the width. */
.set-pill {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: text;
}
.set-pill::after {
  content: attr(data-unit);
  flex: none;
  font: 450 var(--t-sub-size)/1 var(--font);
  color: var(--ink-2);
}
.set-pill[data-bare]::after { content: none; }
.set-pill input {
  flex: 0 1 auto;
  width: 3ch;
  min-width: 1.5ch;
  max-width: 100%;
  height: 100%;
  min-height: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: 600 20px/1 var(--font);
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
.set-pill input::-webkit-outer-spin-button,
.set-pill input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.set-pill input::placeholder { color: var(--ink-3); opacity: 1; }
/* A box with no target says its unit as a label, at the label's size — at
 * the value's size a bare "lb" read as a number that was there. */
.set-pill[data-bare] input::placeholder { font: 450 var(--t-body-size)/1 var(--font); }
.set-pill input:disabled { color: var(--ink); -webkit-text-fill-color: var(--ink); opacity: 1; }
.set-cell:focus-within { box-shadow: inset 0 0 0 2px var(--accent-ink); }

/* The live set shows its target as the value it will log (§2.3: "A tick logs
 * the target shown"), so its placeholder is in ink; a ghost's stays ink-3,
 * so nothing looks done before it is. */
.set-row[data-state="live"] .set-pill {
  flex-direction: column;
  gap: 1px;
}
.set-row[data-state="live"] .set-pill::after { font-size: var(--t-cap-size); line-height: 1; }
.set-row[data-state="live"] .set-pill input { flex: none; height: 22px; line-height: 22px; }
.set-row[data-state="live"] .set-pill:not([data-bare]) input::placeholder { color: var(--ink); }
.set-row[data-state="ghost"] .set-pill::after { color: var(--ink-3); }

/* The tick: the kit's 48px ring. Filled in the person's mark when done,
 * outlined in accent ink while live. */
.set-check {
  justify-self: end;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--edge);
  color: var(--ink-2);
  cursor: pointer;
  transition: background-color .14s var(--ease);
}
.set-check[aria-pressed="true"] { background: var(--accent-mark); box-shadow: none; color: var(--on-accent); }
.set-row[data-state="live"] .set-check { box-shadow: inset 0 0 0 2px var(--accent-ink); color: var(--accent-ink); }
.set-check[disabled] { cursor: default; }

/* A warm-up says so in words, under its boxes (never a bare letter). */
.set-tag { grid-column: 2 / -1; margin-top: 6px; }
.set-tag[hidden] { display: none; }
.set-extra[hidden] { display: none; }
.set-row-warm .set-pill input { font-weight: 450; }
/* NOT RECORDED: the dash in an empty box is read, so it is ink-2, never a
 * ghost's ink-3 (and never a zero). */
.set-row-unset .set-pill input::placeholder { color: var(--ink-2); }

/* The spring on a ticked set (§C4): short, one overshoot, and nothing at all
 * under prefers-reduced-motion (the class is never added then). */
.set-row-pop .set-check { animation: train-pop .24s var(--ease); }
@keyframes train-pop {
  0% { transform: scale(.86); }
  60% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* The set's sheet: reps in reserve, warm-up, plates. */
.set-sheet { display: grid; gap: var(--s-3); }
.set-sheet-cap { margin: 0; font: var(--t-row); }
.set-sheet-hint { margin: -8px 0 0; font: var(--t-sub); color: var(--ink-2); }
.set-sheet-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.set-rir-pick { min-width: 0; }
.set-plates { justify-self: start; }

/* Under the grid: the ratio, the plates on top, the myo field, the chips. */
.train-ratio,
.train-smith-plates {
  margin: 8px 0 0;
  font: var(--t-cap);
  color: var(--ink-2);
}
.train-smith-plates:empty { display: none; }
.train-myo-row { padding: 8px 0 0; }
.train-myo-row[hidden] { display: none; }
.train-ex-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  padding: 14px 0;
}
.train-note-host { display: contents; }
.train-ss[aria-pressed="true"] { border-color: var(--accent-ink); }
[hidden].train-myo-add { display: none; }

/* The words behind the numbers, under the sets. */
.train-ex-info {
  display: grid;
  gap: 6px;
  margin-top: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.train-ex-info:empty { display: none; }
/* The note's line is always there (it fills when a note is written); alone and
 * empty it must not leave a divider over nothing. */
.train-ex-info:has(> .train-note-said:only-child:empty) { display: none; }
.train-ex-info p { margin: 0; font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }
.train-note-said:empty { display: none; }
/* The Smith's convention: what the box wants, and whether the bar is known. */
.train-smith-note { color: var(--ink-2); }
.train-last-today { font-style: normal; color: var(--ink); }
.train-ex-data[hidden] { display: none; }

/* Next time; the estimated 1-rep max with its sparkline. */
.train-sec {
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.train-sec[hidden] { display: none; }
.train-sec-title { margin: 0; font: var(--t-row); }
.train-sec-sub { margin: 2px 0 0; font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }
.train-e1rm { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.train-e1rm-text { min-width: 0; }
.train-e1rm-spark { flex: none; width: 120px; }

/* The live exercise's logger as the wide pane's default (§3.4). */
.train-pane-head { justify-content: flex-end; min-height: var(--tap); }

/* The note sheet. */
.train-note-sheet { display: grid; gap: var(--s-3); }

/* ------------------------------------------------------ the session sheet */

.train-start-menu { display: grid; gap: var(--s-3); }
.train-start-cap { margin: 8px 0 0; font: var(--t-row); }
.train-start-tpls { display: grid; }
.train-start-row {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
}
.train-start-row + .train-start-row { border-top: 1px solid var(--line); }
.train-start-tpl,
.train-prog-tpl {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--tap);
  display: grid;
  gap: 2px;
  padding: 10px 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
}
button.train-start-tpl { cursor: pointer; }
.train-start-name { font: var(--t-row); overflow-wrap: anywhere; }
.train-start-sub { font: var(--t-sub); color: var(--ink-2); }
.train-tpl-open,
.train-prog-open {
  position: relative;
  flex: none;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: 500 var(--t-body-size)/1 var(--font);
  cursor: pointer;
}
.train-tpl-open::before,
.train-prog-open::before { content: ""; position: absolute; inset: -2px 0; }
.train-start-none { margin: 0; font: var(--t-sub); color: var(--ink-2); }
.train-tpl-new,
.train-prog-new { justify-self: start; }

/* ------------------------------------------- history and programs screens */

.train-history,
.train-programs { display: grid; gap: var(--s-2); min-width: 0; }
.train-sec-block { display: grid; gap: 4px; min-width: 0; }
.train-lift { display: grid; min-width: 0; }

/* ------------------------------------------------------------ narrow phones
 *
 * A face under 328 wide is a phone under 360: the boxes keep their numbers
 * by giving the steppers and the gaps a little less (the targets stay 44px
 * tall, and the tick keeps its 48). */
@container (max-width: 327.98px) {
  .set-head,
  .set-row { column-gap: 6px; }
  .set-step { width: 28px; }
  .set-pill input { font-size: 17px; }
  .train-strip-cell { padding: 0 8px; }
  .train-strip-v { font-size: var(--t-body-size); }
}

/* --------------------------------------------------------- add exercise -- */

.train-newex { display: grid; gap: 12px; }
.train-newex-status:empty { display: none; }

.train-newex-cap {
  font: var(--t-cap);
  color: var(--ink-2);
  margin: 0;
}

/* ------------------------------------------------------- exercise picker -- */

.train-pick { display: grid; gap: 14px; }

.train-pick-list {
  display: grid;
  gap: 14px;
  max-height: 46vh;
  overflow-y: auto;
}

.train-pick-group { display: grid; gap: 6px; }

.train-pick-group-name {
  font: var(--t-cap);
  color: var(--ink-2);
}

.train-pick-group-items { display: grid; }

.train-pick-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 10px;
  width: 100%;
  min-height: var(--tap);
  padding: 8px 0;
  border: 0;
  border-top: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  text-align: left;
  font: inherit;
  cursor: pointer;
}

.train-pick-group-items > .train-pick-item:first-child { border-top: 0; }

.train-pick-item:hover { color: var(--ink); }

.train-pick-name { font: 500 var(--t-body-size)/1.3 var(--font); overflow-wrap: anywhere; }

.train-pick-meta {
  grid-column: 1;
  font: var(--t-cap);
  color: var(--ink-2);
}

.train-pick-last {
  grid-row: 1 / span 2;
  grid-column: 2;
  font: var(--t-sub);
  color: var(--ink-2);
  white-space: nowrap;
}

/* A lift you have actually done is the one you are most likely reaching for. */
.train-pick-seen .train-pick-name { color: var(--ink); }

/* -------------------------------------------------------- template editor - */

.train-tpl { display: grid; gap: 12px; }

.train-tpl-head,
.train-tpl-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 50px 56px auto;
  align-items: center;
  gap: 6px;
}

.train-tpl-head {
  font: var(--t-cap);
  color: var(--ink-2);
  padding: 0 2px;
}

.train-tpl-rows { display: grid; gap: 6px; }

.train-tpl-ex {
  font: 500 var(--t-body-size)/1.3 var(--font);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

input.train-tpl-sets,
input.train-tpl-reps {
  min-height: var(--tap);
  padding: 10px 6px;
  text-align: center;
  font: 600 var(--t-row-size)/1 var(--font);
}

.train-tpl-row-actions { display: flex; gap: 4px; }

/* Reorder and delete are the same size as every other control: three 44px
 * squares. The sets/reps tracks pay for the width so the row still fits the
 * 390px sheet. */
.train-tpl-up,
.train-tpl-down,
.train-tpl-del {
  width: var(--tap);
  min-height: var(--tap);
  border: 1px solid var(--edge);
  border-radius: var(--r-field);
  background: transparent;
  color: var(--ink-2);
  font: 600 var(--t-body-size)/1 var(--font);
  cursor: pointer;
}

.train-tpl-up:hover,
.train-tpl-down:hover,
.train-tpl-del:hover { color: var(--ink); }

.train-tpl-actions { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }

.train-tpl-status:empty { display: none; }

.train-tpl-pack { margin: -4px 0 0; }

/* -------------------------------------------------------- plate calculator */

.train-plate { display: grid; gap: 12px; }

.train-plate-bars { min-width: 0; }

.train-plate-cap {
  font: var(--t-cap);
  color: var(--ink-2);
  margin: 0;
}

.train-plate-side {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: var(--tap);
  align-items: center;
}

.train-plate-item {
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  background: var(--surface-2);
  font: 600 var(--t-body-size)/1 var(--font);
  white-space: nowrap;
}

.train-plate-total { font: 600 var(--t-row-size)/1.4 var(--font); margin: 0; }

/* A weight the plates cannot make is said in words, in ink: it is a fact
 * about the iron, not a limit the person crossed (red is only that, §4.1). */
.train-plate-warn {
  font: var(--t-sub);
  color: var(--ink);
  margin: 0;
}

.train-plate-warn:empty { display: none; }

.train-plate-note,
.train-plate-hint { margin: 0; }

/* ------------------------------------------------------- past session ----- */

.train-past { display: grid; gap: 14px; }
/* The logged session as it was logged: the face's own shape, no fields. */
.train-past-view { gap: 0; }
.train-past-line { align-items: center; }
.train-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.train-past-acts .train-past-cancel { margin-left: auto; }
.train-past-exits {
  justify-content: space-between;
  margin-top: var(--s-2);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}
/* A null in a set is NOT RECORDED: the dash in its box, and these words. */
.train-unset-note { margin: 8px 0; font: var(--t-sub); color: var(--ink-2); text-wrap: pretty; }


/* ------------------------------------------------------ recent sessions -- */

/* A row that opens the session: its name and the day on the first line, what
 * it held on the second, a chevron at the end — the nav row's shape (§5),
 * built by hand because the row's words are three spans the tests and the
 * screen reader walk. */
.train-session-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 20px;
  grid-template-areas: "slot date chev" "sub sub chev";
  align-items: center;
  gap: 2px 10px;
  width: 100%;
  min-width: 0;
  min-height: 64px;
  padding: 10px 0;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  font: inherit;
}
button.train-session-main { cursor: pointer; }
button.train-session-main:active { background: var(--surface); }

.train-session-slot { grid-area: slot; min-width: 0; font: var(--t-row); overflow-wrap: anywhere; }
.train-session-date { grid-area: date; font: var(--t-sub); color: var(--ink-2); white-space: nowrap; }
.train-session-sub { grid-area: sub; min-width: 0; font: var(--t-sub); color: var(--ink-2); }
.train-session-chev { grid-area: chev; display: grid; place-items: center; color: var(--ink-3); }
.train-session-chev svg { width: 20px; height: 20px; }

/* ------------------------------------------------------------- history --- */

/* The lifts, on the kit's rail (.chips.is-rail: one line that scrolls); the
 * one shown is the kit's selected chip (a wash and an accent-ink edge). */
.train-sec-history .train-chips { margin-top: 2px; margin-bottom: 6px; }
.train-chip { white-space: nowrap; }

.train-history-chart { display: grid; gap: 8px; }

.train-history-stats { margin-top: 2px; }

.train-loading { margin: 0; font: var(--t-sub); color: var(--ink-2); }

/* ------------------------------------------------------------------ PRs -- */

/* A record per lift, in two lines that never squeeze the name: the lift and
 * its best load on the first, its group and day against its e1RM on the
 * second. The two wrappers dissolve into one 2 x 2 grid (display: contents),
 * so each line's halves share a baseline and the right column is as wide as
 * its widest figure and no wider. */
.train-pr-list { display: grid; }

.train-pr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "ex w" "g sub";
  align-items: baseline;
  column-gap: 16px;
  row-gap: 2px;
  min-height: 60px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.train-pr[hidden] { display: none; }

.train-pr-list > .train-pr:first-child { border-top: 0; }

.train-pr-name,
.train-pr-nums { display: contents; }

.train-pr-ex { grid-area: ex; min-width: 0; font: var(--t-row); overflow-wrap: anywhere; }

.train-pr-group { grid-area: g; min-width: 0; font: var(--t-sub); color: var(--ink-2); }

.train-pr-weight {
  grid-area: w;
  justify-self: end;
  font: 600 var(--t-row-size)/1.3 var(--font);
  white-space: nowrap;
}

.train-pr-sub {
  grid-area: sub;
  justify-self: end;
  font: var(--t-sub);
  color: var(--ink-2);
  text-align: right;
}

.train-pr-more { justify-self: start; margin-top: 8px; }

/* ---------------------------------------------------------------- volume - */

/* The switch, then one line naming the week (and, mid-week, what the tick on
 * each band means), then the bars, then a row per group against its band. */
.train-vol-head { margin-bottom: 4px; }
.train-vol-sofar {
  margin: 0 0 4px;
  font: var(--t-sub);
  color: var(--ink-2);
  text-wrap: pretty;
}

.train-volume-chart { display: grid; gap: 8px; }
.train-volume-chart[hidden],
.train-vol-why[hidden] { display: none; }

/* The target bands (Build Spec 4 §B5). One row per muscle group the program
 * prescribes: the name and "3 / 9–13" on the first line, the track under it
 * (the band a region, the logged sets the fill, the by-now tick while the
 * week runs) with the verdict's word at its end. Grey throughout: under a
 * band is a note, never the accent (it never warns) and never red (a band
 * is not a limit, §4.1). */
.train-vol-bands { display: grid; margin-top: 8px; }
.train-vol-bands:empty { display: none; }

.train-vol-all { margin: 10px 0 0; font: var(--t-sub); color: var(--ink); }
.train-vol-all[hidden] { display: none; }

.train-vol-band {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 72px;
  grid-template-areas: "g n" "t st";
  align-items: center;
  gap: 6px 12px;
  padding: 10px 0 12px;
}
.train-vol-band + .train-vol-band { border-top: 1px solid var(--line); }
.train-vol-band-quiet { grid-template-areas: "g n" "t t"; }
.train-vol-band-quiet .train-vol-st { display: none; }

.train-vol-g { grid-area: g; font: 500 var(--t-body-size)/1.3 var(--font); color: var(--ink); }
.train-vol-n {
  grid-area: n;
  justify-self: end;
  font: 450 var(--t-sub-size)/1.3 var(--font);
  color: var(--ink-2);
  white-space: nowrap;
}
.train-vol-n b { font-weight: 600; color: var(--ink); }

.train-vol-track {
  grid-area: t;
  position: relative;
  display: block;
  height: 10px;
  border-radius: 5px;
  background: var(--surface-2);
}

/* The band: a shaded span with its ends marked, because it is the target,
 * not the reading. */
.train-vol-band-mark {
  position: absolute;
  top: -3px;
  bottom: -3px;
  min-width: 2px;
  border-left: 2px solid var(--ink-3);
  border-right: 2px solid var(--ink-3);
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}

/* What the week asks for by now: an outline (planned, §1), under the fill. */
.train-vol-pace {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 5px;
  box-shadow: inset 0 0 0 1.5px var(--ink-2);
}

/* Done: solid. */
.train-vol-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 5px;
  background: var(--ink);
}

.train-vol-st {
  grid-area: st;
  justify-self: end;
  font: var(--t-cap);
  color: var(--ink-2);
  white-space: nowrap;
}

.train-vol-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 14px;
  font: var(--t-cap);
  color: var(--ink-2);
}
.train-vol-legend[hidden] { display: none; }
.train-vol-key { display: inline-flex; align-items: center; gap: 6px; }
.train-vol-key > i { width: 18px; height: 10px; border-radius: 5px; }
.train-vol-key-done { background: var(--ink); }
.train-vol-key-pace { box-shadow: inset 0 0 0 1.5px var(--ink-2); }
.train-vol-key > i.train-vol-key-band {
  border-radius: 0;
  border-left: 2px solid var(--ink-3);
  border-right: 2px solid var(--ink-3);
  background: color-mix(in srgb, var(--ink) 12%, var(--surface-2));
}

.train-vol-why {
  margin: 12px 0 0;
  font: var(--t-cap);
  color: var(--ink-2);
  text-wrap: pretty;
}

/* ----------------------------------------------------- the review sheet -- */

/* What the ledger is about to be told, before it is told (§C4): the session
 * in three figures, its records, every set, the name and minutes, and Log in
 * the corner. */
.train-sum { display: grid; gap: var(--s-5); }

.train-sum-head { margin: 0; font: var(--t-sub); color: var(--ink-2); }

/* Three figures in a hairline grid: large condensed numbers, a word under
 * each. */
.train-sum-rows {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.train-sum-row {
  display: grid;
  align-content: start;
  gap: 4px;
  min-width: 0;
  padding: 14px 12px 14px 0;
}
.train-sum-row + .train-sum-row { padding-left: 12px; border-left: 1px solid var(--line); }
.train-sum-v {
  font: 600 32px/1 var(--font);
  font-stretch: 85%;
  letter-spacing: -.01em;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.train-sum-k { font: var(--t-cap); color: var(--ink-2); text-wrap: pretty; }

.train-sum-myo { margin: -8px 0 0; font: var(--t-sub); color: var(--ink-2); }

.train-sum-cap {
  margin: 0 0 4px;
  font: var(--t-cap);
  color: var(--ink-2);
}

/* Records: one quiet line when there are none; a block on the surface step
 * with the person's check when there are (a record is theirs, not a
 * warning). */
.train-sum-prs { display: grid; gap: 4px; }
.train-sum-prs.train-sum-prs-on {
  padding: 12px 14px;
  border-radius: var(--r-tile);
  background: var(--surface-2);
}
.train-sum-pr { margin: 0; font: 600 var(--t-body-size)/1.4 var(--font); color: var(--ink); }
.train-sum-none,
.train-sum-check { margin: 0; font: var(--t-sub); color: var(--ink-2); }

/* Every set, per exercise, as it will be posted (Appendix A: "Finish shows
 * every set before writing"). The name wraps above its sets on a narrow phone
 * rather than squeezing them. */
.train-sum-list { display: grid; }

.train-sum-ex {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 12px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}

.train-sum-ex-name { min-width: 0; font: 500 var(--t-body-size)/1.35 var(--font); color: var(--ink); }

.train-sum-ex-sets { font: var(--t-sub); color: var(--ink-2); text-align: right; }

.train-sum-unticked {
  margin: 6px 0 0;
  font: var(--t-sub);
  color: var(--ink-2);
}

/* The session's name and minutes, and "Use 47 min" beside them. */
.train-sum-fields { display: grid; gap: var(--s-2); }
.train-sum-use { justify-self: end; }
.train-sum-use[hidden] { display: none; }

.train-sum-note { margin: 0; font: var(--t-cap); color: var(--ink-2); }

/* §A4: a PR is where a 15 lb assumption stops being academic, so the sheet owns
 * it in a line of its own — neutral, dashed like every estimate (§1: the
 * accent never warns). */
.train-sum-bar {
  margin: 6px 0 0;
  padding: 8px 10px;
  border-radius: var(--r-field);
  border: 1px dashed var(--ink-3);
  font: var(--t-cap);
  color: var(--ink-2);
}

/* ------------------------------------------------------------- skeleton -- */

/* The screen while it is asking (§C4). Grey bars only: nothing here can be
 * mistaken for a number, and the card titles above them are the real ones, so
 * the layout does not jump when the data lands. */
.train-skeleton { display: grid; gap: 14px; }

.train-skel-say {
  font: var(--t-cap);
  color: var(--ink-2);
}

/* The face's own shape: a meter, then rows of a name, a line and a tick. */
.train-skel-meter .train-skel { height: 12px; width: 100%; }
.train-skel-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 68px;
  border-top: 1px solid var(--line);
}
.train-skel-lines { flex: 1 1 auto; display: grid; gap: 8px; }
.train-skel-sub { height: 10px; }
.train-skel.train-skel-tick { flex: none; width: 48px; height: 48px; border-radius: 999px; }

.train-skel {
  display: block;
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg,
    var(--surface-2) 0%,
    color-mix(in srgb, var(--ink-3) 22%, var(--surface-2)) 50%,
    var(--surface-2) 100%);
  background-size: 220% 100%;
  animation: train-shimmer 1.5s linear infinite;
}

@keyframes train-shimmer {
  from { background-position: 120% 0; }
  to { background-position: -120% 0; }
}

/* ---------------------------------------------------------------- cardio - */

/* The screen is the record (the window by kind, then every session); logging
 * is the corner's Log, a sheet (tab_train.js cardioCard). */
.train-cardio-park[hidden] { display: none; }
.train-cardio-form { display: grid; gap: var(--s-4); }
.train-cardio-log[hidden] { display: none; }

/* Three number inputs in a sheet: the tracks must be allowed to go below an
 * input's min-content width or the form overflows and is simply clipped. */
.train-cardio-nums-in { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }

/* The kinds this person has actually logged, as the kit's choice chips.
 * Tapping one puts the LABEL in the field and remembers the ledger's KEY
 * behind it, so the app never mints a second spelling of the same morning. */
.train-cardio-picks { margin-top: calc(-1 * var(--s-2)); }

.train-cardio-cap {
  margin: 0;
  padding: 4px 0 6px;
  font: var(--t-cap);
  color: var(--ink-2);
}

/* The window by kind: a quiet two-column table under a caption. */
.train-cardio-sum { display: grid; margin-bottom: var(--s-5); }
.train-cardio-tag {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.train-cardio-tag-k { min-width: 0; font: 500 var(--t-body-size)/1.3 var(--font); color: var(--ink); }
.train-cardio-tag-v { flex: none; font: var(--t-sub); color: var(--ink-2); white-space: nowrap; }

/* The window in three figures over the table: the finish receipt's hairline
 * grid and its large condensed numbers, a word under each. */
.train-cardio-figs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-bottom: var(--s-2);
  border-top: 1px solid var(--line);
}
.train-cardio-fig {
  display: grid;
  align-content: start;
  gap: 4px;
  min-width: 0;
  padding: 14px 12px 14px 0;
}
.train-cardio-fig + .train-cardio-fig { padding-left: 12px; border-left: 1px solid var(--line); }
.train-cardio-fig-v {
  font: 600 32px/1 var(--font);
  font-stretch: 85%;
  letter-spacing: -.01em;
  color: var(--ink);
}
.train-cardio-fig-k { font: var(--t-cap); color: var(--ink-2); }

.train-cardio-item:first-child { border-top: 1px solid var(--line); }

.train-cardio-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 60px;
  padding: 10px 0;
}

.train-cardio-main { display: grid; gap: 2px; min-width: 0; }

.train-cardio-name { font: var(--t-row); overflow-wrap: anywhere; }

.train-cardio-date { font: var(--t-sub); color: var(--ink-2); }

.train-cardio-nums {
  display: grid;
  gap: 2px;
  text-align: right;
  flex: none;
}
.train-cardio-main-n { font: 500 var(--t-body-size)/1.3 var(--font); color: var(--ink); }
.train-cardio-sub-n { font: var(--t-cap); color: var(--ink-2); }
.train-cardio-sub-n:empty { display: none; }

/* ------------------------------------------------------ interval runner -- */

/* The conditioning timer, as a dial. Everything here is greyscale except one
 * thing: the WORK phase, which takes the person's accent because "am I
 * working or recovering" is the single piece of information this screen
 * exists to broadcast, and it has to survive being read at arm's length,
 * upside down, out of breath. Red is only past a limit (REVAMP-DESIGN §1 rule
 * 3), so it is never the work colour. Rest is plain ink on the ground: the
 * absence of the accent IS the recovery signal.
 */

.train-int { display: grid; gap: var(--s-8); }

/* The stage: the dial, the round pips, one line, the controls. Centred, on
 * the ground, no box. */
.train-int-stage {
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  padding-top: var(--s-2);
}

.train-int-dial {
  position: relative;
  width: min(240px, 72vw);
  aspect-ratio: 1;
}
.train-int-ring { display: block; width: 100%; height: 100%; }
.train-int-ring-track { fill: none; stroke: var(--line); stroke-width: 8; }
.train-int-arc {
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dashoffset .95s linear, stroke .2s var(--ease);
}

.train-int-face {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 2px;
  text-align: center;
}

.train-int-phase {
  font: 500 var(--t-body-size)/1.2 var(--font);
  color: var(--ink-2);
}

.train-int-clock {
  font: 600 60px/1 var(--font);
  font-stretch: 85%;
  letter-spacing: -.01em;
  color: var(--ink-2);
  transition: color .2s var(--ease);
}

.train-int-round {
  font: var(--t-sub);
  color: var(--ink-2);
}

/* Idle, the ring is its track alone: nothing is counting. */
.train-int[data-phase="idle"] .train-int-arc { stroke: transparent; }
.train-int[data-phase="lead"] .train-int-arc { stroke: var(--edge); }
.train-int-live .train-int-clock { color: var(--ink); }
.train-int[data-phase="rest"] .train-int-arc { stroke: var(--ink-2); }

/* The one colour change the runner is allowed: the work phase is the
 * person's own accent — the ring, the clock and its word. Never red. */
.train-int[data-phase="work"] .train-int-arc { stroke: var(--accent-mark); }
.train-int[data-phase="work"] .train-int-clock,
.train-int[data-phase="work"] .train-int-phase { color: var(--accent-ink); }

.train-int[data-phase="done"] .train-int-arc { stroke: var(--accent-mark); }
.train-int[data-phase="done"] .train-int-phase { color: var(--ink); }

.train-int-paused .train-int-clock { color: var(--ink-3); }

.train-int-pulse .train-int-clock { animation: train-breathe 2s var(--ease) infinite; }
@keyframes train-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: .82; }
}

/* A pip per round: planned an outline, done filled, the one under way ringed
 * in accent ink. */
.train-int-pips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; min-height: 10px; }
.train-int-pips i {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1.5px var(--edge);
}
.train-int-pips i.train-int-pip-done { background: var(--accent-mark); box-shadow: none; }
.train-int-pips i.train-int-pip-now { box-shadow: inset 0 0 0 2px var(--accent-ink); }

.train-int-note {
  margin: 0;
  max-width: 34ch;
  font: var(--t-sub);
  color: var(--ink-2);
  text-align: center;
  text-wrap: balance;
}
.train-int-note:empty { display: none; }

.train-int-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--tap);
  margin-top: var(--s-1);
}
.train-int-actions > [hidden] { display: none; }
.train-int-go { min-width: 160px; }
.train-int-pause,
.train-int-stop { min-width: 112px; }

/* Once a run ends: the optional peak heart rate and Log, side by side. */
.train-int-finish {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--s-3);
  width: 100%;
  max-width: 360px;
}
.train-int-finish[hidden] { display: none; }

.train-int-cap {
  margin: 0;
  padding-bottom: 6px;
  font: var(--t-cap);
  color: var(--ink-2);
}

/* The protocols: a list to pick from, one always picked. */
.train-int-protos { display: grid; border-top: 1px solid var(--line); }
.train-int-proto {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24px;
  align-items: center;
  gap: 4px 10px;
  min-height: 60px;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.train-int-proto[disabled] { cursor: default; }
.train-int-proto[disabled]:not(.train-int-proto-on) { opacity: .55; }
.train-int-proto-main { display: grid; gap: 2px; min-width: 0; }
.train-int-proto-name { font: var(--t-row); }
.train-int-proto-shape { font: var(--t-sub); color: var(--ink-2); }

/* Where the protocol came from: words on the shape's line, as templates say it. */
.train-int-proto-tag { white-space: nowrap; }
.train-int-proto-check { display: grid; place-items: center; color: var(--accent-ink); visibility: hidden; }
.train-int-proto-check svg { width: 18px; height: 18px; stroke-width: 2.4; }
.train-int-proto-on .train-int-proto-check { visibility: visible; }

/* The program's own line, quoted: set off by a rule at its left, its
 * attribution a caption over it. */
.train-int-rule {
  margin: 16px 0 4px;
  padding: 2px 0 2px 12px;
  border-left: 2px solid var(--line);
  font: var(--t-sub);
  color: var(--ink);
  text-wrap: pretty;
}
.train-int-rule-k { display: block; margin-bottom: 2px; font: var(--t-cap); color: var(--ink-2); }

.train-int-item:first-child { border-top: 1px solid var(--line); }
.train-int-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 60px;
  padding: 10px 0;
}

.train-int-item-main { display: grid; gap: 2px; min-width: 0; }

.train-int-item-name { font: var(--t-row); }

.train-int-item-date { font: var(--t-sub); color: var(--ink-2); }

.train-int-item-nums {
  flex: none;
  text-align: right;
  font: var(--t-sub);
  color: var(--ink-2);
}

/* ------------------------------------------------------------ responsive - */

@container (max-width: 376px) {
  .train-meta { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .train-routine-months { gap: 8px; }
  .train-tpl-head,
  .train-tpl-row { grid-template-columns: minmax(0, 1fr) 46px 50px auto; gap: 6px; }
}

/* Reduced motion takes the animation and nothing else. The tones keep firing —
 * timer.js never asks this question, because a countdown nobody can hear is
 * the bug, not the courtesy. */
@media (prefers-reduced-motion: reduce) {
  .train-int-pulse .train-int-clock { animation: none; }
  .train-int-arc { transition: none; }
  .set-row-pop .set-check { animation: none; }
  .train-meter-ex > i { transition: none; }
  .set-check { transition: none; }
  .train-skel { animation: none; }
}


/* --------------------------------------------------------- the record rows -
 *
 * Recent sessions, history, records, volume, intervals, cardio: base.css's
 * `.nav-row` inside a `.nav-list`, each opening a screen. The cards they open
 * are parked here, hidden, and moved into the screen on tap. */
.train-screen-store[hidden] { display: none; }

/* ------------------------------------------------------ the day's cardio -
 *
 * fb_4d5aefd9 §4. The conditioning logged on the day being viewed, as rows
 * under the session and above the record: one line naming the day, then
 * base.css's `.nav-row` per session. No box of its own — a card here would be
 * a second session card competing with the real one, which is exactly the
 * proportion this is meant to fix.
 */
.train-day-cardio { display: grid; gap: 2px; }

.train-day-cardio-say { margin: 0; padding-inline: 2px; }

/* The line and the rows are one block — #view's own 12px grid gap is what
 * holds this strip off the session above it and the record below it, the same
 * air every other block on the tab gets. */

/* ------------------------------------------------------- the routine cards -
 *
 * Jordan's first reference, on the Programs screen: per routine, its name and
 * where it stands with its count in words, then three months of days — Mon
 * to Sun down, a column per week, a tinted square per day and the person's
 * mark where that routine was done. Rows
 * on the ground with a hairline between them, no boxes (§4.6), so four
 * routines read as one list rather than four cards.
 */
.train-routine-list { display: grid; }

.train-routine {
  display: grid;
  gap: 12px;
  padding: 14px 0 18px;
}
.train-routine + .train-routine { border-top: 1px solid var(--line); }
.train-routine.train-routine-none { padding-bottom: 14px; }

/* The name and the ring lead; the months follow. */
.train-routine-foot {
  order: -1;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.train-routine-months {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.train-routine-month {
  display: grid;
  gap: 6px;
  justify-items: start;
}

.train-routine-month-name {
  font: var(--t-cap);
  color: var(--ink-2);
}

/* Seven rows, filled column by column: a week is a column, as on the reference.
 * tab_train.js sets the column count per month on the element. Each day is a
 * small rounded square — a tint of ink on any ground, so it reads in both
 * modes — and a day the routine was done is the person's mark, solid. Days
 * still ahead are only outlined: they have not happened. */
.train-routine-grid {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(7, 11px);
  grid-auto-columns: 11px;
  gap: 3px;
}

.train-routine-dot {
  display: block;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 11%, transparent);
}

.train-routine-dot-pad { visibility: hidden; }

.train-routine-dot-future {
  background: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 11%, transparent);
}

.train-routine-dot-on {
  background: var(--accent-mark);
  box-shadow: none;
}

/* The count, as the tab's other rows say a count ("3 sessions"): the number
 * in ink and its word beside it. It was an accent ring, which on Train is
 * the live set's tick — a count must not look like a button. The share of
 * the busiest routine stays on `data-pct` for anything that wants it. */
.train-routine-ring {
  flex: none;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
}
.train-routine-ring::after {
  content: attr(data-unit);
  font: 450 var(--t-sub-size)/1.3 var(--font);
  color: var(--ink-2);
}

.train-routine-ring-n { font: 600 var(--t-row-size)/1.3 var(--font); color: var(--ink); }

/* Never done in the window: the zero is said, quietly. */
.train-routine-none .train-routine-ring-n { color: var(--ink-2); font-weight: 450; }

.train-routine-main {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.train-routine-name {
  margin: 0;
  font: var(--t-row);
  overflow-wrap: anywhere;
}

.train-routine-line {
  margin: 0;
  font: var(--t-sub);
  color: var(--ink-2);
}

/* The next one in the rotation says so in ink. */
.train-routine-next .train-routine-line { color: var(--ink); }

/* Volume: the unmapped-id warning (§A4), in the server's own words. */
.train-vol-unmapped {
  display: grid;
  gap: 4px;
  margin: 8px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font: var(--t-sub);
  color: var(--ink-2);
}

/* ------------------------------------------------------ the plate loader */
/* One line on the row's load line (design V3, made more compact): a tiny full
 * bar, one side's plates as numeral chips and "/side"; a dumbbell and
 * "20 lb each" (on the face, inline before the row's own load); a pulley and
 * "pin 60 · handle 30". The chips are 18px tall and the bar 20px so the line
 * fits the sub line's own height. Red only past the plates. */
.train-load {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font: 500 13px/18px var(--font);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}
/* On the face row the words ("/side", "pin 60") read in the row's own type,
 * not a smaller, heavier one beside "at 135 lb". */
.train-load.train-load-row { font-size: inherit; font-weight: inherit; }
.train-load-show { display: inline-flex; align-items: center; gap: 3px; }
.train-load-show svg { flex: none; display: block; margin-right: 3px; }
.train-load-words { color: var(--ink-2); }
.train-load-short { color: var(--ink); margin-left: 3px; }
.train-load .train-load-over { height: 18px; padding: 0 6px; font-size: 13px; }
.train-plate-chip {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 4px;
  border-radius: 5px;
  font: 600 13px/1 var(--font);
  font-variant-numeric: tabular-nums;
  background: var(--plate-c, var(--plate-steel));
  color: var(--plate-ci, var(--ink));
  box-shadow: inset 0 0 0 1px var(--plate-ce, var(--plate-steel-2));
}
.train-plate-x { font-weight: 500; margin-left: 1px; }
.train-pl-45 { --plate-c: var(--plate-45); --plate-ci: var(--plate-45-ink); --plate-ce: var(--plate-45-edge); }
.train-pl-35 { --plate-c: var(--plate-35); --plate-ci: var(--plate-35-ink); --plate-ce: var(--plate-35-edge); }
.train-pl-25 { --plate-c: var(--plate-25); --plate-ci: var(--plate-25-ink); --plate-ce: var(--plate-25-edge); }
.train-pl-10 { --plate-c: var(--plate-10); --plate-ci: var(--plate-10-ink); --plate-ce: var(--plate-10-edge); }
.train-pl-5 { --plate-c: var(--plate-5); --plate-ci: var(--plate-5-ink); --plate-ce: var(--plate-5-edge); }
.train-pl-2_5 { --plate-c: var(--plate-2_5); --plate-ci: var(--plate-2_5-ink); --plate-ce: var(--plate-2_5-edge); }
.train-pb-plate { fill: var(--plate-c, var(--plate-steel)); stroke: var(--plate-ce, var(--plate-steel-2)); }
.train-pb-sleeve, .train-pb-stack { fill: var(--plate-steel); }
.train-pb-shaft, .train-pb-collar, .train-pb-stack-on { fill: var(--plate-steel-2); }
.train-pb-ghost { fill: none; stroke: var(--ink-3); }
.train-pb-dbhead { fill: var(--plate-db); stroke: var(--plate-db-edge); stroke-width: 1.4; stroke-linejoin: round; }
.train-pb-dbshine { fill: var(--plate-shine); opacity: 0.2; }
/* On the face the dumbbell sits inside the row's own words, before the load
 * ("3 × 8–10 at [db] 25 lb each"), centred on the digits. */
.train-db-inline { display: inline-block; vertical-align: -3px; margin: 0 4px 0 1px; }
.train-pb-rope { fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-linecap: round; }
.train-pb-pulley { fill: none; stroke: var(--plate-steel-2); stroke-width: 2.4; }
.train-pb-handle { fill: none; stroke: var(--ink-2); stroke-width: 2.2; }

/* The logger's head: the same line, and a shortfall's nearest totals as pills. */
.train-strip:has(.train-load-line:not([hidden])) { flex-wrap: wrap; }
.train-load-line { flex: 1 0 100%; margin-top: 8px; }
.train-load-line[hidden] { display: none; }
.train-load-head { flex-wrap: wrap; row-gap: 6px; white-space: normal; }
/* No margin of its own: the line's gap spaces it, and when it wraps under the
 * bar it starts flush with the bar's left edge. */
.train-load-nearset { display: inline-flex; align-items: center; gap: 6px; }
.train-load-near {
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  background: transparent;
  color: var(--ink);
  font: 600 14px/1 var(--font);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.train-load-near:hover { background: var(--surface-2); }
.train-load-near:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
