/* ---------- The Agent Review write-up's own layout ----------
   lab/agent-review.html is the one page that loads this file. It holds
   three things the shared case-study shell does not have, and none of them
   declares a custom property: every size is a token from shell.css or
   type.css.

   1. THE FULL FRAME, IN TWO COLUMNS, FROM 64rem. Until 2026-10-06 every
      chapter sat in .case-narrow, 56rem, a blog's single column down the
      middle of a 1440 screen with 272px of ground either side, and the hero
      left half its width empty beside a 52ch lede. The chapters are in
      .case-wide now, the --container-max frame the nav, the hero and the
      engagement pages use, and each one splits into the words and the
      thing they are about: a figure, or the three kinds of work.
      The words keep --measure, so no line reads longer; what got bigger is
      the room beside them.

      One split, 5 to 7, the words on the left and the evidence on the
      right, so a reader's eye finds the same two columns all the way down.
      The hero takes it too since 2026-10-23: the title, the dek and the
      way in on the left, the problem drawn in code on the right, centred
      on each other. Nothing on the page is sticky. The dark band that flipped the split to 7 to
      5 came off the page on 2026-10-23. Under 64rem nothing is a grid and
      the markup reads in its own order.

   2. THE LOOP AS ONE LINE, where six drawings sat on six steps. A rail
      runs through the six: the change leaves the main line on a branch,
      is checked and read there, and comes back to a system with one more
      part. It is artwork drawn in code, so its colours are the
      palette's sage and inks plus the two the drawings' style spec
      allows as an accent and nothing else (README, img/writing/), each
      held to one meaning: rose where a person has to read, yellow where
      what they read became part of the system. COLOR.md section 6 has
      them as artwork, declared on .ar-rail and nowhere else. From 64rem
      it is one drawing over six equal columns; under that the line runs
      down the left beside each step.

   3. THE PHONE'S VERSION OF THE TOUR. Gone since 2026-10-21, with the
      tour: the walkthrough came off the page.

   4. NO SCREEN OPENS FULL SIZE, since 2026-10-09. From #408 until then
      the captures beside the words and the tour's screen were links that
      lightbox.js opened over the page, with a badge in the corner.

   5. THE INTRO VIDEO'S PLACE. Beside the opening, where the facts card sat
      from #405 until 2026-10-06; a labeled frame until the video exists.

   6. THE TOUR'S PANEL. Gone since 2026-10-21, with the tour.

   7. THE SAGE PANEL IN THE DARK BAND. The words beside the four findings,
      the question the checks left open and the three it comes down to, sit
      on a sage rectangle, so the band is two surfaces and not one charcoal
      field, with room between the findings' two rows.

   8. THE TWO WAYS IN, ON ONE LINE. "Try the prototype" and "Listen to
      this page" sit side by side under the opening, at one height. */

/* ---- 11. the dek, a ramp up ---- */
/* The question and the thesis under the title are the page's claim, and
   since 2026-10-09 (Adam: "make this paragraph larger") they are set on
   the h3's ramp, --type-subsection, 24 -> 34, where every other dek on the
   site is on --type-lede, 18 -> 24. The next ramp up rather than a size
   between the two, so it is on a step at every width the type check
   visits. Since 2026-10-23 it is two plain sentences ("Coding agents can
   do a designer's routine work now. This prototype is about what they
   shouldn't decide alone."), four lines on a phone. Leading stays
   .build-dek's --leading-tight, the prose rule above 18px, and --measure is in ch, so
   it grows with the size and a stacked line is still about 70 characters.
   TYPOGRAPHY.md section 3 records it as the one dek off --type-lede.
   Since the hero went to 5 of 12 (2026-10-23) it sets in four lines at
   1024 and at 1440, balanced so the last is not one word. */
.ar-hero .build-dek { font-size: var(--type-subsection); text-wrap: balance; }

/* ---- 10. the first minute (since 2026-10-12) ----
   The opening is the dek, the way in and the status under it; the four
   labelled lines that were between the dek and the way in came off on
   2026-10-23, when the page was rewritten for a reader new to the topic.
   The decision's two moments are an ordered list of splits, each a
   kicker, short paragraphs and one picture. The paragraph after them
   leads into the loop, so it stands a moment's distance off the last
   one rather than reading as its fourth paragraph. */
.ar-moments + p { margin-top: var(--space-block); }
.ar-status {
  margin: var(--space-lg) 0 0;
  max-width: var(--measure);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-muted-gray);
  text-wrap: pretty;
}
.ar-status strong { color: var(--color-charcoal); font-weight: var(--weight-semibold); }
.ar-hero-feature.quiet-cancel { margin-top: var(--space-2xl); }

/* ---------- Every action is a button. Except cancel. ----------
   Since 2026-10-21, in place of "Same red. Different meaning." (style.css
   until then, when the prototype's first decision changed): the problem
   drawn in code at the top of the case study. Two actions from Relay's
   billing settings, each in the look it has there, what each is under it,
   one label over them and one takeaway under them. Live text at the page's
   own sizes, so it is read, measured and translated like the rest.

   ON THE LOOP'S DARK PANEL since the same day (Adam: "higher visual impact,
   more color", "similar to the one on the homepage"): style.css, "The
   loop", is the model, and the two figures now read as one family. The
   white card it was had its label set off-centre by a three-column grid
   and its two cases at different heights, so nothing lined up; now the
   label is two centred lines and the cases are two screens of one height.

   THE COLOR SAYS WHICH SIDE A THING IS ON, and there are two:
     the system    --color-accent-on-dark: "action", the stem, the branch
                   to "Change plan", its check disc and "The checks pass."
     the exception --color-caution: "Except cancel." and the branch to
                   "Cancel subscription"; its disc is the caution ground
                   with the caution ink, as the loop's person step is.
   --color-caution is 4.17:1 on charcoal, so it is only ever a line or
   type at --text-2xl, where the floor is 3:1, never small text.

   THE CONNECTOR (quiet-cancel.js): one stem from under the label divides
   into a branch down to each screen, landing on the disc that sits on the
   screen's top edge. Three paths, one per stroke color, each a single run
   so it can draw itself.

   THE TWO LOOKS are the product's, on a white screen each, which is the
   product's own ground. "Change plan" is drawn as a button, an edge and a
   white fill; "Cancel subscription" as the link the old billing app built
   by hand, small, underlined and in its grey, #6a6a76, the value of the
   prototype's own muted token. That grey is a picture of a product's
   colour, declared on the figure and used nowhere else (COLOR.md, section
   6), and on white it measures 5.33:1, so it is text that clears 4.5.

   THE BUILD, once, the first time the figure is in view, as the loop's:
   the rule, then the exception, the stem drawing down and dividing, each
   screen landing as its branch arrives, and last the takeaway, whose last
   line is the designer's call, on a line of its own. Without script, or
   under reduced motion, nothing is armed and the figure is simply there,
   which is what the checks measure.

   Two columns from 30rem of figure, stacked under it. */
.quiet-cancel {
  --quiet-cancel-ink: #6a6a76;
  --qc-system: var(--color-accent-on-dark);
  --qc-except: var(--color-caution);
  --qc-disc: calc(var(--space-xl) + var(--space-xs));
  position: relative;
  container: quiet-cancel / inline-size;
  margin: 0;
  padding: var(--space-xl) var(--space-md);
  background: var(--color-charcoal);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
  color: var(--ink-on-dark);
}
@media (min-width: 640px) {
  .quiet-cancel { padding: var(--space-2xl) var(--space-xl); }
}
.quiet-cancel .quiet-cancel-label {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--text-2xl);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--ink-on-dark);
  text-align: center;
  text-wrap: balance;
}
.quiet-cancel-rule,
.quiet-cancel-except { display: block; }
.quiet-cancel-word { color: var(--qc-system); }
.quiet-cancel-except { color: var(--qc-except); }
.quiet-cancel-cases {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xl);
  margin: var(--space-4xl) 0 0;
  padding: 0;
  list-style: none;
  text-align: center;
}
.quiet-cancel-case {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  min-width: 0;
}
/* The product's screen: its own white ground and the action on it,
   centred, so the button and the link sit on one line although the button
   is the taller. The disc sits on its top edge, where the branch lands.
   Since 2026-10-24 there is no page name at its head: it said "Billing
   settings" twice, and the two actions say where they are. */
.quiet-cancel-screen {
  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  width: 100%;
  max-width: 18rem;
  min-height: calc(var(--space-4xl) * 2);
  padding: var(--space-xl) var(--space-md) var(--space-lg);
  background: var(--color-white);
  border-radius: var(--radius-xl);
  box-shadow: 0 0 0 2px var(--qc-tone);
}
.quiet-cancel-case--system { --qc-tone: var(--qc-system); }
.quiet-cancel-case--hand { --qc-tone: var(--qc-except); }
.quiet-cancel-mark {
  position: absolute;
  top: 0;
  left: 50%;
  box-sizing: border-box;
  width: var(--qc-disc);
  height: var(--qc-disc);
  padding: var(--space-2xs);
  border-radius: var(--radius-pill);
  transform: translate(-50%, -50%);
  fill: none;
  stroke: currentColor;
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.quiet-cancel-case--system .quiet-cancel-mark { background: var(--qc-system); color: var(--color-charcoal); }
.quiet-cancel-case--hand .quiet-cancel-mark { background: var(--color-caution-light); color: var(--color-caution-text); box-shadow: 0 0 0 2px var(--qc-except); }
.quiet-cancel-ui {
  display: flex;
  flex: 1;
  align-items: center;
  margin: 0;
  font-family: var(--font-sans);
  line-height: var(--leading-ui);
  white-space: nowrap;
}
.quiet-cancel-button {
  padding: var(--space-xs) var(--space-md);
  border: 1px solid var(--color-muted-gray);
  background: var(--color-white);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--color-charcoal);
}
.quiet-cancel-hand {
  font-size: var(--text-sm);
  color: var(--quiet-cancel-ink);
  text-decoration: underline;
}
/* What each is, in one line: the takeaway under them says the rest. */
.quiet-cancel .quiet-cancel-means {
  margin: 0;
  max-width: 18rem;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  color: var(--ink-on-dark);
  text-wrap: balance;
}
.quiet-cancel-take {
  margin: var(--space-2xl) 0 0;
  padding-top: var(--space-lg);
  border-top: 1px solid var(--rule-on-dark);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  color: var(--ink-on-dark);
  text-align: center;
  text-wrap: balance;
}
.quiet-cancel-pass { color: var(--qc-system); }
.quiet-cancel-call { display: block; margin-top: var(--space-xs); }
.quiet-cancel-leads {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.quiet-cancel-leads path {
  fill: none;
  stroke: var(--qc-system);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.quiet-cancel-leads .quiet-cancel-lead--hand { stroke: var(--qc-except); }
/* Stacked, the second branch runs down the left gutter, so the cases keep
   clear of it. */
@container quiet-cancel (max-width: 29.99rem) {
  .quiet-cancel-cases { padding-inline: var(--space-xl); }
}
@container quiet-cancel (min-width: 30rem) {
  .quiet-cancel-cases { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl); }
}
@container quiet-cancel (min-width: 36rem) {
  .quiet-cancel .quiet-cancel-label { font-size: var(--text-3xl); }
  /* The takeaway is what the figure is for, so it closes at the label's size. */
  .quiet-cancel-take { font-size: var(--text-3xl); }
}

/* The build. Keyed off --qc-beat, the loop's own beat, so the two figures
   move at one pace: about two and a half seconds end to end.

   ARMED ON THE ROOT, before first paint, by the page's head (lab/agent-
   review.html), not by quiet-cancel.js: that file is deferred, and on a
   slow load the finished figure painted, vanished and then built. The
   head takes the arming back if the file never ran.

   A LINE WAITING TO DRAW IS HIDDEN, not only dashed out of sight. Its
   pathLength is 1 and its offset 1, so an empty dash sat exactly on one
   end of the path, and Chrome drew that empty dash's round cap: a dot at
   the foot of each branch on a desktop and under the label on a phone,
   on screen before anything else was. Which end it lands on is rounding,
   so the line stays hidden until its own draw starts (qc-draw), and the
   gap of 2 keeps the far end clear in that first frame. */
.quiet-cancel {
  --qc-beat: calc(var(--motion-move) + var(--motion-stagger) * 2);
}
.quiet-cancel-armed .quiet-cancel-rule,
.quiet-cancel-armed .quiet-cancel-except,
.quiet-cancel-armed .quiet-cancel-case,
.quiet-cancel-armed .quiet-cancel-means,
.quiet-cancel-armed .quiet-cancel-take { opacity: 0; }
.quiet-cancel-armed .quiet-cancel-leads path,
.quiet-cancel-armed .quiet-cancel-mark path { visibility: hidden; stroke-dasharray: 1 2; stroke-dashoffset: 1; }
@keyframes qc-draw { from { visibility: visible; } to { visibility: visible; stroke-dashoffset: 0; } }
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-rule {
  animation: loop-in var(--motion-enter) var(--ease-enter) both;
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-except {
  animation: loop-in var(--motion-enter) var(--ease-enter) both;
  animation-delay: var(--qc-beat);
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-lead--stem {
  animation: qc-draw var(--motion-move) var(--ease) forwards;
  animation-delay: calc(var(--qc-beat) * 2);
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-lead--system,
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-lead--hand {
  animation: qc-draw var(--motion-enter) var(--ease) forwards;
  animation-delay: calc(var(--qc-beat) * 2 + var(--motion-move));
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-case {
  animation: loop-land var(--motion-move) var(--ease-enter) both;
  animation-delay: calc(var(--qc-beat) * 3 + var(--motion-move) + var(--i) * var(--motion-stagger));
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-mark path {
  animation: qc-draw var(--motion-enter) var(--ease) forwards;
  animation-delay: calc(var(--qc-beat) * 4 + var(--motion-move) + var(--i) * var(--motion-stagger));
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-means {
  animation: loop-in var(--motion-enter) var(--ease-enter) both;
  animation-delay: calc(var(--qc-beat) * 4 + var(--motion-move) + var(--i) * var(--motion-stagger));
}
.quiet-cancel-armed .quiet-cancel[data-play] .quiet-cancel-take {
  animation: loop-in var(--motion-enter) var(--ease-enter) both;
  animation-delay: calc(var(--qc-beat) * 5 + var(--motion-move));
}

.ar-moments {
  list-style: none;
  margin: var(--space-2xl) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-block);
}
/* Each moment is headed the way the three kinds' cards are (.ar-sort-kind
   h3): sans, --text-lg, with its step's number in a ring of the icon's size
   and stroke where a card has its icon. Two classes deep, because
   .case-section h3 is class-and-element and sets a subsection's margin. */
.ar-moment .ar-moment-title {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin: 0 0 var(--space-lg);
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-normal);
  color: var(--color-charcoal);
}
.ar-moment-step {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--space-lg);
  height: var(--space-lg);
  border: 1.5px solid var(--color-accent-text);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  line-height: 1;
  color: var(--color-accent-text);
}
/* Under each heading, what happened as labeled answers rather than a run
   of paragraphs: the same label and answer as the argument under the
   three kinds (.ar-sort-why), stacked in the text column. */
.ar-answers {
  display: grid;
  gap: var(--space-lg);
  margin: 0;
}
/* Where the answers close on an action (the second scenario's button), the
   step to it is the one a hero's dek takes to its button: a dl carries no
   paragraph margin to hand on. */
.ar-answers + .build-hero-act { margin-top: var(--space-xl); }
/* From the lead line to the split under it, the step the moments take
   from theirs (.ar-moments), at every width: p + .ar-split only holds
   it where the split is two columns. */
.ar-sort-lead + .ar-split { margin-top: var(--space-2xl); }

/* A crop taller than it is wide (the inspector, the rule) prints at its own
   width at most, so it is not blown up to the column's 700px and three
   screens tall. */
.ar-shot--narrow { max-width: 28rem; }
.ar-split > .ar-shot--narrow { justify-self: center; width: 100%; }
/* The decision's inspector prints at the scale the problem picture beside
   it set until 2026-10-23: both were 2x captures at the app's 1.25 zoom,
   and the inspector is 449 of that picture's 941 CSS pixels, so it takes
   that share of the column at every width. The problem picture came off
   with the rewrite; the share holds until the captures are retaken after
   the prototype's first-minute redesign. From 40rem, where it is the
   desktop capture; on a phone it fills the column. It starts at the
   column's left edge rather than floating in the middle of it. */
@media (min-width: 40rem) {
  .ar-moment .ar-split > .ar-shot--narrow { width: calc(100% * 449 / 941); justify-self: start; }
}

/* The way out to the enterprise evidence: a sentence-length link, larger
   than a prose link, under the second run's button. */
.ar-sap-link { margin: var(--space-lg) 0 0; font-size: var(--text-lg); line-height: var(--leading-tight); }
.ar-sap-link a {
  color: var(--color-accent-text);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  transition: color var(--motion-state) var(--ease);
}
@media (hover: hover) and (pointer: fine) { .ar-sap-link a:hover { color: var(--color-charcoal); } }
.ar-sap-link a:focus-visible { color: var(--color-charcoal); }

.ar-evidence-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-lg) var(--space-xl);
  margin: var(--space-xl) 0;
}
.ar-evidence-links .btn { gap: var(--space-xs); }

/* ---- 9. the three kinds of work ---- */
/* The idea the product is made of, first since 2026-10-23 (#three-kinds).

   A ROW OF THREE, READ AT A GLANCE, since 2026-10-24 (Adam: "hard to
   follow with all the text on the left ... missing heading on the
   right"). Until then the kinds were a column of cards beside five
   paragraphs, and the point, that only two of the three stop for a
   person, was in the third paragraph. Now the page says it in the
   layout before a word is read:
     - one lead line sets the scene;
     - over the cards, two lanes: "Goes through" over the first kind,
       in the sage, and "Stops for a person" bracketing the other two,
       in the caution ink (the lanes, below);
     - each kind is a card with its mark and its name as an h3, one line
       on what it is, then two labeled rows: an example from the
       prototype and who acts;
     - under the cards, the argument as two labeled answers rather than
       two more paragraphs.
   The card is the ladder's rung 2, as the site draws it everywhere
   (shell.css): white, the --rule-card edge, the --shadow-card drop and
   --radius-xl, on the tea ground so its edge reads. On a phone the
   lanes are headings over their cards, in reading order. */
.ar-sort-lead { max-width: var(--measure); }
.ar-sort {
  display: grid;
  gap: var(--space-md);
  margin: var(--space-2xl) 0;
}
/* THE LANES ARE HEADINGS, IN THE SERIF AND IN COLOR, since 2026-10-24
   (Adam: "I really don't like the use of this text ... never want it
   used at the size"). They were the field label's 12px tracked capitals,
   which named the page's whole point in its smallest voice. Now each is
   the serif at 400, set like an article figure's title (TYPOGRAPHY.md,
   Field labels, the last case) and one step larger from 64rem, where it
   brackets a row of cards; and each says go or stop in its color: the
   sage for "Goes through", the caution ink for "Stops for a person"
   (COLOR.md, Status and collection: a stop for a person is the caution
   ink's third use). The same two colors run down into the cards, on each
   card's mark and on its "Who acts" answer, so the color says which lane
   a card is in before its heading is read.
   Two classes deep, because .case-section p is one class and a tag, and
   at one class the lanes lost their size and color to it: the capitals
   this replaces were drawn at 18px in charcoal, never the 12px sage asked
   for here. */
.ar-sort .ar-sort-lane {
  --lane: var(--color-accent-text);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: var(--space-lg) 0 0;
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-heading);
  color: var(--lane);
}
.ar-sort-lane:first-child { margin-top: 0; }
.ar-sort .ar-sort-lane--stops { --lane: var(--color-caution-text); }
/* 2px, not the 1px of a divider: the bracket is what groups the cards. */
.ar-sort-lane::after {
  content: "";
  flex: 1;
  border-top: 2px solid currentColor;
}
@media (min-width: 640px) {
  .ar-sort .ar-sort-lane { font-size: var(--text-2xl); line-height: var(--leading-heading); }
}
.ar-sort-kind {
  --lane: var(--color-accent-text);
  display: flex;
  flex-direction: column;
  padding: var(--space-lg) var(--space-xl);
  background: var(--color-white);
  border: 1px solid var(--rule-card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
}
.ar-sort-kind h3 {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin: 0 0 var(--space-xs);
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-normal);
  color: var(--color-charcoal);
}
.ar-sort-icon {
  flex: none;
  width: var(--space-lg);
  height: var(--space-lg);
  fill: none;
  stroke: var(--lane);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ar-sort-kind p { margin: 0; font-size: var(--text-base); line-height: var(--leading-body); }
.ar-sort-kind .ar-sort-case,
.ar-sort-kind .ar-sort-who {
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-tag-border);
  font-size: var(--text-sm);
  line-height: var(--leading-ui);
}
/* Who acts sits on the card's foot, so the three answers line up across
   the row however long the example above them runs. */
.ar-sort-kind .ar-sort-case { margin-bottom: var(--space-md); }
.ar-sort-kind--stops { --lane: var(--color-caution-text); }
.ar-sort-kind .ar-sort-who { margin-top: auto; font-weight: var(--weight-semibold); color: var(--lane); }
/* The field label the case studies' glance row uses (TYPOGRAPHY.md,
   Field labels), on a line of its own over what it labels. */
.ar-sort-label {
  display: block;
  margin-bottom: var(--space-2xs);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-muted-gray);
}
.ar-sort-why {
  display: grid;
  gap: var(--space-lg);
  margin: 0;
}
.ar-sort-why dt,
.ar-answers dt {
  margin-bottom: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  line-height: var(--leading-ui);
  text-transform: uppercase;
  color: var(--color-accent-text);
}
.ar-sort-why dd,
.ar-answers dd { margin: 0; font-size: var(--text-base); line-height: var(--leading-body); }
@media (max-width: 40rem) {
  .ar-sort-kind { padding: var(--space-md) var(--space-lg); }
}
/* Three across from 64rem, the split's own breakpoint. The lanes take
   the first row: "Goes through" over the first card, and "Stops for a
   person" as a bracket over the other two, its line turning down at
   both ends toward them. */
@media (min-width: 64rem) {
  .ar-sort {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--space-lg);
    row-gap: var(--space-sm);
  }
  .ar-sort .ar-sort-lane { margin: 0; grid-row: 1; font-size: var(--text-3xl); }
  .ar-sort-lane--through { grid-column: 1; }
  .ar-sort-lane--stops { grid-column: 2 / 4; }
  .ar-sort-kind { grid-row: 2; }
  .ar-sort-lane::before { content: ""; flex: 1; }
  .ar-sort-lane::before,
  .ar-sort-lane::after {
    align-self: stretch;
    margin-top: calc(var(--leading-heading) * 0.5em);
    border-top: 2px solid currentColor;
  }
  .ar-sort-lane::before { border-left: 2px solid currentColor; }
  .ar-sort-lane::after { border-right: 2px solid currentColor; }
  .ar-sort-why {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--space-lg);
  }
  .ar-sort-why > div:last-child { grid-column: 2 / 4; max-width: var(--measure); }
}

/* ---- 8. the two ways in, on one line ---- */
/* read-aloud.js puts its bar straight after the element marked
   data-read-aloud="after", which on this page is the row holding "Try the
   prototype", so the two stacked, a --space-xl apart, and the listen pill
   stood 38px beside a 50px button. Where the opening's column holds both,
   it is a grid of two columns: everything spans both, but the button's
   row takes the first and the bar the second, so they share a line a
   --space-md apart. The two with their labels at one size take 455px, so
   the question is the column's width, not the screen's: a container
   query on .ar-hero-text asks it, since 2026-10-23, when the hero's
   column went to 5 of 12 and is 382px at 1024 and 487 at 1440. Grid
   items keep their margins, so the dek and the status sit where they
   did. In a narrower column they stack as before.

   ONE HEIGHT AT EVERY WIDTH: the pill's least height is the button's own,
   written from the same tokens the button is built from (.btn: a
   --space-sm above and below a --text-base line at the body's leading), so
   the two match whether they share a line or not. It is taller than the
   44px floor a coarse pointer gets (read-aloud.css), so that holds too.
   And one size on the line: the pill's label is the button's --text-base
   here, where read-aloud.css sets it at --text-sm under a dek. */
.ar-hero-main .ra-listen {
  min-height: calc(var(--space-sm) * 2 + var(--text-base) * var(--leading-body));
  font-size: var(--text-base);
  white-space: nowrap;
}
.ar-hero-text { container: ar-hero-text / inline-size; }
@container ar-hero-text (min-width: 29rem) {
  .ar-hero-main {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: var(--space-md);
    align-items: center;
  }
  .ar-hero-main > * { grid-column: 1 / -1; }
  .ar-hero-main > .build-hero-act { grid-column: 1; }
  .ar-hero-main > .ra-bar { grid-column: 2; grid-row: auto; margin: 0; }
}

/* ---- 7. the sage panel in the dark band ---- */
/* Nothing, since 2026-10-23: the dark band of what the experiment's two
   runs showed came off the page, its findings one paragraph of the
   experiment's now. The panel's rules and the findings' rows are in the
   diff that took them out. */

/* ---- 6. the tour's panel ---- */
/* Nothing, since 2026-10-21: the walkthrough came off the page, with
   walkthrough.css and walkthrough.js. The tea-light panel it ran on is in
   the diff that took it out. */

/* ---- 5. the hero's picture ---- */
/* The hero's right half is the prototype's trade-off since later still on
   2026-10-09 (agent-review#28): a .build-shot like the page's other
   screens, which gives it its step under the way in on one column, and
   section 1 below puts it in the grid. From earlier that day it was the
   homepage card's composition (lab-feature.css, which this page no longer
   loads); before that the first decision in the homepage card's tablet,
   with a caption (the rules are in #461's diff), and until later on
   2026-10-07 the Loom's frame (#442's diff). */

/* ---- 4. the screens open full size ---- */
/* Nothing, since 2026-10-09 (Adam: the pictures should not open larger).
   From #408 until then each screen was a link lightbox.js opened over the
   page, with the About section's badge in its corner and the picture
   lifting inside its frame on hover; the rules are in the diff that took
   them out. */

/* ---- 3. the tour, on a phone ---- */
/* Nothing, since 2026-10-21, with the tour. */

/* ---- 2. the loop, as one line ---- */
/* The two artwork colours, and the steps the drawing mixes from them and
   from the sage, so every fill below is a name rather than a number. */
.ar-rail {
  --rl-rose: #d9a3b4;
  --rl-butter: #f0df7c;
  --rl-rose-ink: color-mix(in srgb, var(--rl-rose) 70%, var(--color-charcoal));
  --rl-rose-ground: color-mix(in srgb, var(--rl-rose) 18%, var(--color-white));
  --rl-butter-ink: color-mix(in srgb, var(--rl-butter) 70%, var(--color-charcoal));
  --rl-sage-fill: color-mix(in srgb, var(--color-accent-text) 40%, var(--color-tea-light));
  --rl-sage-pale: color-mix(in srgb, var(--color-accent-text) 18%, var(--color-tea-light));
  position: relative;
  margin: var(--space-2xl) 0 0;
}
.rl-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Every stroke is the same 1.25, so the line, the brackets and the arrows
   read as one pen; the parts are a step lighter so the line leads. */
.rl-line, .rl-quiet, .rl-text, .rl-ink {
  fill: none;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rl-line { stroke: var(--color-accent-text); }
.rl-quiet { stroke: var(--rule-card); }
.rl-dashed { stroke-dasharray: 2 4; }
.rl-text { stroke: var(--color-muted-gray); stroke-width: 1; }
.rl-ink { stroke: var(--color-charcoal); stroke-width: 1.5; }
.rl-box { fill: var(--color-warm); stroke: var(--color-muted-gray); stroke-width: 1; }
.rl-box--change { stroke: var(--color-accent-text); }
.rl-mark--sage { fill: var(--rl-sage-fill); stroke: var(--color-accent-text); stroke-width: 1; }
.rl-mark--grey { fill: var(--color-rule); }
.rl-mark--new { fill: var(--rl-butter); stroke: var(--rl-butter-ink); stroke-width: 1; }
.rl-area { fill: none; stroke: var(--rule-card); stroke-width: 1; stroke-dasharray: 2 4; }
.rl-area--agent { fill: var(--color-tea-light); }
.rl-agent { fill: var(--rl-sage-fill); stroke: var(--color-accent-text); stroke-width: 1; }
.rl-pass { fill: var(--rl-sage-pale); stroke: var(--color-accent-text); stroke-width: 1; }
.rl-flag { fill: var(--rl-rose); stroke: var(--rl-rose-ink); stroke-width: 1; }
.rl-review { fill: var(--rl-rose-ground); stroke: var(--rl-rose); stroke-width: 1; }
.rl-note, .rl-cursor { fill: var(--rl-rose); stroke: var(--rl-rose-ink); stroke-width: 1; stroke-linejoin: round; }
.rl-node { fill: var(--color-accent-text); }
.rl-node--decision { fill: var(--rl-rose); stroke: var(--rl-rose-ink); stroke-width: 1; }

/* The steps: no hairline over each, because the line is the rule now, and
   the description a step quieter than the name over it. */
.build-loop--rail { margin-bottom: 0; }
.build-loop--rail li { border-top: 0; padding-top: 0; }
.build-loop--rail li > span { color: var(--color-muted-gray); }

/* UNDER 64rem, ONE COLUMN, the line down the left. Each step is a row:
   its stretch of the line, then its words. A row is as tall as the taller
   of the two, and the stretch's lines are drawn far past its own foot
   (overflow visible) and cut at the row's (.rl-step), so one row's line
   meets the next one's at any height the words take. The rows touch;
   the room between them is padding inside each, which the line crosses.

   THE WORDS SET EVERY ROW, so the gap after each step's words is the
   same --space-4xl whatever its drawing is. That holds because every
   drawing but the last is at most 100 units tall (6.25rem), under the
   shortest step's words, number, name and one line, plus that gap. A
   drawing taller than that sets its own row, and the gap after the words
   beside it grows by the difference: at 112 and 124 units the gaps ran
   28 to 81px down one phone screen. Keep a new drawing under 100. */
.rl-wide { display: none; }
.build-loop--rail {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  max-width: 32rem;
}
.build-loop--rail li {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  grid-template-rows: auto auto 1fr;
  column-gap: var(--space-md);
}
.build-loop--rail li::before { grid-column: 2; grid-row: 1; }
.build-loop--rail strong { grid-column: 2; grid-row: 2; }
.build-loop--rail li > span { grid-column: 2; grid-row: 3; padding-bottom: var(--space-4xl); }
.rl-step {
  grid-column: 1;
  grid-row: 1 / -1;
  overflow: hidden;
}
.rl-step svg { width: 100%; height: auto; overflow: visible; }

/* FROM 64rem, SIX ACROSS UNDER ONE DRAWING. The columns have no gap, so
   each is exactly a sixth of the frame and lines up with its 200 units of
   the drawing's 1200; the room between captions is each one's own right
   padding instead. */
@media (min-width: 64rem) {
  .rl-wide { display: block; width: 100%; height: auto; overflow: visible; }
  .build-loop--rail {
    max-width: none;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    column-gap: 0;
    margin-top: var(--space-2xl);
  }
  .build-loop--rail li { display: block; padding-right: var(--space-xl); }
  .build-loop--rail li > span { padding-bottom: 0; }
  .rl-step { display: none; }
}

/* The line draws itself once, left to right, as the drawing scrolls in:
   the page's script arms it and marks it drawn, as it does the findings'
   icons. Without the script, or with reduced motion, it is simply there.
   The arrowhead waits for the line to arrive and then appears: drawn
   with a dash, its round cap would sit there as a dot while it waited. */
.rl-draw { stroke-dasharray: 1; }
.ar-rail.is-armed .rl-draw { stroke-dashoffset: 1; }
.ar-rail.is-armed .rl-tip,
.ar-rail.is-armed .rl-late { opacity: 0; }
.ar-rail.is-drawn .rl-draw { animation: glance-draw var(--motion-draw) var(--ease) forwards; }
.ar-rail.is-drawn .rl-tip,
.ar-rail.is-drawn .rl-late { animation: rl-tip var(--motion-state) var(--ease) var(--motion-draw) forwards; }
@keyframes rl-tip { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .ar-rail.is-armed .rl-draw { stroke-dashoffset: 0; }
  .ar-rail.is-armed .rl-tip,
  .ar-rail.is-armed .rl-late { opacity: 1; }
  .ar-rail.is-drawn .rl-draw,
  .ar-rail.is-drawn .rl-tip,
  .ar-rail.is-drawn .rl-late { animation: none; }
}

/* ---- 1. the two columns ---- */
@media (min-width: 64rem) {
  /* The hero, on the chapters' own split since 2026-10-23: the kicker,
     the title, the dek and the way in are one column on the left, the
     problem drawn in code is the right, and the two are centred on each
     other. Until then the title ran across the top and the opening and
     the picture split in halves under it, which suited an opening with
     four labelled lines in it; with those gone the opening ended halfway
     down the picture and left a quarter of the screen empty under it, and
     at 1024 a half was too narrow for the picture's two screens to stand
     side by side, so it stacked them and stood twice the opening's
     height. On 5 to 7 the picture's left edge is the three kinds' left
     edge under it, and its column clears 30rem from 64rem up. */
  .ar-hero {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: var(--space-4xl);
    align-items: center;
  }
  .ar-hero > .ar-hero-text { grid-column: 1; }
  .ar-hero > .ar-hero-feature { grid-column: 2; margin: 0; }

  /* Every split but the dark band's, which waits for 80rem (below). */
  .ar-split:not(.ar-split--wide-first) {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: var(--space-4xl);
    align-items: start;
    grid-auto-flow: row dense;
  }
  .ar-split > .ar-split-text { grid-column: 1; }
  .ar-split > .ar-split-media { grid-column: 2; }

  /* A column's own first and last margins are the grid's to give, not
     the element's: a figure's --space-2xl over it would put the screen a
     step lower than the heading beside it. */
  .ar-split:not(.ar-split--wide-first) > .build-shot,
  .ar-split:not(.ar-split--wide-first) > .build-list { margin-top: 0; margin-bottom: 0; }
  .ar-split:not(.ar-split--wide-first) .ar-split-text > :first-child,
  .ar-split:not(.ar-split--wide-first) .ar-split-media > :first-child { margin-top: 0; }
  .ar-split:not(.ar-split--wide-first) .ar-split-text > :last-child,
  .ar-split:not(.ar-split--wide-first) .ar-split-media > :last-child { margin-bottom: 0; }
  .ar-split > .dp-note { margin-bottom: 0; }

  /* One part of a chapter to the next, and a paragraph to the split under
     it: the gap between major blocks inside a band. */
  .ar-split + .ar-split { margin-top: var(--space-block); }
  p + .ar-split { margin-top: var(--space-2xl); }

  /* NOTHING IS STICKY, since 2026-10-23. From 2026-10-12 every split held
     its shorter column still while the taller one scrolled past, which
     suited long runs of words beside small pictures. The words are short
     now and the pictures are as tall as they are, so both columns scroll
     with the page; the rules are in the diff that took them out. */
}

/* THE DARK BAND SPLIT AT 80rem, not 64, until it came off the page on
   2026-10-23; its rules are in the diff that took it out. The splits
   above still name it in :not(.ar-split--wide-first), which now matches
   every split. */

