/* ══════════════════════════════════════════════════════════════════════════
   home.css — the landing page, and nothing else.

   The hero, the showcase carousel and its pager, the syntax anatomy, the agent
   walk, the theme demonstration, the range wall and the install block.
   Everything shared with other pages lives in site.css, which loads first.
   ══════════════════════════════════════════════════════════════════════════ */



/* ── the section shape ───────────────────────────────────────────────────────
   Five sections share one rhythm: h2, lede, content. They were five copies of
   the same rules and the copies had already drifted — `.s-install` was the
   last one out, carrying its own duplicate of both blocks 200 lines below.
   The vertical air between them is `body`'s own gap now, so a section carries
   no padding of its own and cannot drift again. */
.s-range h2,.s-core h2,.s-agents h2,.s-themes h2,.s-install h2{
  font-size:var(--font-size-h2);font-weight:700;
  letter-spacing:var(--letter-spacing-h2);line-height:1.02}
.lede{font-size:var(--font-size-lede);color:var(--color-text);margin:20px 0 0;
  max-width:66ch}
/* The wall is not a pane, but it is a section's content and starts where one
   would. The cards themselves are cards.css's. */
.range-wall{margin-top:var(--space-section-content)}
/* The way out: thirteen specimens here, the rest one click away. A centred pill in
   the hero's quiet-CTA clothes rather than a text link in the corner — the
   corner link read as a footnote, and the one action a convinced reader has
   at the foot of the wall deserves a button. No count in the label: the
   number changes with the registry and a stale one is a small lie — this
   comment used to name one, and it was wrong by three. */
.wall-foot{margin:clamp(24px,3.2vw,40px) 0 0;text-align:center}

/* ── hero: compact, left-aligned, deliberately not a full screen ─────────── */
.s-hero{position:relative;z-index:var(--z-content);
  padding:clamp(30px,6vw,72px) 0 clamp(24px,3.4vw,40px)}
.s-hero h1{font-size:clamp(36px,5.6vw,68px);font-weight:700;letter-spacing:-.043em;
  line-height:1;max-width:15ch}
.s-hero p{font-size:var(--font-size-lede);color:var(--color-text);
  margin:18px 0 0;max-width:47ch}
.cta{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:28px}

/* ── the showcase: overflows the fold on purpose ───────────────────────────
   No bottom padding: it is the last thing in `.l-shell`, and the air under it
   is the gap between that and the first section, which `body` owns. */
.s-showcase{position:relative;z-index:var(--z-content)}
/* No card and no shadow around the pair. The frame is only a grid — the two
   panes carry themselves, exactly as the range wall's cards do, so the two
   sections read as one system.

   The split is 1.2 / 1. It was .78/1.22 while both panes were empty and a
   figure deserved the room, then .94/1.06 once the left held a real source,
   then half-and-half on the argument that the panes are peers — which was
   reasoning about their standing rather than about their contents. They are
   peers in status and not in need: the source has lines that run past the pane
   and scroll, and the figure fits itself to whatever it is given. */
.showcase-frame{position:relative;display:grid;
  grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:var(--space-gap)}
/* One fixed height for both panes, capped at 480px: a tall figure — the
   schematic sheet — used to grow its pane past the fold, and below 760px,
   where the two stack, the source pane fell to its minimum while the figure
   kept its height, so the code read as an afterthought under the picture. A
   height rather than a min-height is what makes them equal in the stack. */
.showcase-box{border-radius:var(--radius-pane);position:relative;
  height:clamp(300px,38vw,470px);display:grid;padding:15px 16px}

/* Every slide sits in the same grid cell and the inactive ones are hidden
   rather than removed. `display:none` would collapse the box onto whichever
   slide is showing, so the frame would resize on every step — the same fault
   the pager's own width rule exists to prevent. Hidden, they still size the
   cell, so the box is as tall as the tallest slide and never moves.
   `visibility` also takes them out of the accessibility tree, which `opacity`
   would not. */
.showcase-slide{grid-area:1/1;min-width:0;min-height:0;visibility:hidden}
.showcase-slide.is-on{visibility:visible}

/* The label is a corner mark, not a row: it must not push the slide down or
   the two panes stop lining up. The source pane's head is the same corner, with
   the run button opposite it — the one place on the page where a control and a
   label share a line, because the button is about the thing the label names. */
.showcase-box > .label{position:absolute;top:15px;left:16px;z-index:1}
.showcase-head{position:absolute;top:15px;left:16px;right:16px;z-index:2;
  display:flex;align-items:center;justify-content:space-between}

.showcase-box--source .showcase-slide{overflow:auto;margin:0;
  font-family:var(--font-code);font-size:13px;line-height:1.6;
  color:var(--color-ink);padding-top:24px}
/* Focus is a rim on the pane, not an outline round the textarea: the textarea's
   own box is invisible, so a ring on it would float unattached to anything.

   The pane's own cast is restated, because `box-shadow` does not add: a rim
   alone dropped the pane off the page's elevation the moment anyone clicked
   into it. Accent, not brand — every interface state on this page is the
   accent's, and focus is the definition of one. */
.showcase-box--source:focus-within{
  box-shadow:0 18px 54px -24px var(--color-glass-cast),
             0 0 0 1px var(--color-accent-tint) inset}

/* The figure fits the box, and is capped at 1.2x its authored size.
   `max-width:100%` alone looked right and was not: the slides are authored
   between 272px and 500px wide, so filling the pane drew them at 1.14x to
   2.09x — the same 15px label came out at 17px on one slide and 31px on the
   next, and a step resized every word on screen. `--nat-w` is set per slide by
   the build. A figure smaller than the cap simply sits smaller in the pane,
   which is the honest outcome: they are not all the same size.

   The height cap still applies, so a portrait figure is limited by the box
   rather than by the multiplier. */
.showcase-box--figure .showcase-slide{display:grid;place-items:center;
  overflow:hidden;padding-top:20px}
/* The inner radius, so a figure that paints its own sheet — the schematic's
   cream, a drawing's white — lands as a rounded card rather than a
   sharp-cornered plate on the glass. A transparent figure clips nothing. */
.showcase-box--figure svg{width:min(100%,calc(var(--nat-w,100%) * 1.2));
  max-height:100%;height:auto;display:block;border-radius:var(--radius-pane-in)}

@media (max-width:760px){
  .showcase-frame{grid-template-columns:1fr}
  .showcase-box--figure{order:-1}
}

/* The pager sits centred under the pair, on the page's own ground — it drives
   both panes, so it belongs to neither. It used to float over the figure's
   bottom-right corner on a paper pill, which is a plate on top of artwork on
   every slide once the panes hold real specimens. Down here it needs no plate
   to separate it from anything, and reads as the quiet control it is.

   The step arrows bookend the dots — `< o o (o) o >` — so the bar is symmetric
   about the row it drives, and there is no transport cluster hanging off one
   end. Play/pause is not a fourth button: the active pill is already the one
   thing you can click that does not navigate, so it carries the toggle. Its
   accessible name says which; the visible word stays the slide's. */
.pager{margin-top:38px;display:flex;align-items:center;justify-content:center;
  gap:8px}
/* The dots may wrap; the arrows may not. Seven identical circles falling onto
   a second centred line is a layout, where an arrow doing it is a stray mark
   above the row it belongs beside.

   The margin is a safety valve, not a layout. Six 26px rings, one pill of
   `--pager-pill + 18` and six 8px gaps sit just inside the 288px a 320px phone
   leaves once `--space-wrap` bottoms out at 16px — one longer family name, or
   a fallback face measuring wider than Google Sans, and the wrap is what stops
   the row overflowing rather
   than a shape anyone chose. */
.pager-dots{display:flex;align-items:center;justify-content:center;
  flex-wrap:wrap;gap:8px}
/* THE ARROWS AND THE RINGS TAKE NO CAST, and the active pill does. That is not
   an inconsistency in the row, it is the row's own reading:
   the control cast, in either of its two hues, is the pool under a SURFACE,
   and of the nine controls here exactly one is a surface. The other eight are ink — a 2px ring and a
   chevron, both on no ground at all, because the pager was moved down here
   precisely so it would need no plate.

   Both ways of giving ink a cast were tried and photographed. `box-shadow` on a
   transparent box paints the ring the box clips out of it, so every arrow and
   every dot came back wearing a pale disc: nine plates, which is the decision
   above undone. `filter: drop-shadow` follows the paint instead and is honest,
   but a 2px stroke has no area to cast from — at the depth that reads under the
   pill it was invisible on a screenshot, so it buys a compositor layer for
   nothing. Ink does not pool. */
.pager-step{display:flex;padding:7px;background:none;
  color:var(--color-text-faint);border-radius:var(--radius-pill);
  transition:color var(--duration-hover) var(--ease-out)}
.pager-step:hover{color:var(--color-accent-deep)}
.pager-step .i{width:18px;height:18px;display:block}
/* The bar is nowrap, so the arrows never stack above and below the dots — the
   comment here used to say they did. What a too-narrow bar actually does is
   shrink `.pager-dots` until the dots break to two lines, leaving each arrow
   centred against a two-row block, which is its own kind of wrong. Measured,
   that starts at 398px. The pair steps aside at 430px, comfortably ahead of
   it, and below that every slide is still one tap away on its own dot. */
@media (max-width:430px){ .pager-step{display:none} }

/* Every dot is the same 26px target, and the mark inside it a 12px ring.
   The circle is a pseudo-element rather than the button's own background:
   `background-clip: content-box` paints the *content rectangle*, which no
   border-radius can round, so the dots used to be squares with rounded
   corners however round the radius claimed they were. The mark and the pill's
   text share one grid cell, so the name appears exactly where the dot was. */
.pager-dot{display:grid;place-items:center;width:26px;height:26px;padding:0;
  background:none;border-radius:var(--radius-pill);
  font-family:var(--font-sans);font-size:12px;font-weight:700;
  letter-spacing:.01em;white-space:nowrap;line-height:1}
.pager-dot > *,
.pager-dot::before{grid-area:1/1}
.pager-dot::before{content:"";box-sizing:border-box;width:12px;height:12px;
  border-radius:50%;border:2px solid var(--color-text-faint);
  transition:border-color var(--duration-hover) var(--ease-out)}
.pager-dot:hover::before{border-color:var(--color-accent-deep)}
/* The pill's own background does not ease either, and for the same reason the
   width does not. `display` cannot animate, so the outgoing dot's circle snaps
   back the instant the class moves while its background is still 200ms from
   gone — a mark sitting on a coloured blob, on every single step. The two
   have to change together, so both snap. Only the mark's hover colour eases,
   which nothing else is racing.

   An inactive dot's name is absent, not merely invisible — transparent text
   still sizes a box, and these boxes must all be the same one.

   And the pill names its slide, full stop. It used to swap that name for the
   word for what clicking does while the pointer was on it, which read as the
   label glitching rather than as an offer; the accessible name carries the
   action instead, where it costs the eye nothing. The empty second span that
   held that word went with it. */
.pager-name{display:none}

/* Nothing about the row's width may depend on which slide is showing, or on
   when you looked. Two rules do that together.

   One width for every name, `--pager-pill`, measured once from the widest of
   them — see `home.js`. It used to be stated as `9ch`, which was exact while
   the pill was set in the monospace face and is meaningless now that it is
   not; a measurement is the only honest form of "as wide as the longest".

   And the width does not animate. Two dots swapping widths sum to a constant
   only while both are the same distance through the same ease; click again
   mid-flight and the new transition restarts its full duration from wherever
   it had got to, so the pair fall out of step and the row breathes under a
   fast hand. Colour still eases — it moves nothing. */
/* The one control in the row with a ground gets the ground's cast, scaled by
   what it is: 26px tall against the CTA's 41, so `0 10px 34px -12px` comes down
   by that ratio and lands on 6/22/-8. The pool is then the same fraction of the
   pill as the CTA's is of the CTA, which is what "the same shadow, smaller"
   has to mean — copying the CTA's numbers onto something two-thirds the height
   would have put twelve pixels of pool under a twenty-six pixel pill.

   The COOL cast, not the rose one. This pill is `--color-accent-solid`, which
   is violet, and a rose pool under it is the wrong light for the same reason a
   grey pool under a watermelon button is dirt — see the token beside it in
   site.css. It is the only control on the page that is violet at rest, and the
   ghost CTA, which becomes violet under a pointer, is the other caller. */
.pager-dot.is-on{width:calc(var(--pager-pill,64px) + 18px);
  padding:6px 9px;background-color:var(--color-accent-solid);
  color:var(--color-on-accent);
  box-shadow:var(--shadow-control-sm)}
.pager-dot.is-on::before{display:none}
.pager-dot.is-on .pager-name{display:block}

.s-install{position:relative;z-index:var(--z-field);text-align:center}
.s-install .lede{max-width:52ch;margin-inline:auto}

.install-pane{margin:clamp(28px,4vw,40px) auto 0;max-width:560px;
  border-radius:var(--radius-pane);padding:8px;text-align:left}
.install-line{display:flex;align-items:center;gap:16px;
  justify-content:space-between;padding:15px 18px;
  font-family:var(--font-code);font-size:15px;
  background:var(--color-paper);border-radius:var(--radius-pane-in);
  box-shadow:10px 0 36px -18px var(--color-sheet-cast)}
.install-line+.install-line{margin-top:8px}
.install-line code{white-space:nowrap;overflow-x:auto}
/* The example, not the instruction. `--color-text-soft` is the transport tier:
   present, clearly not the thing being asked for. */
.install-line--quiet{background:none;box-shadow:none;color:var(--color-text-soft);
  font-size:13.5px;padding-top:11px;padding-bottom:11px}
.install-line--quiet code::before{content:"$ ";opacity:.45}

/* The other way in, and today the common one: the grammar is a file, so an
   agent handed it writes Lini. One quiet sentence under the pane rather than a
   third install line — it is not a command to run. The chip is the agent
   section's, so the file is named the same way twice on one page. */
.install-agent{margin:clamp(18px,2.4vw,26px) auto 0;max-width:58ch;text-align:center;
  font-size:15px;line-height:1.55;color:var(--color-text-soft)}


.install-next{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;
  margin-top:clamp(24px,3vw,34px)}

@media (max-width:520px){
  .install-line{padding:13px 14px;font-size:13.5px}
  .install-line code{overflow-x:auto}
}

/* Landing-page examples share the site's glass panes and violet pill controls. */
.showcase-hint{font-size:14px;color:var(--color-text-soft);margin:14px 0 -2px}
.showcase-hint span{color:var(--color-accent-deep)}
.source-route:focus-visible{outline:2px solid var(--color-accent-deep);outline-offset:4px}

/* The three stages, as a walk rather than three pills. The rule between two
   marks is what says they are ordered; it lives on the list item so it can
   take the leftover width of the row and still not be part of a click
   target. The numbers are the only filled thing, and only one is filled. */
/* Capped, because the rules between the marks are the point. Given the whole
   column they stretch to 400px of hairline and the three steps read as three
   things far apart rather than one sequence. */
/* Capped, not stretched: given the pane's whole width the rules between the
   marks grow to 400px of hairline and the three steps read as three things far
   apart rather than as one sequence. */
.demo-steps{display:flex;align-items:center;list-style:none;margin:0;padding:0;
  width:min(100%,470px)}
/* Two ranks, at every width: the subject centred on top, the walk under it.
   Side by side they competed for one row — one control pinned left and one
   pinned right with the pane's whole width of nothing between them — and the
   subject is the outer choice, so it leads and takes the centre.

   The tabs are flush, not pulled left by their padding. An active pill is the
   row's first visible mark, and a mark starting 14px outside every other edge
   in the pane reads as a spacing mistake, which is exactly how it was
   reported. A box aligns by its box. */
.agent-head{display:flex;flex-direction:column;align-items:center;
  gap:clamp(14px,1.8vw,20px);margin-bottom:clamp(20px,2.6vw,30px)}
.demo-steps[hidden]{display:none}
.demo-step{display:flex;align-items:center;min-width:0}
.demo-step+.demo-step{flex:1 1 auto}
.demo-step+.demo-step::before{content:"";flex:1 1 auto;min-width:10px;height:1px;
  margin:0 10px;background:var(--color-text-faint)}
.demo-step-btn{display:inline-flex;align-items:center;gap:11px;border:0;padding:6px 2px 6px 0;
  border-radius:var(--radius-focus);background:none;cursor:pointer;white-space:nowrap;
  font:600 15px var(--font-sans);color:var(--color-text-soft);
  transition:color .15s}
.demo-step-num{display:grid;place-items:center;flex:none;width:27px;height:27px;
  border-radius:50%;border:1px solid var(--color-text-faint);
  font:600 13px var(--font-code);transition:background .15s,border-color .15s,color .15s}
.demo-step-btn:hover{color:var(--color-accent-deep)}
.demo-step-btn:hover .demo-step-num{border-color:var(--color-accent-solid)}
.demo-step-btn[aria-selected="true"]{color:var(--color-ink)}
.demo-step-btn[aria-selected="true"] .demo-step-num{border-color:transparent;
  background:var(--color-accent-solid);color:var(--color-on-accent);
  box-shadow:var(--shadow-control-sm)}
.demo-step-btn:focus-visible{outline:2px solid var(--color-accent-deep);outline-offset:3px}
/* No per-panel heading. There were four layers of prose over every panel — the
   section's lede, a heading, a sentence under it, and a paragraph under the
   pictures explaining what the pictures showed — and the last one standing was
   still a whole row restating the step name two inches above it. Draw needs no
   gloss at all; Read and Change put theirs at the foot of the left column,
   which had room going spare. */
.demo-panel{min-width:0}
.demo-note{flex:none;margin:14px 0 0;font-size:14px;line-height:1.5;
  color:var(--color-text-soft);max-width:44ch}
/* One pane, like the syntax section's, and for the same reason: the tabs, the
   walk, the listing and the drawing are one instrument, and floating four
   loose elements over the page's ground made them read as four. Same tokens,
   so the two sections measure alike — `--inset` on every edge, `--gutter`
   inside a sheet, and the specimen's column gap equal to the inset. */
.agent-specimen{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--inset);min-height:320px}
.demo-source,.demo-view{display:flex;flex-direction:column;min-width:0}
.demo-source>.demo-sheet{flex:1}
.demo-sheet{padding:var(--gutter);min-width:0}
.demo-view{justify-content:center}
.demo-view>.label{display:block;margin-bottom:10px}
.demo-figure{display:grid;place-items:center;flex:1;min-width:0}
.demo-figure svg{display:block;width:100%;max-height:280px;height:auto}

/* A single specimen with its anatomy always visible. No steps or hidden panels.

   The source is a box inside the pane, not the pane's left half. Tinting the
   half meant the wash ran into three of the pane's corners and stopped dead
   at a horizontal seam across the middle, which reads as two panes badly
   joined rather than one pane holding a listing. Inset by the same amount on
   every side, it reads as what it is: a sheet of code laid on the glass.

   `--inset` is the one number the whole pane is spaced by, so the code box,
   the blocks under it and the footer all line up on the same left edge — the
   blocks subtract their own button padding from it to land there. */
/* ── a section's pane ───────────────────────────────────────────────────────
   Every top-level pane on this page is spaced, inset and rounded the same, so
   that is one class the markup wears and each pane's own rule carries only its
   layout. It was three copies with three different top margins — 32, a clamp
   to 48, and a clamp to 64 — on three panes that sit one under another.

   `--inset` is every edge in the pane. `--gutter` is the padding inside a
   sheet within it. Both are declared here, so a pane that grows a sheet gets
   the right padding without knowing it. */
.section-pane{--inset:clamp(14px,1.7vw,22px);--gutter:22px;
  margin-top:var(--space-section-content);
  border-radius:var(--radius-pane);padding:var(--inset)}
/* 1.2 / 1, the carousel's own split — the two sections show a listing beside a
   figure and should divide the room the same way. */
.syntax-specimen{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);
  gap:var(--inset)}
.syntax-code{padding:var(--gutter);min-width:0}
/* The output column carries no surface, so its padding is not a gutter — it is
   just space between the figure and edges that are already spaced by the
   pane's own inset. */
.syntax-output{min-width:0}
/* ── the code sheet ─────────────────────────────────────────────────────────
   One surface, worn by every listing on this page: the syntax specimen, the
   agent section's ASCII and its statements, the diff and the theme rules.

   No shadow, no cast, no rim. A cast under an inner box on glass is the one
   shadow this site has never allowed itself, and the book's two-colour
   hairline was tried here and dropped: round a listing that already sits on a
   pane it was one line too many. The fill does the separating alone, which is
   why it carries more of the accent's hue than the book's does — the book
   draws its blocks on white paper and can afford to be near-neutral.

   The grey wash this replaced was a dent in the glass; a sheet sits on it. */
.syntax-code,.demo-sheet{background:var(--color-code-sheet);
  border-radius:var(--radius-pane-in)}
/* Nothing is captioned. "The source" over a listing, "The whole picture" over
   a drawing and "Select a building block below" over both were three labels
   for things that announce themselves — a listing looks like a listing, and a
   row of six cards with a hover state looks like a row of six cards. Between
   them they cost the section about eighty pixels and a held-open row. */
/* The carousel's own code metrics, to the decimal. Two listings on one page
   set at two sizes is two answers to "what does Lini source look like here",
   and the smaller one is the one that has to hold seventeen lines beside a
   drawing. It takes ~60px off the pane. */
.syntax-code pre{font:13px/1.6 var(--font-code);color:var(--color-ink);margin:0;overflow-x:auto}
.syntax-code [data-syntax-part]{border-radius:3px;transition:background .15s,box-shadow .15s}
.syntax-code .is-highlighted{background:var(--color-accent-tint);box-shadow:0 0 0 2px var(--color-accent-tint)}
/* Matched to the listing beside it rather than given the column: a figure
   taller than its own source leaves the pane with a band of empty sheet. */
.syntax-output .demo-figure svg{max-height:395px}
/* Every box in this pane starts on the same two lines: its outer edge on the
   pane's `--inset`, its text on `--inset + --gutter`. The blocks used to pull
   themselves 16px left so their TEXT landed on the code's — correct while they
   were bare paragraphs, and wrong the moment they grew a hairline, because a
   visible box aligns by its box. So the row is flush now and the block takes
   the code's own horizontal padding, which puts both edges where they belong
   instead of trading one for the other.

   The gap above the row is the specimen's own column gap, and the space under
   it is the pane's padding and nothing else — it was 18 and 33 against sides
   of 23, which is three different insets in one pane. */
.syntax-blocks{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;
  margin:var(--inset) 0 0;padding:0;list-style:none}
/* A hairline at rest, so the six read as six. They were six paragraphs on one
   surface with nothing but a gap between them, and a gap does not say "each of
   these is a thing you can point at" — the hover state was the only evidence,
   and you have to already be on one to see it. `--color-wash` is the faintest
   mark the palette has and it is a light-dark pair, so it holds in both. */
.syntax-block{width:100%;height:100%;display:flex;flex-direction:column;gap:9px;
  padding:16px var(--gutter);
  border:1px solid var(--color-wash);border-radius:var(--radius-pane-in);background:none;text-align:left;color:var(--color-text);font-family:var(--font-sans);cursor:pointer}
.syntax-block:disabled{cursor:default}
.syntax-block:not(:disabled):hover,.syntax-block[aria-pressed="true"]{background:var(--color-accent-tint);
  border-color:transparent}
.syntax-block:focus-visible{outline:2px solid var(--color-accent-deep);outline-offset:-2px}
.syntax-block-head{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%}
.syntax-block b{font-size:16px;font-weight:600;color:var(--color-ink)}
.syntax-block code{font:13px var(--font-code);white-space:nowrap}
.syntax-description{font-size:14px;line-height:1.5;max-width:29ch}
/* An inline link inside a lede, so it takes the lede's size and sits in the
   sentence rather than on a line of its own. It was the pane's footer row —
   one link alone under six blocks, which made the pane taller to say a thing
   the sentence above it could carry for free. */
.text-link{font-weight:600;color:var(--color-accent-deep)}
.text-link:hover{text-decoration:underline;text-underline-offset:3px}

/* ASCII is the losing side of the comparison and should not be shouting it:
   soft ink, so the eye lands on the drawn figure beside it first. */
.ascii-sheet pre{font:13px/1.6 var(--font-code);margin:0;max-width:100%;
  overflow-x:auto;color:var(--color-text-soft)}

/* Two of the three figures bring paper of their own — a schematic's cream
   sheet, a drawing's white — and painting it only where the svg happens to
   land leaves the drawing floating on a letterbox of glass. The face carries
   the same colour outward so the whole cell reads as the sheet. The values are
   the compiled defaults in the svgs themselves (`--lini-sheet`, `--lini-bg`);
   if a render ever changes them, these two lines are the seam that shows it.
   The flow figure has no ground of its own and keeps none here. */
.demo-view .example-slide[data-example="circuit"]{background:light-dark(#faf6ea,#22201b)}
.demo-view .example-slide[data-example="drawing"]{background:light-dark(#fff,#1b1b1f)}
/* The face fills its cell rather than shrinking to the figure inside it —
   `.example-stack` centres its items, which was invisible while the faces were
   transparent and is a floating plate now that two of them carry paper. The
   figure still centres, one level down, in `.demo-figure`. */
.demo-view .example-stack{place-items:stretch}
.demo-view .example-slide{border-radius:var(--radius-pane-in);display:flex}
.demo-view .example-slide>*{flex:1;min-width:0}

/* Three subjects in one pair of panes. Every face is in the markup and the two
   that are off keep their size, so the panes are as tall as the tallest of the
   three and stepping between them never moves the page. Same reasoning, and
   the same mechanism, as the hero carousel's slides. */
.example-stack{display:grid;flex:1;min-width:0;place-items:center}
.example-stack>*{grid-area:1/1;width:100%;min-width:0;visibility:hidden}
.example-stack>.is-on{visibility:visible}
.ascii-sheet .example-slide{display:grid;place-items:center;min-width:0}
.example-tabs{--example-tab-pad:14px;display:flex;gap:8px;flex:none}
.example-tabs[hidden]{display:none}
/* Sized to read as a control rather than as three words, and violet when it is
   the one you are on — a grey pill at rest is a tab you have to squint at to
   tell from a label. It shares the stepper's own active colour because they
   are one row and one instrument now. */
.example-tab{border:0;border-radius:var(--radius-pill);padding:9px var(--example-tab-pad);background:none;
  font:600 15px var(--font-sans);color:var(--color-text-soft);cursor:pointer;
  transition:background .15s,color .15s}
.example-tab:hover{color:var(--color-accent-deep);background:var(--color-accent-tint)}
.example-tab[aria-pressed="true"]{color:var(--color-on-accent);
  background:var(--color-accent-solid);
  box-shadow:var(--shadow-control-sm)}
.example-tab:focus-visible{outline:2px solid var(--color-accent-deep);outline-offset:3px}
.agent-foot{margin:clamp(26px,3.4vw,42px) 0 0;text-align:center}
/* The statements and the edit both start at the top of their pane; only the
   Create panel's two faces want centring, and that is what `.example-stack`
   defaults to. */
.route-pane .example-stack,.revision-asks{place-items:start;align-content:start}
/* The diff leads and the ask follows. The ask runs two lines on one subject and
   one on another, so at the top it moved the diff — and the diff is the line
   the step exists to show. */
.revision-asks .example-slide{display:flex;flex-direction:column}
/* Sized to the tallest ask rather than stretched, so the button follows the
   line it applies instead of being pushed to the foot of the pane with a band
   of nothing between them. The pane's own min-height keeps the air; it just
   sits under the control now. */
.revision-asks{flex:none}
/* Three rows in a sheet: it IS a listing, so it wears one and the selected
   row is a line in it rather than a card floating over glass. */
.source-routes{display:flex;flex-direction:column;gap:6px;width:100%}
.source-route{display:flex;flex-direction:column;gap:6px;text-align:left;
  padding:10px 12px;width:100%;
  border:1px solid transparent;border-radius:var(--radius-pane-in);background:none;cursor:pointer}
.source-route code{font:13px/1.5 var(--font-code);color:var(--color-ink)}
.source-route span:not([class]){font:14px var(--font-sans);color:var(--color-text-soft)}
.source-route[aria-pressed="true"]{border-color:var(--color-accent-tint);background:var(--color-accent-tint)}
.source-route:hover{background:var(--color-wash)}
/* One class, set by the script on exactly what should recede — see home.js
   for why the choice cannot be made in a selector. Everything else keeps its
   own strength, ancestors of a lit node included. */
.route-output .is-dim{opacity:.18}
.route-output .lini-link.is-traced{filter:drop-shadow(0 0 3px var(--color-accent-tint))}
/* Everything `home.js` can dim, so nothing in the figure snaps while the rest
   of it eases. The list is the script's `candidates` set, written out. */
.route-output .lini-link,.route-output [data-id],
.route-output .lini-dim-line,.route-output .lini-dim-text,
.route-output .lini-ext-line,.route-output .lini-marker,
.route-output .lini-caption,.route-output .lini-footnote,
.route-output .lini-centerline{transition:opacity var(--duration-fast,.18s) var(--ease-out)}
/* A two-sided diff, where the answer replaces a line rather than adding one. */
.revision-diff{padding:12px 14px;flex:none}
.diff-minus{color:var(--color-text-faint);font-weight:600}
.revision-diff pre{margin:0;font:13px/1.6 var(--font-code);color:var(--color-ink)}
.diff-plus{color:var(--color-accent-deep);font-weight:600}

/* The heading and its lede sit on the page above the pane, like every other
   section's; what is left inside is the rule and the specimen it governs, so
   the copy column is now the narrower of the two and holds one line and one
   declaration. Centred against the preview rather than hung from its top edge:
   two lines top-aligned beside a 300px pane read as a stranded caption. */
/* Even columns now that the left one holds a listing rather than a caption:
   a label and four rules is a column's worth of content, and the .8/1 split
   was sized for two lines of text sitting in a lot of nothing. */
.theme-demo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--inset)}
/* Top, not centred: the switch is the column's first mark and should land
   level with the plate beside it, the way the subject tabs land level with the
   sheet under them. */
.theme-copy{align-self:start}
.theme-rule-label{font-size:14px;color:var(--color-text-soft);margin:0}
/* Four lines in the page's own code sheet, not a bare `pre` on glass: it is a
   listing, and the section's claim is that these four names carry both themes.
   `pre-wrap` so a narrow column folds a rule rather than scrolling it. */
.theme-rule{margin-top:12px}
.theme-rule pre{margin:0;font:13px/1.75 var(--font-code);color:var(--color-ink);
  white-space:pre-wrap;overflow-wrap:anywhere}
/* Only the specimen. The switch used to float over it on a toolbar row, which
   cost the plate that row's height while the column beside it sat empty — so
   the control moved to the copy, under the rules it is about to re-colour. */
.theme-preview{border-radius:var(--radius-pane-in);padding:15px;display:flex;
  flex-direction:column;justify-content:center;min-width:0;
  background:light-dark(#fff,#1b1b1f);color:light-dark(#333,#ddd);color-scheme:light}
/* Leads its column, and wears the subject tabs' clothes: it is the same
   control doing the same job one section down, and two ideas of what a pill
   looks like on one page is one too many. */
.theme-switch{margin:0 0 clamp(20px,2.4vw,28px)}
.theme-preview .demo-figure{min-height:160px}
.theme-preview .demo-figure svg{max-width:480px}
/* A chip is a plate with type on it, so the padding and the size correction
   belong to the chip and not to one of the three places it appears. Mono runs
   large against Google Sans at a shared size — `.9em` is what makes the two
   read as one line of text rather than as a word in a bigger face — and
   without the padding the tint stopped at the letterforms, which is a
   highlighter mark, not a chip. */
.s-install .lede code,.code-chip{font-family:var(--font-code);font-size:.9em;
  padding:1px 7px;background:var(--color-accent-tint);
  color:var(--color-accent-deep);border-radius:var(--radius-chip)}
@media (max-width:760px){
  .agent-specimen,.theme-demo{grid-template-columns:1fr}
  .agent-specimen{min-height:0}
  .demo-view .demo-figure svg{max-height:245px}
  .ascii-sheet pre{font-size:12px}
  .example-tabs{--example-tab-pad:12px}
  .example-tab{font-size:14px;padding:8px var(--example-tab-pad)}
  .source-route code,.revision-diff pre,.theme-rule pre{font-size:12px}
  .section-pane{--gutter:18px}
  .syntax-anatomy{display:flex;flex-direction:column}
  .syntax-specimen{display:contents}
  .syntax-code{order:0}
  .syntax-blocks{order:1}
  .syntax-output{order:2}
  .syntax-code pre{font-size:12px}
  /* The carousel's editor takes the phone's code size too. All three layers at
     once and to the same number — the ink is painted over the input, so a
     mismatch anywhere in the stack slides the highlighting off the text it is
     colouring. Scoped to the carousel: /play is its own page and sizes its
     editor for a screen someone is working on. */
  .showcase-box--source .showcase-slide,
  .showcase-box--source .editor-ink,
  .showcase-box--source .editor-input,
  .showcase-box--source .editor-gutter{font-size:12px}
  .syntax-output .demo-figure svg{max-height:300px}
  /* Stacked, the blocks are no longer the pane's last row — the figure is —
     so the row's own bottom margin is what keeps them off it. */
  .syntax-blocks{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;
    margin-bottom:var(--inset)}
  .syntax-block{padding:14px 16px}
  .syntax-block-head{flex-direction:column;align-items:flex-start;gap:7px}

  /* Centred, like the pair at the foot of the page. Left-aligned they sat
     under a heading that has already wrapped, and read as the last ragged
     line of it rather than as the section's two exits. */
  .cta{justify-content:center}
  .desktop-break{display:none}
}
@media (max-width:430px){
  .demo-step-btn{gap:8px;font-size:13.5px;padding:6px 0}
  .demo-step-num{width:23px;height:23px;font-size:11.5px}
  .demo-step+.demo-step::before{margin:0 8px;min-width:8px}
}
