/* #2119, "Who's Who?" (#2165's rename) -- the phone, the call, the reveal.

   Every size and colour here is one a sibling card already ships, reached for
   rather than invented (#1239: "the cards need to be constant as much as
   possible so the eye doesn't jump around"):

     * the Hebrew line is `.pron-cue`'s and `.numgen-cue`'s 19px `--sans-he`;
     * the prompt is muted like `.pron-prompt`;
     * the answer buttons are the shared `.opt` (see beats/speaking_to.js), so
       this file declares no option rule and no `.wrong` selector at all;
     * the phone plate is `.opt`'s own surface, line, 14px radius and Lantern
       elevation, so the thing you tap reads as the same kind of tile as the
       things you tap next.

   Theme: every colour is a token, so both themes come from the tokens'
   own two definitions and nothing here is theme-specific. The drawing's stroke
   is `currentColor`, which is `--ink` on the plate. */

.spk-card { display:flex; flex-direction:column; align-items:center; gap:12px;
            width:100%; max-width:22rem; }

/* The phone. 44px is the floor every tap target in this app is held to; this
   one is far above it on purpose, since it is the only thing on the card. */
.spk-phone { display:flex; flex-direction:column; align-items:center; gap:4px;
             min-width:44px; min-height:44px; padding:14px 30px 12px;
             color:var(--ink); background:var(--surface);
             border:1px solid var(--line); border-radius:14px;
             box-shadow:var(--shadow); cursor:pointer; font:inherit; }
.spk-phone:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* #2905: the art is the ISOMETRIC telephone (140x168 viewBox) on its slab, so its
   box is that ratio, and it is the positioning context for the ring arcs, an
   overlay with the drawing's own viewBox so a point in one is the same point in
   the other. */
.spk-phone-art { display:block; position:relative; width:120px; height:144px; }
.spk-phone-art svg { display:block; width:100%; height:100%; overflow:visible; }
.spk-phone-art svg.spk-arcs { position:absolute; inset:0; pointer-events:none; }
.spk-answer { font-family:var(--serif); font-size:15.5px; line-height:1.35; color:var(--ink); }

/* The ring, silently. A two-tone ring is two short bursts and a pause, and that
   is the rhythm here (2.2s, the shake this replaced): in each burst the handset
   hops in its cradle three times, three small arcs pop off each earpiece, and
   the body rattles a hair. Everything is a TRANSFORM or an opacity on an inner
   `<g>`/`<path>` with `transform-box:fill-box`: WebKit ignores a CSS `filter` on
   an element inside an SVG, so none is used, and the plinth stays put.
   `.iso-obj` is the drawing's own hook for "the object" (picture.css pops it on
   a right answer); `.iso-handset` is #2905's, the handset alone. */
.spk-ringing .iso-obj { transform-box:fill-box; transform-origin:50% 100%;
                        animation:spkRattle 2.2s linear infinite; }
.spk-ringing .iso-handset { transform-box:fill-box; transform-origin:50% 100%;
                            animation:spkHop 2.2s linear infinite; }
.spk-arc { fill:none; stroke:var(--accent); stroke-width:3.2; stroke-linecap:round;
           opacity:0; transform-box:fill-box; transform-origin:50% 50%; }
.spk-ringing .spk-arc { animation:spkArc 2.2s linear infinite; }
.spk-ringing .spk-arc-2 { animation-delay:70ms; }
.spk-ringing .spk-arc-3 { animation-delay:140ms; }
@keyframes spkHop {
  0%, 16%, 36%, 100% { transform:none; }
  2%, 6%, 10%   { transform:translateY(-5px) rotate(-3deg); }
  4%, 8%, 12%   { transform:translateY(0) rotate(0); }
  22%, 26%, 30% { transform:translateY(-5px) rotate(3deg); }
  24%, 28%, 32% { transform:translateY(0) rotate(0); }
}
@keyframes spkRattle {
  0%, 14%, 36%, 100% { transform:none; }
  2%, 6%, 10%   { transform:translateX(-.7px) rotate(-.7deg); }
  4%, 8%, 12%   { transform:translateX(.7px) rotate(.7deg); }
  22%, 26%, 30% { transform:translateX(-.7px) rotate(-.7deg); }
  24%, 28%, 32% { transform:translateX(.7px) rotate(.7deg); }
}
@keyframes spkArc {
  0%, 36%, 100%        { opacity:0; transform:scale(.55); }
  3%, 19%              { opacity:0; transform:scale(.55); }
  6%, 22%              { opacity:1; transform:scale(1); }
  14%, 30%             { opacity:0; transform:scale(1.18); }
  16%, 32%             { opacity:0; transform:scale(1.18); }
}

/* Answered (the tap): the handset comes up off its cradle and stays up while the
   line plays. The phone is still on the card, but spent -- no plate, no label,
   smaller, so the call below keeps the room it had. The arcs are gone: the ring
   has stopped. */
.spk-phone:disabled { cursor:default; color:var(--ink); }
.spk-phone.spk-answered { background:none; border-color:transparent; box-shadow:none;
                          padding:0; gap:0; }
.spk-answered .spk-answer { display:none; }
.spk-answered .spk-phone-art { width:92px; height:110px; }
.spk-answered .iso-handset { transform-box:fill-box; transform-origin:50% 100%;
                             transform:translateY(-15px) rotate(-5deg);
                             transition:transform .34s var(--ease-spring); }
.spk-answered .spk-arc { opacity:0; }

@media (prefers-reduced-motion: reduce) {
  /* A still phone: nothing hops, rattles or pops, and the arcs are SHOWN, once,
     so the card still says "ringing". The lift on answering snaps. */
  .spk-ringing .iso-obj, .spk-ringing .iso-handset, .spk-ringing .spk-arc { animation:none; }
  .spk-ringing .spk-arc { opacity:1; }
  .spk-answered .iso-handset { transition:none; }
}

.spk-call { display:flex; flex-direction:column; align-items:center; gap:10px; width:100%; }
.spk-prompt { color:var(--muted); }

/* #2334: the line and its replay share one row -- the same shape
   `tense.js`'s own `.tense-cue-row` uses (#2066, itself following
   `jumble.js`'s `.jumble-line-row`, #1400) rather than a rule invented for
   this card: no `dir` on the row, only on `.spk-line` itself, so DOM order
   is visual order and "the replay sits at the right of the line" (the
   owner's own words on #2334) is simply "the button is the last child".
   `.spk-replay` is `.cuereplay` (`shared/beat_card.css`), which already
   clears the 44px tap floor (#1973) on its own -- 40x40 with a 2px hit-box
   overhang each side -- so nothing here needs to touch that. */
.spk-line-row { width:100%; max-width:22rem; display:flex; align-items:flex-start; }
.spk-line { 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; }
.spk-line-row .spk-replay { margin-inline-start:8px; }
.spk-line-row .spk-replay[hidden] { display:none; }
.spk-english { margin:0; font-family:var(--serif); font-size:15.5px; line-height:1.4;
               color:var(--ink); max-width:22rem; text-align:center; }

/* #3246: after the answer, the word that says who is addressed is marked in the
   line, and one line says why. The mark is the accent -- the one colour this app
   spends on "the word being taught" (`.beat-text`'s own note) -- as a soft wash
   behind the word plus an underline, so it reads on both themes without a rule
   of its own for either. The reason takes the spent question's own slot (the JS
   holds the slot at the question's height), in the English line's face and size. */
.spk-clue { color:inherit; background:color-mix(in srgb, var(--accent) 28%, transparent);
            border-radius:4px; padding:0 .14em;
            box-shadow:inset 0 -2px 0 var(--accent);
            animation:spkClue var(--dur-slow) var(--ease-out) both; }
@keyframes spkClue { from { background-color:transparent; box-shadow:inset 0 0 0 var(--accent); } }
.spk-prompt.spk-why { display:flex; align-items:center; justify-content:center;
                      font-family:var(--serif); font-size:14.5px; line-height:1.4;
                      color:var(--muted); max-width:22rem; }
.spk-why bdi { font-family:var(--sans-he); font-size:17px; color:var(--ink); }
@media (prefers-reduced-motion: reduce) { .spk-clue { animation:none; } }

/* #2165: seven buttons, so two columns rather than `.pron-options`' one --
   a column of seven pushed Continue below the fold at 393px. The server sends
   them in pairs, masculine beside feminine (`speaking_to.py`'s
   `DEALT_CLASSES`), and an odd last button ("Me, the speaker") spans both
   columns. `.opt` is `width:100%`, so each fills its cell. */
.spk-options { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px;
               width:100%; max-width:22rem; }
.spk-options .opt:last-child:nth-child(odd) { grid-column:1 / -1; }

/* #2905: the owner asked for "the new style for the boxes" on the who-is-it
   options -- read as the tactile press Flip and match's word tiles got in #2853
   (`shared/warm_up.css` `.warmup-card`, PR #2866), mirrored here rather than
   shared because that sheet is not this card's to edit. At rest each button
   carries a crisp drop shadow, `--spk-press-depth` below it, on top of the soft
   Lantern `--shadow` it always had. While pressed it moves DOWN by exactly that
   depth and the whole shadow goes -- it has sunk into where its shadow was -- and
   on release it pops back and the shadow returns. The edge is `--ground` leaned
   toward `--ink` (Flip and match leans it toward black, which is invisible on the
   dark ground; `--ink` is dark on the light theme and light on the dark one, so
   the lip reads in both), so both themes come from the tokens and nothing here is
   theme-specific.
   `.pressing` (set by this card's pointer handlers) is `:active`'s twin because
   iOS Safari does not reliably fire `:active` for a finger.

   What it must not disturb: the right answer's bloom (`.opt.correct` sets its
   own `box-shadow`, so the resting drop is declared `:not(.correct)`), and the
   wrong ring (`beatWrongPulse` holds `--rest-shadow` under the ring, so that
   variable carries the drop too and the shadow does not vanish for 420ms). A
   spent (`:disabled`) button never presses. No rule here names `.wrong`:
   `tests/test_beat_wrong_pulse.py` reads any motion property on one as a
   private wrong-answer treatment. */
.spk-options .opt { --spk-press-depth:3px;
                    --spk-press-edge:color-mix(in srgb, var(--ground) 80%, var(--ink));
                    --rest-shadow:var(--shadow), 0 var(--spk-press-depth) 0 var(--spk-press-edge); }
.spk-options .opt:not(.correct) { box-shadow:var(--rest-shadow); }
.spk-options .opt { transition:background .18s ease, border-color .18s ease, opacity .3s ease,
                               transform 200ms var(--ease-spring), box-shadow 200ms var(--ease-out); }
.spk-options .opt:not(:disabled):active,
.spk-options .opt.pressing:not(:disabled) { transform:translateY(var(--spk-press-depth));
                                            box-shadow:0 0 0 0 transparent; }
/* Going down is quick (60ms, no spring); only the release pops. */
.spk-options .opt:not(:disabled):active,
.spk-options .opt.pressing:not(:disabled) { transition:background .18s ease, border-color .18s ease,
                                                       transform 60ms ease-out, box-shadow 60ms ease-out; }
/* Reduced motion keeps the depth change (down, shadow gone) and loses only the
   glide -- it snaps between the two states. After the rules it overrides, same
   specificity, so the later one wins. */
@media (prefers-reduced-motion: reduce) {
  .spk-options .opt,
  .spk-options .opt:not(:disabled):active,
  .spk-options .opt.pressing:not(:disabled) { transition:none; }
}

/* #2364, the rebuild round (Grammar rung 3). The slots, the tiles and both
   action buttons are `.opt`, so the wrong ring, the correct bloom, the Lantern
   chrome and the disabled cursor come from `shared/beat_card.css` and this file
   declares no `.wrong` or `.correct` selector: it only sizes them. `.opt` is
   `width:100%` and left-aligned in `--serif`, fitted to a column of answers, so
   a slot or a tile is set back to its own width, centred, in the Hebrew face
   the line above uses. 44px is the floor every tap target here is held to. */
.spk-from { margin:0; max-width:22rem; text-align:center; font-family:var(--serif);
            font-size:13.5px; line-height:1.4; color:var(--muted); }
.spk-rebuild { display:flex; flex-direction:column; gap:12px; width:100%; max-width:22rem; }
.spk-ruled, .spk-bank { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.spk-ruled { padding:8px 0; }
.spk-bank { padding-top:4px; }
.spk-w { display:inline-flex; align-items:center; gap:0; font-family:var(--sans-he);
         font-size:calc(19px * var(--milim-text-scale)); color:var(--ink); }
.spk-fixed { padding:0 2px; line-height:44px; }
.spk-slot, .spk-tile { width:auto; min-width:56px; min-height:44px; padding:6px 12px;
                       text-align:center; font-family:var(--sans-he);
                       font-size:calc(19px * var(--milim-text-scale)); line-height:1.3; }
/* An empty slot is a place, not a button: dashed and flat until it holds a tile. */
.spk-slot:not(.spk-filled):not(.correct):not(.wrong) { border-style:dashed; background:transparent;
                                                        box-shadow:none; }
.spk-slot.spk-active { border-style:solid; border-color:var(--accent); }
.spk-actions { display:flex; gap:8px; }
.spk-actions .opt { flex:1 1 0; min-height:44px; text-align:center; }
.spk-verdict { margin:0; padding:8px 12px; font-family:var(--serif); font-size:15.5px;
               line-height:1.4; color:var(--ink); border-left:3px solid var(--line); }
.spk-verdict-ok { border-left-color:var(--ok); }
.spk-verdict-bad { border-left-color:var(--no); }
.spk-reveal { display:flex; flex-direction:column; gap:6px; padding-top:10px;
              border-top:1px solid var(--line); }
.spk-reveal-label { margin:0; font-family:var(--serif); font-size:13.5px; color:var(--muted); }
.spk-reveal-line { flex:0 0 auto; }
.spk-changes { margin:0; padding:0; list-style:none; font-family:var(--serif); font-size:14.5px;
               line-height:1.6; color:var(--muted); }
.spk-changes [lang] { font-family:var(--sans-he); font-size:17px; color:var(--ink); }
.spk-note { margin:0; padding:8px 12px; font-family:var(--serif); font-size:14.5px; line-height:1.4;
            color:var(--ink); border-left:3px solid var(--accent); background:var(--surface); }

/* #866: a `hidden` attribute must compute display:none on its own page. Last
   in the file and !important, so no display rule above can outrank it. */
.spk-phone[hidden], .spk-call[hidden], .spk-english[hidden],
.spk-verdict[hidden], .spk-reveal[hidden] { display:none !important; }
