/* ══════════════════════════════════════════════════════════════════════════
   BARRE — STUDIO MODE (dark full-screen overlay)
   ══════════════════════════════════════════════════════════════════════ */

/* ── How big is big enough? ───────────────────────────────────────────────
   Studio Mode is the only screen read while the dancer is moving, and she is
   not holding the phone — it is propped on the floor or a shelf and she is at
   the barre, one to two and a half metres away. So "legible" here is an angle,
   not a font size, and the sizes below are worked back from one.

   A glyph is at the limit of 20/20 acuity when its cap height subtends about
   5 arcminutes; comfortable reading wants roughly three times that. A CSS
   pixel is 0.2646 mm at the reference viewing angle, and cap height in these
   faces is ~0.7em, so at a viewing distance D:

     D       resolvable (5')   glanceable (10')   comfortable (15')
     1.5 m   12px font         24px               35px
     2.0 m   16px font         31px               47px

   — at 2 m a 5' cap is 2.91 mm, which is 11.0 CSS px of cap height, which is
   a 16px font: the point at which letters stop being letters. Measured
   against that, before this pass:

     clock       46px  ✓ comfortable at 2 m (2.9× threshold)
     name        34px  ✓ glanceable at 2 m
     reps        15px  ✗ BELOW the resolvable limit at 2 m — and set in
                         uppercase with .06em tracking, which is the worst
                         treatment there is for a shape read at the edge of
                         acuity, on the one line that says what to actually do
     up next     14px  ✗ below the limit
     counter     12px  ✗ below the limit

   The clock and the name were already right, and are untouched. Reps goes to
   24 and the up-next NAME to 18 (22 in the last five seconds), both with the
   uppercase and the tracking dropped, because both are read as words. The
   counter is the one that deliberately stays small — 13px, up from 12: it says
   "Exercise 2 of 5", which is position rather than instruction, and the step
   list at the bottom of the screen already says the same thing at the same
   size. Growing it would buy a number she does not act on at the cost of space
   above the one she does. Sizes are set with `.st-wrap` in front of them, so they win over
   css/a11y.css §4 (which loads after this file and set the 15/14/12px floor)
   by specificity rather than by load order. a11y.css keeps working for
   everything here that is not restated.
   ────────────────────────────────────────────────────────────────────── */

/* The wrapper inside .b-studio. THREE stages live in the markup at once —
   `ready`, `running` and `done` — and the data-state attribute chooses which
   is on screen, so neither starting nor finishing re-renders the screen out
   from under the ring. */
.st-wrap {
  min-height: 100%;
  display: flex; flex-direction: column;
}
.st-wrap[data-state="ready"]   .st-body,
.st-wrap[data-state="ready"]   .st-done  { display: none; }
.st-wrap[data-state="running"] .st-ready,
.st-wrap[data-state="running"] .st-done  { display: none; }
.st-wrap[data-state="done"]    .st-ready,
.st-wrap[data-state="done"]    .st-body  { display: none; }

/* The kicker and the one <h1>, shared by all three stages so the screen never
   has more than one heading in its markup — see the comment on `.st-head` in
   js/screens/studio.js. It sits above the stages rather than inside them,
   which also means the exercise name holds the same place on the screen when
   the stage changes instead of jumping with the stage's own centring. */
.st-head { flex: none; text-align: center; }

.st-ready, .st-body, .st-done {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  text-align: center;
}

.st-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-12);
}
.st-routine {
  font: var(--font-eyebrow);
  letter-spacing: var(--ls-mid);
  text-transform: uppercase;
  color: var(--text-on-studio-50);
  text-align: right;
}
.st-counter {
  font: var(--font-kicker);
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--accent-pink-soft);
}
/* The only pointer route out of a full-screen mode used by a child balancing
   at a barre. It measured 9.3 × 16 px — 7.7% of a 44 × 44 target — and the
   box used to travel with the markup as a style attribute, because at the
   time css/a11y.css was not yet wired into the shell and a target that
   critical could not depend on a stylesheet that might not load. a11y.css §3
   is wired now, and it carries these exact values; they live here as well so
   the guarantee survives it being unwired again, and so the markup carries no
   inline styles. The −14px block margin (44/−2 + 8) keeps `.st-top` at its
   designed 16px height, so the target can be 44 square without moving
   anything else on the screen. */
.st-close {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
  margin: -14px 0;
  border-radius: var(--radius-pill);
  font: 400 22px/1 var(--font-ui);
  color: var(--text-on-studio-60);
}
.st-close:hover, .st-close:focus-visible { background: rgba(247, 233, 238, .10); }

.st-name   { font: var(--font-display-studio); color: var(--text-on-studio); margin-top: var(--space-12); }
.st-detail { font: var(--font-body-lg); color: var(--text-on-studio-60); margin-top: var(--space-10); padding: 0 var(--space-4); }

/* The line that says what to actually do — "3 × 12 each foot", "10 each way".
   It is the second most important thing on the screen after the time, and it
   was the least legible thing on it. 24px is glanceable at 1.5 m and still
   resolvable at 2.5 m; the longest reps string in the library is 21 characters,
   which at this size still sets on one line at 375px wide. The uppercase and
   the tracking are gone: both destroy word shape, which is the only cue left
   when a glyph is near the acuity limit. Contrast up from 4.55 to 6.09 for the
   same reason. */
.st-wrap .st-reps {
  font: 400 24px/1.25 var(--font-ui);
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-on-studio-60);
  margin-top: var(--space-14);
  min-height: 1.25em;
}
.st-wrap .st-counter { font-size: 13px; }

/* Ready and done cards: the one-line factual summary under the title. */
.st-summary {
  font: var(--font-body-lg);
  font-size: 16px;
  color: var(--text-on-studio-75);
  margin-top: var(--space-6);
}

/* ── Safety copy ──────────────────────────────────────────────────────────
   Two hooks, both carrying the care guidance authored into the routines: what
   not to do in a stretch, when to stop an ankle set, which work belongs in
   class. A twelve-year-old is reading this alone, on one leg, from about two
   metres. So: never quieter than the exercise detail it sits under, never
   centred when it runs past a line, and always visibly *set apart* from the
   instruction — it is the sentence that says stop, not the one that says go.
   ────────────────────────────────────────────────────────────────────── */

/* Per-exercise care note, under the reps. Rendered as `.st-detail .st-stepnote`
   and hidden entirely when an exercise has no care text, so it must not
   reserve space. The pink rule is the whole visual signal that this line is a
   different kind of sentence from the detail above it. */
.st-stepnote {
  /* `.st-body` is a column flex container, so this is a flex item and any
     inline-level display would be blockified anyway. Say block, and let the
     measure plus auto inline margins do the centring. */
  display: block;
  max-width: 30ch;                       /* a measure, so it wraps evenly       */
  margin: var(--space-12) auto 0;
  padding-left: var(--space-8);
  border-left: 2px solid var(--accent-pink-soft);
  text-align: left;
  font: var(--font-body);
  color: var(--text-on-studio-60);       /* 6.09 on #170A1A                     */
}
.st-stepnote[hidden] { display: none; }  /* [hidden] must beat inline-block     */

/* "Before you start" — the routine-level safety panel.
   Left-aligned on purpose: it runs to four sentences, and centred paragraphs
   of that length are read line-by-line rather than as prose. This rule is
   where that decision lives; do not put it back in a style attribute.

   It now lives on the ready card, ABOVE the Start button, and the reason is a
   measurement: on the combined screen at 375 × 667 the panel rendered at
   575–735px in a 667px viewport while Start sat fully visible at 497–553px.
   More than half the safety copy was past the fold, below the control it was
   meant to gate. Nothing about that is fixable by making the panel prettier. */
.st-care {
  text-align: left;
  margin: var(--space-18) auto 0;
  max-width: 34ch;
  padding: var(--space-12) var(--space-14);
  border: 1px solid var(--border-on-studio);
  border-radius: var(--radius-card);
  background: rgba(247, 233, 238, .05);
}
.st-care .st-counter { text-align: left; }
.st-care .st-detail {
  margin-top: var(--space-4);
  padding: 0;
  text-align: left;
  color: var(--text-on-studio-60);       /* 6.09 — same as the exercise detail  */
}

/* Timer ring — a render island. innerHTML never regenerates it; the loop
   writes strokeDashoffset and one text node. (spec 05 §2, §9) */
.st-ring {
  margin: var(--space-20) auto 0;
  width: 196px; height: 196px;
  position: relative;
  display: flex; align-items: center; justify-content: center;
  will-change: transform;
}
.st-ring svg {
  position: absolute; inset: 0;
  transform: rotate(-90deg);
  width: 100%; height: 100%;
}
.st-ring__track { fill: none; stroke: var(--border-ring-track); stroke-width: 3; }
.st-ring__prog {
  fill: none;
  stroke: var(--accent-pink-soft);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 283;              /* 2πr, r = 45 */
  transition: stroke-dashoffset var(--dur-ring) linear;
}
/* Refilling the ring for a new exercise must not animate backwards through
   the whole circle. Dropped again on the next frame. */
.st-ring__prog.is-instant { transition: none; }

.st-clockstack {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
}
/* No transition on any of the state colours below. Paused and ending are
   STATES, not movements: a quarter-second cross-fade on the word that says
   "this clock is not running" is a quarter-second of ambiguity, and it is
   ambiguity in the one direction that matters — she is watching to see whether
   the number moves. (It also cannot stall: a transition only advances while
   frames are being produced, and this screen deliberately survives the phone
   going to sleep.) */
.st-clock {
  font: var(--font-display-clock);
  letter-spacing: var(--ls-clock);
  color: var(--text-on-studio);
}
/* Taken out of flow, so appearing and disappearing cannot move the clock. In
   flow it added 15px to the stack and shoved the numerals 7px up the ring
   every time she paused — a jump on the one element that must look like it is
   standing still. There is 75px of clear ring below a 46px clock, so it sits
   under the time without touching the stroke. */
.st-clock__note {
  position: absolute;
  top: calc(100% + var(--space-4));
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font: 400 15px/1 var(--font-ui);
  letter-spacing: var(--ls-mid);
  text-transform: uppercase;
  color: var(--text-on-studio-60);
}

/* ── Paused ───────────────────────────────────────────────────────────────
   Pausing used to change one word on one button, at 16px. From where she is
   standing that is invisible: between ticks a paused clock and a running clock
   are the same still image, so the only way to tell was to watch it for a
   second and see whether it moved — while balancing. Three signals now, all at
   clock scale: the numerals go from 16.30:1 to 6.09:1 (still comfortably AA),
   the ring drops to the muted stroke, and the word PAUSED appears under the
   time, which is where her eyes already are.
   ────────────────────────────────────────────────────────────────────── */
.st-wrap[data-paused="1"] .st-clock       { color: var(--text-on-studio-60); }
.st-wrap[data-paused="1"] .st-ring__prog  { stroke: var(--text-on-studio-40); }

/* ── The last five seconds ────────────────────────────────────────────────
   An exercise that simply ends is worse than one that says what is coming:
   she is mid-hold and has to decide whether to come out of it. The ring turns
   rose and the "up next" line goes to reading size, so the handover is visible
   BEFORE it happens. No pulse, no flash: this is peripheral vision for someone
   balancing on one leg, and a colour change carries it without motion.
   ────────────────────────────────────────────────────────────────────── */
.st-wrap[data-phase="ending"] .st-ring__prog { stroke: var(--accent-rose); }
.st-wrap[data-phase="ending"] .st-next       { color: var(--text-on-studio); }
.st-wrap[data-phase="ending"] .st-next__lead { color: var(--accent-pink-soft); }
.st-wrap[data-phase="ending"] .st-next__what { font-size: 22px; }

.st-actions { display: flex; gap: var(--space-7); margin-top: var(--space-20); justify-content: center; }
.st-actions .b-pill--on-dark       { padding: 17px; min-width: 116px; font: var(--font-label-btn); gap: var(--space-5); }
.st-actions .b-pill--on-dark-ghost {
  padding: 17px var(--space-18);
  font: var(--font-label-btn);
  border-color: var(--border-on-studio);
  color: var(--text-on-studio-75);
}
.st-actions .b-pill--on-dark-ghost:hover { background: rgba(247,233,238,.08); }
.st-actions__prev { padding-left: var(--space-14); padding-right: var(--space-14); }
.st-actions__prev[disabled] { opacity: .35; }

/* "What is next" — one of the four things the brief asks to be readable from
   across the room, and it was 14px, i.e. under the resolvable limit at 2 m.
   Split into a label and a name so the size can go where it earns its keep:
   the lead stays small because "Up next" is the same three characters every
   time and is recognised by shape, while the exercise NAME — the part that is
   different each time and so cannot be guessed — goes to 18px, and to 22px in
   the last five seconds when it is the most useful line on the screen. */
.st-next {
  margin-top: var(--space-19);
  text-align: center;
  color: var(--text-on-studio-60);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
}
.st-next__lead {
  font: var(--font-kicker);
  font-size: 12px;
  letter-spacing: var(--ls-mid);
  text-transform: uppercase;
  color: var(--text-on-studio-40);
}
.st-next__what {
  font: 400 18px/1.3 var(--font-display);
}
/* ── The done card ────────────────────────────────────────────────────────
   Warmth, not pressure. Everything on it is a statement about what just
   happened — exercises, minutes, what the work was on, and whether it ticked
   something off tonight's plan. Nothing is at risk, nothing is expiring, and
   there is no streak on this screen at all: a twelve-year-old who is tired on
   a Tuesday should be able to stop without the app making a case.
   ────────────────────────────────────────────────────────────────────── */
.st-done .st-detail { margin-top: var(--space-6); }
.st-done__plan   { color: var(--accent-pink-soft); }
.st-done__worked { color: var(--text-on-studio-60); }
.st-done__care   { text-align: left; }
.st-done__plan[hidden] { display: none; }

/* The exercise-change settle. `pop` is the app's own keyframe (css/motion.css);
   this only says which element takes it. motion.css names its selectors
   individually, so the reduced-motion guard for a new one has to be written
   here — at .01ms the scale still lands on a frame at .86 and reads as a
   flicker rather than as nothing. */
@media (prefers-reduced-motion: reduce) {
  .st-name.anim-pop { animation: none !important; transform: none; }
}

.st-list {
  margin-top: var(--space-17);
  padding-top: var(--space-17);
  border-top: 1px solid var(--border-on-studio);
  display: flex; flex-direction: column; gap: var(--space-8);
  flex: none;
}
.st-list__item {
  display: flex; gap: var(--space-10); align-items: center;
  font: var(--font-body-sm);
  color: var(--text-on-studio-50);
}
.st-list__name { flex: 1; min-width: 0; }
.st-list__secs { flex: none; color: var(--text-on-studio-35); }
.st-list__item[data-current="1"] { color: var(--text-on-studio); }
.st-list__item[data-past="1"] .st-list__name { text-decoration: line-through; }
.st-list__dot {
  width: 6px; height: 6px; border-radius: var(--radius-pill);
  background: var(--text-on-studio-35);
  flex: none;
}
.st-list__item[data-current="1"] .st-list__dot { background: var(--accent-pink-soft); }


/* ══════════════════════════════════════════════════════════════════════════
   THE WAY IN — the routine picker on STRETCH

   These rules are about the screen you choose a routine on, not about Studio
   Mode itself, and in a tidier world they would sit in css/screens.css. They
   are here because screens.css and components.css belong to other agents in
   this build and are not ours to write into; this file is, and it is loaded
   on every route, so the rules land the same way. They are additive and
   attribute-scoped — `[data-scan="length"]` is opted into by stretch.js and by
   nothing else — so a sibling editing `.b-routine` in components.css is not
   fighting anything here.
   ══════════════════════════════════════════════════════════════════════ */

/* Length decides whether the practice happens at all, so length is what the
   eye should land on. It was 17px Marcellus against a 14.5px/500 name — the
   same visual weight as the thing beside it, which makes a column of eighteen
   of them something to READ rather than something to SCAN. At 26px the numeral
   is unambiguously the scanning column, and the eye can run down the right-hand
   edge and stop at the first number that fits tonight. `min-width` keeps one-
   and two-digit numbers on the same axis so that run is straight. */
.b-routines[data-scan="length"] .b-routine__num  { font: var(--font-display-stat); }
.b-routines[data-scan="length"] .b-routine__mins { min-width: 42px; }

/* `.b-routine` sets `display:flex`, which beats the user-agent `[hidden]` rule
   on specificity — without this, filtering by length would hide nothing at
   all. (Same trap as `.st-stepnote[hidden]` above.) */
.b-routine[hidden] { display: none; }

/* The bottom spacer every screen ends with. The other five screens still do it
   with `style="height:24px"`; this is the same gap as a class, so the markup
   in stretch.js carries no inline style. */
.b-screen-foot { height: var(--space-19); }
