/* The guided practice (js/practice/loop.js and its answer practices) and the recorder it shares with the mock test
   (js/recpanel.js): the question with its hint line, the big button's group, Part 2's card and minute to prepare,
   the point and result marks, and the microphone error. The stage itself and the big button are in app.css. */

/* A new screen fades in (360 ms, B.0); under reduced motion a short fade only. */
.stage.in > * { animation: stage-in var(--t-move) var(--ease); }
@keyframes stage-in { from { opacity: 0; transform: translateY(12px); } }
/* Headings take focus when the screen changes; they are not controls, so no ring. */
.stage [tabindex="-1"]:focus { outline: none; }
.stage-main > h1 { margin: 0; overflow-wrap: anywhere; }

/* The eyebrow and the question caption belong together (6px), and stand apart from the headline (24px). */
.stage-main > .eyebrow + .caption { margin-top: -6px; }
.stage-main > .caption + * { margin-top: 12px; }
.stage-main > .t-intro.sub { max-width: 30em; }

/* The hint slot under the question (B.1, C.12): one item of at most two lines (two lines and the 4px between them).
   Its height is kept, so nothing moves when the microphone line appears or the hints go at the first tap. */
.hint-wrap { display: grid; justify-items: center; align-content: start; gap: 4px; min-height: calc(2 * 1.42859em + 4px); font-size: 14px; }
.hint-wrap.collapsed { min-height: 0; }
.hint-slot { display: grid; justify-items: center; gap: 4px; }
.hint-mic:empty { display: none; }
/* The focus pill: a goal for this answer (B.1, B.5). */
.focus-pill { display: inline-flex; align-items: center; padding: 6px 12px; border-radius: var(--r-pill); background: var(--pink-50); color: var(--red-dark); font-weight: 600; }
.phrase-chips { justify-content: center; }
.phrase-chips .chip { background: var(--card); font-weight: 600; }

/* The recorder's group (B.3 to B.6): the big button and its label, the timer, the tip line; in the minute to prepare,
   the ring, the notes, 'Start talking' and 'Show ideas'. */
.rec-stage, .rec-slot { display: grid; justify-items: center; width: 100%; }
.rec-btn .rec-label { min-height: 1.47059em; }
.rec-btn .rec-label.is-note { color: var(--ink-2); font-weight: 400; }
.rec-stage > .rec-time { margin-top: 6px; font-variant-numeric: tabular-nums; }
.rec-stage > .tip-line { margin-top: 12px; width: 100%; text-align: center; }
.rec-stage > .field-err { margin-top: 12px; }
/* 'Listen': a red play mark in the white circle, nudged right so it looks centred. */
.rec.big.play .rec-play-ico { width: 36px; height: 36px; color: var(--red); margin-left: 4px; transition: color .15s; }
@media (hover: hover) { .rec.big.play:hover .rec-play-ico { color: var(--red-dark); } }
/* The ring and its line side by side, so 'Start talking' sits right under them. */
.prep-timer { display: grid; grid-auto-flow: column; align-items: center; justify-content: center; gap: 12px; margin-block: 12px 0; text-align: left; }
.prep-timer + .btn { margin-top: 12px; }
.rec-stage > textarea { max-width: 100%; }
.rec-stage > .btn { margin-top: 24px; min-width: 240px; }
.rec-stage > .quiet { margin-top: 12px; }
.ideas-list { margin: 0; padding: 18px 24px 18px 42px; width: 100%; display: grid; gap: 6px; text-align: left; border-radius: var(--r-inner); background: var(--card); }
.rec-stage > .ideas-list { margin-bottom: 12px; }
/* Under the cue card in the minute to prepare: the ideas (when shown), then the notes. Empty, it takes no room. */
.p2-side { display: grid; gap: 12px; width: 100%; }
.p2-side:empty { display: none; }
.p2-side textarea { display: block; }
@media only screen and (max-width: 734px) { .rec-stage > .btn { width: 100%; min-width: 0; } }
/* On a phone the controls sit at the bottom of the screen, so a line added under the big button would push the button
   and the question up. The recorder's group keeps the height of its tallest state: the button with its 12px margins,
   its label, the timer (6px above) and the two-line tip (12px above); the mock test has no tip line. So nothing moves
   from 'Tap to answer' to the spinner. */
.stage { --rec-group-h: calc(144px + 3 * 1.47059 * 17px + 6px + 1.42859 * 14px + 12px); }
.stage.mock-run { --rec-group-h: calc(144px + 1.47059 * 17px + 6px + 1.42859 * 14px); }
@media only screen and (max-width: 1068px) {
  .stage { --rec-group-h: calc(120px + 3 * 1.47059 * 17px + 6px + 1.42859 * 14px + 12px); }
  .stage.mock-run { --rec-group-h: calc(120px + 1.47059 * 17px + 6px + 1.42859 * 14px); }
}
/* The control group stays in view (B.0: on a phone, the thumb zone): when the content is taller than the screen, the
   group stays at the bottom and the content scrolls under it, fading out in the gap above it (a Part 2 card with
   notes, a long model sentence, a Band 7 answer read aloud), 12px above the screen's edge (or above the iPhone's home
   indicator), with its background reaching that edge. When the content fits, nothing changes. */
.stage > .stage-controls { position: sticky; bottom: max(12px, calc(var(--dock) + 12px), env(safe-area-inset-bottom, 0px)); z-index: 2; background: var(--bg); }
.stage > .stage-controls::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--panel-gap); background: linear-gradient(rgba(245, 245, 247, 0), var(--bg)); pointer-events: none; }
.stage > .stage-controls::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: calc(var(--frame-pad) + max(var(--dock), env(safe-area-inset-bottom, 0px))); background: var(--bg); pointer-events: none; }
/* A point on the cue card, or the ideas, scrolled into view clear the group. */
.stage .cue li, .stage .cue-explain, .p2-side > * { scroll-margin-bottom: calc(var(--rec-group-h) + var(--panel-gap)); }
@media only screen and (max-width: 734px) {
  /* The microphone error takes the group's place and keeps its height, so the question doesn't move either. */
  .stage-controls:has(> .rec-stage, > .rec-slot, > .rec-btn, > .err-group) { align-content: start; min-height: var(--rec-group-h); }
}

/* The minute to prepare for Part 2: a ring that fills. */
.ring { position: relative; display: grid; place-content: center; width: 96px; height: 96px; flex: none; border-radius: 50%; background: conic-gradient(var(--red) calc(var(--p) * 360deg), var(--pink-100) 0); }
.ring::before { content: ""; position: absolute; inset: 8px; border-radius: 50%; background: #fff; }
.ring .rec-time { position: relative; }
.notes-kept { white-space: pre-wrap; padding: 12px; border-radius: var(--r-field); background: var(--bg); max-width: 46em; }
/* Full-width white blocks on the stage share one radius (--r-inner): the cue card, its notes, the ideas, the phrases. */
.stage .notes-kept { width: 100%; max-width: none; text-align: left; background: var(--card); border-radius: var(--r-inner); }

/* Part 2: the topic card. On the stage it is a white card on the page's grey, read from the left. While the student
   speaks, the point they are on is black and semibold, the others grey (B.5). */
.cue { display: grid; gap: 12px; padding: 24px; border-radius: 0 var(--r-inner) var(--r-inner) 0; background: var(--bg); border-left: 4px solid var(--red); max-width: 46em; }
.cue-say { color: var(--ink-2); }
.cue-points { margin: 0; padding-left: 24px; display: grid; gap: 4px; }
/* As the screen's h1 the prompt keeps the card's own type (eyebrow-reduced), not the page title's. */
.cue h1.cue-prompt { margin: 0; font-size: 21px; line-height: 1.19048; font-weight: 600; letter-spacing: 0.011em; }
@media only screen and (max-width: 734px) { .cue h1.cue-prompt { font-size: 19px; line-height: 1.21053; letter-spacing: 0.012em; } }
.stage .cue { width: 100%; max-width: none; text-align: left; background: var(--card); }
.cue.speaking .cue-points li, .cue.speaking .cue-explain { color: var(--ink-2); transition: color var(--t-morph) var(--ease); }
.cue.speaking .cue-points li.now, .cue.speaking .cue-explain.now { color: var(--ink); font-weight: 600; }
@media only screen and (max-width: 734px) { .cue { padding: 18px; } }

/* One Part 2 point to talk about (B.17). */
.p2-point { color: var(--ink); margin-top: 12px; }
.stage-main > .lenbar, .stage-main > .timeline { margin-top: 12px; }

/* A good answer or a met practice: a check drawn over 400 ms in a green circle (B.8, B.19). Not yet: a pink dot;
   nothing could be checked: a grey dot. */
.done-mark, .result-mark { display: grid; place-content: center; width: 72px; height: 72px; border-radius: 50%; }
.done-mark { background: var(--good-50); color: var(--good); }
.done-mark svg { width: 72px; height: 72px; }
.done-mark path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 400ms var(--ease) 120ms forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.result-mark span { width: 24px; height: 24px; border-radius: 50%; }
.result-mark.not-yet { background: var(--pink-50); }
.result-mark.not-yet span { background: var(--pink-300); }
.result-mark.unknown { background: var(--bg-hover); }
.result-mark.unknown span { background: var(--ink-2); }

/* The microphone error (B.37): in place of the button group, under the question. */
.err-group { display: grid; justify-items: center; gap: 6px; width: 100%; }
.err-group .err-title { margin: 0; }
.err-group .btn { margin-top: 18px; min-width: 240px; }
@media only screen and (max-width: 734px) { .err-group .btn { width: 100%; min-width: 0; } }

@media (prefers-reduced-motion: reduce) {
  .stage.in > * { animation: stage-fade 120ms linear; }
  .done-mark path { animation: none; stroke-dashoffset: 0; }
  .cue.speaking .cue-points li, .cue.speaking .cue-explain, .rec.big.play .rec-play-ico { transition: none; }
}
@keyframes stage-fade { from { opacity: 0; } }
