/* Stage ladder — the progress readout INSIDE the question's heading card.
   Markup in index.html (inside .question-number-row), behaviour in
   practice/stage-ladder.js.

   🔴 IT IS NOT A TOP STRIP ANY MORE (Seth, 2026-08-23: "the bar goes on the
   left as well right below the title of the concept ... it is part of a
   rectangle that holds both the bar and the concept right above it"). It was a
   full-width band between the topbar and both panels, and the concept it was
   describing was named twice on the screen — once by the band's pop-up and
   once by the <h2> at the top of the left panel, eight pixels apart. The band
   is gone: the ladder is now a block inside `.question-number-row`, which is
   the rectangle, and the <h2> in that same rectangle is the title it belongs
   to. The rectangle's own chrome (border, radius, padding, the centred
   heading) lives in styles/practice/question.css — this file styles what goes
   INSIDE it.

   Two consequences worth stating before you edit anything here:

   1. The width is a PANEL's, not the page's. Four rung names have to fit in
      half a window rather than a whole one, which is why `.stage-seg-label`
      ellipsises and why the Colab rail's overrides (colab-edition.css) now
      apply to the normal layout's narrow end too.
   2. Nothing in here is measured or positioned by script any more. The
      pop-up callout — an absolutely-positioned box with an arrow aimed at the
      fill's leading edge, re-clamped on every render and on resize — was
      DELETED with the strip, and `--dd-ladder-gap`, `--dd-callout-arrow-x`
      and the reserve above the bar went with it. The reading is a plain line
      of text under the track now.

   Replaces concept-topbar.css and difficulty-bar.css, which drew two separate
   full-width strips for two quantities that were being read as one. */

/* The ladder inside the card: the track, then one line of reading under it.
   No background and no border of its own — the rectangle around it is the
   card, and a bordered box inside a bordered box is two boxes. */
.stage-ladder {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.stage-ladder.hidden {
  display: none;
}

/* 🔴 OFF unless the learner asked for it. Seth, 2026-08-23: the ladder is
   extra information above every question and it costs attention the question
   needs — so it rides with Advanced mode (the Account toggle that also
   restores Knowledge Graph, Course content and Notebooks), and basic mode is
   the default.

   `display: none`, not `visibility` and not a JS teardown: practice/stage-
   ladder.js is untouched and still renders into it — nothing has to be
   re-wired when the toggle flips, and the reading is correct the instant it is
   switched on. `body.dd-basic-mode` is written by app.js
   `applyModeVisibility`.

   🔴 The heading card SURVIVES this. `.question-number-row` keeps its border
   and its centred title in both modes — basic mode loses the bar, not the
   concept it is about. */
body.dd-basic-mode .stage-ladder {
  display: none;
}

/* ── The track: ONE bar, cut into four by chevron seams ────────────────

   Was four separate bars side by side, one per rung. Four meters read as four
   quantities, and the learner's question is one quantity: how far into this
   concept am I. So the four became one continuous bar the fill crosses end to
   end, and the rungs became CUTS in it — sideways Vs pointing right, drawn in
   the panel's own colour so the bar reads as four arrow segments rather than
   as a bar with tick marks laid over it.

   The rung NAMES are inside the track now, not captions under it. The reading
   is a line of text under the track — see `.stage-ladder-reading` below. */

.stage-ladder-meter {
  /* ONE source for the bar's height, kept as a variable because the Colab rail
     and the phone breakpoint both retune it. It no longer has anything
     anchored off it — the reading that used to be positioned against this
     token is a line of text below the track now. */
  --dd-ladder-bar-h: 26px;
  display: flex;
  flex-direction: column;
  margin: 0;
  /* 🔴 NO `padding-top`. The strip reserved 28px above the bar for a pop-up
     that was absolutely positioned and would otherwise have been clipped by
     `#page-practice { overflow: hidden }`. There is no pop-up and no reserve;
     adding one back here just pushes the bar off its title. */
  position: relative;
}

.stage-ladder-meter[hidden] {
  display: none;
}

/* The bar itself. Rounded at both ends, square in between, and tall enough to
   carry a rung name and its ⓘ without either touching an edge. */
.stage-ladder-bar {
  /* Lighter than the 0.07 the four small bars used. The seams are cut in the
     PANEL colour, so an empty track that close to the panel hid every cut
     ahead of the learner — the divisions only existed where the fill had
     already reached. */
  background: rgb(var(--tint-rgb) / calc(0.13 * var(--tint-k)));
  border: 1px solid var(--border);
  border-radius: 999px;
  flex: 0 0 auto;
  height: var(--dd-ladder-bar-h);
  overflow: hidden;
  position: relative;
}

/* One fill for the whole ladder: (rungs behind you + progress through the one
   you are on) / rungs.

   Rounded at the START only. The leading edge has to be SQUARE: a pill cap
   sitting a few pixels from a chevron seam reads as a separate little bar that
   stopped short of the cut, which is the four-bars look this replaced. The
   right end never needs a radius of its own — at 100% the parent's
   `overflow: hidden` clips it to the track's own rounding. */
.stage-ladder-fill {
  background: var(--accent);
  border-radius: 999px 0 0 999px;
  bottom: 0;
  display: block;
  left: 0;
  position: absolute;
  top: 0;
  transition: width 400ms ease;
}

/* The sideways V. A stroke, not a solid triangle: the polygon traces the
   outside of the chevron and comes back along the inside, so what is drawn is
   a ~4px line bent at the midline. Drawn in the panel colour, which is why it
   reads as the bar being cut rather than as something sitting on it.
   `top`/`bottom` overshoot by a pixel so the cut meets the bar's border
   instead of stopping just inside it. */
.stage-ladder-seam {
  background: var(--surface-2);
  bottom: -1px;
  clip-path: polygon(0 0, 4px 0, 14px 50%, 4px 100%, 0 100%, 10px 50%);
  position: absolute;
  top: -1px;
  transform: translateX(-50%);
  width: 14px;
  z-index: 1;
}

/* ── The rung names, INSIDE the track, in two contrast layers ──────────── */

/* Both layers are the same grid over the same box, so a name sits in the
   middle of its own quarter of the bar and the two copies land on exactly the
   same pixels. Anything that changes the width of one and not the other — an
   ⓘ injected into one layer, a different font-weight — shows up immediately as
   a doubled glyph at the fill's edge. */
.stage-ladder-track {
  align-items: center;
  display: grid;
  gap: 0;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  inset: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  position: absolute;
  z-index: 2;
}

/* The copy painted for the ACCENT, clipped to exactly what the fill covers.
   `--dd-ladder-pct` is written by practice/stage-ladder.js in the same call
   that sets the fill's width, so the clip cannot lag the fill. */
.stage-ladder-track--on {
  clip-path: inset(0 calc(100% - var(--dd-ladder-pct, 0%)) 0 0);
  pointer-events: none;
}

.stage-seg {
  align-items: center;
  display: flex;
  gap: 4px;
  justify-content: center;
  min-width: 0;
  /* The names are centred in their own quarter, but a quarter of a narrow
     window is not wide enough for "Worked example" — it ellipsises rather
     than pushing its neighbours out of position. */
  overflow: hidden;
  padding: 0 6px;
}

.stage-seg-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- colours, base layer: over the EMPTY track ------------------------- */

/* `--muted` and `--white` are theme tokens: in the light theme `--white` is
   near-black, which is the whole reason the layer is coloured with tokens
   rather than with a literal. */
.stage-ladder-track--base .stage-seg-label {
  color: var(--muted);
}

.stage-ladder-track--base .stage-seg.is-active .stage-seg-label {
  color: var(--white);
  font-weight: 700;
}

.stage-ladder-track--base .stage-seg.is-todo .stage-seg-label {
  color: var(--muted-dim);
}

/* ---- colours, clipped layer: over the FILL ----------------------------- */

/* One colour for all three states here, and deliberately: over the accent the
   distinction between done, current and still-to-come is carried by the fill
   itself — everything this layer shows IS done or current. Fading a name on
   this layer would only make it harder to read on a saturated ground. */
.stage-ladder-track--on .stage-seg-label {
  color: var(--on-accent);
}

.stage-ladder-track--on .stage-seg.is-active .stage-seg-label {
  font-weight: 700;
}

/* ---- the ⓘ on each rung ------------------------------------------------ */

/* Sized against the label rather than the app's default dot: this one sits
   inside a 30px bar beside 11px text, and the standard 16px dot pushes the
   name off-centre in its quarter. Both layers use it — the clipped copy is an
   inert `<span>` with the same class, so the two boxes match. */
.stage-seg-info.dd-info {
  border-color: currentColor;
  color: inherit;
  flex: 0 0 auto;
  font-size: 8px;
  height: 13px;
  line-height: 13px;
  min-width: 0;
  opacity: 0.75;
  width: 13px;
}

.stage-seg-info.dd-info:hover,
.stage-seg-info.dd-info:focus-visible {
  opacity: 1;
}

.stage-ladder-track--base .stage-seg .stage-seg-info {
  color: var(--muted);
}

.stage-ladder-track--base .stage-seg.is-active .stage-seg-info {
  color: var(--white);
}

.stage-ladder-track--on .stage-seg-info {
  color: var(--on-accent);
}

/* ── The reading: one line of text UNDER the track ─────────────────────

   Five shapes, in order, and the fifth is the plainest.

   1. A caption under the whole strip — read as a caption for the whole strip.
   2. A bordered box UNDER the bar with an arrow pointing up at the fill edge.
      It could land on `#practice-notch`, so the script had to measure both and
      shove the notch sideways.
   3. A tab welded to the bar's top edge — which read as PART of the bar, one
      taller lumpy track rather than a label about a position on it.
   4. Shape 2's pop-up moved above the bar, out of the notch's reach: all four
      borders, a shadow, and an arrow aimed at the fill's leading edge in the
      box's own coordinates (`--dd-callout-arrow-x`), re-clamped on every
      render and again on resize.
   5. This. The ladder sits in the heading card now and the concept is named
      by the <h2> directly above it, so the pop-up's whole job — say which
      concept, and point at where you are in it — is done by the card and the
      fill. What is left is the percentage and the occasional caveat, and
      neither of those is worth a floating box with an arrow: they are a line
      of small text under the track.

   🔴 That deletion is why nothing in this file is script-positioned any more.
   If a future shape needs aiming again, it needs `--dd-ladder-gap`, the
   reserve above the bar, and the resize handler back — all three were removed
   together (practice/stage-ladder.js, styles/practice/watch.py). */
.stage-ladder-reading {
  align-items: baseline;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  font-size: 11.5px;
  gap: 5px;
  /* Centred under a centred title, on the axis the card is built around. */
  justify-content: center;
  line-height: 1.3;
}

.stage-ladder-reading b {
  color: var(--white);
  font-size: 13px;
  font-weight: 700;
}

/* The concept's name, and the jump to it on the map.

   🔴 HIDDEN ON THE PRACTICE SCREEN, and that is the point of the move. The
   <h2> at the top of this same card already IS the concept name — ui.js writes
   it from `ladder_kc_title`, the same field this button is labelled from — so
   showing both put the name on screen twice, a centimetre apart, in two
   different type sizes. practice/stage-ladder.js hides this button whenever
   its label would repeat the heading, which leaves it for the one screen where
   the heading says something else: the lesson (`#question-number` = "Lesson").

   The jump itself is not lost when it is hidden — "See in knowledge graph" in
   the notch's three-dot menu (#practice-graph-jump) is the same trip, gated on
   the same thing, and it is on screen in both modes. */
.stage-ladder-kc {
  background: transparent;
  border: 0;
  border-bottom: 1px dashed var(--border);
  color: var(--accent-text);
  cursor: pointer;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
  max-width: 26ch;
  overflow: hidden;
  padding: 0;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stage-ladder-kc[hidden] {
  display: none;
}

.stage-ladder-kc:hover:not(:disabled),
.stage-ladder-kc:focus-visible:not(:disabled) {
  border-bottom-color: var(--accent-text);
  color: var(--white);
}

/* A KC-less problem still names itself; it just has nowhere to jump to. */
.stage-ladder-kc:disabled {
  border-bottom-color: transparent;
  cursor: default;
}

/* Where this concept sits in its lesson — set on the lesson screen only. */
.stage-ladder-eyebrow {
  color: var(--muted-dim);
  font-size: 10.5px;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}

.stage-ladder-eyebrow[hidden],
.stage-ladder-note[hidden] {
  display: none;
}

/* A promise the page is not keeping, and the topic-level reading. */
.stage-ladder-note {
  color: var(--muted-dim);
  font-size: 10.5px;
  max-width: 40ch;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The integrated chip. NOT a rung — see practice/stage-ladder.js: it is a
   property of the problem on screen, riding on a `solo` record, and it flips
   from question to question. */
.stage-ladder-flag {
  background: rgb(var(--tint-rgb) / calc(0.08 * var(--tint-k)));
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 1px 7px 2px;
  text-transform: uppercase;
  white-space: nowrap;
}

.stage-ladder-flag[hidden] {
  display: none;
}

@media (max-width: 720px) {
  /* A quarter of a phone is about six characters. The names stay — dropping
     any of them would take the point of the ladder with it — and the ⓘs go,
     because a 13px target beside a truncated word is neither readable nor
     hittable. The copy is still reachable from the concept's own ⓘ. */
  .stage-seg-label {
    font-size: 10px;
    letter-spacing: 0;
  }

  .stage-seg-info.dd-info {
    display: none;
  }

  .stage-ladder-meter {
    --dd-ladder-bar-h: 24px;
  }

  .stage-ladder-reading {
    font-size: 11px;
  }
}
