/* ==========================================================================
   LLM Training guide — shared styles across all llm-training-*.html pages.

   The same kit as assets/css/guide.css, under the `llmt-` prefix. The two
   files are kept in step deliberately: the 16 existing LLM-training pages
   link this one through _includes/llm-head.html and will keep doing so, and
   a rule that exists in one and not the other is a page that renders one way
   on the LLM series and another way on the fifteen series that have been
   ported to `guide.css`. Only the prefix differs between them.

   Consumes the token layer in assets/css/theme.css and nothing else: every
   colour is `var(--color-*)`, every space is a `--space-*` step, every
   radius is `--radius-md` / `--radius-lg` / `--radius-xl` / `--radius-pill`,
   every type size is a `--text-*` step and every duration is `--dur-fast`.
   No raw hex, no bare rem for a space, no bare millisecond. The two
   literals that survive are marked where they occur and explained.

   WHAT CHANGED FROM "BROADSHEAT" (warm greys, Source Serif 4, 1-4px radii,
   liquid glass): the cool neutral surface scale and one azure accent from
   the token layer; no `backdrop-filter` anywhere in this file; the
   `surface-2` wells and the raised plates separated by rule rather than by
   taste; and the verdict colours moved off the series palette onto the ok /
   warn / bad status inks, which is what `.hi` and `.bad` have always meant
   on these pages.

   NOTHING RENAMED. Every class in the previous version of this file is still
   here under the same spelling, including `.llmt-next`.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Page frame
   --------------------------------------------------------------------------
   The 1180px is deliberately NOT `--content-width` (1160px). It is a layout
   constant this kit has always shipped and these pages are composed around
   it; moving it 20px is a reflow, not a restyle. */
.llmt { max-width: 1180px; }
.llmt .page-header { padding-top: clamp(var(--space-8), 6vw, var(--space-12)); }


/* --------------------------------------------------------------------------
   The step band
   --------------------------------------------------------------------------
   A step is an article section, so its heading takes `--text-xl` — the token
   the scale documents as "section heading" — rather than a fluid clamp
   between two pixel values that no longer exist in the system. */
.llmt-step { padding: var(--space-12) 0; border-top: 1px solid var(--color-divider); }
.llmt-step:first-of-type { border-top: none; }

/* The step number is a BADGE, not a control: no href, no tabindex, not
   focusable. It therefore gets no hover and no press state, and a later pass
   should read that as a decision rather than as an oversight. */
.llmt-step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-8); height: var(--space-8);
  border-radius: 50%;
  background: var(--color-text); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: var(--text-label-sm);
  flex: 0 0 auto;
}
.llmt-step-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-1); }
.llmt-step-head h2 {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--text-xl-lh);
  letter-spacing: var(--text-xl-ls);
}
.llmt-eyebrow {
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--text-micro-ls);
  text-transform: uppercase;
  color: var(--c-accent-ink);
  /* Indented to clear the step number it hangs beside. Written as the sum
     rather than the old hard-coded 42px so the indent follows the badge and
     the head's gap if either is ever re-stepped. */
  margin: 0 0 var(--space-1) calc(var(--space-8) + var(--space-3));
}


/* --------------------------------------------------------------------------
   Callouts — `.llmt-goal` and `.llmt-warn`
   --------------------------------------------------------------------------
   RECESSED. A `surface-2` fill with a hairline and no elevation at all: a
   note that casts a shadow would assert that it is above the page, which is
   the opposite of what a dimmer fill already says. Read by the fill.

   The two variants do NOT differ by a coloured left rule — that accent edge
   is exactly what the instrument theme removes. They differ by INK: the
   lead-in `<b>` is accent-ink in one and warn-ink in the other, next to the
   emoji the markup already carries, over an identical plate. */
.llmt-goal,
.llmt-warn {
  display: flex; gap: var(--space-3);
  margin: var(--space-4) 0 var(--space-5);
  padding: var(--space-4) var(--space-inset);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-lh);
  /* The reading measure, declared HERE, on the box that carries it. `ch`
     resolves against this element's own computed font size, so a measure
     set on an ancestor and a size set here would be two different widths. */
  max-width: var(--pref-measure);
  hyphens: auto;
}
.llmt-goal b { color: var(--c-accent-ink); }
.llmt-warn b { color: var(--color-warn-ink); }


/* --------------------------------------------------------------------------
   Math
   --------------------------------------------------------------------------
   Also a recessed well, for the same reason as the callouts: a display
   equation is read content, not floating UI, and a borderless white plate
   on the canvas is a fill difference doing a border's job. */
.llmt-math {
  font-family: var(--font-mono); font-size: var(--text-sm);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-inset);
  border-radius: var(--radius-md);
  overflow-x: auto;
  margin: 0 0 var(--space-4);
  line-height: 1.7;
}
.llmt-math.llmt-katex { font-family: var(--font-body); font-size: var(--text-base); overflow-x: auto; }


/* --------------------------------------------------------------------------
   The demo panel
   --------------------------------------------------------------------------
   The densest surface on a page and the one the tool chrome hangs off.
   RAISED, unlike the callouts: it is an object the reader manipulates, and
   its `surface-2` fill is lifted by a real elevation pair rather than by a
   blur. `--elev-shadow` and `--elev-inset` are declared as locals and
   combined in ONE `box-shadow`, so a later state change can move the
   elevation without silently dropping the lit top edge. */
.llmt-demo {
  --elev-shadow: var(--c-elev-2);
  --elev-inset: inset 0 1px 0 var(--c-elev-inset-hi);
  display: flex; gap: var(--space-5); flex-wrap: wrap; align-items: flex-start;
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--elev-shadow), var(--elev-inset);
  padding: var(--space-inset);
  margin-top: var(--space-2);
}
.llmt-canvas-wrap { flex: 1 1 380px; min-width: 280px; max-width: 100%; }
/* The plot is a WELL and the well is the canvas colour — one step below the
   panel it sits in, in both themes, so the plot is a real recess without
   costing the palette a dedicated token. The hairline is an INSET box-shadow
   rather than a border on purpose: llm-guide.js sizes the backing store from
   this element's box, and a border would move that box by 2px for a reason
   that has nothing to do with the data. */
.llmt-canvas-wrap canvas {
  width: 100%; height: auto; display: block;
  background: var(--plot-bg);
  box-shadow: inset 0 0 0 1px var(--color-border);
  border-radius: var(--radius-md);
}
.llmt-canvas-hint { font-size: var(--text-micro); color: var(--color-text-subtle); margin-top: var(--space-1); }


/* --------------------------------------------------------------------------
   The control column
   --------------------------------------------------------------------------
   DENSITY, not decoration. A control column holds six fields, so its own
   spacing is the densest rhythm in the kit and reads a step tighter than the
   page around it. */
.llmt-controls { flex: 1 1 260px; min-width: 240px; max-width: 100%; font-size: var(--text-sm); }
.llmt-field { margin-bottom: var(--space-4); }
.llmt-field label {
  display: flex; justify-content: space-between; gap: var(--space-2);
  margin-bottom: var(--space-1);
  font-size: var(--text-label-sm);
  line-height: var(--text-label-sm-lh);
  color: var(--color-text-muted);
}
/* The value a slider has printed back. Tabular figures because it changes
   under the thumb and proportional digits make the last digit jump sideways
   as the number grows. */
.llmt-field label span.val {
  font-family: var(--font-mono);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* ---- range inputs --------------------------------------------------------
   THE HIT-AREA QUARTET. `box-sizing: content-box`, `height: 4px`,
   `padding-block` and `margin-block` and `background-clip: content-box` are
   one mechanism, and dropping ANY ONE of them makes the track vanish:

     · the global `* { box-sizing: border-box }` in styles.css would make
       `height: 4px` the BORDER box, so the 20px of padding would eat the
       content box entirely and `background-clip: content-box` would paint
       the gradient into nothing;
     · the padding is what makes a 4px-tall control a 24px hit target;
     · the negative block margin takes exactly that 20px back out of the
       flow, so `4 + 20 - 20 = 4` and nothing below the slider moves;
     · the clip is what stops the padding from being SEEN — without it the
       4px track is painted as a 24px bar.

   Do not tidy this up. It is load-bearing and it is measured, not guessed.

   Both `.llmt-field input` and `.llmt-controls input` are targeted: most of
   these pages' sliders sit inside a `.llmt-field`, but a large minority are
   direct children of the control column with only a `.val` label, and both
   shapes have to get the same treatment. */
.llmt-field input[type=range],
.llmt-controls input[type=range] {
  /* The filled portion. Nothing in this repo writes `--pct` — the slider
     binder in llm-guide.js mirrors the value into the adjacent `.val` span
     and stops there — so it is declared at 0% and the track renders as an
     unfilled groove in `--c-border-strong`. Declaring the hook costs
     nothing and means a page that starts writing it gets the filled track
     for free, with no change here. The alternative — leaving the input's
     native appearance alone — is not available, because a native range
     squeezed to a 4px box squashes the thumb to 4px with it. */
  --pct: 0%;
  width: 100%;
  height: 4px;
  box-sizing: content-box;
  padding-block: 10px;
  margin-block: -10px;
  background-clip: content-box;
  -webkit-background-clip: content-box;
  border-radius: var(--radius-1);
  background-image: linear-gradient(
    to right,
    var(--color-accent) 0 var(--pct),
    var(--c-border-strong) var(--pct) 100%
  );
  -webkit-appearance: none;
  appearance: none;
  /* `pan-y`, not `none`. A vertical swipe that starts on a 4px-tall control
     must still scroll the page, or every miss on a phone is a dead end.
     A horizontal drag is the slider's. */
  touch-action: pan-y;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.llmt-field input[type=range]::-webkit-slider-thumb,
.llmt-controls input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-text);
  border: 1px solid var(--c-border-strong);
  /* A 3px ring in the PANEL's own fill, so the thumb reads as sitting on the
     groove rather than floating over it. */
  box-shadow: 0 0 0 3px var(--color-surface-2);
  cursor: pointer;
  transition: transform var(--dur-fast) ease;
}
.llmt-field input[type=range]::-moz-range-thumb,
.llmt-controls input[type=range]::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-text);
  border: 1px solid var(--c-border-strong);
  box-shadow: 0 0 0 3px var(--color-surface-2);
  cursor: pointer;
  transition: transform var(--dur-fast) ease;
}

/* Hover is an ENHANCEMENT, so it sits behind a pointer query: on touch the
   hover state sticks after the tap and the slider never returns to rest.
   `:active` is deliberately OUTSIDE the query, because unlike `:hover` it
   does fire on touch — on a range input it means "the drag is live", which
   is information a finger cannot get any other way. `scale` rather than a
   translate: growing the thumb about its own centre cannot move it out from
   under the pointer, and 1.18 rather than 1.12 because a press is a
   confirmation, not an invitation. */
@media (hover: hover) and (pointer: fine) {
  .llmt-field input[type=range]:hover::-webkit-slider-thumb,
  .llmt-controls input[type=range]:hover::-webkit-slider-thumb { transform: scale(1.12); }
  .llmt-field input[type=range]:hover::-moz-range-thumb,
  .llmt-controls input[type=range]:hover::-moz-range-thumb { transform: scale(1.12); }
}
.llmt-field input[type=range]:active::-webkit-slider-thumb,
.llmt-controls input[type=range]:active::-webkit-slider-thumb { transform: scale(1.18); }
.llmt-field input[type=range]:active::-moz-range-thumb,
.llmt-controls input[type=range]:active::-moz-range-thumb { transform: scale(1.18); }

/* A range takes a ring on the THUMB, not an outline: a 2px outline around a
   4px-tall track is all but invisible, and this is the same 40% accent wash
   every other focusable thing on the site uses, so "focus is here" is one
   visual event across the whole tool. */
.llmt-field input[type=range]:focus-visible,
.llmt-controls input[type=range]:focus-visible { outline: none; }
.llmt-field input[type=range]:focus-visible::-webkit-slider-thumb,
.llmt-controls input[type=range]:focus-visible::-webkit-slider-thumb {
  box-shadow:
    0 0 0 3px var(--color-surface-2),
    0 0 0 6px color-mix(in srgb, var(--color-accent) 40%, transparent);
}
.llmt-field input[type=range]:focus-visible::-moz-range-thumb,
.llmt-controls input[type=range]:focus-visible::-moz-range-thumb {
  box-shadow:
    0 0 0 3px var(--color-surface-2),
    0 0 0 6px color-mix(in srgb, var(--color-accent) 40%, transparent);
}

/* Typed input, text areas, selects. RAISED — a `surface` fill on the canvas
   reads as above it, so these take a hairline and, on focus, a wash rather
   than a shadow. */
.llmt-field input[type=text],
.llmt-field textarea,
.llmt-field select {
  width: 100%;
  font-family: var(--font-mono); font-size: var(--text-sm);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-text);
  transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}
.llmt-field textarea { resize: vertical; min-height: var(--space-16); }

/* 18% is the accent ladder's "active" step, reused here rather than the
   slider's 40%: that one is a tight ring around a 16px disc, and this is a
   wide wash around a whole field, where the same alpha would be a wall. */
.llmt-field input[type=text]:focus-visible,
.llmt-field textarea:focus-visible,
.llmt-field select:focus-visible {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 18%, transparent);
}


/* --------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------
   `.llmt-btnrow button` IS a control — it is a real <button>, focusable and
   operable — so unlike the step badge it does get hover and press states,
   both gated on a real pointer. `color` is in the transition list because the
   selected and primary states change the label as well as the fill, and
   without it the text swapped instantly while the fill eased, which reads as
   two different presses. */
.llmt-btnrow { display: flex; gap: var(--space-2); flex-wrap: wrap; margin: var(--space-3) 0 var(--space-4); }
.llmt-btnrow button {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: var(--text-label-sm); line-height: var(--text-label-sm-lh);
  cursor: pointer;
  border: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-text);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--dur-fast) ease,
    border-color var(--dur-fast) ease,
    color var(--dur-fast) ease,
    opacity var(--dur-fast) ease;
}

/* Primary is INVERTED, not accent-filled. The accent carries interaction —
   links, focus, the active row — and is never a button fill. A page can
   carry twenty of these; they have to recede until the reader goes looking
   for one. */
.llmt-btnrow button.llmt-primary {
  background: var(--color-text); color: var(--color-bg);
  border-color: var(--color-text);
}

/* Selected: the ladder's 10% "active row" wash and a real border — the same
   vocabulary as a selected nav row and a revealed quiz answer. */
.llmt-btnrow button.active {
  background: color-mix(in srgb, var(--color-accent) 10%, var(--color-surface));
  border-color: var(--color-accent);
  color: var(--c-accent-ink);
}

/* The `:not(.active)` guard is not redundant. `.llmt-btnrow button:hover:not(…)`
   is more specific than `.llmt-btnrow button.active`, so without it hovering
   a selected button would erase its own selection. */
@media (hover: hover) and (pointer: fine) {
  .llmt-btnrow button:hover:not(.llmt-primary):not(.active) {
    background: var(--color-surface-2);
    border-color: var(--c-border-strong);
  }
  /* A selected row that is also under the pointer goes one step stronger —
     18%, the ladder's "active-while-active". */
  .llmt-btnrow button.active:hover:not(.llmt-primary) {
    background: color-mix(in srgb, var(--color-accent) 18%, var(--color-surface));
  }
  .llmt-btnrow button.llmt-primary:hover { opacity: 0.85; }
  .llmt-toc a:hover { color: var(--c-accent-ink); text-decoration: underline; text-underline-offset: 0.18em; }
}

/* `:not(:disabled)` is load-bearing in a way that looks redundant: a disabled
   button still matches `:active` in both engines while it is being pointed
   at, so without the guard a dead control would brighten at the exact moment
   the reader tried to use it. */
.llmt-btnrow button.llmt-primary:active:not(:disabled) { opacity: 0.7; }
.llmt-btnrow button:active:not(:disabled):not(.llmt-primary) { border-color: var(--c-border-strong); }
.llmt-btnrow button:disabled,
.llmt-btnrow button.llmt-primary:disabled:hover { opacity: 0.45; cursor: not-allowed; }


/* --------------------------------------------------------------------------
   Readout
   --------------------------------------------------------------------------
   RECESSED, like the notes: a well the numbers are read out of, so a hairline
   and no shadow. Tabular figures throughout, because a readout's whole job is
   being compared against the last one and a proportional digit moves sideways
   when it gains a place.

   The verdict colours are the point of this block. `.hi` and `.bad` used to
   be a blue and a crimson borrowed from the series palette; they are now the
   ok and bad status inks, which is what they have meant on every one of
   these pages all along. `.k` was 60% opacity, which also dimmed any child it
   wrapped; a colour does the same job without that side effect. */
.llmt-readout {
  font-family: var(--font-mono);
  font-size: var(--text-label-sm);
  line-height: var(--read-line);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-variant-numeric: tabular-nums;
}
.llmt-readout .k { color: var(--color-text-subtle); }
.llmt-readout .hi { color: var(--color-ok-ink); font-weight: 600; }
.llmt-readout .bad { color: var(--color-bad-ink); font-weight: 600; }


/* --------------------------------------------------------------------------
   Token strip
   --------------------------------------------------------------------------
   A token is a CHIP, so `--radius-sm` and a hairline step, not a pill: it
   sits in a row with its neighbours and a pill would out-shout the tokenizer
   the row exists to show. */
.llmt-tokens { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.llmt-tok {
  font-family: var(--font-mono); font-size: var(--text-label-sm);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-accent-100); color: var(--color-accent-800);
  border: 1px solid var(--color-accent-200);
  position: relative;
}
/* LITERAL 9.5px, and the only type size in this file that is not a token.
   The scale's smallest step is `--text-micro` at 11px, and 11px would make
   the id line as tall as the token it labels, doubling the height of every
   chip in a 50-token row. Inventing a step below `--text-micro` would put a
   one-off value into a scale the reader's text-size preference has to reach,
   which is the one thing that scale must not contain. */
.llmt-tok .id {
  display: block;
  font-size: 9.5px;
  /* The old 0.6 opacity, expressed as a colour instead. Mixing toward the
     chip's OWN fill rather than toward the page is what makes this read the
     same in both themes, where the 800 and 100 steps swap places. */
  color: color-mix(in srgb, var(--color-accent-800) 62%, var(--color-accent-100));
  margin-top: var(--space-hair);
}


/* --------------------------------------------------------------------------
   Cheat sheet
   --------------------------------------------------------------------------
   `th` drops its 0.6 opacity for a real muted colour, and its rule darkens to
   `--c-border-strong` so the header row is separated from the body by
   more than the body rows are from each other. */
.llmt-cheat { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.llmt-cheat th,
.llmt-cheat td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-divider);
  vertical-align: top;
  text-align: start;
}
.llmt-cheat th {
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--text-micro-ls);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--color-text-subtle);
  border-bottom-color: var(--c-border-strong);
}
.llmt-cheat code { white-space: nowrap; }

.llmt-refs { font-size: var(--text-sm); line-height: calc(var(--read-line) * 1.0857); }
.llmt-refs li { margin-bottom: var(--space-hair); }


/* --------------------------------------------------------------------------
   Table of contents and the "next part" plate
   --------------------------------------------------------------------------
   Both were blur panels. Both are now recessed wells: a jump list and a
   "read this next" prompt are reading aids sitting in the page, not objects
   floating over it, so they take the same fill-and-hairline treatment as the
   callouts and no elevation. `.llmt-next` is a card rather than a well only
   because it is the one thing on the page the reader is meant to act on, and
   it is therefore raised by an elevation pair. */
.llmt-toc {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  font-size: var(--text-label-sm);
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-inset);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.llmt-toc a { color: var(--color-text-muted); text-decoration: none; }

.llmt-next {
  --elev-shadow: var(--c-elev-1);
  --elev-inset: inset 0 1px 0 var(--c-elev-inset-hi);
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--space-4); flex-wrap: wrap;
  margin-top: var(--space-6);
  padding: var(--space-4) var(--space-inset);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-shadow), var(--elev-inset);
}


/* --------------------------------------------------------------------------
   Grids and cards
   --------------------------------------------------------------------------
   `.llmt-card` is RAISED: a `surface-2` fill lifted by an elevation pair. It
   is the one kit surface that hovers, and the hover moves `--elev-shadow`
   alone so the lit top edge survives the change. */
.llmt-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.llmt-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.llmt-card {
  --elev-shadow: var(--c-elev-1);
  --elev-inset: inset 0 1px 0 var(--c-elev-inset-hi);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-shadow), var(--elev-inset);
  padding: var(--space-4) var(--space-inset);
}
@media (hover: hover) and (pointer: fine) {
  .llmt-card:hover { --elev-shadow: var(--c-elev-2); }
}

.llmt-source { font-size: var(--text-micro); color: var(--color-text-subtle); margin-top: var(--space-1); }


/* --------------------------------------------------------------------------
   Selection
   --------------------------------------------------------------------------
   22% is the ladder's selection step. The explicit `color` is load-bearing
   rather than decorative: `::selection` is painted with the matched
   ancestor's own resolved pair, and these pages are full of KaTeX spans that
   inherit — a formula selected across a line break would otherwise be half
   accent ink and half prose colour, and the highlight would read as a
   rendering fault. Pinning the foreground to the text colour makes the wash a
   background change and leaves the glyphs on it contrast-guarded. */
.llmt ::selection {
  background-color: color-mix(in srgb, var(--color-accent) 22%, transparent);
  color: var(--color-text);
}


/* --------------------------------------------------------------------------
   Narrow viewports
   --------------------------------------------------------------------------
   Unchanged from before: the eyebrow stops indenting past the step badge, the
   step heading wraps instead of squeezing, and the grids become one column. */
@media (max-width: 640px) {
  .llmt-eyebrow { margin-left: 0; }
  .llmt-step-head { flex-wrap: wrap; }
  .llmt-grid2, .llmt-grid3 { grid-template-columns: 1fr; }
}
