/* Pocket Praxis — the mobile layer over praxis.css.
 *
 * praxis.css is a print and desktop document system: it has no breakpoints and
 * its grids are fixed columns. Everything phone-shaped lives here, and nothing
 * here redefines a design-system token.
 *
 * House rule from praxis-design-system/SKILL.md: no animations, gradients or
 * drop shadows, and "this brand doesn't pop". Points and streaks are markup and
 * copy, not effects. Flat amber, no glow, no confetti, no exclamation marks.
 */

:root {
  --plato-ink:    #1F1F1F;
  --plato-cloth:  #FFFFFF;
  --plato-shade:  #E4DFD6;
  --plato-amber:  hsl(var(--primary));
  --plato-skin:   #E8C9A4;
  --plato-muzzle: #C6A279;
  --plato-beard:  #CECAC5;
  --plato-hair:   #928D87;

  --app-w: 430px;
  --tap: 44px;
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) {
    --plato-ink:   #14100D;
    --plato-shade: #D4CEC4;
    --plato-muzzle: #B08F6A;
    --plato-hair:  #7C7770;
  }
}

html, body { height: 100%; }
body {
  margin: 0;
  background: hsl(var(--muted));
  display: flex;
  flex-direction: column;
  align-items: center;
  overscroll-behavior: contain;
}

/* ---- the app frame ------------------------------------------------------ */
.app {
  width: 100%;
  max-width: var(--app-w);
  flex: 1;
  display: flex;
  flex-direction: column;
  background: hsl(var(--background));
  position: relative;
  overflow: hidden;
}
@media (min-width: 480px) {
  body { padding: var(--space-6) 0; }
  .app {
    height: min(900px, calc(100vh - 6rem));
    flex: 0 0 auto;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-xl);
  }
}

/* ---- top chrome --------------------------------------------------------- */
.bar {
  flex: 0 0 auto;
  padding: calc(var(--space-4) + env(safe-area-inset-top)) var(--space-5) var(--space-3);
  border-bottom: 1px solid hsl(var(--border));
}
.bar-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3);
  font-size: var(--text-xs); letter-spacing: var(--tracking-wider);
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
.bar-row b {
  color: hsl(var(--foreground)); font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
/* Course names run to "AI Fluency: Framework and Foundations", which wraps the
   row onto three lines and squeezes the score. The name gives way; the score
   and the back control keep their space. */
#bar-left {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
#bar-right { flex: 0 0 auto; white-space: nowrap; }
.bar-back { flex: 0 0 auto; white-space: nowrap; }

/* The row is aligned on the baseline, which a button with no text in it does
   not really have: centre these instead. The padding is a tap target the 20px
   glyph does not need to grow to fill, and the negative margin keeps it from
   pushing the row taller than the text already makes it. */
.bar-icon {
  flex: 0 0 auto;
  align-self: center;
  display: block;
  background: none; border: 0; cursor: pointer;
  padding: var(--space-2);
  margin: calc(var(--space-2) * -1);
  color: hsl(var(--muted-foreground));
}
.bar-icon svg {
  display: block; width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 1.75;
  stroke-linecap: round; stroke-linejoin: round;
}
.bar-icon:hover, .bar-icon:focus-visible { color: hsl(var(--foreground)); }
.bar-icon[hidden] { display: none; }

/* Home, back, the course name, the score and the account all want the same
   row, and on a 320px phone they stop fitting once the score reaches four
   digits — which it does, since the course set is worth a few thousand points.
   The back control gives up its word: the arrow is the affordance, the label is
   the least load-bearing part of the row, and it stays in the accessible name
   so nothing is lost to a screen reader. */
@media (max-width: 374px) {
  .bar { padding-left: var(--space-4); padding-right: var(--space-4); }
  .bar-row { gap: var(--space-2); }
  .bar-back .bl {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}
.bar-back {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit;
  text-transform: inherit;
}
.bar-title {
  margin: var(--space-2) 0;
  font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-base); letter-spacing: var(--tracking-tight);
}
.track { height: 4px; background: hsl(var(--muted)); border-radius: 2px; overflow: hidden; }
.track i { display: block; width: 0; height: 100%; background: hsl(var(--primary)); }

/* ---- scrolling body ----------------------------------------------------- */
.screen {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--space-5) var(--space-5) var(--space-6);
}
.foot {
  flex: 0 0 auto;
  padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom));
  border-top: 1px solid hsl(var(--border));
}
.foot:empty { display: none; }

/* ---- Plato ---------------------------------------------------------------
   The pointer is a 624x624 video of a black silhouette on white. Two things
   follow from that.

   The dog only occupies a 543x355 window of that square (x29,y107), so the
   frame is cropped to the window and the video oversized inside it. Without
   that the dog would sit in a lap of empty canvas and read as half the size of
   the head it replaces; cropped, it takes the same 62px the head did. The
   magic numbers are the measured extent across all 121 frames, so they only
   change if the artwork does.

   The white is dropped with a blend rather than an alpha channel, because the
   one format that carries alpha and plays everywhere does not exist: HEVC with
   alpha is Safari-only, VP9-in-WebM is everyone else. Multiply leaves white
   untouched and keeps the black, which is exactly the cut-out, and costs
   nothing. Dark mode inverts first and screens instead, so the dog comes back
   as light-on-dark like the rest of the theme. */
.plato {
  --plato-w: 62px;
  width: var(--plato-w);
  flex: 0 0 var(--plato-w);
  height: calc(var(--plato-w) * 355 / 543);
  position: relative;
  overflow: hidden;
}
.plato video {
  position: absolute;
  left: calc(var(--plato-w) * -29 / 543);
  top: calc(var(--plato-w) * -107 / 543);
  width: calc(var(--plato-w) * 624 / 543);
  height: calc(var(--plato-w) * 624 / 543);
  display: block;
  /* The clip's background is not quite white — 248 to 253, and noisy with it,
     which is a visible block on any surface that is actually white. A slight
     lift clips all of it to 255 and leaves the silhouette alone: black stays
     black through a brightness multiply. Paired with .top being that same
     white, the background disappears without a blend mode, which matters
     because Safari does not apply mix-blend-mode to a video at all. */
  filter: brightness(1.06);
  pointer-events: none;
}
.plato-lg { --plato-w: 108px; margin: 0 auto var(--space-4); }

/* ---- the masthead ------------------------------------------------------- */
/* The bar and the character block are one white section; the page proper
   starts below it. The break is the change of colour, so there is no rule
   drawn across it and the bar gives up its border — two lines close together
   would read as a boundary in the wrong place.

   White specifically, and not the page's warm off-white: the animation carries
   its own white background that no browser will knock out for us (see
   .plato video), so the surface it sits on has to be the colour it already is.
   Dark mode takes that to its conclusion and goes to black, with the clip
   inverted to match — a near-black square on a near-black band. */
.top {
  background: #fff;
  margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) var(--space-6);
  padding: var(--space-5) var(--space-5) var(--space-6);
}
.top > :last-child { margin-bottom: 0; }
.bar { background: #fff; border-bottom: 0; }

.dark .top, :root.dark .top, .dark .bar, :root.dark .bar { background: #000; }
.dark .plato video, :root.dark .plato video { filter: brightness(1.06) invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not(.light) .top, :root:not(.light) .bar { background: #000; }
  :root:not(.light) .plato video { filter: brightness(1.06) invert(1); }
}

.speech { display: flex; gap: var(--space-4); align-items: center; margin-bottom: var(--space-5); }
.speech .said { flex: 1; min-width: 0; }
.speech h2 {
  font-size: var(--text-xl); line-height: var(--leading-tight);
  margin: 0 0 var(--space-2); letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
.speech h2:last-child { margin-bottom: 0; }
.speech p { margin: 0; font-size: var(--text-sm); color: hsl(var(--muted-foreground)); }

.teach { font-size: var(--text-base); line-height: var(--leading-relaxed); margin: 0 0 var(--space-5); }

/* ---- buttons ------------------------------------------------------------ */
.btn-lg {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; min-height: var(--tap);
  padding: var(--space-3) var(--space-5);
  border: 0; border-radius: var(--radius);
  background: hsl(var(--foreground)); color: hsl(var(--background));
  font-family: var(--font-sans); font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.btn-lg[disabled] { opacity: .4; cursor: default; }
.btn-lg .arr { opacity: .6; }

.opt {
  display: block; width: 100%; text-align: left;
  min-height: var(--tap);
  margin-bottom: var(--space-3);
  padding: var(--space-4);
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  font-family: var(--font-sans); font-size: var(--text-sm);
  line-height: var(--leading-snug); color: hsl(var(--foreground));
  cursor: pointer;
}
/* The option they chose is marked as theirs, not as wrong, and the correct
   answer stays hidden: the question gets re-offered, so revealing it here would
   end the thinking rather than restart it. */
.opt.picked {
  border-color: hsl(var(--muted-foreground));
  background: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
}
.opt.ok { border-color: hsl(var(--primary)); border-width: 2px; padding: calc(var(--space-4) - 1px); }
.opt[disabled] { cursor: default; }
.opt .k {
  display: inline-block; width: 1.4em;
  font-weight: var(--weight-bold); color: hsl(var(--muted-foreground));
}

/* The offer to make an account, signed out, at the top of the home screen.
   It used to sit under the course list, which on a phone is below the fold on
   every screen size we have. Spaced off the character below it so the two do
   not read as one block. */
.acct-top { margin-bottom: var(--space-5); }

.q { font-size: var(--text-lg); line-height: var(--leading-snug); margin: 0 0 var(--space-5); text-wrap: balance; }

:where(button, a, textarea):focus-visible {
  outline: 2px solid hsl(var(--primary));
  outline-offset: 2px;
}

/* ---- diagram ------------------------------------------------------------ */
/* House rule: diagram content is centred in the viewBox. A pair of boxes set
   symmetrically about the centre line counts as centred and stays put; a lone
   element does not, and gets moved. */
.diagram { margin: 0 0 var(--space-5); overflow-x: auto; }
.diagram svg { width: 100%; height: auto; display: block; }
.box       { fill: hsl(var(--card));       stroke: hsl(var(--border));  stroke-width: 1.5; }
.box-amber { fill: hsl(var(--card));       stroke: hsl(var(--primary)); stroke-width: 2; }
.box-ink   { fill: hsl(var(--foreground)); }
.t-band { font: 600 10px var(--font-sans); letter-spacing: .09em; fill: hsl(var(--muted-foreground)); text-transform: uppercase; }
.t-lbl  { font: 600 14px var(--font-sans); fill: hsl(var(--foreground)); }
.t-sub  { font: 400 12px var(--font-sans); fill: hsl(var(--muted-foreground)); }
.t-tiny { font: 400 11px var(--font-sans); fill: hsl(var(--muted-foreground)); }
.t-mono { font: 400 12px var(--font-mono); fill: hsl(var(--foreground)); }
.t-white{ font: 600 13px var(--font-sans); fill: hsl(var(--background)); }
.l-ink   { stroke: hsl(var(--foreground)); fill: none; }
.l-amber { stroke: hsl(var(--primary));    fill: none; }
.l-faint { stroke: hsl(var(--border));     fill: none; }
.s-ink   { fill: hsl(var(--foreground)); }
.s-amber { fill: hsl(var(--primary)); }
.s-muted { fill: hsl(var(--muted-foreground)); }

/* ---- video card --------------------------------------------------------- */
.video {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: var(--tap);
  padding: var(--space-3) var(--space-4);
  border: 1px solid hsl(var(--border)); border-left: 3px solid hsl(var(--primary));
  border-radius: var(--radius-sm);
  text-decoration: none; color: inherit;
  margin-bottom: var(--space-5);
}
.video .play {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: hsl(var(--primary));
  display: grid; place-items: center;
}
.video .play svg { width: 8px; height: 8px; fill: hsl(var(--primary-foreground)); }
.video .vt { font-size: var(--text-sm); font-weight: var(--weight-medium); line-height: 1.3; }
.video .vm { font-size: var(--text-xs); color: hsl(var(--muted-foreground)); }

/* ---- verdict ------------------------------------------------------------ */
.verdict {
  border-top: 1px solid hsl(var(--border));
  border-bottom: 1px solid hsl(var(--border));
  padding: var(--space-4) 0; margin: var(--space-5) 0;
}
.verdict .vl { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-base); display: block; margin-bottom: var(--space-2); }
.verdict p { margin: 0; font-size: var(--text-sm); line-height: var(--leading-relaxed); color: hsl(var(--muted-foreground)); }

/* ---- lists -------------------------------------------------------------- */
.lesson-list { list-style: none; margin: 0; padding: 0; }
/* Rows are <li> when they are inert and <button> when they can be opened, so
   this has to match both. A bare `li` selector leaves the buttons unstyled and
   their contents stretch to fill the row. */
.lesson-list > * {
  display: flex; gap: var(--space-4); align-items: center;
  width: 100%; min-height: var(--tap);
  padding: var(--space-3) 0;
  border: 0; border-bottom: 1px solid hsl(var(--border));
  background: none; text-align: left;
  font-family: var(--font-sans); font-size: var(--text-sm); color: inherit;
}
.lesson-list button.li { cursor: pointer; }
.lesson-list .n {
  flex: 0 0 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  background: hsl(var(--muted)); color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}
.lesson-list .done .n { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
.lesson-list .now .n  { background: hsl(var(--foreground)); color: hsl(var(--background)); }
.lesson-list .t { flex: 1; line-height: var(--leading-snug); min-width: 0; }
.lesson-list .locked { opacity: .45; }
.lesson-list .meta {
  font-size: var(--text-xs); color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}

/* ---- stats -------------------------------------------------------------- */
.stat-row { display: flex; gap: var(--space-3); margin-bottom: var(--space-5); }
.stat {
  flex: 1; min-width: 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm);
}
.stat .v {
  font-family: var(--font-display); font-weight: var(--weight-black);
  font-size: var(--text-2xl); line-height: 1; font-variant-numeric: tabular-nums;
}
.stat .l {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-wider); color: hsl(var(--muted-foreground));
  margin-top: var(--space-1);
}

/* ---- odds and ends ------------------------------------------------------ */
.note { font-size: var(--text-sm); color: hsl(var(--muted-foreground)); line-height: var(--leading-relaxed); }
/* Classes rather than inline style attributes, so the deployment can run a
   Content-Security-Policy without 'unsafe-inline' on styles. */
.video-lead { margin-bottom: var(--space-3); }

/* ---- sign-in form ------------------------------------------------------- */
.field {
  display: block; width: 100%; box-sizing: border-box;
  min-height: var(--tap);
  margin-bottom: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  background: hsl(var(--card)); color: hsl(var(--foreground));
  font-family: var(--font-sans); font-size: var(--text-base);
}
.field::placeholder { color: hsl(var(--muted-foreground)); }
#code { font-variant-numeric: tabular-nums; letter-spacing: var(--tracking-widest); }
.speech-done { margin-bottom: var(--space-4); }
.speech-done .said { text-align: center; }
.rule { border: 0; border-top: 1px solid hsl(var(--border)); margin: var(--space-5) 0; }
.link { color: hsl(var(--primary)); font-weight: var(--weight-medium); text-decoration: none; }

