/* TECH·STAGE (301) + TECH·STEPS (302) — THE TECHNIQUE PLAYER. (D-458 · D-450 · D-571)
 *
 * ═══════════════════════════════════════════════════════════════════════════════════════════════
 * 🔴 THIS FILE IS THE FIRST STYLESHEET THE PLAYER HAS EVER HAD THAT A LINTER COULD READ.
 *
 * The player's CSS used to live as TWO escaped string literals inside technique.js, injected into
 * a shadow root — the exact arrangement the collection reader was pulled off of (D-560), and for
 * the same reason: not one check in this repo can see inside a JS string. The proof is in what was
 * hiding there: `.tanim-gate` styled with `border-radius: var(--radius-8)` — **`--radius-8` is not
 * a token**, the scale skips it, so the rule passed every linter and rendered with NO radius. A
 * valid-looking variable resolving to nothing, invisible to the tools and to anyone not staring at
 * the corner radius of one gold box. And beside it sat forty-odd rules for markup this view has
 * never emitted (.slider, .dcard, .dots — another card's CSS, pasted in and never questioned).
 *
 * Registry truth: cards.json said 301's css was `web/css/app.css`. Also false — app.css contains
 * no rule for any class this view emits. Check 36 (orphan markup) now exists so a card whose
 * markup has no stylesheet can never again be registered as reviewable (D-571).
 *
 * ── COLOUR, RE-DERIVED PER VALUE (never copied from a reference) ────────────────────────────────
 *   · interactive chrome = --accent (teal-600); --accent-hover on press only (D-430: teal-700 at
 *     rest belongs to the week hero ALONE)
 *   · gold NOTICES, teal ACTS (D-440): the hard gate + the anim-gate are --gold-90 wash with
 *     --gold-700 text. Nothing interactive is ever gold.
 *   · steps ::marker = --kind-do-icon (clay): a how-to is a DO kind (D-454/D-466).
 * ═══════════════════════════════════════════════════════════════════════════════════════════════ */

.tqp { max-width: var(--layout-col-max); margin: 0 auto; min-height: 100%;
  padding: 0 0 var(--space-24); display: flex; flex-direction: column; }

/* ── the drill-in masthead — wordmark left, actions-chevron + close right (D-453 · D-469) ────── */
.tqp-mast { display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-12) var(--rhythm-inset) var(--space-4); }
.tqp-word { font-family: var(--font-display); font-weight: var(--weight-wordmark);
  font-size: var(--size-20); /* token-exception: canonical wordmark size — matches topbar.css (D-411) */
  letter-spacing: var(--tracking-neg-01); color: var(--text-primary); }
.tqp-word b { color: var(--accent); font-weight: inherit; }
.tqp-mast-r { display: flex; align-items: center; gap: var(--space-8); }
.tqp-close { width: var(--dim-40); height: var(--dim-40); border-radius: var(--radius-round);
  background: var(--surface-card); box-shadow: var(--shadow-card); color: var(--accent); border: 0;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none; }
.tqp-close svg { width: var(--size-18); height: var(--size-18); display: block; }
.tqp-close:active { color: var(--accent-hover); opacity: 0.72; }
.tqp-close:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

/* ── kind eyebrow + title (D-458) ────────────────────────────────────────────────────────────── */
.tqp-head { padding: var(--space-8) var(--rhythm-inset) var(--space-12); }
.tqp-eyebrow { font-family: var(--font-label); font-size: var(--text-label);
  font-weight: var(--weight-700); letter-spacing: var(--tracking-05); text-transform: uppercase;
  color: var(--kind-watch-icon); margin: 0 0 var(--space-8); }
.tqp-title { font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-display-sm); line-height: var(--leading-110);
  letter-spacing: var(--tracking-neg-01); color: var(--text-primary); margin: 0; }
.tqp-stand { font-family: var(--font-body); font-size: var(--text-standfirst);
  line-height: var(--leading-150); color: var(--text-secondary); margin: var(--space-8) 0 0;
  max-width: 34em; } /* token-exception: measure */

.tqp-well { padding: 0 var(--rhythm-inset); }

/* ── 🔴 THE RULES-ENGINE GATE — above everything. Gold NOTICES (D-440); teal acts. ───────────── */
.tqp-gate { display: flex; flex-direction: column; gap: var(--space-4);
  padding: var(--space-12) var(--space-16); margin: 0 0 var(--space-16);
  background: var(--gold-90); border-radius: var(--radius-card); }
.tqp-gate-h { font-family: var(--font-label); font-size: var(--text-body-sm);
  font-weight: var(--weight-700); color: var(--gold-700); margin: 0; }
.tqp-gate-b { font-family: var(--font-body); font-size: var(--text-body-sm);
  line-height: var(--leading-150); color: var(--text-primary); margin: 0; }

/* ── THE ANIMATION (D-450). Autoplay muted loop; reduce-motion ⇒ poster + play. ──────────────── */
.tqp-anim { position: relative; aspect-ratio: 16 / 10; border-radius: var(--radius-card-lg);
  overflow: hidden; background: var(--surface-sunken); background-size: cover;
  background-position: center; margin: 0 0 var(--space-12); }
.tqp-vid { width: 100%; height: 100%; object-fit: cover; display: block; }
.tqp-play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: var(--dim-44); height: var(--dim-44); border-radius: var(--radius-round); border: 0;
  cursor: pointer; background: var(--overlay-scrim); color: var(--text-on-dark);
  display: none; place-items: center; }
.tqp-play svg { width: var(--size-18); height: var(--size-18); display: block; margin-left: var(--space-4); }
.tqp-play:active { opacity: 0.8; }
/* RESTART — icon-only round arrow, bottom-right (D-458). Always available, even mid-play,
 * so a parent who wasn't ready can replay from the top and follow along in sync. */
.tqp-restart { position: absolute; right: var(--space-8); bottom: var(--space-8);
  width: var(--dim-32); height: var(--dim-32); border-radius: var(--radius-round); border: 0;
  cursor: pointer; background: var(--overlay-scrim); color: var(--text-on-dark);
  display: grid; place-items: center; }
.tqp-restart svg { width: var(--size-15); height: var(--size-15); display: block; }
.tqp-restart:active { opacity: 0.8; }
.tqp-restart:focus-visible, .tqp-play:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.tqp-dur { position: absolute; left: var(--space-8); bottom: var(--space-8);
  font-family: var(--font-label); font-size: var(--text-label); font-weight: var(--weight-700);
  color: var(--text-on-dark); background: var(--overlay-scrim); border-radius: var(--radius-pill);
  padding: var(--space-4) var(--space-8); }

/* 🔴 THE ANIMATION GATE — the limit rides WITH the animation ("video beats text", the corpus).
 * Gold wash, gold text (D-440) — a notice, never a control. */
.tqp-anim-gate { background: var(--gold-90); border-radius: var(--radius-card);
  padding: var(--space-12) var(--space-16); margin: 0 0 var(--space-16);
  font-family: var(--font-label); font-weight: var(--weight-600); font-size: var(--text-body-sm);
  line-height: var(--leading-150); color: var(--gold-700); }

/* ── body prose ──────────────────────────────────────────────────────────────────────────────── */
.tqp-p { font-family: var(--font-body); font-size: var(--text-body); color: var(--text-primary);
  line-height: var(--leading-155); margin: 0 0 var(--space-12); max-width: 34em; } /* token-exception: measure */
.tqp-p strong { font-weight: var(--weight-600); }

/* ── 302 · NUMBERED STEPS. A how-to has an order that matters ⇒ numbered, ::marker in clay
 * (--kind-do-icon, D-454/D-466). NOT a checklist: options are not a quota (D-452). ───────────── */
.tqp-steps { margin: var(--space-4) 0 var(--space-16); padding-left: var(--space-20);
  display: flex; flex-direction: column; gap: var(--space-8); }
.tqp-steps li { font-family: var(--font-body); font-size: var(--text-body);
  line-height: var(--leading-150); color: var(--text-primary); }
.tqp-steps li::marker { font-family: var(--font-label); font-weight: var(--weight-700);
  color: var(--kind-do-icon); }

/* ── 🔴 PROVENANCE — FROM DATA, OR NOT AT ALL (D-439 · D-465 · D-541). Source (theirs) on the
 * LEFT, reviewer (ours) on the RIGHT, never fused, no date. Not one corpus item carries either
 * field today, so this footrow DOES NOT RENDER — that absence is the honest state. ───────────── */
.tqp-prov { margin-top: var(--space-16); padding-top: var(--space-12);
  border-top: 1px solid var(--border-hairline); /* token-exception: a hairline */
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-12); }
.tqp-src { font-family: var(--font-label); font-size: var(--text-label);
  font-weight: var(--weight-600); color: var(--text-tertiary); }
.tqp-rev { display: inline-flex; align-items: center; gap: var(--space-4);
  font-family: var(--font-label); font-size: var(--text-label);
  font-weight: var(--weight-700); color: var(--accent); }

/* ── D-450 / WCAG 2.2.2 — reduce motion: poster + play, her choice. ────────────────────────────
 * TWO layers, deliberately (neither alone is correct):
 *   · the MEDIA QUERY reacts live if the OS setting flips mid-session (a JS-only fix would not);
 *   · the `.is-reduced` class is set by the wire, which is what ACTUALLY prevents the download —
 *     it gates the `autoplay` attribute and sets `preload="none"` (a CSS-only fix still downloads
 *     and decodes a video it never shows).
 * `.is-playing` (set on the video's own play/pause events) un-hides the video once she taps play —
 * without it the poster would sit over a video she just asked for. */
@media (prefers-reduced-motion: reduce) {
  .tqp-anim .tqp-vid { display: none; }
  .tqp-anim .tqp-play { display: grid; }
  .tqp-anim.is-playing .tqp-vid { display: block; }
  .tqp-anim.is-playing .tqp-play { display: none; }
}
.tqp-anim.is-reduced .tqp-vid { display: none; }
.tqp-anim.is-reduced .tqp-play { display: grid; }
.tqp-anim.is-reduced.is-playing .tqp-vid { display: block; }
.tqp-anim.is-reduced.is-playing .tqp-play { display: none; }
