/* The method route -----------------------------------------------------------
   Reference 1 is a grid of square cards, and the square is the unit: each card
   is one composition, complete on its own, and the page is what you get when
   you set them next to each other. It is not a slide deck and not a stepper.

   Every measurement below is a fraction of the card's own side, taken off the
   reference at 380px:

       inset          20 / 380   = 5.3%
       meta label      8 / 380   = 2.1%
       body copy    10.5 / 380   = 2.8%
       display        82 / 380   = 21.6%   (leading 1.0)
       gap             7 / 380   = 1.8%

   They are written in cqw against the card, not in vw or px, so a card is the
   same composition at any column width — which is the only way a grid of
   squares stays one system when it reflows.

   Two things about cqw that are easy to get wrong, and both were:

   1. An element's cqw resolves against its nearest ANCESTOR container, never
      against itself. So the card's own inset cannot be in cqw — written that
      way it silently fell back to the viewport and came out at 76px instead
      of 25px. The inset is a percentage, which resolves against the grid
      area, i.e. the card side. Percentage padding uses the inline size on all
      four edges, which is exactly right for a square.
   2. cqw is 1% of the container's CONTENT box, not its border box. With a
      5.3% inset on each side that box is .894 of the card, so every fraction
      above is multiplied by 1/.894 = 1.118 to land on the reference value.
      Display 21.6% of the card side is therefore 23.48cqw, not 21.6cqw. */

body[data-page="guide"] { margin: 0; }

/* ── DOM = reading order, CSS = composition ───────────────────────────────
   ⭐ This is the whole fix for the sequence, and it is structural rather than
   a tuning. The cards used to sit in the DOM in mosaic order and the grid
   reflowed around them, so at two columns the five steps came out
   01-right, 02-right, 03-left, 04-left, 05-right — the order was not hard to
   follow, it was wrong.

   Now the DOM is the true order: rail, title, what, 01…05, the way in, then
   the fields. Three columns place that order into the mosaic explicitly by
   name; below 900px the placement is simply dropped and the DOM order is what
   renders, which is correct by construction rather than by care.

   The rows are heterogeneous on purpose — a card that spans two columns is a
   2:1 landscape and a single is a square, so no two neighbours are the same
   shape and the grid reads as a set of compositions rather than as a table.
   Each step gets a different frame; that is what a step is here. */
.mt-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--bk-gap);
  margin-top: var(--bk-gap);
}

@media (min-width: 901px) {
  .mt-grid {
    grid-template-areas:
      "rail  title title"
      "rail  what  d1"
      "s1    s1    s2"
      "s3    s4    s4"
      "d2    s5    s5"
      "cta   cta   d3";
  }
  .mt-card[data-cell="rail"]  { grid-area: rail; }
  .mt-card[data-cell="title"] { grid-area: title; }
  .mt-card[data-cell="what"]  { grid-area: what; }
  .mt-card[data-cell="s1"]    { grid-area: s1; }
  .mt-card[data-cell="s2"]    { grid-area: s2; }
  .mt-card[data-cell="s3"]    { grid-area: s3; }
  .mt-card[data-cell="s4"]    { grid-area: s4; }
  .mt-card[data-cell="s5"]    { grid-area: s5; }
  .mt-card[data-cell="cta"]   { grid-area: cta; }
  .mt-card[data-cell="d1"]    { grid-area: d1; }
  .mt-card[data-cell="d2"]    { grid-area: d2; }
  .mt-card[data-cell="d3"]    { grid-area: d3; }

  /* The shapes. A square is the unit; the ones that break it are the ones
     doing something different. The rail is two units tall because it is a
     list; the wide ones are the steps that carry a widget worth room. */
  .mt-card[data-cell="rail"]  { aspect-ratio: 1 / 2; }
  .mt-card[data-cell="title"],
  .mt-card[data-cell="s1"],
  .mt-card[data-cell="s4"],
  .mt-card[data-cell="s5"],
  .mt-card[data-cell="cta"]   { aspect-ratio: 2 / 1; }

}

/* Below the three-column composition the fields are decoration with no
   composition left to serve, and they were a third of the page's length on a
   phone. The steps stay; the wallpaper goes. */
@media (max-width: 900px) {
    /* ⚠️ [data-horizon] is NOT in this list. The pattern cards are decoration
     with no composition left to serve at one column; the skyline is a picture,
     and on a phone the pictures are what stop the page being a column of
     coloured slabs — the same call the About route already makes. */
  /* ⚠️ [data-canopy] is not in this list either, for the same reason as
     [data-horizon]: it is a picture, not a pattern. */
  .mt-card:is([data-pattern], [data-land]) { display: none; }
}

.mt-card {
  container-type: inline-size;
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;              /* the crop: type runs off the card edge */
  padding: 5.3%;      /* NOT cqw — see note below */
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* Fields go edge to edge. A pattern with an inset is a picture of a pattern. */
.mt-card:is([data-pattern], [data-land], [data-horizon], [data-canopy], [data-mass]) { padding: 0; color: var(--bk-cream); }
.mt-card:is([data-pattern], [data-land], [data-horizon], [data-canopy], [data-mass]) svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* ── the two type sizes, and nothing between them ─────────────────────────
   The reference sets a display and a functional label and simply omits the
   middle. That gap is the effect; a comfortable 18px subhead destroys it. */
body[data-page="guide"] .mt-display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: calc(23.48 * var(--mt-u));
  line-height: .96;
  letter-spacing: -.035em;
  margin: 0 0 0 -.05em;
  text-wrap: balance;
}
/* Half-size display, for cards that carry a full sentence rather than a name.
   It is the ONLY second size — a step card and a sentence card use the same
   one, so combining a heading with a widget in one card introduces no new
   type size, it just fills the card that used to hold only the heading. */
body[data-page="guide"] :is(.mt-card--half, .mt-card--step) .mt-display {
  font-size: calc(12.86 * var(--mt-u)); line-height: 1.02;
}

/* ── step cards ───────────────────────────────────────────────────────────
   The name of the step and the thing it explains, in one square. Split over
   two cards each step left a colour void under every heading and took six
   rows to say five things, so each square read as a tile in a long scroll
   rather than as a part of the page. */
.mt-card--step { gap: calc(3.35 * var(--mt-u)); }
.mt-card--step .mt-display { margin-bottom: 0; }
/* ⚠️ `> ` no longer reaches these. Once the faces were introduced the widget
   became .mt-card > .mt-faces > .mt-face > .mt-work, so the rule that anchored
   it to the foot stopped matching and every open card put its widget at the top
   with a third of the card empty beneath it — while the display type it
   replaces sits at the foot. The two faces have to occupy the same place or the
   swap is a jump. */
/* ⚠️⚠️ Anchored to the foot by an AUTO MARGIN, not by `justify-content:
   flex-end`. Flex-end overflows past the START edge, so a face with more
   content than height opens already scrolled to its bottom — the moment the
   slider grew from a fake 8px to a real 44px, step 05 opened showing only its
   own answer, with the control that produces the answer scrolled off the top.
   An auto margin anchors identically when there is room and collapses to 0
   when there is not, so a tight face starts where you read from. */
.mt-card--step :is(.mt-work, .mt-cast) { flex: 1 1 auto; justify-content: flex-start; }
.mt-card--step :is(.mt-work, .mt-cast) > :first-child { margin-block-start: auto; }
/* Deliberate crop. The word is read as texture first and as language second,
   and running it past the edge is what forces that order. */
/* ⚠️ The horizontal crop is REMOVED from the display type. It was manufactured
   — white-space:nowrap plus a negative margin — and it cut the page's own name
   into "The meth", which is not a word anyone can recover. The repo already
   记录 this exact mistake once, about the rail: a crop reads only where the
   reader can put the word back, and the rail can be put back because it repeats
   similar words down a column. A title cannot. The type still runs to the card's
   edge; it simply is not pushed past it. */
body[data-page="guide"] .mt-card[data-bleed] .mt-display {
  margin-left: -.05em;
  text-wrap: balance;
}

/* The drawn overlay sits across the display type, not beside it — in the
   reference the branch crosses the word and neither one moves out of the
   way. It is inert to the pointer so it never eats a click. */
.mt-fig-art {
  position: absolute; right: -5%; top: 3%; width: 76%; height: 58%;
  pointer-events: none; opacity: .85; color: var(--bk-ink);
}
.mt-fig-art svg { width: 100%; height: 100%; }

body[data-page="guide"] .mt-meta {
  margin: 0;
  font-family: var(--mono, var(--sans));
  font-size: max(9px, calc(2.46 * var(--mt-u)));
  letter-spacing: .12em;
  line-height: 1.5;
  /* ⚠️ Was .74. Under a rotating palette that folded the label toward its own
     carrier until it measured 3.88:1 on group 089 — and the site's own rule is
     that a tier you cannot read is not a tier, it is lost text. The hierarchy
     here is already carried by size and by .12em of tracking; the fade was
     only ever the third signal, so it gives way rather than the words. */
  opacity: .88;
}
body[data-page="guide"] .mt-card p:not(.mt-meta), body[data-page="guide"] .mt-card li, body[data-page="guide"] .mt-card dd {
  font-size: max(12px, calc(3.24 * var(--mt-u)));
  line-height: 1.5;
  margin: 0;
}
.mt-fill { flex: 1 1 auto; }      /* pushes the block below it to the foot */

/* ── the masthead card ────────────────────────────────────────────────────
   The reference opens on a column of display words cut by the card edge.
   Ours lists what the page covers, in the order it covers it.

   ⚠️ It bleeds on the VERTICAL axis, not the horizontal one. These six words
   are 172–273cqw-scaled px wide inside a 427px box, so nothing overflows
   sideways on its own — a horizontal crop has to be manufactured with a
   negative margin, and then every line loses its first letter at once:
   "uestion / epth / asting / eading / harge / ollow-up", six non-words. The
   reference survives that only because it repeats ONE word, so the reader
   recovers it from any row. Six different words cannot be recovered.
   The column is genuinely taller than the square (6 × 1.16em > 100%), so
   cropping top and bottom is the same effect with nothing invented, and it
   reads the way a contents list should: it continues past the frame. */
.mt-stack { display: flex; flex-direction: column; justify-content: center; height: 100%; }
body[data-page="guide"] .mt-stack span { font-family: var(--serif); font-size: calc(16.86 * var(--mt-u)); line-height: 1.16;
  white-space: nowrap; letter-spacing: -.03em; }
/* The masthead column alternates WEIGHT, not opacity — same device as the
   headlines, so the page has one idea about emphasis rather than two. */
.mt-stack span:nth-child(even) { font-weight: 300; }
.mt-stack span:nth-child(odd) { font-weight: 700; }
/* The glow comes from --glow-on-color in typography.css, applied on the block
   route in blocks.css. This used to carry its own .30/.18 pair — a third,
   slightly different set of numbers for the same effect, which is how a device
   stops being one device. */

/* ── working cards ────────────────────────────────────────────────────────
   These hold the interactions. They keep the square: every widget below is
   sized to fit one, because a card that grows turns the whole row into
   rectangles and there is no grid of squares left. */
/* ── one unit, and the wide cards halve it ─────────────────────────────────
   ⭐⭐ A two-wide card has TWICE the container width, so the same cqw fraction
   paints everything on it at twice the size. That was already known for the
   display type and fixed there — and nowhere else, so every widget on the
   three wide step cards was drawn at double: the checklist at 27.8px against
   13.9 on the square beside it, step 04's terms at 32.6px, and step 05's cost
   figure at 124.6px, which pushed the number that is the whole point of the
   card clean off the panel.

   ⭐ So the doubling is now known in ONE place. `--mt-u` is the card's own
   unit — 1cqw on a square, half that on a two-wide — and every size below is a
   multiple of it. A new widget cannot miss the rule, because there is no
   separate list to keep in step with; this repo has already paid for a rule
   wired into half its selectors once, in the touch-target hardening. */
body[data-page="guide"] .mt-card { --mt-u: 1cqw; }

.mt-work { display: flex; flex-direction: column; gap: calc(3.35 * var(--mt-u)); height: 100%; min-height: 0; }
.mt-work > .mt-meta { margin-bottom: calc(1.12 * var(--mt-u)); }

/* ── the controls wear this route's material ──────────────────────────────
   ⭐⭐ A control here is a FLAT OPAQUE FIELD in the card's own colour, square,
   with a hard edge. What was here instead was translucency — ink at 8% for the
   input, cream at 52% for the options — which is the glass route's device, and
   on a page with nothing behind it a wash of 8% ink is not a surface at all:
   it read as a smear, and the reader could not see there was anywhere to type.

   ⭐ The field is a lightness band on the INK'S SIDE of the card's fill, taken
   from that fill so it keeps the group's hue. Same construction as the mark
   rings, same reason: it cannot collide with its own ground in any of the 114
   groups, and it is never a foreign grey.

   ⭐ What marks a control as active is an ADJACENT BAR of the loud colour, not
   a glow or a shadow — depth on this route comes from one colour meeting
   another, which is the whole material rule. */
body[data-page="guide"] .mt-card {
  --mt-field: color-mix(in srgb, var(--bk-fill, var(--bk-cream)) 78%, var(--bk-cream));
  --mt-field-on: var(--bk-cream);
  --mt-edge: calc(.9 * var(--mt-u));
}
@supports (color: oklch(from red l c h)) {
  /* ⚠️⚠️ ONE band, high, for every card — not one band per fill role. The first
     version stepped the field towards each card's own ink, which put it at L .60
     on the deep cards; the widgets set `color: var(--bk-ink)`, so that is dark
     type on a middling ground and the sweep found five classes below AA, worst
     2.51:1. Every card that carries a widget has a fill at .87 or below, so a
     field at .93 clears all of them by at least .06 in lightness AND gives its
     dark ink better than 9:1 in every group — headroom the labels' own fades
     then spend, instead of borrowing it. */
  body[data-page="guide"] .mt-card {
    --mt-field: oklch(from var(--bk-fill, var(--bk-cream)) .93 clamp(.01, c, .05) h);
    --mt-field-on: oklch(from var(--bk-fill, var(--bk-cream)) .99 clamp(.005, c, .03) h);
  }
}

body[data-page="guide"] .mt-try textarea {
  width: 100%; padding: calc(3.35 * var(--mt-u)); resize: none;
  font: inherit; font-size: max(12px, calc(3.24 * var(--mt-u))); line-height: 1.5;
  color: var(--bk-ink);
  background: var(--mt-field);
  border: 0; border-bottom: max(2px, var(--mt-edge)) solid var(--bk-clay);
  border-radius: 0; outline: 0;
  transition: border-color 190ms var(--ease-out);
}
body[data-page="guide"] .mt-try textarea:focus { border-bottom-color: var(--bk-ink); }
.mt-try textarea::placeholder { color: var(--bk-ink); opacity: .52; }
.mt-checks { list-style: none; margin: calc(3.35 * var(--mt-u)) 0 0; padding: 0; display: grid; gap: calc(1.79 * var(--mt-u)); }
/* ⚠️ The words stay at full strength; only the MARKER carries the state. Fading
   a whole line to show it is not yet met costs the reader the line — measured
   3.67:1 on group 048 at .72, and this route's rule is that a tier you cannot
   read is not a tier, it is lost text. ○ against ● already says everything the
   fade was saying, and it says it at any contrast. */
body[data-page="guide"] .mt-checks li { display: flex; gap: calc(2.46 * var(--mt-u)); align-items: baseline; }
.mt-checks li::before { content: "○"; font-size: .82em; line-height: 1; opacity: .62;
  transition: opacity 190ms var(--ease-out); }
.mt-checks li[data-ok="1"]::before { content: "●"; opacity: 1; }

.mt-switch { display: grid; gap: 2px; }
body[data-page="guide"] .mt-switch button {
  display: grid; grid-template-columns: 1fr auto; gap: 1px calc(3.35 * var(--mt-u));
  padding: calc(3.35 * var(--mt-u)); cursor: pointer; text-align: left;
  font: inherit; color: var(--bk-ink);
  background: var(--mt-field);
  /* the marker for "this one" is a bar of the loud colour against the field —
     adjacency, which is this route's only way of showing depth */
  border: 0; border-left: max(3px, calc(1.6 * var(--mt-u))) solid transparent;
  border-radius: 0;
  transition: background 190ms var(--ease-out), border-color 190ms var(--ease-out);
}
body[data-page="guide"] .mt-switch button b { font-family: var(--serif); font-weight: 400; font-size: max(14px, calc(4.02 * var(--mt-u))); }
body[data-page="guide"] .mt-switch button i { font-style: normal; font-size: max(9px, calc(2.46 * var(--mt-u))); letter-spacing: .1em; opacity: .86; }
body[data-page="guide"] .mt-switch button span { grid-column: 1 / -1; font-size: max(11px, calc(3.02 * var(--mt-u))); opacity: .92; }
body[data-page="guide"] .mt-switch button[aria-checked="true"] {
  background: var(--mt-field-on); border-left-color: var(--bk-clay);
}
.mt-compare { display: grid; gap: calc(2.24 * var(--mt-u)); }
.mt-compare .row { display: flex; align-items: center; gap: calc(3.35 * var(--mt-u)); }
body[data-page="guide"] .mt-compare .row b { font-family: var(--mono, var(--sans)); font-weight: 400;
  font-size: max(9px, calc(2.46 * var(--mt-u))); letter-spacing: .1em; min-width: calc(22.36 * var(--mt-u)); opacity: .88; }
.mt-compare svg { color: currentColor; width: calc(24.6 * var(--mt-u)); height: auto; }

.mt-cast { display: flex; flex-direction: column; gap: calc(3.35 * var(--mt-u)); height: 100%; }
/* Sized so the pair of figures, the readout, the button and the note all clear
   one square. At calc(29 * var(--mt-u)) the card overflowed by 89px and overflow:hidden ate the
   note — the crop is for display type, never for content. */
.mt-cast-fig { display: flex; align-items: center; gap: calc(5 * var(--mt-u)); min-height: calc(20 * var(--mt-u)); }
.mt-cast-fig svg { height: calc(20 * var(--mt-u)); width: auto; }
/* Three label/value pairs on one row rather than three rows: the readout is a
   caption on the figures, and stacked it cost the card its last 24px. */
.mt-readout { margin: 0; display: flex; flex-wrap: wrap; gap: calc(.6 * var(--mt-u)) calc(4 * var(--mt-u)); align-items: baseline; }
.mt-readout dd { margin: 0 0 0 calc(1.4 * var(--mt-u)); }
body[data-page="guide"] .mt-readout dt { font-family: var(--mono, var(--sans)); font-size: max(9px, calc(2.46 * var(--mt-u)));
  letter-spacing: .1em; opacity: .7; }

/* ⚠️ The label had no size rule at all, so it sat at the browser's 16px while
   everything around it was 10.5 — and the slider ran the full 1700px of a
   two-wide card, which is not a control, it is a rule across the page. */
body[data-page="guide"] .mt-meter label {
  display: block; margin: calc(2.24 * var(--mt-u)) 0 calc(1.12 * var(--mt-u));
  font-family: var(--mono, var(--sans));
  font-size: max(9px, calc(2.46 * var(--mt-u))); letter-spacing: .12em; opacity: .88;
}
/* ⚠️ `appearance: none`, and it is the only reason any of this lands. A native
   range has a fixed intrinsic height and IGNORES `height` outright while
   appearance is auto — a declared 44px computed back as 16px with the rule
   sitting in the matched list, looking applied. This repo has the same note for
   the native checkbox and border-radius; it is one fact about native controls,
   not two.

   16px is a line, not something you can put a thumb on, and this control is the
   whole point of step 05. It is drawn here rather than left native: square
   corners are this route's material rule, and a native thumb is a lozenge. */
body[data-page="guide"] .mt-meter input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; max-width: calc(52 * var(--mt-u)); display: block;
  height: var(--ctl); background: transparent; margin: 0;
  /* ⚠️ `color: inherit`. Form controls do not inherit colour, so the thumb's
     `currentColor` was resolving to the UA grey rather than to the card's own
     ink — the one element on the card not wearing the palette. */
  color: inherit;
  /* ⚠️ `flex: none`, or the height is only a suggestion. `.mt-work` is a column
     flex container, so `height` is the item's base size and the default
     shrink factor takes it back when the face is tight — a declared 44px
     computed as 7.8px, and even an inline `height: 44px !important` computed
     as 7.8px, which is what finally named the cause. Nothing was overriding
     the declaration; flex was allowed to shrink the result. */
  flex: none;
}
body[data-page="guide"] .mt-meter input[type="range"]::-webkit-slider-runnable-track {
  height: calc(1.7 * var(--mt-u)); min-height: 6px; background: var(--mt-field); border: 0;
}
body[data-page="guide"] .mt-meter input[type="range"]::-moz-range-track {
  height: calc(1.7 * var(--mt-u)); min-height: 6px; background: var(--mt-field); border: 0;
}
/* The thumb is a block of the card's own ink — the one place on this route
   where a control says "here" by weight rather than by glow. */
body[data-page="guide"] .mt-meter input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; border: 0; border-radius: 0;
  width: calc(5 * var(--mt-u)); min-width: 16px;
  height: calc(7.4 * var(--mt-u)); min-height: 24px;
  background: currentColor;
  /* centre the thumb on the track: half the thumb, less half the track */
  margin-top: calc((max(6px, 1.7 * var(--mt-u)) - max(24px, 7.4 * var(--mt-u))) / 2);
}
body[data-page="guide"] .mt-meter input[type="range"]::-moz-range-thumb {
  border: 0; border-radius: 0;
  width: calc(5 * var(--mt-u)); min-width: 16px;
  height: calc(7.4 * var(--mt-u)); min-height: 24px;
  background: currentColor;
}
.mt-figure { margin: calc(3.35 * var(--mt-u)) 0 0; display: flex; align-items: baseline; gap: calc(2.8 * var(--mt-u)); }
body[data-page="guide"] .mt-figure b { font-family: var(--serif); font-weight: 400; font-size: calc(14.53 * var(--mt-u)); line-height: 1; }

.mt-defs { margin: 0; display: grid; gap: calc(3.35 * var(--mt-u)); }
body[data-page="guide"] .mt-defs dt { font-family: var(--serif); font-size: max(13px, calc(3.8 * var(--mt-u))); margin-bottom: calc(.67 * var(--mt-u)); }
.mt-defs dd { margin: 0; opacity: .84; }

/* The call to action is a filled bar hard against the inset, as in the
   reference — not a pill and not centred. */
.mt-card .bk-go { align-self: flex-start; padding: calc(2.91 * var(--mt-u)) calc(3.8 * var(--mt-u));
  font-size: max(11px, calc(2.91 * var(--mt-u))); text-decoration: none; }

@media (max-width: 900px) {
  .mt-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .mt-grid { grid-template-columns: minmax(0, 1fr); }
  /* A full-width square is most of a phone screen. The card releases its
     aspect here and takes the height its content needs. */
  .mt-card { aspect-ratio: auto; min-height: 62vw; }
  /* ⚠️ The interactive cards get room for what is inside them. At 62vw four of
     the five widgets overflowed their face by ~100–126px — including step 03's
     "Toss the coins", which is the whole card — and the face's own scroll then
     competes with the page's under the same finger. A nested scroll region on a
     phone is a worse answer than a taller card. */
  .mt-card--flip { min-height: 96vw; }
  .mt-card:is([data-pattern], [data-land]) { min-height: 30vw; }
  .mt-card[data-horizon] { min-height: 44vw; }
  /* 9px of tracked label, and on one column it is the only chrome the card has.
     At three columns 9px reads as a caption inside a mosaic; at one column
     there is no mosaic left for it to be a caption of — §3 says the composition
     is not laid out below 900px — so the label is simply small text, and this
     site's own rule is that a tier you cannot read is lost text, not a tier.
     Raised here only: the cqw ladder the composition is measured in is
     untouched. */
  body[data-page="guide"] .mt-meta { font-size: 11px; }
  /* ⭐ Raise the UNIT, not a list of sizes. Seven parts inside the widgets
     bottom out at 9px on a phone — the card's cqw is ~3.5px there — and the
     obvious fix is a rule naming each one. That is the shape of the mistake
     this page has already paid for twice: a second list of sizes that has to
     be kept in step, and is not. The work face gets a larger unit and every
     part of the widget scales together. It already scrolls inside itself, so
     the extra height cannot clip anything. */
  body[data-page="guide"] .mt-face[data-face="work"] { --mt-u: max(4.6px, 1cqw); }
}

/* ── woven weight, and a light in the type ─────────────────────────────────
   One typeface, weight alternating word by word. BioRhyme is a variable font
   (wght 200–800) shipped as a single file, so this costs no extra bytes and
   introduces no fourth family — the three-font rule holds.

   The alternation is deterministic: even words light, odd words heavy, by
   index. The same rule the brush follows, and for the same reason — random
   per render would reshuffle on every navigation and read as a fault. */
/* The weight pair and the glow moved to blocks.css: they belong to the
   block route, not to this page. */

/* The glow is a halo of neutral white, never a palette tint — the same rule
   the glass follows. It is static: nothing here pulses. Two stops, a tight one
   for the edge and a wide one for the bloom, both well under half an em so the
   counters stay open and the type stays readable rather than fogged. */


/* ── the two faces ─────────────────────────────────────────────────────────
   A step card holds its name and the thing it teaches. The name is what you
   see; one click swaps to the widget in place. The faces stack absolutely
   inside .mt-faces rather than on the card itself, so the card keeps its
   percentage inset and every cqw below still measures against the same box. */
.mt-faces { position: relative; flex: 1 1 auto; min-height: 0; }
/* ⚠️⚠️ THE OUTGOING FACE WAS NOT FADING. `visibility` is not in the transition
   list, so removing .is-on hid it in the same frame while only the incoming
   face animated — a hard cut followed by a 190ms fade-in, which is exactly what
   made the swap feel like a stutter rather than a turn. Visibility is
   transitioned too now, held until the opacity has finished on the way out and
   switched immediately on the way in.

   ⚠️ And the two faces cross on ONE timeline. Before, the swap happened 90ms
   in, the faces took 190ms and the wash ran 260ms, so for most of the move you
   were looking at two faces and a veil at once. The wash now peaks where the
   faces cross and everything is finished together. */
/* ⚠️ The NAME face centres; the work face still sits at the foot. Anchoring
   the name to the bottom left every step card reading as a 300px field of flat
   colour with a caption on its floor — five of those in a column is the "I
   don't know what to look at" on this page. Centred, each card reads as one
   thing. The widget keeps the foot, because a control wants a base. */
.mt-face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 160ms var(--ease-out), visibility 0s linear 160ms;
}
.mt-face[data-face="name"] { justify-content: center; }
.mt-face.is-on {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity 160ms var(--ease-out), visibility 0s linear 0s;
}
/* The work face is absolutely positioned, so anything taller than the card was
   simply cut — step 04's closing line lost 52px of itself that way. It scrolls
   inside its own face now, which is the seam this route already softens
   elsewhere rather than a new behaviour. */
.mt-face[data-face="work"] {
  justify-content: flex-end;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 10px,
    #000 calc(100% - 10px), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 10px,
    #000 calc(100% - 10px), transparent 100%);
}

.mt-card--flip { cursor: pointer; }
.mt-card--flip:focus-visible { outline: 2px solid currentColor; outline-offset: -6px; }
/* ⭐ The affordance, which the page did not have. This was 9px at opacity .5
   and carried aria-hidden="true", so nothing on screen and nothing in the
   accessibility tree said a card could be opened; its wording was a caption
   ("Write one and watch the checks") rather than an instruction. It is legible
   now, it is announced, and it carries a marker so it reads as a control. */
body[data-page="guide"] .mt-hint {
  margin: 0; display: flex; align-items: center; gap: calc(1.8 * var(--mt-u));
  font-family: var(--sans);
  font-size: max(11px, calc(3.1 * var(--mt-u))); letter-spacing: .06em; opacity: .92;
  transition: opacity 140ms var(--ease-out);
}
body[data-page="guide"] .mt-hint i {
  flex: none; width: calc(5.4 * var(--mt-u)); height: calc(5.4 * var(--mt-u)); min-width: 15px; min-height: 15px;
  border-radius: 50%; border: 1px solid currentColor;
  display: grid; place-items: center;
  font-style: normal; font-size: max(9px, calc(3.2 * var(--mt-u))); line-height: 1;
  transition: background 190ms var(--ease-out), color 190ms var(--ease-out);
}
.mt-card--flip:hover .mt-hint,
.mt-card--flip:focus-visible .mt-hint { opacity: 1; }
/* Opened, the marker fills — the card says which of its steps you have been
   into without a separate progress widget anywhere on the page. */
.mt-card--flip.is-seen .mt-hint i {
  background: currentColor; color: var(--bk-ink);
}

/* The instruction sits at the top of the sentence card, ahead of the
   description, because it is the thing a first-time reader needs and the
   description is the thing they need second. */
body[data-page="guide"] .mt-open {
  margin: 0 0 calc(2.4 * var(--mt-u));
  font-family: var(--sans);
  font-size: max(12px, calc(3.4 * var(--mt-u))); line-height: 1.45;
}
body[data-page="guide"] .mt-open b { font-weight: 700; }

/* The wash as the faces cross, so the swap reads as the card turning rather
   than as a dissolve. It runs once per click and leaves nothing running — the
   casting figure's rule, applied here: once it lands, nothing keeps moving.

   ⚠️⚠️ NOT WHITE. It was rgb(255 255 255 / .55) peaking at .9, so half the
   card went white for a moment — and white is the one colour on this route
   that does not rotate with the 114 groups, on a page whose entire material
   rule is flat palette colour. A big foreign flash is the cheapest-looking
   thing here. It is the card's own ink now, so the blink is the card getting
   momentarily denser rather than a light being shone on it, and it follows the
   colour group like everything else.

   ⚠️ Shorter and gentler: .34 rather than an effective .5, over 220ms, peaking
   at 40% — which is exactly when the faces cross. */
.mt-card--flip::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--bk-ink); opacity: 0;
}
.mt-card--flip.is-flashing::after { animation: mt-blink 220ms var(--ease-out) 1; }
@keyframes mt-blink {
  0%   { opacity: 0; }
  40%  { opacity: .34; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .mt-face { transition: none; }
  .mt-card--flip.is-flashing::after { animation: none; }
}

/* ── the two-wide cards halve their unit ───────────────────────────────────
   ⚠️ ONE declaration, and everything on the card follows it: display type,
   widget type, gaps, padding. It used to be a list of .mt-display selectors,
   which meant the front face was corrected and the back face was not — the
   whole reason step 05's cost figure was drawn at 124px and fell off its own
   panel.

   ⚠️ It still has to carry body[data-page="guide"] and sit at the END of the
   file. Written as .mt-card[data-cell="s1"] it is (0,2,0) against the base
   rule's (0,2,1) and loses silently, which is exactly how the first version of
   the halving failed. Same weight, later in the cascade. */
@media (min-width: 901px) {
  body[data-page="guide"] .mt-card:is([data-cell="title"], [data-cell="cta"],
                                      [data-cell="s1"], [data-cell="s4"],
                                      [data-cell="s5"]) {
    --mt-u: .5cqw;
  }
}
