/* PRAXIS marketing / landing page (served at /landing).
   ---------------------------------------------------------------------------
   Bespoke layout for the public front door. Dependency-free, no build step —
   matching the rest of static/. The palette (--bg/--panel/--fg/--accent/…),
   the light theme, the four accents, the motion primitives (praxis-bubble-in /
   praxis-strip-in / praxis-fade-in / praxis-dot keyframes), and the .skip-link
   all live in theme.css, which is <link>ed BEFORE this file. Everything here
   reads those custom properties, so the page themes for free across light/dark
   and all four accents.

   Two rules the shared conventions demand:
     * NEVER hard-code a hex that sits on/near the accent — use the derived
       tokens (--on-accent, --accent-weak/-mid, --code-fg, --shadow) so it stays
       correct in light mode and on off-blue accents. Accent-filled buttons
       hover via filter:brightness(), not a hard-coded hover color.
     * EVERY custom animation lives inside the reduced-motion guard at the bottom
       (@media prefers-reduced-motion: no-preference + :root:not([data-motion=off]))
       so a motion-sensitive user gets a still page. The replay's JS also renders
       statically when motion is off (see landing.js), so the stage never sits
       empty for those users. */

* { box-sizing:border-box; }
body {
  margin:0; font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  background:var(--bg); color:var(--fg);
  -webkit-font-smoothing:antialiased;
}
main { display:block; }
a { color:var(--accent); text-decoration:none; }
a:hover { text-decoration:underline; }
code {
  font:0.88em/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:var(--accent-weak); color:var(--code-fg); border:1px solid var(--line);
  border-radius:5px; padding:0.5px 5px; overflow-wrap:anywhere;
}

/* The appearance control (theme + accent) is styled in theme.css; here we only
   place it — floated top-right, out of the scrolling content's way. */
.theme-switch { position:fixed; top:16px; right:16px; z-index:50; }

/* ---- Shared section scaffolding ---------------------------------------- */
section { max-width:1160px; margin:0 auto; padding:48px 24px; }
.section-head { max-width:660px; margin:0 auto 26px; text-align:center; }
.section-title { font-size:28px; line-height:1.2; margin:0 0 12px; letter-spacing:-.4px; }
.section-lead { color:var(--muted); font-size:16px; margin:0; }
.section-lead em { color:var(--fg); font-style:normal; }

/* Two-column section: heading on the LEFT, its content on the RIGHT, so a short
   centered block (the meter, the debrief card) sits beside its heading instead
   of stacked under it — wider + shorter. Collapses to a centered stack on narrow
   screens (same 820px breakpoint as the demo grid). */
.split { display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); gap:44px; align-items:center; }
.split > .section-head { text-align:left; margin:0; max-width:420px; }
@media (max-width:820px){
  .split { grid-template-columns:1fr; gap:26px; }
  .split > .section-head { text-align:center; margin:0 auto; max-width:660px; }
}

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  display:inline-flex; align-items:center; gap:6px; font:inherit; font-weight:600;
  cursor:pointer; border-radius:10px; padding:13px 22px; text-decoration:none;
  border:1px solid transparent;
}
.btn:hover { text-decoration:none; }
.btn-primary { background:var(--accent); color:var(--on-accent); }
.btn-primary:hover { filter:brightness(1.12); }
.btn-primary:active { filter:brightness(.96); }
.btn-ghost { background:transparent; color:var(--fg); border-color:var(--line); }
.btn-ghost:hover { border-color:var(--accent); color:var(--accent); }
.btn-text { background:transparent; color:var(--muted); padding:13px 8px; }
.btn-text:hover { color:var(--accent); }
.btn.sm { padding:10px 16px; }
.cta-row { display:flex; flex-wrap:wrap; gap:12px; align-items:center; justify-content:center; }

/* ---- HERO -------------------------------------------------------------- */
.hero { text-align:center; padding:72px 24px 48px; max-width:860px; }
.hero-title { font-size:clamp(36px, 6vw, 60px); line-height:1.05; margin:0 0 22px; letter-spacing:-1.2px; font-weight:800; }
.hero-title .grad { color:var(--accent); }
.hero-sub { color:var(--muted); font-size:19px; line-height:1.55; max-width:620px; margin:0 auto 32px; }
.hero .cta-row { margin-bottom:16px; }
.hero-note { color:var(--muted); font-size:13px; margin:0; }

/* ---- INTERACTIVE DEMO -------------------------------------------------- */
.demo-grid { display:grid; grid-template-columns:1.15fr .85fr; gap:22px; align-items:start; }
@media (max-width:820px){ .demo-grid { grid-template-columns:1fr; } }

.stage-wrap { background:var(--panel); border:1px solid var(--line); border-radius:14px; overflow:hidden; box-shadow:0 16px 40px var(--shadow); }
.stage-bar {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 16px; border-bottom:1px solid var(--line); background:var(--bg);
}
.stage-title { font-size:13px; color:var(--muted); }
.stage-title b { color:var(--fg); }
.stage-controls { display:inline-flex; gap:6px; }
.mini {
  font:inherit; font-size:12px; font-weight:600; cursor:pointer;
  background:transparent; color:var(--muted); border:1px solid var(--line);
  border-radius:8px; padding:5px 10px;
}
.mini:hover { color:var(--fg); border-color:var(--accent); }
.mini.spk[aria-pressed="true"] { color:var(--accent); border-color:var(--accent); }
/* Spent Step (replay fully revealed): greyed + inert, no hover affordance. */
.mini:disabled { opacity:.4; cursor:default; }
.mini:disabled:hover { color:var(--muted); border-color:var(--line); }

/* The transcript scrolls WITHIN the card (bounded height + overflow) so the
   .stage-bar controls above it stay put — a long synthetic conversation no
   longer pushes Play/Step/↺/🔊 off-screen. landing.js's scrollStage() keeps the
   newest turn in view as it grows. */
.stage { padding:18px 18px 22px; min-height:280px; max-height:min(58vh, 420px); overflow-y:auto; }
.stage-hint { color:var(--muted); font-size:14px; margin:0; }

/* Per-segment progress bar, timed to that party's audio clip (landing.js fills
   it over the clip's `dur` via an inline width transition). Subtle: a thin track
   under each bubble. Only added on the animated reveal, so it needs no extra
   motion gate (reduced motion renders the transcript statically, no bars).
   MUST be display:block — it's a <span>, and height/margin/overflow are ignored
   on an inline box, which would collapse the track to nothing. */
.ldg-progress { display:block; height:3px; border-radius:999px; background:var(--line); overflow:hidden; margin:7px 0 0; }
.ldg-progress-fill { display:block; height:100%; width:0; border-radius:inherit; background:var(--accent); }
.ldg-turn.student .ldg-progress-fill { background:var(--good); }
/* Once a segment's dwell ends (landing.js adds .spent, on both natural
   completion and interrupt) the bar has done its job — collapse it away so a
   finished segment doesn't leave a full bar under its bubble. Height + margin go
   to 0 (the track disappears) and it fades out. The transition is gated for
   reduced motion below; here it just snaps to gone. */
.ldg-progress.spent { height:0; margin:0; opacity:0; }

/* "See the debrief ↓" bar, revealed by landing.js when the replay ends. Sits at
   the foot of the stage; a full-width accent-tinted link into the debrief. It's
   display:flex, so it carries its own [hidden] rule (author CSS beats UA
   [hidden]{display:none}) — the same gotcha as the demo/mic strips in the app. */
.stage-done {
  display:flex; justify-content:center; padding:12px 16px;
  border-top:1px solid var(--line); background:var(--bg);
}
.stage-done[hidden] { display:none; }
.stage-done a {
  font-size:13.5px; font-weight:600; color:var(--accent); text-decoration:none;
}
.stage-done a:hover { text-decoration:underline; }

/* Conversation bubbles the replay builds. */
.ldg-turn { margin:0 0 12px; max-width:88%; }
.ldg-turn .who { display:block; font-size:11px; text-transform:uppercase; letter-spacing:.06em; margin-bottom:3px; }
.ldg-turn .bubble { border-radius:12px; padding:9px 13px; font-size:14.5px; line-height:1.5; border:1px solid var(--line); }
.ldg-turn.ta { margin-left:auto; text-align:right; }
.ldg-turn.ta .who { color:var(--accent); }
.ldg-turn.ta .bubble { background:var(--accent-weak); border-color:var(--accent); }
.ldg-turn.student .who { color:var(--good); }
.ldg-turn.student .bubble { background:var(--bg); }
.ldg-turn .bubble code { background:var(--accent-mid); }

/* The TA move chip that resolves from pending → graded. */
.ldg-move-row { margin:-4px 0 12px; text-align:right; }
.ldg-coach {
  display:flex; gap:9px; align-items:baseline; font-size:13px; line-height:1.45;
  border-left:3px solid var(--bad); background:color-mix(in srgb, var(--bad) 8%, transparent);
  border-radius:0 8px 8px 0; padding:8px 12px; margin:0 0 14px;
}
.ldg-coach[hidden] { display:none; }
.ldg-coach .note { color:var(--fg); }

/* ---- Move chips (color coding is NOT in theme.css — declared here, keyed to
   the same tokens as index.html's inline styles so they stay theme-correct). */
.move-chip {
  display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.05em; padding:2px 9px; border-radius:999px;
  border:1px solid var(--line); color:var(--muted); vertical-align:middle;
}
.move-chip.probe { color:var(--good); border-color:var(--good); }
.move-chip.tell, .move-chip.lead { color:var(--bad); border-color:var(--bad); }
.move-chip.neutral { color:var(--muted); border-color:var(--line); }
/* Pending state: holds the shared .thinking-dots so it inherits the praxis-dot
   animation + reduced-motion gating from theme.css. */
.move-chip.pending { color:var(--muted); border-color:var(--line); display:inline-flex; align-items:center; }
.move-chip.pending .thinking-dots i { width:4px; height:4px; background:var(--muted); }

/* ---- Demo side column: code card + sandbox ----------------------------- */
.demo-side { display:flex; flex-direction:column; gap:18px; }
.code-card { background:var(--panel); border:1px solid var(--line); border-radius:14px; overflow:hidden; }
.code-card-head { font-size:12px; text-transform:uppercase; letter-spacing:.07em; color:var(--muted); padding:12px 16px; border-bottom:1px solid var(--line); }
.code-pre, .code-card pre {
  margin:0; padding:14px 16px; font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  color:var(--fg); background:var(--panel); overflow-x:auto; white-space:pre;
}
/* Once the replay swaps the code card to per-line spans, a changed line flashes
   the accent tint briefly (motion-gated) — mirrors the app's code_edit render.
   Every line reserves a 2px transparent left rule so toggling .pointed (below)
   doesn't shift the text. */
.code-pre .code-line { display:block; border-left:2px solid transparent; }
@keyframes ldg-code-flash { from { background:var(--accent-mid); } to { background:transparent; } }
/* A line the TA is pointing at (the landing analog of the app's `pointed_lines`):
   accent tint + a left rule, mirroring index.html's .code-line.pointed. */
.code-pre .code-line.pointed { background:var(--accent-weak); border-left-color:var(--accent); }
@keyframes ldg-code-point { from { background:var(--accent-mid); } to { background:var(--accent-weak); } }
/* Blinking caret riding the line the student is "typing" (setCodeCard animate). */
.code-pre .code-caret { display:inline-block; width:1px; height:1.05em; margin-left:1px;
                        vertical-align:text-bottom; background:var(--accent); }
@keyframes ldg-code-caret-blink { 50% { opacity:0; } }
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="off"]) .code-pre .code-line.changed { animation:ldg-code-flash 1.4s ease-out; }
  :root:not([data-motion="off"]) .code-pre .code-line.pointed { animation:ldg-code-point 1.4s ease-out; }
  :root:not([data-motion="off"]) .code-pre .code-caret { animation:ldg-code-caret-blink 1s steps(2) infinite; }
}

/* Shared-whiteboard card in the demo (right column). The board is an opaque
   white surface — like the app's real whiteboard, so the sketch reads the same
   in light or dark mode — carrying an inline SVG the replay draws on turn 3. */
.wb-card { background:var(--panel); border:1px solid var(--line); border-radius:14px; overflow:hidden; }
.wb-card-tag { text-transform:none; letter-spacing:normal; color:var(--accent); font-weight:600; }
.wb-board { background:#fff; }
.wb-board svg { display:block; width:100%; height:auto; }
/* The strokes draw on with a dash-offset sweep so the diagram appears to be
   sketched (motion-gated — reduced motion shows it drawn). */
@keyframes ldg-wb-draw { to { stroke-dashoffset:0; } }
@keyframes ldg-wb-fade { from { opacity:0; } to { opacity:1; } }
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="off"]) .wb-board .wb-stroke {
    stroke-dasharray:var(--len); stroke-dashoffset:var(--len);
    animation:ldg-wb-draw .5s ease-out forwards; animation-delay:var(--delay,0ms); }
  :root:not([data-motion="off"]) .wb-board .wb-ink { opacity:0;
    animation:ldg-wb-fade .3s ease-out forwards; animation-delay:var(--delay,0ms); }
}

.sandbox { background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:16px 18px; }
.sandbox-head { font-size:15px; font-weight:700; margin-bottom:4px; }
.sandbox-sub { color:var(--muted); font-size:13px; margin:0 0 12px; }
.sandbox-form { display:flex; gap:8px; margin-bottom:12px; }
.sandbox-form input {
  flex:1; min-width:0; font:inherit; font-size:14px; background:var(--bg); color:var(--fg);
  border:1px solid var(--line); border-radius:10px; padding:11px 13px;
}
.sandbox-form input:focus { outline:none; border-color:var(--accent); }
.sandbox-result { border:1px solid var(--line); border-radius:10px; padding:12px 14px; background:var(--bg); font-size:13.5px; line-height:1.5; }
.sandbox-result[hidden] { display:none; }
.sandbox-result .sr-head { display:flex; align-items:center; gap:8px; margin-bottom:6px; }
.sandbox-result .sr-note { color:var(--fg); }
/* Shown when the classifier model is unavailable and the keyword-heuristic
   fallback answered instead — a soft warning, keyed to the --bad token like the
   coaching / mic-warning strips. */
.sandbox-result .sr-warn {
  color:var(--bad); font-size:12.5px; margin-bottom:6px;
  border-left:3px solid var(--bad); background:color-mix(in srgb, var(--bad) 8%, transparent);
  border-radius:0 6px 6px 0; padding:6px 10px;
}
.sandbox-examples { margin-top:12px; font-size:12.5px; color:var(--muted); display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.chip-btn {
  font:inherit; font-size:12px; cursor:pointer; background:transparent; color:var(--accent);
  border:1px solid var(--line); border-radius:999px; padding:3px 11px;
}
.chip-btn:hover { border-color:var(--accent); }

/* ---- MOVE TAXONOMY ----------------------------------------------------- */
.move-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:16px; }
.move-card {
  background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:18px 18px 16px;
  display:flex; flex-direction:column; gap:10px;
}
.move-card p { margin:0; color:var(--fg); font-size:14px; line-height:1.5; flex:1; }
.move-card .move-chip { align-self:flex-start; }
.move-verdict { font-size:11.5px; font-weight:600; }
.move-verdict.good { color:var(--good); }
.move-verdict.bad { color:var(--bad); }
.move-verdict.muted { color:var(--muted); }
.taxonomy-foot { max-width:720px; margin:26px auto 0; text-align:center; color:var(--muted); font-size:14.5px; line-height:1.55; }
.taxonomy-foot b { color:var(--fg); }
.taxonomy-foot em { color:var(--fg); font-style:normal; }

/* ---- BELIEVABILITY FLOOR / METER --------------------------------------- */
.meter { width:100%; margin:0; }
.meter-track {
  position:relative; height:44px; background:var(--panel); border:1px solid var(--line);
  border-radius:12px; overflow:hidden;
}
.meter-fill { position:absolute; left:0; top:0; bottom:0; width:0; border-radius:12px 0 0 12px; }
.meter-fill.good { background:color-mix(in srgb, var(--good) 30%, transparent); border-right:2px solid var(--good); }
.meter-fill.bad { background:color-mix(in srgb, var(--bad) 30%, transparent); border-right:2px solid var(--bad); }
/* Floor marker sits at ~92.5% of the 0–2000ms track (1850/2000). */
.meter-floor { position:absolute; top:0; bottom:0; left:92.5%; border-left:2px dashed var(--muted); }
.meter-floor span {
  position:absolute; top:50%; left:6px; transform:translateY(-50%); white-space:nowrap;
  font-size:11px; color:var(--muted);
}
.meter-label { display:flex; align-items:baseline; gap:10px; margin-top:12px; }
.meter-val { font-size:26px; font-weight:800; font-variant-numeric:tabular-nums; letter-spacing:-.5px; }
.meter-verdict { font-size:13px; font-weight:600; }
.meter-verdict.good { color:var(--good); }
.meter-verdict.bad { color:var(--bad); }
.floor-foot { color:var(--muted); font-size:13.5px; margin:18px 0 0; }
@media (max-width:820px){ .floor-foot { text-align:center; } }

/* ---- FEATURE GRID ------------------------------------------------------ */
.feat-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:18px; }
.feat { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:22px 20px; }
.feat h3 { margin:0 0 8px; font-size:17px; }
.feat p { margin:0; color:var(--muted); font-size:14.5px; line-height:1.55; }
.feat p b { color:var(--fg); }

/* ---- MOCKED DEBRIEF CARD ----------------------------------------------- */
.dbf-card { width:100%; margin:0; background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:24px 26px; box-shadow:0 16px 40px var(--shadow); }
/* Anchor back up to the replay conversation — the counterpart to the stage's
   "See the debrief ↓" link, so the two sections round-trip. On its own line
   above the verdict chip (display:block), not sharing the row with it. */
.dbf-back { display:block; width:fit-content; font-size:12.5px; font-weight:600; color:var(--muted); text-decoration:none; margin-bottom:14px; }
.dbf-back:hover { color:var(--accent); text-decoration:underline; }
.dbf-verdict { display:inline-block; font-weight:700; font-size:13px; padding:5px 13px; border-radius:999px; margin-bottom:14px; }
.dbf-verdict.good { color:var(--good); border:1px solid var(--good); }
.dbf-tally { display:flex; flex-wrap:wrap; gap:7px; margin-bottom:14px; }
.dbf-summary { color:var(--fg); font-size:14.5px; line-height:1.55; margin:0 0 16px; }
.dbf-h { font-size:11px; text-transform:uppercase; letter-spacing:.08em; color:var(--accent); margin:0 0 6px; font-weight:600; }
.dbf-list { margin:0 0 16px; padding-left:18px; font-size:14px; line-height:1.55; color:var(--fg); }
.dbf-list li { margin:4px 0; }
.dbf-cite { font-size:12px; color:var(--muted); border-top:1px solid var(--line); padding-top:10px; margin:0; }

/* ---- CLOSING CTA ------------------------------------------------------- */
.closer { text-align:center; max-width:720px; }
.closer-title { font-size:34px; letter-spacing:-.6px; margin:0 0 12px; font-weight:800; }
.closer-sub { color:var(--muted); font-size:17px; margin:0 auto 28px; max-width:560px; }
.closer .cta-row { margin-bottom:18px; }
.closer-note { color:var(--muted); font-size:13px; margin:0; }

/* ---- MOTION (gated) ----------------------------------------------------
   Every custom animation is confined here, behind BOTH prefers-reduced-motion
   AND the Settings "Reduce motion" opt-out — mirroring theme.css. A reduced-
   motion visitor gets a still page (and landing.js renders the replay
   statically), so nothing ever sits mid-animation. The keyframes themselves
   (praxis-bubble-in / -strip-in / -fade-in / -dot) are declared in theme.css. */
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="off"]) {
    /* Smooth-scroll in-page anchors (the hero's "Watch it work ↓" → #demo) so
       the jump glides rather than snapping. Gated with the rest of the motion. */
    scroll-behavior:smooth;
    .ldg-turn { animation:praxis-bubble-in .28s ease-out both; }
    .ldg-coach:not([hidden]) { animation:praxis-strip-in .3s ease-out both; }
    .sandbox-result:not([hidden]) { animation:praxis-fade-in .26s ease-out both; }
    /* Meter fill eases to its target width when the value is set. */
    .meter-fill { transition:width .9s cubic-bezier(.22,.61,.36,1); }
    /* Card hover-lift — subtle, communicates interactivity. */
    .move-card, .feat { transition:transform .16s ease, border-color .16s ease, box-shadow .16s ease; }
    .move-card:hover, .feat:hover { transform:translateY(-3px); border-color:var(--accent); box-shadow:0 10px 26px var(--shadow); }
    .chip-btn, .mini { transition:color .14s ease, border-color .14s ease; }
    /* The finished progress bar collapses+fades away smoothly (it snaps when
       motion is off, since this transition lives inside the guard). */
    .ldg-progress { transition:height .35s ease, margin .35s ease, opacity .35s ease; }
    /* Hero entrance — on the inner section, NEVER on <body> (a residual body
       transform would break the position:fixed .theme-switch). */
    .hero > * { animation:praxis-bubble-in .5s ease-out both; }
    .hero-title { animation-delay:.08s; }
    .hero-sub { animation-delay:.16s; }
    .hero .cta-row { animation-delay:.24s; }
    .hero-note { animation-delay:.3s; }
  }
}
