/* ============================================================================
   AI Learning OS — utilitarian workspace theme
   ----------------------------------------------------------------------------
   Design contract enforced by this file:
   1. FLAT HIERARCHY. There is exactly one level of surface. Grouping is done
      with hairlines (--rule), spacing and typography — never a box inside a
      box. The only bordered objects are the shell, the focused flashcard and
      modals.
   2. MONO DATA. Every number, label, meter and axis renders in --mono with
      tabular figures, so columns line up and values never reflow as they
      change. Progress is drawn by the segmented .meter primitive.
   3. STABLE GRID. No hover state changes geometry — hover only repaints
      background/border colour. Nothing translates, scales or bounces.
   4. MULTI-DIMENSIONAL COLOUR. Hue carries meaning: --t1..--t10 identify the
      ten curriculum tracks, --d-* the four mastery dimensions, --c1..--c5 the
      confidence ramp. Accent is reserved for interactive intent.
   ========================================================================== */

/* --- palette -------------------------------------------------------------
   Paper-white and neutral: a soft grey page, a pure white workspace, a light
   grey rail, and a single blue as the only interactive hue. Ink, rules and
   surfaces are all drawn from one cool grey ramp, so the only colour on the
   page is colour that means something — track hue, mastery dimension,
   confidence.
   Light is the default in both directions: the dark theme is opt-in via
   data-theme="dark" on <html> (the topbar toggle sets it), so the app is
   white unless the learner asks otherwise.
------------------------------------------------------------------------- */

:root {
  color-scheme: light;

  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* --- surfaces & ink ---------------------------------------------------- */
  --bg:         #eff1f4;
  --surface:    #ffffff;
  --surface-2:  #f7f8fa;
  --hover:      #f3f5f8;
  --rule:       #ebeef2;
  --rule-2:     #dbe0e6;
  --ink:        #10141a;
  --ink-2:      #4d555f;
  --ink-3:      #79828d;
  --ink-4:      #a3abb5;

  /* blue: --accent carries text and fills that need contrast,
     --accent-bright is the decorative sibling used on meters and marks */
  --accent:     #2563eb;
  --accent-2:   #1d4ed8;
  --accent-bright: #3b82f6;
  --accent-wash:#eef3ff;
  --on-accent:  #ffffff;

  --ok:         #17803d;
  --ok-wash:    #ecf7f0;
  --warn:       #b45309;
  --danger:     #cf3a2d;
  --danger-wash:#fdefed;

  /* --- rail: a quiet grey band, themed with the rest ---------------------- */
  --rail:        #f7f8fa;
  --rail-ink:    #10141a;
  --rail-ink-2:  #79828d;
  --rail-hover:  #eef0f4;
  --rail-active: #e7edfb;

  /* --- track hues (10 curriculum tracks) --------------------------------- */
  --t1:#dd5252; --t2:#dd8636; --t3:#c09a22; --t4:#3f9e6b; --t5:#2f9a8c;
  --t6:#3a86c8; --t7:#5c6bd6; --t8:#8f5fd0; --t9:#c25aa6; --t10:#78838f;

  /* --- mastery dimensions ------------------------------------------------ */
  --d-int:#8f5fd0; --d-math:#3a86c8; --d-code:#3f9e6b; --d-app:#c09a22;

  /* --- confidence ramp 1..5 ---------------------------------------------- */
  --c1:#cf3a2d; --c2:#d8802f; --c3:#bd9a1e; --c4:#3d84c4; --c5:#3d9a63;
  --c1-wash:#fdefed; --c2-wash:#fdf4ea; --c3-wash:#fbf7e4; --c4-wash:#eef4fb; --c5-wash:#ecf6f0;

  --seg-track:  #eef0f4;
  --seg-active: #ffffff;

  --meter-track: #e8ebef;
  --meter-fill:  var(--accent);

  --shadow-1: 0 1px 2px rgba(16, 20, 26, .04), 0 8px 24px rgba(16, 20, 26, .05);
  --shadow-2: 0 18px 48px rgba(16, 20, 26, .18);
  --scrim:    rgba(16, 20, 26, .42);

  --ease: cubic-bezier(.2,.7,.2,1);
}

/* Opt-in dark: same neutral ramp inverted, same single blue. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:#0a0c0f; --surface:#14181d; --surface-2:#191e24; --hover:#1e242b;
  --rule:#252b32; --rule-2:#343c45;
  --ink:#e9edf2; --ink-2:#aeb7c1; --ink-3:#828b96; --ink-4:#646d78;

  --accent:#5b93f5; --accent-2:#7aa9ff; --accent-bright:#5b93f5;
  --accent-wash:#16223a; --on-accent:#08111f;
  --ok:#4ec27e; --ok-wash:#122a1d; --warn:#e0a94a; --danger:#f0796c; --danger-wash:#2c1614;

  --rail:#10141a; --rail-ink:#e9edf2; --rail-ink-2:#828b96;
  --rail-hover:#1c222a; --rail-active:#1d2739;

  --t1:#f07373; --t2:#eda05c; --t3:#d8bd4e; --t4:#6cc48a; --t5:#4fbdad;
  --t6:#5fa4e0; --t7:#8590ea; --t8:#ac86e6; --t9:#dd7fc0; --t10:#98a5b3;

  --d-int:#ac86e6; --d-math:#5fa4e0; --d-code:#6cc48a; --d-app:#d8bd4e;

  --c1:#f0796c; --c2:#e79b57; --c3:#d8bd4e; --c4:#6ea8e8; --c5:#5cbb83;
  --c1-wash:#2c1614; --c2-wash:#2b1e10; --c3-wash:#282311; --c4-wash:#142130; --c5-wash:#12271b;

  --seg-track:#1c222a; --seg-active:#2b333c;

  --meter-track:#2a323b;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 28px rgba(0, 0, 0, .32);
  --shadow-2: 0 18px 48px rgba(0, 0, 0, .5);
  --scrim:    rgba(4, 6, 9, .62);
}

/* ==========================================================================
   BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; height: 100%; }

/* The app is a fixed frame that never page-scrolls: the white shell floats
   on the grey page and .main is the only scroll container, so the rail and
   the topbar stay put while a 66-node roadmap moves underneath them. */
body {
  height: 100%;
  margin: 0;
  padding: 14px;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "cv05" 1, "ss01" 1;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: var(--accent); }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.008em; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

.hidden { display: none !important; }

::selection { background: var(--accent-wash); }

/* ==========================================================================
   PRIMITIVES
   ========================================================================== */

/* --- icons: 24-viewBox stroke sprite, never emoji ------------------------ */
.ic {
  width: 14px; height: 14px; flex: 0 0 auto;
  fill: none; stroke: currentColor;
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
.ic--16 { width: 16px; height: 16px; }
.ic--18 { width: 18px; height: 18px; }

/* --- mono label: the workhorse for every axis, key and caption ----------- */
.lbl {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.lbl--accent { color: var(--accent); }

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* --- segmented meter -----------------------------------------------------
   One CSS mask carves the track AND the fill into identical ticks, so the bar
   reads as a discrete instrument rather than a smooth blob, while the fill
   still animates as one continuous width. --pct drives it; inline width from
   JS overrides for the persistent (animated) meters.                        */
.meter {
  --seg: 4px; --gap: 2px; --h: 6px;
  position: relative;
  display: block;
  width: 100%;
  height: var(--h);
  background: var(--meter-track);
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 var(--seg), transparent var(--seg) calc(var(--seg) + var(--gap)));
          mask-image: repeating-linear-gradient(90deg, #000 0 var(--seg), transparent var(--seg) calc(var(--seg) + var(--gap)));
}
.meter > i {
  display: block;
  position: absolute; inset: 0 auto 0 0;
  width: var(--pct, 0%);
  background: var(--meter-fill);
  transition: width .55s var(--ease);
}
.meter--lg  { --h: 10px; --seg: 5px; --gap: 2px; }
.meter--sm  { --h: 5px;  --seg: 3px; --gap: 2px; }
.meter--xs  { --h: 4px;  --seg: 3px; --gap: 2px; }

/* --- tick ring ------------------------------------------------------------
   Same instrument language as .meter, wrapped around a circle: a mask of
   dashed stroke turns both track and fill into ticks.                       */
.ring { position: relative; width: 44px; height: 44px; flex: 0 0 auto; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); display: block; }
.ring circle { fill: none; stroke-width: 5; }
.ring .ring-track { stroke: var(--meter-track); }
.ring .ring-fill  { stroke: var(--accent); transition: stroke-dashoffset .55s var(--ease); }
.ring > span {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 10px; font-weight: 500; color: var(--ink);
}
.ring--lg { width: 76px; height: 76px; }
.ring--lg > span { font-size: 15px; }

/* --- pill: a bare mono tag, no fill -------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px;
  border: 1px solid var(--rule-2);
  border-radius: 5px;
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .04em;
  color: var(--ink-3);
  white-space: nowrap;
}
.pill--accent { border-color: color-mix(in srgb, var(--accent) 40%, var(--rule)); color: var(--accent); }
.pill--ok     { border-color: color-mix(in srgb, var(--ok) 40%, var(--rule)); color: var(--ok); }

/* --- buttons: fixed geometry, hover repaints only ------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 30px;
  padding: 0 12px;
  border: 1px solid var(--rule-2);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font-size: 12px; font-weight: 500;
  white-space: nowrap;
  transition: background .12s linear, border-color .12s linear, color .12s linear;
}
.btn:hover { background: var(--hover); border-color: var(--ink-4); }
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn:disabled:hover { background: var(--surface); border-color: var(--rule-2); }

.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-2); border-color: var(--accent-2); }
.btn--primary:disabled:hover { background: var(--accent); border-color: var(--accent); }

.btn--quiet { border-color: transparent; color: var(--ink-2); }
.btn--quiet:hover { background: var(--hover); border-color: var(--rule); }

.btn--icon { width: 30px; padding: 0; color: var(--ink-3); }
.btn--wide { width: 100%; }

/* --- inputs -------------------------------------------------------------- */
input[type=text], input[type=search], select, textarea {
  width: 100%;
  min-height: 30px;
  padding: 6px 10px;
  border: 1px solid var(--rule-2);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font-size: 12px;
  outline: none;
  transition: border-color .12s linear;
}
input::placeholder, textarea::placeholder { color: var(--ink-4); }
input:focus, select:focus, textarea:focus { border-color: var(--accent); }
textarea { min-height: 92px; resize: vertical; line-height: 1.6; padding: 9px 11px; }
select { appearance: none; padding-right: 26px; background-image: none; }

/* --- section head: a title line with a rule under it --------------------- */
.head {
  display: flex; align-items: baseline; gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 12px;
}
.head h3 { font-size: 13px; }
.head .lbl { margin-left: auto; }

/* --- hairline-separated grid: dividers are gaps, not borders ------------- */
.rules {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}
.rules > * { background: var(--surface); }

/* --- key/value readout --------------------------------------------------- */
.kv { display: grid; gap: 3px; padding: 11px 14px; }
.kv > .lbl { font-size: 9.5px; }
.kv b {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 17px; font-weight: 500; letter-spacing: -.02em; line-height: 1.1;
}
.kv small { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }

.stack { display: grid; gap: 22px; }

/* ==========================================================================
   SHELL — one white card on a grey page
   ========================================================================== */

.app-shell {
  height: 100%;
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 16px;
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

/* --- rail ---------------------------------------------------------------- */
.sidebar {
  height: 100%;
  display: flex; flex-direction: column; align-items: center;
  padding: 16px 8px 12px;
  background: var(--rail);
  border-right: 1px solid var(--rule);
  overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none;
}
.sidebar::-webkit-scrollbar { display: none; }

.brand { display: grid; justify-items: center; gap: 6px; padding-bottom: 18px; }
.brand-mark { width: 24px; height: 24px; display: block; }
.brand h1 {
  font-family: var(--mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--rail-ink-2);
  white-space: nowrap;
}
.brand p { display: none; }

nav { display: grid; gap: 2px; width: 100%; }
.nav-item {
  display: grid; justify-items: center; gap: 5px;
  width: 100%; padding: 9px 2px;
  border-radius: 9px;
  color: var(--rail-ink-2);
  text-align: center; white-space: nowrap;
  transition: background .12s linear, color .12s linear;
}
.nav-item .ic { width: 17px; height: 17px; }
.nav-item span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .01em; }
.nav-item:hover { background: var(--rail-hover); color: var(--rail-ink); }
.nav-item.active { background: var(--rail-active); color: var(--accent); }
.nav-item.active .ic { color: var(--accent); }

.rail-foot {
  margin-top: auto; padding-top: 14px;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .08em;
  color: var(--rail-ink-2); opacity: .7;
}

/* --- workspace ----------------------------------------------------------- */
.main {
  background: var(--surface);
  padding: 0 28px 46px;
  overflow-y: auto; overscroll-behavior: contain;
}

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 15px 0 13px;
  margin-bottom: 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.topbar h2 { font-size: 16px; font-weight: 600; }
.topbar .lbl { margin-bottom: 2px; }

.topbar-right { display: flex; align-items: center; gap: 16px; }

/* Profile is a global data-scope switch — every number on screen belongs to
   the selected learner — so it reads as a segmented control at the top rather
   than a menu buried in the rail. */
.who {
  display: flex; gap: 2px;
  padding: 2px;
  background: var(--seg-track);
  border-radius: 8px;
}
.profile-btn {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 9px 4px 5px;
  border: 1px solid transparent; border-radius: 6px;
  transition: background .12s linear, border-color .12s linear;
}
.profile-btn:hover { background: var(--hover); }
.profile-btn.active { background: var(--seg-active); border-color: var(--rule-2); }
.profile-btn strong { display: block; font-size: 11.5px; font-weight: 500; }
.profile-btn small { display: block; font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); }

.avatar {
  width: 22px; height: 22px; flex: 0 0 auto;
  display: inline-grid; place-items: center;
  border-radius: 6px;
  background: var(--t1); color: #fff;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
}
.avatar.alt { background: var(--t5); }
.avatar.mini { width: 18px; height: 18px; font-size: 9px; border-radius: 5px; }

.player-stats { display: flex; align-items: stretch; }
.stat-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 12px;
  border-left: 1px solid var(--rule);
  color: var(--ink-3);
}
.stat-chip .ic { color: var(--ink-4); }
.stat-chip strong {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 12.5px; font-weight: 500; color: var(--ink);
}
.stat-chip.xp .ic { color: var(--accent); }
.player-stats .btn--icon { margin-left: 12px; align-self: center; }

/* XP delta: a quiet fade, no motion beyond 2px */
.delta {
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  color: var(--ok);
  opacity: 0; transform: translateY(2px);
  transition: opacity .2s linear, transform .2s var(--ease);
  min-width: 26px;
}
.delta.show { opacity: 1; transform: none; }

.view { display: none; }
.view.active { display: block; }

/* ==========================================================================
   LEARNING PATH
   ========================================================================== */

/* status line — rank + level meter side by side, separated by a rule only */
/* Tinted, not outlined — an off-white field groups the rank and level readouts
   without adding another box edge to the page. */
.status-line {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, .8fr);
  gap: 1px;
  background: var(--rule);
  border-radius: 12px;
  overflow: hidden;
}
.status-line > div { background: var(--surface-2); padding: 16px 18px; }
.status-rank h3 { font-size: 15px; margin: 5px 0 4px; }
.status-rank p { margin: 0; color: var(--ink-3); font-size: 12px; }
.level-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-family: var(--mono); font-size: 11px; margin-bottom: 9px;
}
.level-head span:last-child { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.level-foot { margin: 8px 0 0; font-family: var(--mono); font-size: 10px; color: var(--ink-4); letter-spacing: .04em; }

/* metric strip — five readouts, hairline gutters, no boxes */
.metric-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.metric-strip .kv { background: var(--surface); }
.metric-strip { border-radius: 2px; }

.week-dots { display: flex; gap: 3px; margin-top: 3px; }
.week-dots span {
  width: 21px; height: 18px;
  display: grid; place-items: center;
  border: 1px solid var(--rule-2); border-radius: 5px;
  background: var(--surface);
  font-family: var(--mono); font-size: 9.5px; color: var(--ink-4);
}
.week-dots span.done { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* --- roadmap ------------------------------------------------------------- */
.path-layout { display: grid; grid-template-columns: minmax(0, 1fr) 268px; gap: 26px; align-items: start; }

.skill-path { display: grid; gap: 24px; }

.map-track-head {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) 130px auto; align-items: center; gap: 10px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 2px;
}
.map-track-head::before { content: ""; height: 13px; border-radius: 1px; background: var(--track, var(--ink-4)); }
.map-track-head h4 { font-size: 12.5px; }
.map-track-head .track-sub { font-family: var(--mono); font-size: 10px; color: var(--ink-4); margin-top: 1px; display: block; }
.map-track-stat {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 11px; color: var(--ink-2); text-align: right; min-width: 54px;
}

.map-nodes { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 1px 20px; }
.map-node {
  display: grid;
  grid-template-columns: 15px minmax(0, 1fr) 62px 40px;
  align-items: center; gap: 10px;
  width: 100%;
  padding: 7px 8px;
  border: 1px solid transparent; border-radius: 7px;
  border-bottom-color: var(--rule);
  text-align: left;
  transition: background .12s linear, border-color .12s linear;
}
.map-node:hover { background: var(--hover); border-color: var(--rule-2); }
.map-node .ic { color: var(--ink-4); }
.map-node.complete .ic { color: var(--ok); }
.map-node.current  .ic { color: var(--accent); }
.map-node.locked { color: var(--ink-3); }
.map-node.locked .map-node-name { color: var(--ink-3); }
.map-node-body { min-width: 0; }
.map-node-name {
  display: block; font-size: 12.5px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.map-node-track { display: block; font-family: var(--mono); font-size: 10px; color: var(--ink-4); margin-top: 1px; }
.map-node-count {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 10.5px; color: var(--ink-3); text-align: right;
}

/* --- right rail: sections divided by rules, never nested cards ----------- */
.right-rail { display: grid; gap: 0; align-content: start; }
.rail-card { padding: 16px 0; border-top: 1px solid var(--rule); }
.rail-card:first-child { padding-top: 0; border-top: 0; }
.rail-card h3 { font-size: 13px; margin: 6px 0 5px; }
.rail-card p:not(.lbl) { margin: 0; color: var(--ink-3); font-size: 12px; }
.rail-card .btn { margin-top: 11px; }

.race-row {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 9px;
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
}
.race-row:last-of-type { border-bottom: 0; }
.race-row strong { display: block; font-size: 12px; font-weight: 500; }
.race-row small { font-family: var(--mono); font-size: 10px; color: var(--ink-3); }
.position { font-family: var(--mono); font-size: 11px; color: var(--ink-3); }

/* ==========================================================================
   PRACTICE / PROJECTS — dense rows, not tiles
   ========================================================================== */

.section-intro { margin-bottom: 18px; }
.section-intro h3 { font-size: 15px; margin: 4px 0 5px; }
.section-intro p:not(.lbl) { margin: 0; max-width: 660px; color: var(--ink-3); font-size: 12.5px; }

.challenge-grid { grid-template-columns: minmax(0, 1fr); border-radius: 10px; overflow: hidden; }
.challenge-card {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: 13px 15px;
  background: var(--surface);
  transition: background .12s linear;
}
.challenge-card:hover { background: var(--hover); }
.challenge-card::before {
  content: ""; align-self: stretch; border-radius: 1px; background: var(--tone, var(--ink-4));
}
.challenge-card h3 { font-size: 13px; margin: 4px 0 3px; }
.challenge-card p { margin: 0; color: var(--ink-3); font-size: 12px; }
.card-actions { display: flex; align-items: center; gap: 12px; }
.reward { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; color: var(--ink-2); }
.meta { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.meta span {
  padding: 1px 6px;
  border: 1px solid var(--rule); border-radius: 3px;
  font-family: var(--mono); font-size: 9.5px; color: var(--ink-3);
}

/* ==========================================================================
   RECALL
   ========================================================================== */

.review-shell { max-width: 760px; }

.recall-options { border-radius: 10px; overflow: hidden; margin-bottom: 22px; }
.recall-option {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: 15px;
  background: var(--surface);
}
.recall-option > .ic { color: var(--ink-3); align-self: start; margin-top: 2px; }
.recall-option h4 { font-size: 13px; margin: 4px 0 4px; }
.recall-option p { margin: 0; color: var(--ink-3); font-size: 12px; max-width: 46ch; }
.recall-option-side { display: flex; align-items: center; gap: 12px; }
.recall-option-meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); text-align: right; }
.recall-option .btn { min-width: 158px; }
.ai-import-actions { display: flex; gap: 8px; margin-top: 10px; }
.ai-import-note { margin: 8px 0 0; font-size: 11.5px; color: var(--ink-4); max-width: 60ch; }

/* --- session ------------------------------------------------------------- */
.review-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
.review-top-left { display: flex; align-items: center; gap: 10px; }
.review-top h3 { font-size: 13px; margin-top: 2px; }
.round-stats-block { display: flex; align-items: center; gap: 12px; }
.round-stats { display: grid; gap: 2px; justify-items: end; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }

.session-progress-track { margin-bottom: 18px; }

/* the focal object: an off-white fill lifts it off the white workspace,
   so it needs no outline to sit apart */
.flashcard {
  min-height: 320px;
  display: flex; flex-direction: column;
  padding: 24px 26px;
  border-radius: 14px;
  background: var(--surface-2);
}
.flash-meta { display: flex; gap: 6px; margin-bottom: 18px; }
.flashcard-label { margin: 0 0 8px; }
.flashcard h3 { font-size: 19px; font-weight: 500; line-height: 1.45; letter-spacing: -.01em; }
.flash-answer {
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--rule-2);
  color: var(--ink-2); font-size: 13px; line-height: 1.65;
}

/* confidence gauge: five ascending mono cells, colour-coded to the ramp */
.understanding-meter { margin-top: auto; padding-top: 20px; }
.meter-label { display: block; margin-bottom: 8px; }
.meter-pips { display: flex; align-items: flex-end; gap: 3px; height: 26px; }
.pip {
  flex: 1;
  border: 1px solid var(--rule-2); border-radius: 2px;
  background: var(--surface);
  transition: background .18s linear, border-color .18s linear;
}
.pip:nth-child(1) { height: 10px; }
.pip:nth-child(2) { height: 14px; }
.pip:nth-child(3) { height: 18px; }
.pip:nth-child(4) { height: 22px; }
.pip:nth-child(5) { height: 26px; }
.pip.filled:nth-child(1) { background: var(--c1-wash); border-color: var(--c1); }
.pip.filled:nth-child(2) { background: var(--c2-wash); border-color: var(--c2); }
.pip.filled:nth-child(3) { background: var(--c3-wash); border-color: var(--c3); }
.pip.filled:nth-child(4) { background: var(--c4-wash); border-color: var(--c4); }
.pip.filled:nth-child(5) { background: var(--c5-wash); border-color: var(--c5); }
.meter-status { display: block; margin-top: 8px; font-size: 11.5px; color: var(--ink-3); }

.flash-actions { margin-top: 14px; }
.rating-prompt { margin: 0 0 8px; text-align: center; }
.rating-actions { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.rating-actions button {
  padding: 8px 6px;
  border: 1px solid var(--rule-2); border-top: 2px solid var(--rule-2); border-radius: 7px;
  background: var(--surface);
  text-align: center; line-height: 1.35;
  transition: background .12s linear, border-color .12s linear;
}
.rating-actions button strong { display: block; font-size: 11.5px; font-weight: 500; }
.rating-actions button small { display: block; margin-top: 2px; font-family: var(--mono); font-size: 9.5px; color: var(--ink-4); }
.rating-actions button .rk { display: block; font-family: var(--mono); font-size: 10px; color: var(--ink-4); margin-bottom: 3px; }
.rating-actions .r1 { border-top-color: var(--c1); }
.rating-actions .r2 { border-top-color: var(--c2); }
.rating-actions .r3 { border-top-color: var(--c3); }
.rating-actions .r4 { border-top-color: var(--c4); }
.rating-actions .r5 { border-top-color: var(--c5); }
.rating-actions .r1:hover { background: var(--c1-wash); border-color: var(--c1); }
.rating-actions .r2:hover { background: var(--c2-wash); border-color: var(--c2); }
.rating-actions .r3:hover { background: var(--c3-wash); border-color: var(--c3); }
.rating-actions .r4:hover { background: var(--c4-wash); border-color: var(--c4); }
.rating-actions .r5:hover { background: var(--c5-wash); border-color: var(--c5); }

/* --- summary ------------------------------------------------------------- */
.recall-summary { padding: 28px 26px; border-radius: 14px; background: var(--surface-2); }
.summary-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.summary-badge { color: var(--ok); }
.summary-badge.pause { color: var(--accent); }
.recall-summary h3 { font-size: 15px; }
.recall-summary p { margin: 0; color: var(--ink-2); font-size: 12.5px; line-height: 1.65; }
.recall-summary strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 500; color: var(--ink); }
.summary-weak { margin-top: 8px !important; padding-top: 12px; border-top: 1px solid var(--rule); color: var(--ink-3) !important; font-size: 11.5px !important; }
.summary-actions { display: flex; gap: 8px; margin-top: 18px; }

/* ==========================================================================
   LEAGUE
   ========================================================================== */

.league-hero { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 20px; }
.league-hero h3 { font-size: 15px; margin: 4px 0 5px; }
.league-hero p:not(.lbl) { margin: 0; max-width: 640px; color: var(--ink-3); font-size: 12.5px; }
.league-hero .ic { color: var(--ink-4); }

.league-table { border-radius: 10px; overflow: hidden; }
.league-row {
  display: grid; grid-template-columns: 60px minmax(0, 1fr) 120px 90px;
  align-items: center; gap: 12px;
  padding: 11px 15px;
  background: var(--surface);
  font-size: 12.5px;
}
.league-row.header { background: var(--surface-2); }
.league-row.header span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
.league-row.highlight { background: var(--accent-wash); }
.league-row > span:first-child, .league-row strong, .league-row > span:nth-child(3) {
  font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 500;
}
.league-row > span:nth-child(2) { display: flex; align-items: center; gap: 8px; }

.duel-panel { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--rule); }
.duel-panel h3 { font-size: 13px; margin: 5px 0 4px; }
.duel-panel p:not(.lbl) { margin: 0; color: var(--ink-3); font-size: 12.5px; }
.duel-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0; }
.duel-result {
  margin-top: 14px; padding: 12px 14px;
  border-left: 2px solid var(--ok); background: var(--ok-wash);
  border-radius: 0 4px 4px 0;
  font-size: 12.5px; line-height: 1.6;
}

/* ==========================================================================
   VAULT
   ========================================================================== */

.vault-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 16px; }
.vault-head h3 { font-size: 15px; margin: 4px 0 0; }
.toolbar { display: flex; gap: 8px; width: min(420px, 50vw); }
.toolbar input { flex: 1; }
.toolbar select { width: 160px; }

.concept-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 0 24px; }
.concept-card { padding: 13px 0; border-bottom: 1px solid var(--rule); }
.concept-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.concept-card h3 { font-size: 12.5px; font-weight: 500; margin: 6px 0 9px; }
.concept-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.mastery-total { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink); }

/* the 4-D readout: one hue per dimension, aligned mono columns */
.dims { display: grid; gap: 5px; }
.dim { display: grid; grid-template-columns: 30px minmax(0, 1fr) 24px; align-items: center; gap: 8px; }
.dim span { font-family: var(--mono); font-size: 9.5px; color: var(--ink-4); letter-spacing: .05em; }
.dim b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 10px; font-weight: 500; color: var(--ink-3); text-align: right; }

/* ==========================================================================
   TOPIC DETAIL
   ========================================================================== */

.back-link {
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 14px;
  color: var(--ink-3); font-size: 12px;
  transition: color .12s linear;
}
.back-link:hover { color: var(--ink); }

.topic-hero { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 30px; align-items: start; margin-bottom: 18px; }
.topic-hero-main h3 { font-size: 17px; margin: 7px 0 6px; }
.topic-hero-main > p { margin: 0 0 12px; max-width: 68ch; color: var(--ink-2); font-size: 12.5px; line-height: 1.6; }
.topic-sources { display: flex; flex-wrap: wrap; gap: 6px; }
.source-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--rule-2); border-radius: 6px;
  color: var(--ink-2); font-size: 11.5px; text-decoration: none;
  transition: border-color .12s linear, color .12s linear;
}
.source-chip:hover { border-color: var(--accent); color: var(--accent); }
.topic-hero-side { display: flex; align-items: center; gap: 16px; }
.topic-ring-wrap { display: grid; justify-items: center; gap: 6px; }
.topic-stats { display: grid; gap: 9px; }
.topic-stats div { display: grid; grid-template-columns: 42px auto; align-items: baseline; gap: 9px; }
.topic-stats strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 500; text-align: right; }
.topic-stats span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); }

.topic-actionbar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px; align-items: center;
  padding: 14px 0; margin-bottom: 18px;
  border-block: 1px solid var(--rule);
}
.topic-actionbar-head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 9px; font-family: var(--mono); font-size: 11px; }
.topic-actionbar-head span:last-child { color: var(--ink-3); }
.topic-actionbar-buttons { display: flex; gap: 8px; }

.topic-layout { display: grid; grid-template-columns: minmax(0, 1fr) 272px; gap: 28px; align-items: start; }

.lesson-toolbar { display: flex; gap: 9px; align-items: center; margin-bottom: 10px; }
.lesson-toolbar input[type=search] { flex: 1; min-width: 150px; }
.lesson-filter { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-2); white-space: nowrap; cursor: pointer; }
.lesson-filter input { width: 14px; height: 14px; min-height: 0; accent-color: var(--accent); }

.ghost-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  border: 1px solid var(--rule-2); border-radius: 6px;
  color: var(--ink-2); font-size: 11px;
  transition: background .12s linear, border-color .12s linear, color .12s linear;
}
.ghost-btn:hover { background: var(--hover); border-color: var(--rule-2); color: var(--ink); }

/* lesson rows: rule-separated, and the expanded body uses labels + rules
   rather than a nested panel */
.lesson-list { display: grid; border-top: 1px solid var(--rule); }
.lesson { border-bottom: 1px solid var(--rule); }
.lesson.open { background: var(--surface-2); border-radius: 10px; }
.lesson-head { display: grid; grid-template-columns: 18px minmax(0, 1fr) 22px; align-items: start; gap: 10px; padding: 9px 8px; }
.lesson-check {
  width: 16px; height: 16px; margin-top: 1px;
  display: grid; place-items: center;
  border: 1px solid var(--rule-2); border-radius: 5px;
  color: transparent;
  transition: background .12s linear, border-color .12s linear, color .12s linear;
}
.lesson-check:hover { border-color: var(--ok); }
.lesson.done .lesson-check { background: var(--ok); border-color: var(--ok); color: #fff; }
.lesson-title { display: block; width: 100%; text-align: left; min-width: 0; }
.lesson-title h4 { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 8px; font-size: 12.5px; font-weight: 500; }
.lesson-num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 10.5px; color: var(--ink-4); }
.lesson.done .lesson-title h4 { color: var(--ink-3); }
.lesson-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px;
  margin: 3px 0 0 34px;
  font-family: var(--mono); font-size: 10px; color: var(--ink-4);
}
.lesson-meta > span { display: inline-flex; align-items: center; gap: 3px; }
.lesson-meta .ic { width: 11px; height: 11px; }
.lesson-meta .sep { color: var(--rule-2); }
.lesson-chevron { color: var(--ink-4); display: grid; place-items: center; height: 18px; }
.lesson-chevron:hover { color: var(--ink); }

.lesson-body { display: grid; gap: 16px; padding: 4px 8px 16px 36px; }
.lesson-sub { margin: 0 0 7px; }
.lesson-summary { margin: 0; padding-left: 15px; display: grid; gap: 4px; }
.lesson-summary li { font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.lesson-flash { padding-left: 11px; border-left: 2px solid var(--rule-2); }
.lesson-q { margin: 0 0 9px; font-size: 12.5px; font-weight: 500; line-height: 1.55; }
.lesson-a { margin: 9px 0 0; font-size: 12.5px; line-height: 1.65; color: var(--ink-2); }
.lesson-card-foot { margin-top: 10px; }
.card-status { font-family: var(--mono); font-size: 10.5px; color: var(--ink-4); }
.card-status.in-deck { color: var(--ok); }
.lesson-empty { padding: 24px 12px; text-align: center; color: var(--ink-4); font-size: 12.5px; }

.notes-area { font-size: 12.5px; }
.notes-area.small { min-height: 68px; }
.notes-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.notes-hint { margin: 8px 0 0; font-size: 11px; color: var(--ink-4); line-height: 1.5; }
.watch-link {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: auto;
  font-size: 11px; color: var(--accent); text-decoration: none;
}
.watch-link:hover { text-decoration: underline; }

.topic-nav { display: grid; gap: 1px; }
.topic-nav-btn {
  display: grid; gap: 2px;
  width: 100%; padding: 8px 10px;
  border: 1px solid var(--rule); border-radius: 7px;
  text-align: left;
  transition: background .12s linear, border-color .12s linear;
}
.topic-nav-btn:hover { background: var(--hover); border-color: var(--rule-2); }
.topic-nav-btn span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .07em; color: var(--ink-4); }
.topic-nav-btn strong { font-size: 12px; font-weight: 500; }

/* ==========================================================================
   MODALS / TOAST
   ========================================================================== */

.modal-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: var(--scrim);
}
.modal {
  display: flex; flex-direction: column;
  width: 100%; max-width: 520px; max-height: 82vh;
  border: 1px solid var(--rule-2); border-radius: 14px;
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--rule); }
.modal-head h3 { font-size: 13px; margin-top: 3px; }
.topic-picker-list { flex: 1; overflow-y: auto; padding: 6px 16px 12px; }
.topic-group-title { margin: 14px 0 3px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); }
.topic-row {
  display: grid; grid-template-columns: 14px minmax(0, 1fr) auto; align-items: center; gap: 9px;
  padding: 6px 6px; border-radius: 3px; cursor: pointer;
  transition: background .12s linear;
}
.topic-row:hover { background: var(--hover); }
.topic-row input { width: 14px; height: 14px; min-height: 0; accent-color: var(--accent); }
.topic-row > span:first-of-type { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topic-row-meta { display: flex; align-items: center; gap: 4px; font-family: var(--mono); font-size: 10px; color: var(--ink-4); }
.modal-foot { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--rule); }
.modal-foot .btn { flex: 1; }

.import-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--rule); font-size: 12px; line-height: 1.55; }
.import-row:last-child { border-bottom: 0; }
.import-row.bad > span:first-child { color: var(--danger); }
.import-badge { flex: 0 0 auto; padding: 1px 6px; border: 1px solid currentColor; border-radius: 3px; font-family: var(--mono); font-size: 9px; letter-spacing: .06em; }
.import-badge.new { color: var(--t2); }
.import-badge.existing { color: var(--ok); }
.import-badge.error { color: var(--danger); }

.note-card-form { display: grid; gap: 5px; padding: 14px 16px; overflow-y: auto; }
.field-label { margin-top: 8px; }
.note-card-error { margin: 6px 0 0; font-size: 11.5px; color: var(--danger); }

.toast {
  position: fixed; left: 50%; bottom: 22px; z-index: 300;
  transform: translateX(-50%);
  padding: 8px 14px;
  border: 1px solid var(--rule-2); border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  font-family: var(--mono); font-size: 11px; color: var(--ink);
}

/* ==========================================================================
   RESPONSIVE
   Below the tablet breakpoint the fixed app frame is abandoned for ordinary
   document scroll — a 100vh shell with an inner scroller fights mobile
   browser chrome and costs more than the floating frame is worth there.
   ========================================================================== */

@media (max-width: 1180px) {
  .path-layout, .topic-layout { grid-template-columns: minmax(0, 1fr); }
  .right-rail { grid-template-columns: repeat(3, 1fr); gap: 0 24px; }
  .right-rail .rail-card { border-top: 1px solid var(--rule); padding-top: 16px; }
}
@media (max-width: 960px) {
  html, body { height: auto; }
  body { padding: 0; overflow: visible; }
  .app-shell {
    height: auto; border: 0; border-radius: 0;
    grid-template-columns: minmax(0, 1fr);
  }
  .sidebar {
    height: auto; flex-direction: row; align-items: center; gap: 4px;
    padding: 8px 10px; overflow-x: auto;
    border-right: 0; border-bottom: 1px solid var(--rule);
  }
  .brand { padding: 0 10px 0 4px; }
  nav { grid-auto-flow: column; width: auto; }
  .nav-item { padding: 7px 11px; }
  .rail-foot { display: none; }
  .main { overflow: visible; padding: 0 18px 40px; }
  .status-line, .topic-hero, .topic-actionbar { grid-template-columns: minmax(0, 1fr); }
  .metric-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .right-rail { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .main { padding: 0 14px 40px; }
  .topbar { flex-direction: column; align-items: flex-start; }
  .topbar-right { width: 100%; flex-wrap: wrap; gap: 10px; }
  .vault-head, .review-top { flex-direction: column; align-items: flex-start; }
  .player-stats { overflow-x: auto; }
  .stat-chip:first-child { border-left: 0; padding-left: 0; }
  .toolbar { width: 100%; flex-direction: column; }
  .toolbar select { width: 100%; }
  .metric-strip, .duel-inputs, .map-nodes { grid-template-columns: 1fr; }
  /* the per-node meters already carry the detail; the track roll-up bar is
     the first thing to drop when the row runs out of width */
  .map-track-head { grid-template-columns: 3px minmax(0, 1fr) auto; }
  .map-track-head > .meter { display: none; }
  .map-track-head .track-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .rating-actions { grid-template-columns: repeat(5, 1fr); gap: 3px; }
  .rating-actions button small { display: none; }
  .recall-option { grid-template-columns: minmax(0, 1fr); }
  .league-row { grid-template-columns: 44px minmax(0, 1fr) 70px; }
  .league-row > *:nth-child(3) { display: none; }
  .summary-actions { flex-direction: column; }
}

/* ==========================================================================
   PROJECTS — the build ladder + one project's brief

   Same instrument set as the roadmap and topic views: track hue on a rule,
   flat rows separated by rules rather than nested cards, and the shared
   .meter for every progress bar.
   ========================================================================== */

.projects-summary {
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 26px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 20px;
}

.project-ladder { display: grid; gap: 26px; }

.project-track-head {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 4px;
}
.project-track-head .track-dot { height: 13px; border-radius: 1px; background: var(--hue, var(--ink-4)); }
.project-track-head h4 { font-size: 12.5px; }
.project-track-count {
  font-family: var(--mono); font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-4);
}

.project-rows { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 1px 20px; }

.project-row { border-bottom: 1px solid var(--rule); }
.project-open {
  display: block; width: 100%; text-align: left;
  padding: 13px 10px 14px;
  border-radius: 8px;
  transition: background .12s linear;
}
.project-open:hover { background: var(--hover); }
.project-row.is-locked .project-open:hover { background: transparent; cursor: default; }
.project-row.is-locked { opacity: .58; }

.project-row-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.project-state {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--tone, var(--ink-4));
}
.project-state .ic { width: 11px; height: 11px; }
.project-xp { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 10.5px; color: var(--ink-4); }

.project-row h4 { font-size: 13px; font-weight: 500; margin: 0 0 3px; }
.project-summary { margin: 0 0 7px; font-size: 12px; line-height: 1.55; color: var(--ink-3); }
.project-anchor-line {
  display: flex; align-items: center; gap: 5px;
  margin: 0 0 10px; font-size: 11px; color: var(--ink-4); line-height: 1.5;
}
.project-anchor-line .ic { width: 11px; height: 11px; flex: none; }

.project-row-foot { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 9px; }
.project-count { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 10.5px; color: var(--ink-3); }
.project-dataset-chip {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-4);
}

/* ---- one project ------------------------------------------------------- */

.project-hero-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 9px; }

.project-brief { display: grid; gap: 18px; padding-bottom: 20px; border-bottom: 1px solid var(--rule); }
.brief-block p:not(.lbl) { margin: 0; font-size: 12.5px; line-height: 1.65; color: var(--ink-2); }
.brief-block .lesson-sub { display: flex; align-items: center; gap: 6px; }
.brief-block .lesson-sub .ic { width: 12px; height: 12px; }
.brief-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.brief-milestones { margin: 0; padding-left: 17px; display: grid; gap: 9px; }
.brief-milestones li { font-size: 12.5px; line-height: 1.6; }
.brief-milestones strong { display: block; font-weight: 500; margin-bottom: 1px; }
.brief-milestones span { color: var(--ink-3); }

.brief-list { margin: 0; padding-left: 15px; display: grid; gap: 5px; }
.brief-list li { font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }

.brief-benchmark, .brief-stretch { padding-left: 11px; border-left: 2px solid var(--rule-2); }
.brief-benchmark { border-left-color: var(--accent-bright); }
.brief-stretch { border-left-color: var(--t3); }
.brief-pitfalls li::marker { color: var(--warn); }

.project-dod { padding-top: 20px; }
.dod-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.dod-hint { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); }
.dod-list { list-style: none; margin: 4px 0 0; padding: 0; display: grid; }
.dod-item {
  display: grid; grid-template-columns: 16px minmax(0, 1fr) auto;
  align-items: start; gap: 10px;
  padding: 9px 8px;
  border-bottom: 1px solid var(--rule);
}
.dod-item:last-child { border-bottom: 0; }
.dod-item.done .lesson-check { background: var(--ok); border-color: var(--ok); color: #fff; }
.dod-item .lesson-check:disabled { opacity: .45; }
.dod-text { font-size: 12.5px; line-height: 1.55; }
.dod-item.done .dod-text { color: var(--ink-3); }
.dod-xp { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 10.5px; color: var(--ink-4); }
.dod-item.done .dod-xp { color: var(--ok); }

.dataset-meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-4); margin: 3px 0 0; line-height: 1.5; }
.dataset-warn, .dataset-ok { display: flex; align-items: center; gap: 5px; margin: 7px 0 0; font-size: 11px; }
.dataset-warn { color: var(--warn); }
.dataset-ok { color: var(--ok); }
.dataset-warn .ic, .dataset-ok .ic { width: 11px; height: 11px; flex: none; }

.submit-label {
  display: block; margin: 11px 0 5px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-4);
}
.submit-input {
  width: 100%; padding: 7px 9px;
  border: 1px solid var(--rule-2); border-radius: 7px;
  background: var(--surface); color: var(--ink);
  font-family: var(--mono); font-size: 11px;
}
.submit-input:focus { outline: none; border-color: var(--accent); }

/* the "finishing this unlocks a project" banner inside a lesson body */
.lesson-gate { padding-left: 11px; border-left: 2px solid var(--accent-bright); }
.gate-title { margin: 0 0 2px; font-size: 12.5px; font-weight: 500; }
.gate-copy { margin: 0 0 9px; font-size: 12px; line-height: 1.55; color: var(--ink-3); }

@media (max-width: 960px) {
  .projects-summary { gap: 18px; }
  .project-rows { grid-template-columns: minmax(0, 1fr); }
  .dod-head { flex-direction: column; gap: 2px; }
}

/* ==========================================================================
   RECALL PROGRESS — confidence strip + per-topic table

   The five confidence hues (--c1..--c5) are the same ones the rating buttons
   use, so a band in the strip and the button that produced it always match.
   Never-rated cards take --meter-track: absent, not bad.
   ========================================================================== */

.recall-progress { margin-top: 30px; padding-top: 24px; border-top: 1px solid var(--rule-2); }
.recall-progress .section-intro { margin-bottom: 16px; }

.spread { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--meter-track); min-width: 0; }
.spread i { display: block; height: 100%; }
.spread--lg { height: 12px; }

.strip-head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 7px; }
.strip-total { font-family: var(--mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-4); }

.strip-legend { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.band {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px;
  border: 1px solid var(--rule-2); border-radius: 999px;
  transition: background .12s linear, border-color .12s linear;
}
.band:hover:not(:disabled) { background: var(--hover); border-color: var(--accent); }
.band:disabled { opacity: .45; }
.band-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.band strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11.5px; font-weight: 500; }
.band-label { font-size: 11.5px; color: var(--ink-3); }

.progress-toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 22px 0 10px; }
.progress-toolbar input[type="search"] {
  flex: 1 1 200px; min-width: 0; padding: 7px 10px;
  border: 1px solid var(--rule-2); border-radius: 7px;
  background: var(--surface); color: var(--ink); font-size: 12px;
}
.progress-toolbar input[type="search"]:focus { outline: none; border-color: var(--accent); }

.topic-progress { display: grid; gap: 20px; }

.prog-track-head {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  padding-bottom: 6px; border-bottom: 1px solid var(--rule-2);
}
.prog-track-head .track-dot { height: 12px; border-radius: 1px; background: var(--hue, var(--ink-4)); }
.prog-track-head h4 { font-size: 12px; }
.prog-track-pct { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; color: var(--ink-2); }

.prog-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 90px 40px auto;
  align-items: center; gap: 12px;
  padding: 8px 6px;
  border-bottom: 1px solid var(--rule);
}
.prog-row:last-child { border-bottom: 0; }
.prog-row.is-fresh { color: var(--ink-3); }
.prog-name { display: block; text-align: left; min-width: 0; font-size: 12.5px; }
.prog-name:hover { color: var(--accent); }
.prog-cards { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-4); margin-top: 1px; }
.prog-pct { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 11px; text-align: right; color: var(--ink-2); }
.prog-study { white-space: nowrap; }

.summary-spread { margin: 14px 0 4px; }
.spread-label { margin: 0 0 7px; }
.spread-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 9px; }
.spread-legend span { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--ink-3); }
.spread-legend i { width: 8px; height: 8px; border-radius: 50%; }
.spread-legend strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 500; color: var(--ink); }

@media (max-width: 960px) {
  .prog-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 8px; }
  .prog-row .spread { grid-column: 1 / -1; order: 3; }
  .prog-study { order: 2; justify-self: start; }
  .strip-head { flex-direction: column; gap: 2px; }
}

/* ==========================================================================
   LIBRARY — one shared shelf

   Visual by design: a thumbnail grid, because the point of a shelf is seeing
   what's on it. Entries with no image get a track-tinted plate carrying the
   type icon so rows never go ragged.
   ========================================================================== */

.library-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding-bottom: 14px; margin-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}
.library-bar-filters { display: flex; gap: 8px; align-items: center; flex: 1 1 320px; min-width: 0; }
.library-bar-actions { display: flex; gap: 8px; align-items: center; }
.library-bar input[type="search"], .library-bar select {
  padding: 7px 10px;
  border: 1px solid var(--rule-2); border-radius: 7px;
  background: var(--surface); color: var(--ink); font-size: 12px;
}
.library-bar input[type="search"] { flex: 1 1 auto; min-width: 0; }
.library-bar input[type="search"]:focus, .library-bar select:focus { outline: none; border-color: var(--accent); }

.library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 22px; }

.lib-card {
  display: grid; grid-template-rows: 132px auto;
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--surface); overflow: hidden;
  transition: border-color .12s linear, box-shadow .12s linear;
}
.lib-card:hover { border-color: var(--rule-2); box-shadow: var(--shadow-1); }

.lib-thumb { position: relative; background: var(--surface-2); overflow: hidden; }
.lib-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lib-thumb-fallback { display: none; position: absolute; inset: 0; place-items: center; color: var(--ink-4); }
.lib-thumb.is-blank { background: var(--accent-wash); }
.lib-thumb.is-blank img { display: none; }
.lib-thumb.is-blank .lib-thumb-fallback { display: grid; }

.lib-body { padding: 12px 14px 14px; display: grid; gap: 6px; align-content: start; }
.lib-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.lib-type {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-4);
}
.lib-type .ic { width: 11px; height: 11px; }
.lib-edit { padding: 2px 5px; color: var(--ink-4); }
.lib-edit:hover { color: var(--accent); }

.lib-card h3 { margin: 0; font-size: 13px; font-weight: 500; line-height: 1.45; }
.lib-card h3 a { color: inherit; text-decoration: none; }
.lib-card h3 a:hover { color: var(--accent); }
.lib-summary { margin: 0; font-size: 12px; line-height: 1.55; color: var(--ink-3); }
.lib-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 2px; }
.lib-tag { cursor: pointer; }
.lib-tag:hover { border-color: var(--accent); color: var(--accent); }
.lib-meta { margin: 2px 0 0; font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-4); }

.library-form input[type="url"], .library-form input[type="text"], .library-form select {
  width: 100%; padding: 7px 9px;
  border: 1px solid var(--rule-2); border-radius: 7px;
  background: var(--surface); color: var(--ink); font-size: 12.5px;
}
.library-form input:focus, .library-form select:focus { outline: none; border-color: var(--accent); }
.library-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.field-optional { color: var(--ink-4); text-transform: none; letter-spacing: 0; }

.btn--danger { color: var(--danger); border-color: var(--rule-2); }
.btn--danger:hover { background: var(--danger-wash); border-color: var(--danger); }

@media (max-width: 960px) {
  .library-bar { flex-direction: column; align-items: stretch; }
  /* A wrapped flex row defaults to align-content: stretch, which spreads the
     three controls down the whole column. Stack them explicitly instead. */
  .library-bar-filters { flex-direction: column; align-items: stretch; flex: 0 0 auto; }
  .library-bar-actions { flex-wrap: wrap; }
  .library-grid { grid-template-columns: minmax(0, 1fr); }
  .library-form-row { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   SIGN-IN GATE + SYNC BADGE

   The gate is a full-bleed scrim over the whole app rather than a modal in the
   shell, because there is nothing behind it worth seeing until a session
   resolves. It reuses the shared .submit-input / .btn primitives so the sign-in
   screen looks like the rest of the app rather than a bolted-on page.
   ========================================================================== */

.login-gate{
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  padding: 24px;
  background: var(--bg);
}
.login-gate.hidden{ display: none; }

.login-card{
  width: 100%; max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: 26px 24px;
  box-shadow: var(--shadow-1);
}
.login-brand{ display: flex; align-items: center; gap: 11px; margin-bottom: 16px; }
.login-mark{
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: 9px;
  background: var(--accent-wash); color: var(--accent);
}
.login-brand h3{ font-size: 14px; margin: 1px 0 0; }
.login-copy{ margin: 0 0 18px; font-size: 12.5px; line-height: 1.6; color: var(--ink-3); }
.login-card .submit-label:first-of-type{ margin-top: 0; }
.login-card .btn--wide{ margin-top: 16px; }
.login-error{
  margin: 12px 0 0; padding: 8px 10px;
  background: var(--danger-wash); color: var(--danger);
  border-radius: 7px; font-size: 12px; line-height: 1.5;
}
.login-error.hidden{ display: none; }
.login-card .notes-hint:empty{ display: none; }

.sync-badge{
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-4);
  padding: 4px 8px; border-radius: 999px; border: 1px solid var(--rule-2);
  white-space: nowrap;
}
.sync-badge.hidden{ display: none; }
.sync-badge.is-ok{ color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.sync-badge.is-warn{ color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }

@media (max-width: 960px){
  .login-card{ max-width: 100%; }
  .sync-badge{ display: none; }
}

/* ==========================================================================
   PHONE ERGONOMICS

   Two rules that are not cosmetic:

   1. Every form control goes to 16px. iOS Safari zooms the whole page whenever
      a focused input is smaller than 16px, and it does not zoom back out. At
      the app's 11-12.5px type that fired on the sign-in password field — the
      very first thing anyone touches. The desktop sizes are untouched.

   2. Tap targets reach 44px, Apple's minimum. The icon buttons were 30x30 and
      .btn--wide was 30px tall, which is fine for a mouse and fiddly for a thumb.

   Scoped to coarse pointers and narrow screens so nothing about the desktop
   layout shifts.
   ========================================================================== */

@media (max-width: 960px) {
  input[type="text"], input[type="search"], input[type="url"],
  input[type="email"], input[type="password"], input[type="number"],
  textarea, select,
  .submit-input, .notes-area, .notes-area.small,
  .progress-toolbar input[type="search"], .lesson-toolbar input[type="search"],
  .library-toolbar input[type="search"],
  /* Named explicitly: these carry higher specificity than the bare element
     selectors above and would otherwise keep their 12px. */
  .library-bar input[type="search"], .library-bar select,
  .library-form input[type="url"], .library-form input[type="text"],
  .library-form select, .library-form textarea {
    font-size: 16px;              /* do not lower: this is the iOS zoom threshold */
  }

  /* Roomier fields, now that the text inside them is bigger. */
  .submit-input { padding: 10px 12px; }
  .notes-area { min-height: 96px; }

  .btn, .ghost-btn, .nav-item, .band, .profile-btn, .lib-edit, .prog-study {
    min-height: 44px;
  }
  .btn--icon { min-width: 44px; min-height: 44px; }
  .btn--wide { min-height: 46px; }

  /* Checkbox-style controls are their own hit area, so grow the label instead. */
  .lesson-filter, .library-filter { min-height: 44px; display: inline-flex; align-items: center; }
  .lesson-filter input[type="checkbox"],
  .library-filter input[type="checkbox"] { width: 18px; height: 18px; }

  /* The lesson and DoD tick boxes are the most-tapped controls in the app. */
  .lesson-check { width: 22px; height: 22px; }
  .lesson-head { grid-template-columns: 22px minmax(0, 1fr) 26px; }
  .dod-item { grid-template-columns: 22px minmax(0, 1fr) auto; }
}

/* Touch devices of any width: never let a hover-only affordance be the only
   way to reach an action. */
@media (hover: none) {
  .lib-edit, .prog-study { opacity: 1; }
}

/* ==========================================================================
   MOTION POLICY
   Transitions exist to explain a state change (a meter filling as XP lands),
   never to decorate. Everything here collapses under reduced-motion.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
