/* #314, the tense beat's card (#307's one-file-per-beat split). */

/* Muted, matching pick-in-cue's `.pick-prompt` -- the one line naming the
   question, not the point of the card the way `.beat-text` alone is for
   reward. */
.tense-prompt { color:var(--muted); }

/* #2066: the cue and its replay button share one row -- `jumble.js`'s
   `.jumble-line-row` (#1400) is the precedent this is adopting rather than
   re-deriving: no `dir` on the row (only `.tense-cue` inside it carries
   `dir="rtl"`), so DOM order is visual order and "the button sits at the
   right of the line" is simply "the button is the last child". The row owns
   the width this card used to give `.tense-cue` directly; see that rule's
   own comment for why it no longer needs it. */
.tense-cue-row { width:100%; max-width:22rem; display:flex; align-items:flex-start; }

/* Same Hebrew size as the other two judged beats' own cue lines (19px):
   sibling card, not a smaller-print variant of it.

   `flex:1 1 auto; min-width:0` (added by #2066): the line fills whatever the
   row does not spend on the button, the same "text fills its row" shape
   `.cuerow .cue`/`.jumble-line` already use -- `min-width:0` is the usual
   flex-item companion that lets a line with no natural minimum still wrap.
   `max-width` moved up to `.tense-cue-row` above, since it is now the row's
   own budget to split between the two children, not this element's alone. */
.tense-cue { margin:0; font-family:var(--sans-he); font-size:calc(19px * var(--milim-text-scale)); line-height:1.7;
             color:var(--ink); flex:1 1 auto; min-width:0; }

/* The drawn verb, in --accent -- the same colour the reader gives the word a
   session is teaching, and the only thing on this card that answers "which
   word". */
.tense-target { color:var(--accent); font-weight:700; }

.tense-options { display:flex; flex-wrap:wrap; gap:8px; justify-content:center;
                 max-width:22rem; }
/* English captions ("Past"/"Future"), so --serif -- the same face `.opt`
   (the question card's own English gloss buttons) uses, not `--sans-he`. */
.tense-opt { font-family:var(--serif); font-size:16px; color:var(--ink);
             background:var(--surface); border:1px solid var(--line);
             border-radius:14px; padding:10px 14px; cursor:pointer;
             min-height:44px; min-width:96px;
             /* #1764, Direction B "Lantern": radius 14 and the two-layer
                elevation, reading the same `--shadow` token `.opt` and
                `.cloze-option` read (defined per theme in the host page's own
                `:root`). Phase 1 (#1759) restyled `.opt` and `.cloze-option`,
                which was the whole of its stated scope -- but
                `03-motion-system.md` §1's selector list is four selectors, so
                this one kept Lantern's COLOURS on the old flat shape. Visible
                to anyone playing two beats in a row. `--rest-shadow`
                publishes the elevation to the shared `beatWrongPulse`
                keyframe (#1777); without it a wrong answer blanks the shadow
                for 420ms. */
             box-shadow:var(--shadow); --rest-shadow:var(--shadow); }
.tense-opt:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.tense-opt[disabled] { cursor:default; }

/* Right and wrong both stay --ink, not --muted -- the same measured trap
   `pick_in_cue.css`/`cloze.css` record: dimming this text measured 4.46:1
   against the composited green, under the 4.5:1 bar. */
/* #1764 / 03-motion-system.md §1, "the one 'moment'": the same bloom `.opt`
   and `.cloze-option` already run -- 2px `--ok` ring, 6px halo, 22px outer
   glow, arriving over `--dur-bloom` and never looping. The keyframe is
   document-global and is declared once in `shared/beat_card.css`; this
   references it by name rather than redeclaring it, exactly as cloze.css
   does. The resting `box-shadow` here settles on the keyframe's own 100%
   values, so there is no jump at the frame the animation ends. */
.tense-opt.correct { border-color:var(--ok); background:var(--ok-soft); color:var(--ink);
                     box-shadow:0 0 0 2px var(--ok), 0 0 0 6px var(--ok-halo), 0 0 22px var(--ok-bloom);
                     animation:verdictBloom var(--dur-bloom) var(--ease-out) 1; }
/* The tint only -- #1586/#1411 declares the three-pulse red ring once, in
   `shared/beat_card.css`, and that block's list names `.tense-opt.wrong`.
   No animation property belongs in this file; `tests/test_beat_wrong_pulse.py`
   fails if one reappears. */
.tense-opt.wrong   { border-color:var(--no); background:var(--no-soft); color:var(--ink); }

@media (hover: hover) {
  .tense-opt:not([disabled]):hover { border-color:var(--accent); }
}

/* #1242 candidate A, widened by #1943: the block the card shows once it is
   answered -- the verb again and its English. Shape borrowed from
   `docs/demos/2026-08-29-aitan/index.html`'s `.mock .reveal` mock, which the
   owner approved this candidate against. **#2066 moved the audio control OUT
   of this block and onto `.tense-cue-row` above** -- see that rule and the
   `.tense-replay` rule below the gloss for where it lives now; this block is
   the word/caption/gloss trio only.

   **It is `.beat-reserve`, not `[hidden]`, and that is #1283.** This file used
   to carry a `.tense-reveal[hidden] { display:none; }` rule and #866's
   explanation of why it was needed. Both are gone, because the attribute is
   gone: `hidden` takes the box OUT of flow, so a block that appears on the
   answer grows the card and moves everything below it -- including the
   Continue button, whose position the owner has reported four times (#1728).
   `.beat-reserve` (shared/beat_card.css) is `visibility:hidden` alone, so the
   box is sized and spends its `gap` from the first paint and answering only
   makes it visible.

   #866's underlying concern is unchanged and still met: the pointing must not
   be readable before the learner has answered. `visibility:hidden` also drops
   the subtree from the accessibility tree and the tab order, which is the
   whole reason `.beat-reserve` is `visibility` rather than `opacity` -- see
   that rule's own comment. What changed is the mechanism, not the promise.
   `tests/js/test_beat_dismiss_reflow_contract.mjs` is the guard for the new
   half; it caught this file doing it the wrong way round on #1943's first cut.

   The price is stated rather than hidden, the same way `.beat-reserve`'s own
   comment states it: an UNANSWERED tense card holds this block's height as
   blank space below the options -- smaller since #2066 took the replay
   control out of it, since there is one fewer row to reserve. */
.tense-reveal { width:100%; max-width:22rem; border-top:1px dashed var(--line);
                padding-top:12px; margin-top:4px; display:flex; flex-direction:column;
                gap:6px; align-items:center; }
.tense-reveal-word { margin:0; font-family:var(--sans-he);
                      font-size:calc(28px * var(--milim-text-scale)); color:var(--ink); }
.tense-reveal-cap { margin:0; font-size:13px; color:var(--muted); text-align:center; }

/* #1943, the owner: "once answered I think it would help to still see the
   English underneath the Hebrew." Underneath is literal -- it is the next line
   inside the same column, not a second column beside the word.

   `--serif`, the face every other piece of English on a beat card wears
   (`.tense-opt` above, `.opt` on a study board), and `--ink` rather than
   `--muted`: this is the answer to "what does it mean", not a caption about
   the line above it. `.tense-reveal-cap` stays muted precisely so the two do
   not read as one block of small print.

   Wrapping is allowed and is not a defect. Measured over every draw this beat
   can make on `demo.db` 2026-09-07 the served gloss runs 2-50 characters
   (median 13); the eight longest wrap to two lines at 22rem and are readable
   there, which is why nothing here reaches for `_board_label`'s 24-character
   button ceiling -- see `tense.py`'s `_english`. */
.tense-gloss { margin:0; font-family:var(--serif);
               font-size:calc(15px * var(--milim-text-scale)); line-height:1.4;
               color:var(--ink); text-align:center; max-width:22rem; }
/* #1906: `.tense-gloss .approx` used to sit here -- CLAUDE.md's invariant,
   applied to a relaxed-POS gloss the same way `.opt .approx` marked one on a
   study board. Gone as dead code, not merely unused: `tense.py`'s `_english`
   now returns no caption at all for a relaxed match (0 of 102 draws on
   today's corpus) rather than a weaker one, so nothing here can ever build
   this class again. See that function's own docstring for the invariant and
   the measurement that made removal safe. */

/* #2066: the audio control, ON `.tense-cue-row` now rather than beside the
   post-answer reveal -- see that row's own comment and `tense.js`'s `html()`
   for why moving it there does not give the answer away. A `.cuereplay`
   (shared/beat_card.css owns its look) with no caption: the caption
   ("Hear the line above") existed only because #1943's control sat apart
   from the line it played, and a control sitting ON the line names itself by
   being there, the same way `.cuereplay` beside `study.html`'s own `#cue`
   and `jumble.js`'s `#jumbleReplay` (#1400) carry none either.

   `margin-inline-start` is the gap to the cue text, at the same value
   `.jumble-line-row .jumble-replay` (jumble.css) already settled on rather
   than a second number invented here. There is no balance flank on this
   row's other side -- unlike `.cuerow`, this card is a one-shot render with
   nothing to keep centred, the same reason `.jumble-line-row` carries none
   either.

   `[hidden]` needs its own rule for #866's reason, the same one
   `.tense-reveal[hidden]` used to carry above: `.cuereplay`'s own `display:
   flex` (shared/beat_card.css) is an author declaration and outranks the UA
   stylesheet's `[hidden] { display:none }` on ORIGIN regardless of
   specificity, so without this the button would keep painting -- and stay
   tappable -- while `tense.js` believes it has hidden it. Scoped to
   `.tense-cue-row .tense-replay` rather than bare `.tense-replay`, and to
   `.tense-replay` rather than `.cuereplay`, for the same reason
   `.jumble-line-row .jumble-replay`'s margin above is scoped: a bare rule on
   the shared class would reach every OTHER copy of this control. */
.tense-cue-row .tense-replay { margin-inline-start:8px; }
.tense-cue-row .tense-replay[hidden] { display:none; }

/* #1764: this file's first `animation` declaration, so it needs its own
   `prefers-reduced-motion` escape -- `tests/test_reduced_motion_escape.py`
   asks the question per file, the same way `shared/beat_card.css`'s own
   escape (foot of that file) does for `.opt.correct`'s identical bloom, and
   `cloze.css` for `.cloze-option.correct`. Parked, not shortened: the ring
   and halo stay, because they are in the base `.tense-opt.correct` rule above,
   not the keyframe, so a reduced-motion learner still sees the full verdict
   shape at the instant the answer is judged and simply never sees it arrive
   over 540ms. */
@media (prefers-reduced-motion: reduce) {
  .tense-opt.correct { animation:none; }
}
