/* Foundations: the page. Every length is a token or a whole number of
   cells (calc(var(--ds-grid-cell) * N)); the only literals are 0, the
   1px and 2px of rules and rings, and percentages. Figures keep their own sheets in figures/.

   Type: Instrument Sans 16 on a 24 line for every word, 32 on 48 for
   section titles, 14 on 20 in a compact window and in the panes' and
   the Global card's chrome; Geist Mono 15 on the same 24 line for every
   value (its x-height meets the sans's), 14 on 20 beside 14 px words
   (the panes' radios, a compact window's values) and 14 on 16 for the
   Proof key. Two weights, 400 and 500 (a title, the brand, a selected
   control).

   Colour: the system's roles by reference (canvas = page, field =
   inactive, line = stroke, dim = text-dim, ink = text, measure = focus,
   attention only, never at rest), and the lab's own off (off the 4 px
   grid only). At rest the page is ink for what is read (titles, laws,
   the section you are in, a selected control) and dim for the rest.

   One ladder of states on every control: rest is the field ground and
   dim text; hover the same ground and ink text; selected the line
   ground and ink text; focus a 1 px measure ring, inset where a
   neighbour could cover it; lit from elsewhere, measure. A text button
   has no ground: dim, ink under the hand or selected.

   The architecture, three zones with one job each (round 5,
   2026-10-10, the owner's brief, §1: "The canvas in the centre shows
   the live components, and those components are the documentation";
   "The inspector on the right shows only the controls for whatever is
   selected"; "The nav on the left keeps today's sections"; the
   inspector's two tabs of that brief went in round 6, iteration 4):
     nav      every page's (nav.js, nav.css, lib/nav.js; round 6,
              iteration 23): the brand, the bible's sections (nav.js
              window.DSSections, the one list), the lab's pages, then
              Inspect, Export and the Proof grid: bare, no ground, its
              blocks parted by hairlines, fixed at the page's left from
              1200 (288, nav.css --nav-w, the sheet's room for it); a
              sticky bar of the same list below; on a phone the section
              links only;
     canvas   the sections in reading order, each the stage (1056 at
              most, --stage-max): title, the law, one dim line, the
              figure in a frame of the chrome, with its hint line; every
              component once, live, at the page's Density; no tokens in
              the flow;
     inspector the rail at the page's right (384 to 408 by its one sash,
              the margin after its cards; lib/split.js), fixed to the
              window from 960: the Global dock at its head (the page's
              modes and the system's tokens every section reads,
              lib/globals.js), then one column of each section's own
              card, the column following the section in view and every
              card's head sticking (lib/inspector.js; round 6, iteration
              13);
     export   the Export drawer, the system's CSS as one block, standing
              on the inspector's track from 960 and hiding the column
              it covers (lib/export.js);
     foot     the occlusion gradient's band over the window's foot.

   The lab's chrome is one family (the chrome density below): heads of
   48, rows of 32 and 8 apart, 16 in, cards 16 apart; a figure's box on
   the canvas, a card of controls (the panes', the Global card, its
   stubs) the canvas lifted 2 %; the index and the drawer on no ground;
   everything square, hairlined in the line colour, state-swapped, never
   deep (owner, 2026-10-05: "use no rounding at all, just straight
   angles").

   The phone gets only things to play with: every debug or explanatory
   element carries data-chrome="debug" (in the markup, or from the module
   that builds it), and one rule hides them all below 768 (the end of
   this sheet). */

/* below 1200 the sticky bar covers the top 48: a section reached by its
   link, and a control reached by the keys, stops under it. At the foot
   the occlusion band (48, the fade rule below) dissolves what passes
   under the window's edge: a control the keys reach scrolls clear of
   its room (64: the band and a space), and the page ends lower than
   that (.sheet), so the last control can always be scrolled above it.
   The controls column's width is the page's (lib/split.js writes it
   here, so the index and the drawer, fixed boxes, read it too) */
html {
  --foot-room: calc(var(--ds-grid-cell) * 16);
  color-scheme: dark;
  background: var(--ds-color-canvas);
  -webkit-text-size-adjust: 100%;
  /* the nav's bar (nav.css), so a section reached by its link stops
     under it */
  scroll-padding-top: var(--nav-bar-h);
  scroll-padding-bottom: var(--foot-room);
}
/* the page's scheme (round 4, 2026-10-10: "make sure you apply theme
   across page"): the Global card's Scheme writes html[data-scheme]
   (lib/globals.js, and the head's script before the first paint): dark
   by default, light, or the system's; every colour of the page and of
   its windows is a role in light-dark(), so the whole page turns */
html[data-scheme="light"] {
  color-scheme: light;
}
html[data-scheme="system"] {
  color-scheme: light dark;
}
/* ---- a still page (round 4, owner, 2026-10-10: "Remove all animations
        APART stretch bits and bubbles"): every clock of the page is zero,
        so every transition and every scripted tween lands at once (the
        system's reduced-motion path, which every component honours). The
        Slider keeps its whole clock for its stretch and its bubble, one
        clock and one curve for the one gesture (2026-08-22, "One clock,
        one curve"), and its follow share is 0, so its fill, its light and
        its marks land at once; its grip under a finger rides the clock
        with the stretch (components/effects.css) ------------------------ */
:root {
  --ds-motion-clock: 0ms;
  --ds-motion-state: 0ms;
}
.ds-slider {
  --ds-motion-clock: 240ms;
  --ds-motion-follow-share: 0;
}
/* the Dropdown plays too (round 6, iteration 16; owner, iteration 15:
   "Add chevron and its animation from my previous iterations"): its
   list arrives on the follow and the bounce and its chevron's arms
   fold with it, so the whole clock is its own and the follow is said
   again here (a follow said on the root is the root's clock, 0, by the
   time it is inherited); its states still answer at once */
.ds-dropdown {
  --ds-motion-clock: 240ms;
  --ds-motion-follow: calc(
    var(--ds-motion-clock) * var(--ds-motion-follow-share)
  );
}
/* the handles play with the sliders' (round 6, iteration 20; owner,
   2026-10-12: "Make sure all these little handles in sliders (range and
   color) animate in the same way and it's the same as other transitions
   as well"): the colour wheel's handles take the Slider's clock, so
   their light under the hand and their size when chosen move as the
   Range's ends' and a colour channel's mark do; the square picker's
   mark the same. The whole wheel since iteration 24 (its audit: the
   shades' dots, said to arrive from their handle along their ties,
   landed at once here): the dots and ties, the guides of a gesture and
   the handles a gesture leaves aside on the follow, said again from the
   clock (a follow inherited from the root is the root's 0; the legend
   left the grant in iteration 24's refinement, its word no longer
   lighting). Palette hints also use this clock to emerge from behind
   their masked container, like Slider bubbles. The picker's buttons,
   check and channels stay as still as every other on the page */
.ds-picker__wheel,
.ds-picker__tip-mask,
.ds-cpick__mark {
  --ds-motion-clock: 240ms;
}
.ds-picker__wheel {
  --ds-motion-follow: calc(
    var(--ds-motion-clock) * var(--ds-motion-follow-share)
  );
}
/* reduced motion stops these clocks too (the code audit, 2026-10-12:
   re-declared here with no guard, the Slider's stretch and the list's
   arrival still played under it) */
@media (prefers-reduced-motion: reduce) {
  .ds-slider,
  .ds-dropdown,
  .ds-picker__wheel,
  .ds-picker__tip-mask,
  .ds-cpick__mark {
    --ds-motion-clock: 0ms;
  }
}
/* a change of colour (a stroke, a colour edited) lands at once, on every
   box of the page, as the still page's clock says; a change of Scheme is
   the one recolour that plays (round 6, 2026-10-11, owner: "make it so
   colors animate when I toggle modes"): a view transition (lib/core.js
   crossfade), one cross-fade of the whole page on the chrome's clock
   below, not a transition on every element (measured: seven transitions
   on every element froze the page for 380 ms and then snapped). The
   Colour rows' halves ride the same clock (the pane rules). Reduced
   motion zeroes both at the end of this sheet. (The lab's hold of
   html[data-recolour] for one clock of the page's went in iteration 24:
   that clock is 0 here, so it never ran; the components keep their own
   html[data-recolour] rules, the system's behaviour for a page whose
   clock is not 0) */
:root {
  --recolour-clock: var(--chrome-clock);
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--recolour-clock);
  animation-timing-function: var(--ds-motion-ease);
}
/* a part shown live through a fade (lib/globals.js previewScheme: the
   swatches whose halves slide, the popup in the hand): its new picture
   alone, where it stands, never dissolved from its old one (iteration
   21; owner: "theres some ghosting on transition while previewing
   light mode") */
::view-transition-group(*.live),
::view-transition-new(*.live) {
  animation: none;
}
::view-transition-old(*.live) {
  display: none;
}
/* smooth once the page has built (ds.js data-ds-ready): the browser's
   own scroll to a link's section at load lands at once, and is never
   still gliding when the page lands it again (the behaviour audit,
   2026-10-12: under a finger the glide ran past the section's head) */
@media (prefers-reduced-motion: no-preference) {
  html[data-ds-ready] {
    scroll-behavior: smooth;
  }
}
body {
  margin: 0;
  position: relative;
  container-type: inline-size;
  background: var(--ds-color-canvas);
  color: var(--ds-color-ink);
  font-family: var(--ds-font-sans);
  font-size: var(--ds-text-16);
  font-weight: 400;
  line-height: calc(var(--ds-grid-cell) * 6);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
/* the page is a whole number of cells wide, from the page origin; the
   0-3 px left over sits past its right edge (the Proof grid shows it) */
.page {
  --bar-h: var(--nav-bar-h);
  width: round(down, 100cqi, var(--ds-grid-cell));
}
@supports not (width: round(down, 1px, 1px)) {
  .page {
    width: 100%;
  }
}
/* (.sr-only is every page's, nav.css) */
:where(.page, .drawer) :where(button) {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
/* a value inside a line of words: the mono at its own size (15, which
   meets the 16 sans's x-height), dim like its words until attention
   lights it, on a 16 line of its own so the second face never grows the
   line (WebKit would, by half a px) */
.hint b {
  color: inherit;
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-15);
  font-weight: 400;
  line-height: var(--ds-space-16);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- the index: one nav on every page of the lab, its rules in
        nav.css since round 6, iteration 23; the bible keeps what its
        page reads of it ------------------------------------------ */
/* from 1200 the index is a column, no bar over the page: a section
   reached by its link stands its card 48 down, on the line the first
   card, the dock and the nav's brand start on (the section's own 16
   and 32; the refinement of iteration 24, the owner's "refine": a landed
   card stood at 16, off the page's line) */
@media (min-width: 1200px) {
  html {
    scroll-padding-top: calc(var(--ds-grid-cell) * 8);
  }
  .page {
    --bar-h: 0px;
  }
}

/* ---- the sheet: one section per foundation -------------------------
   head over the preview row (the stage and its side); no tokens in the
   flow (they are the drawer's). The side and its sash span the preview
   row only. */
.sheet {
  position: relative;
  min-width: 0;
  overflow-x: clip;
  /* room at the page's end, so its last controls scroll clear of the
     foot band: a module, more than the band's room */
  padding-bottom: calc(var(--ds-grid-cell) * 24);
  /* the page's offset (what is left past its cap, halved), and from
     1200 the nav's column, whose fixed box stands there (nav.css
     --index-w) */
  padding-left: calc(var(--page-x) + var(--index-w));
}
/* the page sits on a 96 module (24 cells): one gutter of 48, a head of
   144 (48 above, the title on 48, 8, the law's 24, 16 below), 48 under
   a section, so title to title is whole modules; a stage at most 960
   (its column 1056 with the gutters). From 960 to 1199 two tracks (the
   stage, the rail's, which the fixed rail stands over); from 1200 three
   (the index's track between them, below). No section holds a column
   of its own since round 3: every section's controls stand under its
   figure, and the tracks past the stage are the index's and the
   rail's */
.sec {
  display: grid;
  /* the canvas's track what the rail leaves, rounded down to the 16
     lattice, as the rail's edge is (round 6, iteration 19; the visual
     audit at 1000: cards of 568 and 584, 16 before them and 33 after) */
  grid-template-columns:
    minmax(
      0,
      min(
        var(--stage-max),
        round(down, 100% - var(--side-w), var(--ds-space-16))
      )
    )
    var(--side-w);
  grid-template-areas: "card .";
  /* 16 above a card and 32 under it, so every card's edge stands on
     the 16 lattice and cards are 48 apart (round 6, iteration 12;
     owner: "make sure containers sit on grid") */
  padding-block: calc(var(--ds-grid-cell) * 4) calc(var(--ds-grid-cell) * 8);
}
/* the card (round 6, iteration 4, 2026-10-11; owner, of the title and
   the law standing outside the frame: "make it more intuitive"): the
   title, the law and the figure in one frame of the lab's chrome, 24
   into the gutter so the words keep the stage's measure; a press
   anywhere on it selects the section (lib/inspector.js), and the
   selected card's hairline is ink; cards 48 apart, the first one's
   title on the index's brand line */
.sec__card {
  grid-area: card;
  min-width: 0;
  /* 16 into the gutter and 32 in (iteration 12: the frame on the 16
     lattice, the words where they were, 48 in) */
  margin-inline: calc(var(--ds-grid-cell) * 4);
  /* the chrome's line, as the page had it (lib/chrome.js): the frame is
     the tool's, its stage the system's (iteration 22's audit: an edit
     of Stroke turned every card's frame) */
  box-shadow: inset 0 0 0 var(--rule) var(--chrome-line, var(--ds-color-line));
}
/* a selected card's edge: the line stepped toward the ink, never the
   ink itself (round 6, iteration 16; owner: "There are weird black lines
   here and there ... fix it holistically": a hairline of the full ink
   read as a stray black line in light) */
.sec[data-selected] > .sec__card {
  box-shadow: inset 0 0 0 var(--rule)
    color-mix(
      in srgb,
      var(--chrome-line, var(--ds-color-line)),
      var(--chrome-ink, var(--ds-color-ink)) 28%
    );
}
.sec__head {
  min-width: 0;
  /* and its pad to the 16 lattice (a law of two lines made it 152,
     lib/lattice.js, iteration 18) */
  padding: calc(var(--ds-grid-cell) * 8) calc(var(--ds-grid-cell) * 8)
    calc(var(--ds-grid-cell) * 4 + var(--lattice-b));
}
.sec__title {
  margin: 0;
  font-size: var(--ds-text-32);
  line-height: calc(var(--ds-grid-cell) * 12);
  font-weight: 500;
  letter-spacing: -0.01em;
}
/* the law: one dim line under the title (desktop; a phone has none) */
.sec__law {
  text-wrap: pretty;
  margin: var(--ds-space-8) 0 0;
  color: var(--ds-color-dim);
}
.sec__stage {
  min-width: 0;
  padding: 0 calc(var(--ds-grid-cell) * 8)
    calc(var(--ds-grid-cell) * 8 + var(--lattice-b));
  container-type: inline-size;
}
/* ---- the Global card's rail (round 3, 2026-10-09) -------------------
   One track at the page's right holds the Global card: the rail, fixed
   to the window from 960, its x the page's rounded width less --side-w
   (on the 1248 line once the window is wider than the page, plus the
   page's offset), as the index and the drawer are placed; the card in
   its scroll box, 48 (the page's gutter) from the window's edge, its
   head on the index's brand line from 1200 (48 down) and 24 under the
   bar below. The scroll box is the column's of round 2: no scrollbar,
   its tail under the foot band (which is the only sign it scrolls; the
   band's room at its foot and in its scroll padding, so a control the
   keys reach stands above the band). A wheel over it scrolls it, not
   the page, until its end; past its end the page (the engines' own
   chaining). A Tab into it never scrolls the page either: lib/split.js
   corrects the engines' own smooth scroll toward a control in a nested
   scroller. Never narrower than the least column (384): while the
   column gives past its least (16 at most), the overflow is its right
   padding, clipped. Below 960 the card stands in the flow after the
   sections (the source's order, the eye's since the refinement of
   iteration 24), on the stage's gutter, the foot band's room under it
   as the sheet keeps above it */
.rail {
  /* the one gap of the column: the dock to the first card (or to the
     chosen token's head, and that head to the first card) as card to
     card, 32 on the 16 lattice (the refinement of iteration 24, the
     owner's "refine": 16 under the dock and 32 between the cards stuck
     the dock to the first card and parted it from the rest) */
  --rail-gap: calc(var(--ds-grid-cell) * 8);
  padding: calc(var(--ds-grid-cell) * 6) calc(var(--ds-grid-cell) * 12)
    var(--foot-room);
}
.side__inner {
  /* the cards' offset parent, so lib/inspector.js reads where a card is
     laid out in the column's own frame, whatever its leave scales */
  position: relative;
  box-sizing: border-box;
  min-width: 0;
}
@media (min-width: 960px) {
  .rail {
    position: fixed;
    top: var(--bar-h);
    bottom: 0;
    /* the Global dock at its head, the column of sections under it
       taking what is left (round 6, iteration 16) */
    display: flex;
    flex-direction: column;
    /* the inspector's track (nav.css --side-x) */
    left: var(--side-x);
    z-index: 10;
    width: var(--side-w);
    padding: 0;
  }
  .side__inner {
    flex: 1 1 auto;
    min-height: 0;
    min-width: calc(var(--ds-grid-cell) * 96);
    /* 32 before the cards (the sash's band; with the canvas card's 16
       margin a gutter of 48 between the columns, round 6, iteration
       10: "add more width to spacing between each column"; iteration
       12: on the 16 lattice), and the margin after them (32, or what
       the right sash set: --rail-margin, lib/split.js) */
    /* under the last card, room for any card to reach the column's
       top when the column follows it (the last pass, 2026-10-11: with
       the foot room alone the last two cards never could): a block the
       column's own height less a head (::after, below: a padding that
       tall would floor the column's height, and since the dock shares
       the rail, iteration 16, the column is shorter than the window);
       the column's own foot dissolves what passes under its edge, as
       the page's band does (the band lies under the rail) */
    /* the column's gap at its top (iteration 18: the lattice under the
       dock's 80, and the line the rows are cut at; 16 until the
       refinement of iteration 24, --rail-gap above) */
    padding: var(--rail-gap) var(--rail-margin) var(--foot-room)
      calc(var(--ds-grid-cell) * 8);
    overflow-x: hidden;
    overflow-y: auto;
    scrollbar-width: none;
    scroll-padding-bottom: var(--foot-room);
    /* a focus walked upward stands clear of a pinned head and its band
       (iteration 22's audit: a radio 3 under the head, 10 dissolved);
       the column's own glide is a scrollTo, which this never moves */
    scroll-padding-top: calc(
      var(--rail-gap) + var(--chrome-head) + var(--chrome-pad)
    );
    /* the rows cut at the content edge, where a card's head pins: the
       16 over it stays empty, so the dock and the pinned head stand
       apart as two cards (round 6, iteration 18) */
    clip-path: inset(var(--rail-gap) 0 0 0);
    /* its foot dissolves what passes under it, as the page's band
       does; its top is the dock's edge, which rows pass under as under
       a toolbar (round 6, iteration 16's follow-up; owner: "content is
       glitching behind heading": a dissolve over the gap above the
       cards showed rows passing above the pinned head). A card on its
       way out leaves before its end reaches its head (.insp__scope
       [data-leaving], below), so nothing is cut at the line (the mask
       of iteration 21 that dissolved a pushed head there went with
       it) */
    --cut-line: var(--rail-gap);
    -webkit-mask-image: linear-gradient(
      to bottom,
      transparent var(--cut-line),
      black var(--cut-line),
      black calc(100% - var(--foot-room)),
      transparent
    );
    mask-image: linear-gradient(
      to bottom,
      transparent var(--cut-line),
      black var(--cut-line),
      black calc(100% - var(--foot-room)),
      transparent
    );
  }
  /* exactly the room the last card needs to reach the column's top,
     whole: the column's own height less the last card's (--last-h,
     lib/inspector.js; round 6, iteration 18: a room of the column less
     a head let the last card scroll on until its head and one row stood
     over empty room). A share of the column's height, so it changes in
     the same layout as the column does (iteration 19, the behaviour
     audit: a room written a frame late let WebKit clamp the column's
     scroll when the dock's drawer closed, 1200 to 1004) */
  .side__inner::after {
    content: "";
    display: block;
    height: max(0px, calc(100% - var(--last-h, var(--chrome-head))));
  }
  /* the dock: on the column's edges (32 before the cards, the margin
     after them), 24 under the bar; the column under it starts a card's
     gap below (its own top padding) */
  .rail .dock {
    flex: none;
    /* most of the rail, the column keeping a third for its cards, on
       the 16 lattice (round 6, iteration 19) */
    max-height: 64%;
    max-height: round(down, 64%, var(--ds-space-16));
    /* 16 under the bar (round 6, iteration 19; the visual audit at
       1000: 24 set the dock and every card 8 off the lattice) */
    margin: var(--ds-space-16) var(--rail-margin) 0
      calc(var(--ds-grid-cell) * 8);
  }
}
@media (min-width: 1200px) {
  /* the dock's head on the index's brand line (48 down) */
  .rail .dock {
    margin-top: calc(var(--ds-grid-cell) * 12);
  }
  /* and the canvas's first card with them: the three columns start on
     one line, 48 down (iteration 21; owner, with a line drawn across
     the nav's brand, the first card and the dock: "make sure to align
     content properly": the card stood 16 down) */
  .sheet > .sec:first-of-type {
    padding-top: calc(var(--ds-grid-cell) * 12);
  }
}
.side__inner::-webkit-scrollbar {
  display: none;
}
/* what a side column holds (the Global card or its stub, Colour's
   squares, then its pane) stands 16 apart, as the pane's cards do; at
   (0,2,0), so a box's own margin: 0 (the colour box's, swatches.css,
   once the column's first) gives way to it under the card */
.rail .side__inner > * + * {
  /* 32 (round 6, iteration 18: on the 16 lattice; 24 left every card
     after the first 8 off it), the column's one gap */
  margin-top: var(--rail-gap);
}
/* a hidden block (the chosen token's, while none is chosen) leaves no
   gap under it, so the first card stands at the column's top, on the
   16 lattice (iteration 12) */
.rail .side__inner > [hidden] + * {
  margin-top: 0;
}
/* the chosen token's head (round 6, iteration 20): between the dock and
   the column, on the column's edges, 16 under the dock; the column under
   it starts its own 16 below (the behaviour audit: at the column's top
   it was scrolled away with the cards, and with it Override locally
   and Clear) */
.rail > .insp__token {
  flex: none;
  margin-top: var(--rail-gap);
  /* and its pad to the 16 lattice (lib/lattice.js; iteration 24's audit:
     the pad was measured and written, and no rule read it, so every card
     under the chosen token stood 4 off the lattice) */
  padding-bottom: var(--lattice-b);
}
@media (min-width: 960px) {
  .rail > .insp__token {
    margin: var(--rail-gap) var(--rail-margin) 0 calc(var(--ds-grid-cell) * 8);
  }
}
.pane-host {
  min-height: calc(var(--ds-grid-cell) * 8);
}
/* a pane with no groups yet (its section's figure comes next) holds
   nothing and takes no room */
.pane-host:empty {
  display: none;
}
.pane-error {
  margin: 0;
  color: var(--ds-color-dim);
}

/* the sizes: two windows of the system side by side, each with its name
   above it in the lab's words (the size and its control height) */
.sizes {
  display: grid;
  /* one window (round 5: at the page's Density, the two sizes side by
     side of 2026-10-05 superseded), 480 at most, the stage where it
     has less */
  grid-template-columns: min(100%, calc(var(--ds-grid-cell) * 120));
  margin-block: calc(var(--ds-grid-cell) * 6);
}
.size {
  display: grid;
  align-content: start;
  row-gap: var(--ds-space-8);
  min-width: 0;
}
/* a try (round 6, iteration 12): the Slider stage holds the window and,
   32 after it, three sliders bare on the card, on the window's rows
   (16 down, as the window's inset puts its own). To drop the try: this
   rule, #slider-bare in the HTML, buildBare in components/slider.js */
#slider-demo {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--ds-grid-cell) * 8);
}
#slider-demo > .size {
  flex: 0 1 calc(var(--ds-grid-cell) * 120);
  max-width: 100%;
}
/* the bare sliders beside the window where the stage holds both (at
   least 192 for them), under it where it does not (the last pass,
   2026-10-11: squeezed beside it, their words were cut) */
#slider-demo > .size--bare {
  flex: 1 1 calc(var(--ds-grid-cell) * 48);
  /* and its pad to the 16 lattice, evenly (lib/lattice.js; the visual
     audit: 120 at Compact) */
  padding-block: calc(var(--ds-space-16) + var(--lattice-t))
    calc(var(--ds-space-16) + var(--lattice-b));
  /* the window's spacing (components/slider.lab.css .slider-demo; round
     6, iteration 18's follow-up, owner, of the two sets on his phone:
     "These both sets of sliders should have the same spacing"): its
     rows the stack's gap apart (the Global tab's Gap), not a fixed 8 */
  row-gap: var(--stack-gap, var(--ds-space-8));
}
/* and under a finger the window's pitch of 48: every bar's hit band is
   48 high about its centre, so no band covers its neighbour's */
@media (pointer: coarse) {
  #slider-demo > .size--bare {
    row-gap: max(
      var(--stack-gap, var(--ds-space-8)),
      calc(var(--ds-grid-cell) * 12 - var(--ds-slider-height))
    );
  }
}
.size--bare .ds-slider {
  width: 100%;
  min-width: 0;
}
/* the dropdowns in a size's window: a stack 8 apart; compact's label
   column 72, as the sliders' */
.dropdown-demo {
  display: grid;
  /* its fields the Panel space apart (components/surface.css) */
  row-gap: var(--stack-gap);
  align-content: start;
  min-width: 0;
}
/* compact by the page's density (html's since round 5), or by a host of
   its own: the label column 72, as the sliders' (iteration 24's audit:
   the rule named the window's own attribute, which no window carries) */
html[data-density="compact"] .dropdown-demo,
[data-density="compact"] > .dropdown-demo {
  --ds-slider-label: calc(var(--ds-grid-cell) * 18);
}
/* the Colour picker's dialog (round 6, components/dialog.js): one, the
   sizes' margin above and below, the stage's width (a dialog fits its
   content; here the picker's rows take the stage) */
.picker-demo {
  min-width: 0;
  /* 32 (iteration 18: the square's dialog on the lattice; 24 set it 8
     off) */
  margin-block: calc(var(--ds-grid-cell) * 8);
}
.picker-demo > .ds-dialog {
  width: 100%;
}
/* the square picker's dialog (iteration 15) fits its content, the
   compact picker's own width */
.picker-demo--fit > .ds-dialog {
  width: fit-content;
  max-width: 100%;
}
/* a finger: every field's hit band is 48 high about its centre
   (components/dropdown.css), so the stack's pitch is 48 */
@media (pointer: coarse) {
  .dropdown-demo {
    row-gap: max(
      var(--stack-gap),
      calc(
        var(--ds-grid-cell) * 12 - var(--control, calc(var(--ds-grid-cell) * 8))
      )
    );
  }
}

/* ---- the Global card: the controls every section reads, one card of
        the lab's chrome in flow at the head of ONE controls column, its
        seat (lib/globals.js). Supersedes the floating menu of 2026-10-05
        ("a floating menu sticky to the edges"; its "They should affect
        all the elements" stands): nothing floats, nothing covers a
        control, nothing moves on scroll ---------------------------------
   The column's width (352 in the least column), the canvas lifted 2 %,
   a hairline; a head of 48 (the glyph, the title that folds it, Reset
   and the chevron as 32-boxes in the action column, the chevron last, 8
   from the edge; interaction.md: "the label at the row labels' inset,
   the chevron in the action column"), a hair of line under it; its
   groups below as sections of the one card, a hair of line between
   them, their heads 48, their rows 32 and 8 apart, 16 in, the label
   column 112. The fold rides the pane folders' clock: the body's
   height and opacity on the clock (lib/globals.js writes the height),
   its visibility flipping at the clock's end, so a folded card's rows
   leave the Tab order and nothing is display: none mid-flight */
.globals {
  box-sizing: border-box;
  /* the lift as a veil of the ink over whatever lies under the card,
     the proof grid among it (round 6, iteration 12; owner: "add subtle
     transparency for containers") */
  background: color-mix(in srgb, var(--ds-color-ink) 3%, transparent);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
.globals .pane-host {
  max-width: none;
}
.globals__bar {
  position: relative;
  display: flex;
  align-items: stretch;
  height: var(--chrome-head);
  box-shadow: inset 0 calc(var(--rule) * -1) 0 var(--ds-color-line);
}
.globals__reset {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: calc(var(--ds-grid-cell) * 8);
  height: calc(var(--ds-grid-cell) * 8);
}
/* Reset: the action column's box, 8 from the edge (the fold and its
   chevron went with the inspector's tabs, round 5) */
.globals__reset {
  position: absolute;
  top: calc((var(--chrome-head) - var(--ds-grid-cell) * 8) / 2);
  right: var(--ds-space-8);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--ds-color-dim);
  cursor: pointer;
}
.globals__icon {
  display: flex;
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: var(--ds-color-dim);
}
.globals__icon svg {
  width: 100%;
  height: 100%;
}
/* under the hand the chrome's rung: the icon in ink (the title is ink
   already); nothing rounded, no box */
@media (hover: hover) {
  .globals__reset:hover,
  .globals__reset:hover .globals__icon {
    color: var(--ds-color-ink);
  }
}
.globals__reset:focus-visible {
  outline: none;
}
html[data-kbd] .globals__reset:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
/* ---- the Global dock (round 6, iteration 16, 2026-10-11; owner: "it
        would be nice to always have access to global settings ... dock
        the global controls"): the Global card pinned at the inspector's
        head (lib/globals.js), its head, a row of tabs, and the drawer
        holding the open tab's group. The card's lift and hairline are
        the .globals card's; the drawer opens as the dropdown's flow does
        (its one track from 0fr to 1fr) on the chrome's clock, and
        scrolls inside where the group is taller than the dock's room
        (most of the rail: the column of sections keeps a share) ------- */
.dock {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.dock > .globals__bar {
  flex: none;
}
/* the tabs: one per group, words in the chrome's small type, dim and
   in ink under the hand or open; a mark of ink at the row's foot under
   the open tab, gliding between tabs on the chrome's clock */
.dock__tabs {
  position: relative;
  flex: none;
  /* five equal cells across the dock (64 at its 320), the row's own
     width read by the names (below) */
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  padding-inline: 0;
  container-type: inline-size;
  box-shadow: inset 0 calc(var(--rule) * -1) 0 var(--ds-color-line);
}
.dock__tab {
  display: flex;
  align-items: center;
  justify-content: center;
  /* its group's glyph and its name on one line, in a row of 32 (round
     6, iteration 18; owner: "add icons to tabs", then "Put icons in
     tabs in same line. Make it rather compact"): the dock's head and
     tabs 80 on the lattice. Glyph and name for all five need 292 of the
     dock's 320 and stood 6 apart, so the open tab names itself and the
     others show their glyph (their name under the hand, as a tooltip,
     and to a reader); a dock of 400 or more names them all */
  height: calc(var(--ds-grid-cell) * 8);
  min-width: 0;
  padding: 0;
  overflow: hidden;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  white-space: nowrap;
  /* its ink swaps at once, as every state's colour of the chrome
     (nav.css: a state change is never a fade; iteration 24's audit: a
     quarter of the clock here, 320 ms on the nav's glyphs, none on the
     heads); the mark and the name below move on the clock */
}
.dock__tab[aria-expanded="true"] {
  color: var(--ds-color-ink);
}
.dock__tab > .pane__glyph {
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: inherit;
}
/* the name opens out of its glyph's side as its tab opens, inside its
   own cell, so no other tab moves, on the chrome's clock and curve with
   the mark; it fades in on half the clock */
.dock__word {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 0;
  margin-left: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transition:
    max-width var(--chrome-clock) var(--chrome-ease),
    margin-left var(--chrome-clock) var(--chrome-ease),
    opacity calc(var(--chrome-clock) / 2) linear;
}
.dock__tab[aria-expanded="true"] .dock__word {
  max-width: calc(var(--ds-grid-cell) * 14);
  margin-left: var(--ds-space-4);
  opacity: 1;
}
@container (min-width: 400px) {
  .dock__word {
    max-width: calc(var(--ds-grid-cell) * 14);
    margin-left: var(--ds-space-4);
    opacity: 1;
  }
}

@media (hover: hover) {
  .dock__tab:hover {
    color: var(--ds-color-ink);
  }
}
.dock__tab:focus-visible {
  outline: none;
}
html[data-kbd] .dock__tab:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.dock__mark {
  position: absolute;
  bottom: 0;
  left: 0;
  width: var(--w, 0px);
  height: 2px;
  border-radius: 1px;
  background: var(--ds-color-ink);
  transform: translateX(var(--x, 0px));
  opacity: 0;
  transition:
    transform var(--chrome-clock) var(--chrome-ease),
    width var(--chrome-clock) var(--chrome-ease),
    opacity calc(var(--chrome-clock) / 2) linear;
  pointer-events: none;
}
.dock__mark[data-on] {
  opacity: 1;
}
/* the drawer: one track holding the open group, nothing tall while
   closed; its height glides on the chrome's clock between the heights
   it shows, measured (lib/globals.js resize), so the group inside
   keeps its layout while the drawer opens, closes or changes group;
   inside, the group scrolls where it is taller than the dock's room */
.dock__drawer {
  display: grid;
  flex: 0 1 auto;
  min-height: 0;
  grid-template-rows: minmax(0, 1fr);
}
.dock:not([data-open]) .dock__drawer {
  height: 0;
}
.dock__clip {
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* no bar (the column's way): its edges dissolve what passes under
     them instead, over the group's own room at either end (16), so a
     group that fits is never dimmed and one that scrolls is never cut
     through its words */
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent,
    black var(--chrome-pad),
    black calc(100% - var(--chrome-pad)),
    transparent
  );
  mask-image: linear-gradient(
    to bottom,
    transparent,
    black var(--chrome-pad),
    black calc(100% - var(--chrome-pad)),
    transparent
  );
}
.dock__clip::-webkit-scrollbar {
  display: none;
}
/* a colour's swatch cut at the foot keeps out of the dissolve, its
   column whole to the edge (lib/globals.js peek: faded, a swatch read
   as a gradient it is not) */
.dock__clip[data-keep] {
  -webkit-mask-image:
    linear-gradient(
      to bottom,
      transparent,
      black var(--chrome-pad),
      black calc(100% - var(--chrome-pad)),
      transparent
    ),
    linear-gradient(black, black);
  mask-image:
    linear-gradient(
      to bottom,
      transparent,
      black var(--chrome-pad),
      black calc(100% - var(--chrome-pad)),
      transparent
    ),
    linear-gradient(black, black);
  -webkit-mask-position:
    0 0,
    var(--keep-x) 0;
  mask-position:
    0 0,
    var(--keep-x) 0;
  -webkit-mask-size:
    100% 100%,
    var(--keep-w) 100%;
  mask-size:
    100% 100%,
    var(--keep-w) 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
/* a list opened in the drawer is brought into view clear of its edges'
   dissolves (lib/panes.js; iteration 22's audit: at 1440 by 420 the
   Family list's hairline and chosen row stood under the top's) */
.dock__clip .ds-dropdown__list {
  scroll-margin-block: var(--chrome-pad);
}
/* the open group padded at its foot to the 16 lattice (lib/lattice.js,
   iteration 19): its first row 16 under the tabs on every tab, so
   nothing moves under a row of tabs that stands still (the review of
   iteration 24's refinement: the pad shared between head and foot put
   the first row 20 under the tabs on four tabs and 16 on Shape), and its
   foot 16 and what the lattice leaves over, 16 to 28 (the rows' pitch of
   44 is off the 16) */
.dock .pane-host .tp-fldv {
  padding-bottom: var(--lattice-b);
}
/* the open group alone, whole, its own head gone (its tab names it) */
.dock .pane-host .tp-fldv:not([data-shown]) {
  display: none;
}
.dock .pane-host .tp-fldv > .tp-fldv_b {
  display: none;
}
.dock .pane-host .tp-fldv.tp-fldv-expanded > .tp-fldv_c {
  padding-top: var(--chrome-pad);
}
/* the card's groups: sections of the one card, no card of their own */
.globals .pane-host .tp-fldv {
  background: none;
  box-shadow: none;
}
.globals .pane-host {
  --chrome-card-gap: 0px;
}
.globals .pane-host .tp-rotv_c > .tp-fldv + .tp-fldv {
  box-shadow: inset 0 var(--rule) 0 var(--ds-color-line);
}
/* the label column 112 (28 cells: "Window corner" is 99 at 14 and a
   column of 100 cut it); a slider row's words the same, less the
   Slider's gap, so its bar starts where every row's value does */
.globals .pane-host .tp-rotv {
  --tp-blade-value-width: calc(100% - calc(var(--ds-grid-cell) * 28));
}
.globals .pane-host .pane-slider > .ds-slider[data-label][data-value] {
  grid-template-columns:
    calc(var(--ds-grid-cell) * 26) minmax(0, 1fr)
    var(--ds-slider-value);
}
/* a finger: the head's box 48 */
@media (pointer: coarse) {
  .globals__reset {
    top: 0;
    right: 0;
    width: calc(var(--ds-grid-cell) * 12);
    height: calc(var(--ds-grid-cell) * 12);
  }
}

/* ---- the inspector (round 5, 2026-10-10, the brief's §1; its two
        tabs went in round 6, iteration 4, their rules in iteration
        22): the Global card docked at the rail's head, the chosen
        token's breadcrumb under it, then one card a section. A firm
        selection (a press on a figure) draws its frame's hairline in
        ink ---------------------------------------------------------- */
/* a section's head in the one column (round 6, iteration 4): the
   card's bar with a hairline above it too, parting it from the groups
   before it; its name dim until its section is in view (ink), its
   word saying In view or Selected; a firm selection draws two rules of
   ink at its left edge */
/* round 6, iteration 10: each section's controls a card of their own
   (.insp__scope), its head the card's bar; the section's name dim until
   it is in view, and a firm selection inks the card's hairline, as it
   inks the section's card on the canvas (one sign for one state) */
.insp__head .scope__name {
  color: var(--ds-color-dim);
  transition: color var(--ds-motion-state) linear;
}
.insp__head[data-current] .scope__name {
  color: var(--ds-color-ink);
}
.insp__scope:has(> .insp__head[data-firm]) {
  box-shadow: inset 0 0 0 var(--rule) var(--line-strong);
}
/* a card of the column padded at its foot to the 16 lattice
   (lib/lattice.js, iteration 18) */
.rail .insp__scope {
  padding-bottom: var(--lattice-b);
}
/* the connection, since round 6, iteration 13 (owner: "Rethink this
   attachment/node stuff. use other logic to indicate connection,
   perhaps just sticky behaviour can be enough"): the column follows
   the canvas (lib/inspector.js: the section in view has its card
   scrolled to the column's top, smoothly, unless the hand is on the
   column), and the current card's head sticks to the column's top while its
   groups scroll under it, so the name at the top of the inspector is
   always the name of what the controls below belong to; a press still
   inks both cards. The wire of iteration 5 is archived
   (archive/2026-10-11-wire). The head's ground is the card's lift
   made opaque, so the rows pass under it.
   Every card's head sticks, within its own card (the behaviour audit,
   2026-10-12: the current card's alone did, so at a section change the
   old card's rows stood under the dock with no head while the column
   glided, and for as long as the hand kept the column): a card's rows
   are always under their own name, and the next card's head takes the
   top as its card arrives, as a list's section heads do */
.rail .insp__head {
  position: sticky;
  /* pinned at the column's content edge, its gap under the dock, the rows
     cut at that line (.side__inner's clip, below), so a pinned head is
     its card's top and never one of the dock's rows (round 6, iteration
     18; owner: "Sticky and layout gotten better but it has weird
     behavior when I scroll": pinned flush, iteration 17, a head read as
     the dock's last row, and one its card pushed out was cut by the
     dock's edge through its words). Its card leaves before its end can
     push it out (.insp__scope[data-leaving], below), so it never shows
     as half a name (iteration 24's audit: the words' fade as the end
     pushed it styled a head already gone). Its sides drawn with its
     card's hairline, which its ground covers while it is pinned */
  top: 0;
  z-index: 2;
  background: color-mix(
    in srgb,
    var(--ds-color-ink) 3%,
    var(--ds-color-canvas)
  );
  /* its card's lines all round, which its ground covers */
  --head-line: var(--ds-color-line);
  box-shadow: inset 0 0 0 var(--rule) var(--head-line);
}
/* the rows its card scrolls under it dissolve below it, never cut at
   its edge: a band of the card's ground under a pinned head, while its
   card's rows pass under it (data-stuck, lib/inspector.js), inside the
   card's side lines; it leaves with the head (iteration 21; owner, of a
   row's sliver under the Slider card's head: "add our overflow
   gradient in this cases as well") */
.rail .insp__head::after {
  content: "";
  position: absolute;
  top: 100%;
  right: var(--rule);
  left: var(--rule);
  height: var(--chrome-pad);
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--ds-color-ink) 3%, var(--ds-color-canvas)),
    transparent
  );
  opacity: 0;
  pointer-events: none;
}
.rail .insp__head[data-stuck]::after {
  opacity: 1;
}
/* a card leaving the column's top (round 6, iteration 23; owner, of a
   pinned head over a sliver of its last row: "make it so this card
   animates as it approaches limit, scales down and disappears instead of
   glitch out"): over the last head's height of its rows under its pinned
   head it scales down into its head's top, where it is pinned, and fades,
   with the scroll (lib/inspector.js --leave, 0 to 1, and --leave-top),
   so it is gone before its end can push its head out; gone, it takes no
   hand. Under reduced motion it fades in place */
.rail .insp__scope[data-leaving] {
  transform-origin: 50% var(--leave-top, 0px);
  scale: calc(1 - var(--leave, 0) * 0.08);
  opacity: calc(1 - var(--leave, 0));
  /* nothing of it above its head's top (its rows scrolled past, which
     the scale would bring down past the column's cut line) */
  clip-path: inset(var(--leave-top, 0px) 0 0 0);
}
.rail .insp__scope[data-gone] {
  visibility: hidden;
}
@media (prefers-reduced-motion: reduce) {
  .rail .insp__scope[data-leaving] {
    scale: none;
  }
}
.insp__scope:has(> .insp__head[data-firm]) > .insp__head {
  --head-line: var(--line-strong);
}
/* below 960 the rail is in the flow and the sticky bar covers the
   window's top: the head pins under the bar (the last pass, 2026-10-11) */
@media (max-width: 959px) {
  .rail .insp__head {
    top: var(--bar-h);
  }
}
.globals__bar > .scope {
  flex: 1 1 auto;
  min-width: 0;
  padding-left: var(--chrome-pad);
  padding-right: calc(var(--ds-grid-cell) * 10);
}
.crumb__sep {
  color: var(--ds-color-dim);
}
.crumb__sep[hidden] {
  display: none;
}
.crumb__token {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.crumb__token--mono {
  font-family: var(--ds-font-mono);
}
.crumb__head {
  padding: var(--ds-space-8) var(--chrome-pad) 0;
}
.crumb__head[hidden] {
  display: none;
}
.crumb__uses {
  margin: 0;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
/* a firm selection draws its card's hairline in ink (the card rule,
   above) */

/* ---- the preview: the figure, then its one hint line --------------- */
.preview {
  min-width: 0;
  margin: 0;
}
/* ---- a section's container (round 4, owner, 2026-10-10: "add more
        structure to containers of the contents"): past a phone the
        stage is one frame of the lab's chrome (square, a hairline) on
        the page's canvas, holding the figure and its hint. The
        section's own controls stood under it on a lifted ground until
        round 5 moved them into the inspector (the brief's §1; its card
        a section's since round 6); the frame stays, and a firm
        selection draws its hairline stepped to the ink ------------------ */
@media (min-width: 768px) {
  /* the frame is the card's (round 6, iteration 4): the figure stands
     in it on the card's inset, its first window on no margin of its
     own */
  .sec__stage > .preview {
    margin: 0;
    padding: 0;
  }
  .sec__stage > .preview > :first-child {
    margin-top: 0;
  }
}
/* the reach of a block of controls: "Local" in the ink, the section's
   name dim, on a head of 48 (the Global card's); a card's heading (an
   h2 since iteration 22: a reader's list of headings had none of the
   inspector's cards) */
.scope {
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  height: var(--chrome-head);
  margin: 0;
  font-size: var(--ds-text-14);
  font-weight: inherit;
  line-height: calc(var(--ds-grid-cell) * 5);
}
/* a scope's name at the text size, over the groups' 14 (round 6,
   iteration 10: the ladder of the column, a card a scope, a fold a
   group, a row a control) */
.scope__name {
  color: var(--ds-color-ink);
  font-size: var(--ds-text-16);
  font-weight: 500;
}
.scope__what {
  color: var(--ds-color-dim);
}
/* a section's glyph before its name in the inspector, the nav's own
   (round 6, iteration 16: the same mark for the same section in the
   index, on the canvas's selection and over its controls), dim until
   its section is in view */
.scope__glyph {
  display: flex;
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: var(--ds-color-dim);
}
.scope__glyph svg {
  width: 100%;
  height: 100%;
}
.insp__head[data-current] .scope__glyph {
  color: var(--ds-color-ink);
}
/* the Shape group's figure (lib/globals.js nestFigure): the corners the
   one nesting rule derives, drawn at their size from the same tokens the
   surfaces read: a window (its inset the Window space) around a panel
   (its inset the Panel space) around a control (32 high), and a window
   around a control; each box's corner the base plus the insets it
   holds. Under each, its corners in px, outermost first, the mono's
   values in the ink */
.pane-host [data-figure] {
  padding: var(--ds-space-8) var(--chrome-pad) var(--ds-space-16);
}
/* in the Global dock a figure stands on the rows' own edges, the row
   gap above it as above any row and nothing of its own below, so the
   group's foot is its one inset (the critique of iteration 24: inset 16
   on both sides, off the lattice's edges, and 40 to 44 under its ink
   against the 16 over the first row) */
.dock .pane-host [data-figure] {
  padding: 0;
}
.dock .pane-host .tp-fldv_c > [data-figure]:not(.tp-v-fst) {
  margin-top: var(--tp-container-unit-spacing);
}
/* ---- the Button states card (panes/states.js; round 6, iteration 16,
        2026-10-11; owner: "This entire Button States is too complicated
        for what it does. Make it way simpler, minimal, compact yet
        still make it very clear what is what"): no groups, three rows
        and a ladder, the card's own inset round them and the rows a
        chrome gap apart. Shows: the three switches as compact chips
        where every row's value starts. The ladder: a grid of six lines
        under three column heads (Fill, Text, Edge), each line a
        specimen painted by its state's own tokens, the state's name,
        then only what the state owns; a line under the hand, lit by a
        token or chosen on the canvas takes the lifted ground and its
        name the ink. Every line shares the grid's columns (subgrid; the
        gap on the grid itself) ------------------------------------- */
#pane-states .tp-rotv_c {
  display: grid;
  row-gap: var(--chrome-gap);
  padding: var(--pane-pad);
}
#pane-states [data-figure] {
  padding: 0;
}
/* Shows: three check buttons across the card, the stack's gap apart */
.shows {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--stack-gap, var(--ds-space-8));
}
.shows > .ds-check-button {
  min-width: 0;
}
.ladder {
  display: grid;
  /* the specimen 40, the name 64 ("Disabled" whole), three columns of
     28 (a swatch of the control's 24 and room for its head's word), the
     weight what is left; 4 apart, the name 4 further in */
  grid-template-columns:
    calc(var(--ds-grid-cell) * 10) calc(var(--ds-grid-cell) * 16)
    repeat(3, calc(var(--ds-grid-cell) * 7))
    minmax(0, 1fr);
  column-gap: var(--ds-space-4);
  margin-top: var(--ds-space-8);
}
.ladder__name,
.ladder__head--state {
  padding-left: var(--ds-space-4);
}
.ladder__line {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: center;
  min-height: calc(var(--ds-grid-cell) * 8);
  margin-inline: calc(var(--ds-space-4) * -1);
  padding-inline: var(--ds-space-4);
  border-radius: var(--ds-radius-corner);
}
.ladder__line[data-lit],
.ladder__line[data-chosen] {
  background: color-mix(in srgb, var(--ds-color-ink) 5%, transparent);
}
@media (hover: hover) {
  .ladder__line:not(.ladder__heads):hover {
    background: color-mix(in srgb, var(--ds-color-ink) 4%, transparent);
  }
}
.ladder__heads {
  min-height: calc(var(--ds-grid-cell) * 6);
}
.ladder__head {
  justify-self: center;
  color: var(--ds-color-dim);
  font-size: calc(var(--ds-grid-cell) * 3);
  line-height: var(--ds-space-16);
  white-space: nowrap;
}
/* the heads' words centred over the swatch (the control's square at
   its column's start), spilling past it either side */
.ladder__head:not(.ladder__head--state) {
  display: flex;
  justify-content: center;
  justify-self: start;
  width: var(--control, calc(var(--ds-grid-cell) * 6));
  min-width: 0;
  overflow: visible;
}
.ladder__head--state {
  grid-column: 1 / 3;
  justify-self: start;
  padding-left: 0;
}
/* the weight's head over its slider's start, as the bars it heads (the
   visual audit, 2026-10-12: centred on a swatch's square it spilled
   into Edge's and read "EdgeWeight") */
.ladder__head.ladder__head--weight {
  justify-content: flex-start;
  width: auto;
}
/* the specimen: a button of 40 by 24 in the compact type, its rung the
   state's own tokens (components/button.css paints the canvas's the
   same way), the words "Aa" */
.ladder__spec {
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: calc(var(--ds-grid-cell) * 10);
  height: calc(var(--ds-grid-cell) * 6);
  border-radius: min(var(--ds-radius-corner), calc(var(--ds-grid-cell) * 3));
  background: var(--ds-color-inactive);
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
  color: var(--ds-color-text);
  font-size: var(--ds-text-14);
  line-height: 1;
}
.ladder__spec[data-state="hover"] {
  background: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--ds-state-hover)
  );
  box-shadow: inset 0 0 0 var(--hover-edge-w) var(--ds-state-hover-edge);
  color: var(--ds-state-hover-text);
}
.ladder__spec[data-state="held"] {
  background: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--ds-state-held)
  );
  box-shadow: inset 0 0 0 var(--held-edge-w) var(--ds-state-held-edge);
  color: var(--ds-state-held-text);
}
.ladder__spec[data-state="active"] {
  background: var(--ds-color-active);
  box-shadow: inset 0 0 0 var(--stroke-active-w) var(--ds-stroke-active);
  color: var(--ds-color-page);
}
.ladder__spec[data-state="focus"] {
  outline: var(--focus-ring-w) solid var(--ds-color-focus);
  outline-offset: var(--focus-ring-gap);
}
.ladder__spec[data-state="disabled"] {
  color: var(--ds-color-text-dim);
}
.ladder__name {
  min-width: 0;
  overflow: hidden;
  color: var(--ds-color-dim);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.ladder__line[data-lit] .ladder__name,
.ladder__line[data-chosen] .ladder__name {
  color: var(--ds-color-ink);
}
@media (hover: hover) {
  .ladder__line:hover .ladder__name {
    color: var(--ds-color-ink);
  }
}
/* a swatch at its column's start, so the swatches stand 8 apart, on
   the bars' left edge and 8 from the weight (round 6, iteration 17's
   review: centred in a cell of 28 they sat 2 off) */
.ladder__cell {
  display: flex;
  justify-content: flex-start;
}
/* a swatch: the role's value the Scheme shows, the control's square,
   its corner the control's, a hairline of the line inside so a value
   near the ground still has an edge */
.ladder__swatch {
  position: relative;
  box-sizing: border-box;
  width: var(--control, calc(var(--ds-grid-cell) * 6));
  height: var(--control, calc(var(--ds-grid-cell) * 6));
  border-radius: var(--control-corner, var(--ds-radius-corner));
  background: var(--c);
  box-shadow: inset 0 0 0 var(--rule) var(--colour-hair);
  cursor: pointer;
}
.ladder__swatch:focus-visible {
  outline: none;
}
html[data-kbd] .ladder__swatch:focus-visible {
  outline: 1px solid var(--ds-color-measure);
  outline-offset: 2px;
}
/* the tint, across the three columns and the weight's; the weight in
   its own: each a compact Slider with its value inside, its words the
   line's name (the label a reader's alone) */
.ladder__tint {
  grid-column: 3 / -1;
  min-width: 0;
}
.ladder__weight {
  grid-column: 6;
  min-width: 0;
}
/* a rung's More (round 6, iteration 21; owner: "hidden in more
   advanced (integrate it neatly)"): the state's name a fold, its words
   and the system's folding chevron, which turns as a group's does; the
   panel under the line, its rows a word under the names and a control
   from the Fill column on */
/* its words dim as every state's name (.ladder__name), in the ink only
   where the line is lit or chosen: the chevron alone says it folds (the
   critique of iteration 24: Hover and Held stood in the ink at rest,
   the colour that says chosen in the same card) */
.ladder__fold {
  display: flex;
  align-items: center;
  gap: var(--ds-space-4);
  min-width: 0;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  line-height: inherit;
  text-align: left;
  cursor: pointer;
}
.ladder__fold:focus-visible {
  outline: none;
}
html[data-kbd] .ladder__fold:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.ladder__chev {
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: var(--ds-color-dim);
}
.ladder__chev line {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--chrome-clock) var(--ds-motion-bounce);
}
.ladder__fold[aria-expanded="true"] .ladder__chev line[data-arm="left"] {
  transform: rotate(-90deg);
}
.ladder__fold[aria-expanded="true"] .ladder__chev line[data-arm="right"] {
  transform: rotate(90deg);
}
.ladder__more {
  grid-column: 1 / -1;
  box-sizing: border-box;
  min-height: 0;
}
.ladder__morebody {
  box-sizing: border-box;
  display: grid;
  row-gap: var(--ds-space-4);
  padding-block: var(--ds-space-4) var(--ds-space-8);
}
.ladder__more[hidden] {
  display: none;
}
.ladder__more[data-moving] {
  overflow: clip;
}
.ladder__morerow {
  display: grid;
  /* the word under the states' names (the specimen's 40, the gap, the
     name's own 4 in), the control from the Fill column on */
  grid-template-columns: calc(var(--ds-grid-cell) * 27) minmax(0, 1fr);
  align-items: center;
}
.ladder__morename {
  padding-left: calc(var(--ds-grid-cell) * 12);
  color: var(--ds-color-dim);
}
.ladder__more .ds-dropdown {
  grid-template-columns: minmax(0, 1fr);
}
/* a role's colour: one square, not a strip of five */
.ladder__more .ds-dropdown__strip {
  flex: none;
  grid-template-columns: minmax(0, 1fr);
  width: var(--ds-space-16);
}
.ladder__more .ds-dropdown__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ladder .ds-slider[data-label="beside"] {
  grid-template-columns: minmax(0, 1fr);
}
.ladder .ds-slider__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
@media (forced-colors: active) {
  .ladder__line[data-chosen],
  .ladder__line[data-lit] {
    outline: 1px solid Highlight;
    outline-offset: -1px;
  }
  .ladder__swatch,
  .ladder__spec {
    forced-color-adjust: none;
  }
  /* the dock's open tab and the rail's thumb draw with grounds the
     system drops: an outline and the system's text instead */
  .dock__tab[aria-expanded="true"] {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
}
/* the two cases on one grid, their boxes on a row of their own standing
   on its foot and their numbers on the next, so both legends start on
   one line (the critique of iteration 24: "Window 28" and "Window 20"
   stood 16 apart, each under its own box) */
.nest {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: auto auto;
  column-gap: var(--ds-space-16);
  row-gap: var(--ds-space-8);
}
.nest__case {
  display: grid;
  grid-row: 1 / span 2;
  grid-template-rows: subgrid;
  min-width: 0;
}
.nest__case > .nest__box {
  align-self: end;
}
.nest__box {
  box-sizing: border-box;
  min-width: 0;
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
}
.nest__win {
  padding: var(--ds-space-window);
  border-radius: calc(var(--ds-radius-corner) + var(--ds-space-window));
}
.nest__win--panels {
  border-radius: calc(
    var(--ds-radius-corner) + var(--ds-space-panel) + var(--ds-space-window)
  );
}
.nest__panel {
  padding: var(--ds-space-panel);
  border-radius: calc(var(--ds-radius-corner) + var(--ds-space-panel));
  background: color-mix(in srgb, var(--ds-color-text) 4%, transparent);
}
.nest__ctl {
  /* the page's control (a specimen: lib/chrome.js hands it the page's
     --control, 24 at Compact), its corner at most its half, as every
     control's (components/surface.css --control-corner); the numbers
     are read from it (lib/globals.js sayNest) */
  height: var(--control, calc(var(--ds-grid-cell) * 8));
  border-radius: min(
    var(--ds-radius-corner),
    var(--control, calc(var(--ds-grid-cell) * 8)) / 2
  );
  background: var(--ds-color-inactive);
}
/* the icon presets in their slots (lib/globals.js iconsFigure; owner,
   2026-10-14: "make it so user can set up how big icons sit in our slot
   across our entire UI"): standing under the Icons row on its own
   columns (lib/panes.js alignUnder writes the row's template, width and
   gap on the cells, so each case stands under its cell to the pixel),
   the slot's size at the label's column. Each case
   is the system's slot (a Button of its icon slot alone, components/
   button.css: a square of the page's control, its glyph at the slots'
   rule, components/surface.css --icon) at its preset, the glyph's box
   in a bubble, the preset in use bright. A specimen (lib/chrome.js):
   the page's tokens as edited, the chrome around it keeping its own;
   hover or focus reads its size */
.pane-host [data-figure][data-under-row] {
  padding-inline: 0;
}
.slots {
  display: grid;
  grid-template-columns:
    calc(100% - var(--tp-blade-value-width))
    minmax(0, 1fr);
}
/* a row wrapped under its label: its cells across the card, and so the
   cases; the words beside them go */
.slots[data-wide] {
  grid-template-columns: 0 minmax(0, 1fr);
}
.slots[data-wide] .slots__keys {
  visibility: hidden;
}
.slots__keys,
.slots__cells {
  display: grid;
  align-items: center;
  min-width: 0;
}
.slots__cells {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-flow: column;
  justify-items: center;
}
.slots__case {
  position: relative;
  display: grid;
  justify-items: center;
}
.slots__slot {
  opacity: var(--ds-state-recede);
  transition: opacity var(--ds-motion-state) var(--ds-motion-state-ease);
}
.slots__case[data-live] .slots__slot {
  opacity: 1;
}
.slots__tip {
  position: absolute;
  bottom: calc(100% + var(--ds-space-4));
  z-index: 3;
  padding: var(--ds-space-4) var(--ds-space-8);
  border-radius: var(--control-corner, var(--ds-radius-corner));
  background: var(--ds-color-page);
  color: var(--ds-color-text);
  box-shadow: inset 0 0 0 var(--rule) var(--colour-hair);
  font: var(--ds-text-14) / calc(var(--ds-grid-cell) * 5) var(--ds-font-mono);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--ds-motion-state) var(--ds-motion-state-ease);
}
.slots__case:not([data-tip-dismissed]):is(:hover, :focus-within) .slots__tip {
  opacity: 1;
  visibility: visible;
  transition-delay: var(--ds-motion-clock);
}
.slots__case[data-preset="small"] {
  --ds-icon-scale: var(--ds-icon-small);
}
.slots__case[data-preset="medium"] {
  --ds-icon-scale: var(--ds-icon-medium);
}
.slots__case[data-preset="large"] {
  --ds-icon-scale: var(--ds-icon-large);
}
.slots__key {
  overflow: hidden;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.slots__key b {
  font-family: var(--ds-font-mono);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.slots__key b {
  color: var(--ds-color-ink);
}
/* one line a level, outermost first: its name, its corner at the end */
/* its lines from the shared first line down, each on the legend's own
   pitch, never shared out over the taller case's row (the review of
   iteration 24's refinement: a legend of two lines beside one of three
   stood 30 apart) */
.nest__nums {
  display: grid;
  align-content: start;
  margin: 0;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  white-space: nowrap;
}
.nest__nums > span {
  display: flex;
  justify-content: space-between;
  gap: var(--ds-space-8);
}
.nest__nums b {
  color: var(--ds-color-ink);
  font-family: var(--ds-font-mono);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.preview__foot {
  margin-top: calc(var(--ds-grid-cell) * 6);
}
/* what the hand can do (or, under attention, what it is on), in the
   sans, values in the mono, across the hint's whole measure; the line
   keeps the height of the longest message it can show (lib/core.js
   reserveHint), so lighting a part never moves the controls under the
   hand */
.hint {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  min-height: calc(var(--ds-grid-cell) * 6);
  color: var(--ds-color-dim);
}
.hint__live {
  min-width: 0;
  /* a wrapped line never leaves a word alone */
  text-wrap: pretty;
}

/* a text button: no ground; dim, ink under the hand (the inspector's
   Clear beside Override locally, lib/inspector.js; the drawer's Copy
   CSS is its kin, nav.css .drawer__copy, since the Tokens rows' copies
   went) */
.hint__reset {
  position: relative;
  color: var(--ds-color-dim);
  white-space: nowrap;
  padding-inline: var(--ds-space-4);
  margin-right: calc(var(--ds-space-4) * -1);
}
@media (hover: hover) {
  .hint__reset:hover {
    color: var(--ds-color-ink);
  }
}
.hint__reset:focus-visible {
  outline: none;
}
html[data-kbd] .hint__reset:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
/* Reset shows once something is edited */
.hint__reset[hidden] {
  display: none;
}

/* ---- the Export drawer (nav.css draws it and places it on every page):
        the bible's inspector column it covers leaves paint and the Tab
        order (layout kept, as a collapsed column's) ------------------ */
@media (min-width: 960px) {
  html[data-export] .rail {
    visibility: hidden;
  }
}

/* ---- the markers (lib/markers.js; round 5, the brief's §1: "Hovering a
        component shows its tokens as small labelled markers"): a strip
        of chips over a component's top edge (under it where the window's
        top is in the way), each a token the component reads, in the
        chrome's small mono: a colour its name over its two values (a
        split square of 12), a number its name and value; the canvas
        ground, a hairline round each; a chip under the hand or chosen
        in measure. A lit id outlines every reader on the canvas (the
        scenes' idiom: dashed, in measure, inset on a surface and a
        button); a part with a local override wears a dotted line of the
        dim ink, so it is never mistaken for the system's -------------- */
/* round 6 (2026-10-11; owner: "These tags look really ugly, refine
   even them so they feel minimal compact but well designed"): one quiet
   strip, not a box per chip: the canvas lifted 4 % with a hairline, the
   control's corner, 24 high, its chips inside 12 apart with no box of
   their own. A colour is a dot of 12 split light and dark (its name for
   a reader and the hover); a number its name in the dim mono, its
   value in the ink beside it. The chip under the hand or chosen takes
   the ink, the chosen a measure underline; nothing else is drawn */
/* round 6, iteration 10 (owner: "make this tags very clear what they
   are and make it only in inspect mode ... add some more spacing and
   design to it"): the strip is a small window that says what it is: a
   head ("Tokens this part reads", and the way in: "press one to edit"),
   then the chips in their groups, each group under its caption (Colour,
   Shape, Stroke, States, Type, the section's own), a chip a box of 24
   with the token's name dim and its value in ink (a colour its dot of
   12, split light and dark, and its name), 8 apart, groups 24 apart,
   16 in. Shown only while Inspect is on (html[data-inspect], ds.js;
   lib/markers.js) */
.marks {
  position: absolute;
  z-index: 32;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-8);
  box-sizing: border-box;
  /* two rows of groups at most over a window of the stage's width */
  max-width: calc(var(--ds-grid-cell) * 180);
  padding: calc(var(--ds-grid-cell) * 3) var(--ds-space-16) var(--ds-space-16);
  border-radius: var(--ds-radius-corner);
  /* the canvas under a veil of the ink (iteration 12: a subtle
     transparency, as the inspector's cards) */
  /* opaque (round 6, iteration 17's review: at 96 % the words under
     it ghosted through): the canvas lifted by the ink at 6 % */
  background: color-mix(
    in srgb,
    var(--ds-color-ink) 6%,
    var(--ds-color-canvas)
  );
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
  font-family: var(--ds-font-sans);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
.marks[hidden] {
  display: none;
}
.marks__head {
  display: flex;
  gap: var(--ds-space-8);
  margin: 0;
  color: var(--ds-color-ink);
  font-weight: 500;
  white-space: nowrap;
}
.marks__hint {
  color: var(--ds-color-dim);
  font-weight: 400;
}
.marks__body {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-8) calc(var(--ds-grid-cell) * 6);
}
/* a strip cut to its room (lib/markers.js place: no room above the
   part clear of its section's head, none whole below): its chips scroll,
   with no bar, the column's way, and the half row at its foot dissolves,
   saying there is more, until the last row is reached (the owner,
   iteration 21: "we show half of last line to indicate more content") */
.marks[data-cut] .marks__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.marks[data-cut] .marks__body::-webkit-scrollbar {
  display: none;
}
.marks[data-cut]:not([data-end]) .marks__body {
  -webkit-mask-image: linear-gradient(
    to bottom,
    black calc(100% - var(--ds-grid-cell) * 3),
    transparent
  );
  mask-image: linear-gradient(
    to bottom,
    black calc(100% - var(--ds-grid-cell) * 3),
    transparent
  );
}
.marks__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ds-space-8);
}
.marks__cap {
  margin-right: var(--ds-space-4);
  color: var(--ds-color-dim);
}
.mark {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-4);
  box-sizing: border-box;
  height: calc(var(--ds-grid-cell) * 6);
  margin: 0;
  padding: 0 var(--ds-space-8);
  /* the strip stands outside the page (on the body), so the page's
     button reset does not reach it */
  border: 0;
  border-radius: var(--ds-radius-corner);
  background: var(--ds-color-canvas);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
  font: inherit;
  cursor: pointer;
  color: var(--ds-color-dim);
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition:
    color var(--ds-motion-state) linear,
    box-shadow var(--ds-motion-state) linear;
}
.mark__value {
  color: var(--ds-color-ink);
}
/* a colour chip: its dot, then its name */
.mark--colour {
  gap: var(--ds-space-8);
}
.mark__swatch {
  display: flex;
  width: calc(var(--ds-grid-cell) * 3);
  height: calc(var(--ds-grid-cell) * 3);
  overflow: hidden;
  border-radius: 50%;
  box-shadow: inset 0 0 0 var(--rule)
    color-mix(in srgb, var(--ds-color-ink) 24%, transparent);
}
.mark__swatch > i {
  flex: 1 1 0;
  background: linear-gradient(var(--c), var(--c)) var(--ds-color-page);
}
.mark__swatch > i[data-mode="light"] {
  color-scheme: light;
}
.mark__swatch > i[data-mode="dark"] {
  color-scheme: dark;
}
/* a chip under the hand: its words in ink and its hair too; chosen, or
   the keys' focus: the measure ring */
@media (hover: hover) {
  .mark:hover {
    color: var(--ds-color-ink);
    box-shadow: inset 0 0 0 var(--rule) var(--ds-color-ink);
  }
}
.mark[data-chosen] {
  color: var(--ds-color-ink);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.mark:focus-visible {
  outline: none;
}
html[data-kbd] .mark:focus-visible {
  color: var(--ds-color-ink);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
/* the parts a hand's rest lights (lib/panes.js link): a dash of the
   measure round each, drawn only while no work's recede stands
   (components/task.js html[data-task-drawn]): while a value is worked
   what the work keeps is said by what stays at full strength, and a dash
   over the specimen being judged is the clutter a manipulation drops
   (owner, 2026-10-14: "on manipulation we want use to focus on the task
   so we tone down unnecessary clutter and unrelated stuff"). The dash is
   withheld, never overridden, so a part's own outline comes back under
   the work (the review of iteration 24: an override of none took the
   Focus cell's ring while the corner it hugs was dragged), and a click,
   which draws no recede, blinks nothing; the condition weighs nothing
   (:where), so the dash ranks as it did */
:where(html:not([data-task-drawn])) main .sec__stage [data-reads-lit] {
  outline: 1px dashed var(--ds-color-measure);
  outline-offset: 2px;
}
:where(html:not([data-task-drawn]))
  main
  .sec__stage
  [data-surface][data-reads-lit],
:where(html:not([data-task-drawn]))
  main
  .sec__stage
  .ds-button[data-reads-lit] {
  outline-offset: -1px;
}
/* a part's own override: its dots, lit or not, under the work too */
main .sec__stage [data-local] {
  outline: 1px dotted var(--ds-color-dim);
  outline-offset: 2px;
}
:where(html:not([data-task-drawn]))
  main
  .sec__stage
  [data-local][data-reads-lit] {
  outline: 1px dashed var(--ds-color-measure);
}
/* the token's head in the inspector: Override locally and Clear on one
   row, 8 under the uses */
.crumb__local[hidden] {
  display: none;
}
.crumb__local {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ds-space-8);
  min-height: var(--chrome-row);
  padding-top: var(--ds-space-8);
}
/* Override locally: a check button on the radios' rungs, as the panes'
   (iteration 19), its words in the chrome's small type */
.crumb__local .ds-check-button {
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
@media (forced-colors: active) {
  .mark {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .mark[data-chosen],
  html[data-kbd] .mark:focus-visible {
    outline: var(--focus-ring-forced-w) solid Highlight;
  }
  /* nothing steps back in forced colours (components/task.js never
     draws the recede), so the dashes stay through the work: they are
     its only cue */
  :where(html:not([data-task-drawn])) main .sec__stage [data-reads-lit] {
    outline: 2px dashed Highlight;
  }
}

/* ---- the occlusion gradient: the lab's instances ---------------------
   visual.md (Maciek, 2026-08-27): "Wherever content meets an edge it
   should feel like it slides under, the hard edge is dissolved by ONE
   shared gradient." One rule lists its consumers; the direction is each
   instance's own (--fade-to), the band one width (--fade-band, 48): the
   index bar's two (where it continues past an edge), the window's foot
   (owner, 2026-10-08: "add short gradient fade at the bottom of the
   screen in the same color as bg": the page role by reference, so a
   colour edited on the page reaches it; static, since a fade that comes
   and goes is a motion with no meaning; no pointer, so the control under
   it is still the hit; the page's own, so a phone keeps it) and the
   drawer's scrolling body. The dropdown list's bands stay the
   component's, in the same form (components/dropdown.css).
   The z ladder, said once: fade 1 = proof strip 1 < chip 5 < rail 10 <
   lists 20 = index 20 < chips 32 < picker popup 35 < drawer 45 (the
   hover popover's 30 left with it, archive/2026-10-14-popover). The
   band lies over every in-flow part and every z-auto context (the
   sticky columns, a slider's bubble in its own context: unavoidable
   without lying under the columns too) and under the chip, the lists,
   the index (its tools paint over it undimmed), the popup and the
   drawer */
.foot-fade {
  background: linear-gradient(
    to var(--fade-to),
    transparent,
    var(--ds-color-canvas)
  );
  pointer-events: none;
}
.foot-fade {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1;
  height: var(--fade-band);
  --fade-to: bottom;
}

/* ---- the sash: the rail's, on its outer edge, the window's height
        (round 6, iteration 12; owner: "make it so i can scale it from
        the other side"; since iteration 16's follow-up the only one:
        "remove manipulation from this side"): its band is the margin
        after the cards (lib/split.js --rail-margin), the card's right
        edge following the hand and its left edge mirroring it. Never
        thinner than 16, and never over the card: a margin under 16 takes
        the rest past the rail's edge (iteration 24's audit: at a margin
        of 8 the band lay over the card's last 8), its grip and its line
        at the margin's middle ------------------------------------------ */
.split {
  --sash-mid: calc(var(--rail-margin) / 2);
  position: absolute;
  top: 0;
  right: min(0px, calc(var(--rail-margin) - var(--ds-space-16)));
  bottom: 0;
  z-index: 5;
  width: max(var(--ds-space-16), var(--rail-margin));
  cursor: col-resize;
  touch-action: none;
}
/* the grip (round 6, iteration 10; owner: "i saw that I can resize the
   right panel but i couldnt figure it out for a while"): a pill of 4 by
   32 in the line colour at the band's middle, seen at rest, so the sash
   is found; the measure colour under the hand, a grab or the keys' focus
   (a pill, the shape rule's exception) */
.split::before {
  content: "";
  position: absolute;
  top: 50%;
  left: var(--sash-mid);
  width: var(--ds-grid-cell);
  height: calc(var(--ds-grid-cell) * 8);
  border-radius: calc(var(--ds-grid-cell) / 2);
  background: var(--ds-color-line);
  transform: translate(-50%, -50%);
  transition: background-color var(--ds-motion-state) linear;
}
@media (hover: hover) {
  .split:hover::before {
    background: var(--ds-color-measure);
  }
}
.split[data-dragging]::before,
html[data-kbd] .split:focus-visible::before {
  background: var(--ds-color-measure);
}
/* the line lights after the lab's one hover intent, 150 ms (lib/core.js
   INTENT; a pointer passing by lights nothing), at once on a grab or a
   keyboard focus, and goes out at once */
.split::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--sash-mid);
  width: var(--rule);
  background: transparent;
  /* a box under a CSS px is painted a whole one wide in Chromium unless
     it is clipped, and clipped alone it laid down three quarters of a
     pixel's ink at 80 % (review, 2026-10-08): lit, it is painted past
     its box (a spread of 2 in its own colour) and cut back to its own
     edges, as the Slider's closing line is (components/slider.css), so
     it is a rule wide, one device pixel at 125 %, and a pixel's ink
     between two below 100 % */
  clip-path: inset(0);
}
@media (hover: hover) {
  .split:hover::after {
    background: var(--ds-color-measure);
    box-shadow: 0 0 0 2px var(--ds-color-measure);
    transition: 0s linear 150ms;
    transition-property: background-color, box-shadow;
  }
}
.split[data-dragging]::after,
html[data-kbd] .split:focus-visible::after {
  background: var(--ds-color-measure);
  box-shadow: 0 0 0 2px var(--ds-color-measure);
  transition: none;
}
.split:focus-visible {
  outline: none;
}
/* forced colours drop the measure line: an outline says the keys'
   focus on a sash (the last pass, 2026-10-11) */
@media (forced-colors: active) {
  html[data-kbd] .split:focus-visible {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
}
/* the chip: on the cards' side, the left, 8 from the sash's line (the
   code audit, 2026-10-12: placed for the left sash, it stood past the
   window's edge, never seen), at the hand's height (lib/split.js; the
   refinement of iteration 24: at the window's top it stood 450 from
   the hand) */
.split__chip {
  position: absolute;
  top: 0;
  right: calc(100% - var(--sash-mid) + var(--ds-space-8));
  padding: 0 var(--ds-space-8);
  background: var(--ds-color-canvas);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
  color: var(--ds-color-measure);
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-15);
  white-space: nowrap;
  pointer-events: none;
}
html[data-resizing],
html[data-resizing] * {
  cursor: col-resize !important;
  user-select: none;
}
/* a finger has no sash: a 48 px strip down the page that will not
   scroll is worse than a fixed column (the column keeps its width) */
@media (pointer: coarse) {
  .split {
    display: none;
  }
}

/* ---- the control panes: Tweakpane, themed onto the seven colours and
        the one ladder (variables first, then a short override sheet for
        what the variables cannot reach) --------------------------------
   Owner, 2026-10-06: "refine debug so it has nice margins and paddings
   and it looks sleek even though its simple. you can use basic icons".
   A pane's controls stand in groups; a group is a card of the lab's
   chrome: square, a hair of line at its edge, the canvas lifted by 2 %
   of ink, a head of 48 (its glyph, its title, the chevron that folds
   it), its rows 16 in from the edges and 16 above its foot. A row is
   one unit (32, or 48 under a finger), 8 apart (the chrome density,
   above; supersedes the 40 head and the 4 between of 2026-10-06); its
   label 14 on a 20 line in the dim words, a column of 100; its value
   the rest. Every part has one corner: 0. A radio row is a segmented
   track: the field ground and a hair of line around it, no lines
   between its cells, the chosen cell the line ground and the ink (the
   ladder's selected). A checkbox is a box of 16 on the field ground,
   its hair of line, the line ground and an ink mark when checked.
   WebKit drops :focus-visible after an arrow moves a radio, so the
   keyboard flag (html[data-kbd]) carries the ring. */
.pane-host .tp-rotv {
  --tp-base-background-color: transparent;
  --tp-base-shadow-color: transparent;
  --tp-base-border-radius: 0px;
  --tp-base-font-family: var(--ds-font-sans);
  --tp-blade-border-radius: 0px;
  --tp-blade-horizontal-padding: 0px;
  --tp-blade-value-width: calc(100% - calc(var(--ds-grid-cell) * 25));
  --tp-container-background-color: transparent;
  --tp-container-background-color-hover: transparent;
  --tp-container-background-color-focus: transparent;
  --tp-container-background-color-active: transparent;
  --tp-container-unit-size: var(--chrome-row);
  --tp-container-unit-spacing: var(--chrome-gap);
  --tp-container-horizontal-padding: 0px;
  --tp-container-vertical-padding: 0px;
  --tp-input-background-color: var(--ds-color-field);
  --tp-input-background-color-hover: var(--ds-color-field);
  --tp-input-background-color-focus: var(--ds-color-field);
  --tp-input-background-color-active: var(--ds-color-field);
  --tp-input-foreground-color: var(--ds-color-dim);
  --tp-label-foreground-color: var(--ds-color-dim);
  --tp-groove-foreground-color: var(--ds-color-line);
  /* the radio cells are Tweakpane's buttons: no ground of their own (the
     track's), the chosen one drawn below */
  --tp-button-background-color: transparent;
  --tp-button-background-color-hover: transparent;
  --tp-button-background-color-focus: transparent;
  --tp-button-background-color-active: transparent;
  --tp-button-foreground-color: var(--ds-color-dim);
  /* the group card; its head 40, under a scope's 48 (round 6, iteration
     10: the ladder of the column) */
  --pane-pad: var(--chrome-pad);
  --pane-head: calc(var(--ds-grid-cell) * 10);
  --pane-ground: color-mix(
    in srgb,
    var(--ds-color-ink) 2%,
    var(--ds-color-canvas)
  );
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  font-weight: 400;
}
.pane-host .tp-dfwv,
.pane-host > .tp-rotv {
  width: 100%;
}
/* the groups of a pane: a stack 16 apart (in a side column; a grid under
   a figure and the Global card set 0). Five classes deep on purpose:
   Tweakpane injects its sheet after this one at runtime, and its
   .tp-rotv_c>.tp-cntv:not(.tp-v-hidden)+.tp-cntv{margin-top:0} is
   (0,4,0), the same as a four-class rule here, so the later one won and
   the States cards measured 0 apart since 2026-10-06 (round 2's finding) */
.pane-host .tp-rotv_c > .tp-fldv + .tp-fldv:not(.tp-v-hidden) {
  margin-top: var(--chrome-card-gap);
}
/* a note (lib/panes.js): why the rows under it are greyed (the page's
   style, or another control: Levels, Opens) and the way back: a row of
   its own, the words in ink on no ground, a hair of line around it,
   whole on a phone; a button, so it takes the keys and their ring */
.pane-host [data-note] .tp-btnv_b {
  height: auto;
  min-height: calc(var(--ds-grid-cell) * 8);
  padding: var(--ds-space-4) var(--ds-space-8);
  background: none;
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
  color: var(--ds-color-ink);
  font-size: var(--ds-text-14);
  font-weight: 400;
  line-height: calc(var(--ds-grid-cell) * 5);
  text-align: left;
  white-space: normal;
}
@media (hover: hover) {
  .pane-host [data-note] .tp-btnv_b:hover {
    background: var(--ds-color-field);
  }
}
html[data-kbd] .pane-host [data-note] .tp-btnv_b:focus {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.pane-host [data-note] .tp-btnv_t {
  white-space: normal;
}
/* a line of words at a group's head (lib/panes.js "words": the corner
   law, said once, over the Global card's Corners): the lab's dim hint
   words at the pane's 14 on 20, wrapping across the card, never cut;
   8 to the first row under it (Tweakpane gives a row after a separator
   none) */
.pane-host .pane__words {
  margin: 0;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-wrap: pretty;
}
.pane-host
  .tp-fldv_c
  > [data-words-line]:not(.tp-v-hidden)
  + *:not(.tp-v-hidden) {
  margin-top: var(--ds-space-8);
}
/* a slider row (lib/panes.js "slider"): the lab's own Slider, compact
   (24 on 14 / 20 type, the mono 14), standing in the row's unit (32, 48
   under a finger) 8 from the rows beside it, as every row does; its
   words in the label column (92 and the Slider's gap, 8, so the bar
   starts where every row's value does), the bar, its value field (the
   Slider's 72) */
.pane-host .tp-fldv_c > .tp-sprv[data-slider-row]:not(.tp-v-fst),
.pane-host .tp-fldv_c > .tp-sprv[data-slider-row] + *:not(.tp-v-hidden) {
  margin-top: var(--tp-container-unit-spacing);
}
.pane-host .pane-slider {
  display: grid;
  align-items: center;
  min-height: var(--tp-container-unit-size);
}
.pane-host .pane-slider > .ds-slider[data-label][data-value] {
  grid-template-columns:
    calc(var(--ds-grid-cell) * 23) minmax(0, 1fr)
    var(--ds-slider-value);
}
.pane-host .pane-slider[data-lit] .ds-slider__label {
  color: var(--ds-color-measure);
}
/* off as a row is (.tp-v-disabled below): the Slider's own off rung
   (components/slider.css data-off), no hand */
.pane-host .pane-slider.tp-v-disabled {
  pointer-events: none;
}
/* the reason runs across the row in the label's words and wraps, never
   cut to the label column; the way back sits beside it at its own
   width */
.pane-host .tp-lblv[data-note] .tp-lblv_l {
  flex: 1 1 0;
  min-width: 0;
  overflow: visible;
  white-space: normal;
  text-wrap: pretty;
  text-overflow: clip;
}
.pane-host .tp-lblv[data-note] .tp-lblv_v {
  flex: none;
  width: auto;
}
.pane-host .tp-lblv_l {
  padding: 0 var(--ds-space-8) 0 0;
  overflow: hidden;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  white-space: nowrap;
  text-overflow: ellipsis;
  opacity: 1;
}
.pane-host .tp-lblv[data-lit] .tp-lblv_l {
  color: var(--ds-color-measure);
}
/* a control that is off (a slot the page's tier has not, or a control
   another one turns off) is the ladder's off, readable: it keeps its
   place and its value and takes no hand; its words dim, no tint, and a
   chosen cell's fill at the Slider's off share of its ink, so the value
   still reads (components/slider.css data-off). Never a fade: an
   opacity of its own, 0.65, stood beside the recede's 0.4 and the
   Disabled rung's dim words, a third dim level, and a greyed row in a
   receded card reached 0.26 (the critique of iteration 24). The
   library's own fade (its cells and their words at half) is undone */
.pane-host .tp-lblv.tp-v-disabled {
  pointer-events: none;
}
.pane-host .tp-v-disabled .tp-radgridv,
.pane-host .tp-v-disabled .tp-radv_b,
.pane-host .tp-v-disabled .tp-radv_t,
.pane-host .tp-v-disabled .tp-btnv_b,
.pane-host .tp-lblv.tp-v-disabled .tp-lblv_l {
  opacity: 1;
}
.pane-host .tp-v-disabled .tp-radv_t,
.pane-host .tp-v-disabled .tp-radv_i:checked + .tp-radv_b .tp-radv_t {
  color: var(--ds-color-text-dim);
}
.pane-host .tp-v-disabled .tp-radv_i:checked + .tp-radv_b {
  background-color: color-mix(
    in srgb,
    var(--ds-color-active) var(--off-ink),
    var(--ds-color-inactive)
  );
}

/* a group of controls (a Tweakpane folder): a card */
.pane-host .tp-fldv {
  margin: 0;
  background: var(--pane-ground);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
}
.pane-host .tp-fldv_b {
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  box-sizing: border-box;
  width: 100%;
  height: var(--pane-head);
  padding: 0 var(--ds-space-8) 0 var(--pane-pad);
  border-radius: 0;
  background: none;
  color: var(--ds-color-ink);
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.pane-host .tp-fldv_t {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  color: inherit;
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  overflow: hidden;
  text-overflow: ellipsis;
}
.pane-host .pane__glyph {
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: var(--ds-color-dim);
}
/* The frame stays fixed; the chevron's arms fold about their own centres. */
.pane-host .tp-fldv_m {
  position: static;
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: calc(var(--ds-grid-cell) * 6);
  height: calc(var(--ds-grid-cell) * 6);
  margin: 0;
  background: none;
  color: var(--ds-color-dim);
  opacity: 1;
  transform: none;
  transition: none;
}
.pane-host .tp-fldv_m::before {
  display: none;
}
.pane-host .pane__chevron {
  width: var(--ds-space-16);
  height: var(--ds-space-16);
}
/* a group's chevron folds as the Dropdown's does (round 6, iteration
   16; "Rotation is suspect"): shut it points down, open its arms swing
   a right angle about their middles and it points up, on the fold's
   own clock and the bounce */
.pane-host .pane__chevron line {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--chrome-clock) var(--ds-motion-bounce);
}
.pane-host .tp-fldv.tp-fldv-expanded .pane__chevron line[data-arm="left"] {
  transform: rotate(-90deg);
}
.pane-host .tp-fldv.tp-fldv-expanded .pane__chevron line[data-arm="right"] {
  transform: rotate(90deg);
}
.pane-host .tp-fldv > .tp-fldv_c,
.pane-host .tp-fldv.tp-fldv-expanded > .tp-fldv_c {
  margin: 0;
  padding: 0 var(--pane-pad) var(--pane-pad);
  border: 0;
  /* Inspector disclosures use the chrome clock: the canvas intentionally
     has a zero clock. Reveal the rows with their height, without a delayed
     fade that leaves an empty expanding folder. */
  transition:
    height var(--chrome-clock) var(--chrome-ease),
    opacity var(--chrome-clock) var(--chrome-ease),
    padding var(--chrome-clock) var(--chrome-ease);
}
/* the library's own padding rule names the open state too */
.pane-host .tp-fldv.tp-fldv-expanded > .tp-fldv_c {
  padding-top: 0;
  padding-bottom: var(--pane-pad);
}
.pane-host .tp-fldv:not(.tp-fldv-expanded) > .tp-fldv_c {
  padding-bottom: 0;
}
/* Keep revealing rows behind their own edge, including on opening. At rest
   the library restores visible overflow so dropdowns can leave the folder. */
.pane-host .tp-fldv > .tp-fldv_c[data-folding] {
  overflow: clip;
}
/* the library's indent bar beside a folder's rows: none */
.pane-host .tp-fldv_i {
  display: none;
}
@media (hover: hover) {
  .pane-host .tp-fldv_b:hover {
    background: none;
    color: var(--ds-color-ink);
  }
  .pane-host .tp-fldv_b:hover .tp-fldv_m,
  .pane-host .tp-fldv_b:hover .pane__glyph {
    color: var(--ds-color-ink);
  }
}
.pane-host .tp-fldv_b:focus-visible {
  outline: none;
}
html[data-kbd] .pane-host .tp-fldv_b:focus {
  outline: none;
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}

/* the radio row: the system's choice of one, on the one ladder (the
   critique of iteration 24: the dock drew its chosen cell on the line
   ground, 43, five levels under the system's Hover, 48, in the card that
   shows the rungs, while the side pages' bars, components/choice.js,
   drew it as the fill; one setting, Icons and Density, looked like two
   controls; owner, 2026-09-06: a chosen check "should have same color as
   active part of slider"). The track the inactive ground, outlined in
   the inactive stroke, a hair of it between two cells (the group's,
   components/button.css: each cell but the last draws its right side, a
   chosen cell its own ring in the active stroke, none at the defaults),
   a cell's words in the ink at the system's weight; under the hand and
   held the ground tinted by the rungs, and a chosen cell the same tints
   over its fill; the chosen cell the fill, the active ground and the
   page's words. The chrome's tokens are the page's as it had them
   (lib/chrome.js), so an edit reaches none of it */
/* a row with fewer cells than its card's widest row keeps that row's
   cell width and ends short (lib/panes.js alignRows writes its width),
   so the cells of a card stand in columns */
.pane-host .tp-radgridv {
  position: relative;
  gap: 0;
  /* the control's corner, its cells clipped to it, as the check
     buttons, dropdowns and sliders beside it (round 6, iteration 17's
     review: square at every corner setting) */
  overflow: clip;
  border-radius: var(--control-corner, var(--ds-radius-corner));
  background: var(--ds-color-inactive);
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
}
.pane-host .tp-radv_b {
  min-width: calc(var(--ds-grid-cell) * 8);
  border-radius: 0;
  opacity: 1;
  background-color: transparent;
  box-shadow: none;
  font-weight: var(--ds-type-weight);
  transition:
    background-color var(--ds-motion-state) var(--ds-motion-state-ease),
    box-shadow var(--ds-motion-state) var(--ds-motion-state-ease);
}
/* a cell's words are the control's, never the page's text, as the
   Button's are (components/button.css). WebKit still selects the page's
   text from a press dragged off a cell (from the merge of iteration 24's
   refinement the sheet stands before the rail, so that selection takes
   in the cards), and a press on a check among them that moves becomes
   the selection's drag: the Button lets go on dragstart */
.pane-host .tp-radv {
  user-select: none;
  -webkit-user-select: none;
}
/* (no weight of its own, so the checked cell's rule and the forced
   colours' outrank it) */
.pane-host :where(.tp-radv:not(:last-child)) .tp-radv_b {
  box-shadow: inset calc(var(--stroke-inactive-w) * -1) 0 0
    var(--ds-stroke-inactive);
}
.pane-host .tp-radv_t {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ds-color-text);
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  opacity: 1;
  transition: color var(--ds-motion-state) var(--ds-motion-state-ease);
}
.pane-host [data-words] .tp-radv_t,
.pane-host .tp-radv_t[data-word] {
  font-family: var(--ds-font-sans);
}
@media (hover: hover) {
  .pane-host .tp-radv_l:hover > .tp-radv_b {
    background-color: color-mix(
      in srgb,
      var(--ds-color-inactive),
      var(--ds-color-text) var(--ds-state-hover)
    );
  }
  .pane-host .tp-radv_l:hover > .tp-radv_b .tp-radv_t {
    color: var(--ds-state-hover-text);
  }
}
.pane-host .tp-radv_l:active > .tp-radv_b {
  background-color: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--ds-state-held)
  );
}
.pane-host .tp-radv_l:active > .tp-radv_b .tp-radv_t {
  color: var(--ds-state-held-text);
}
.pane-host .tp-radv_i:checked + .tp-radv_b {
  background-color: var(--ds-color-active);
  box-shadow: inset 0 0 0 var(--stroke-active-w) var(--ds-stroke-active);
}
.pane-host .tp-radv_i:checked + .tp-radv_b .tp-radv_t,
.pane-host
  .tp-radv_l:is(:hover, :active)
  > .tp-radv_i:checked
  + .tp-radv_b
  .tp-radv_t {
  color: var(--ds-color-page);
}
@media (hover: hover) {
  .pane-host .tp-radv_l:hover > .tp-radv_i:checked + .tp-radv_b {
    background-color: color-mix(
      in srgb,
      var(--ds-color-active),
      var(--ds-color-text) var(--ds-state-hover)
    );
  }
}
.pane-host .tp-radv_l:active > .tp-radv_i:checked + .tp-radv_b {
  background-color: color-mix(
    in srgb,
    var(--ds-color-active),
    var(--ds-color-text) var(--ds-state-held)
  );
}
/* a cell's ring: 1 px of measure, inside the cell */
html[data-kbd] .pane-host .tp-radv_i:focus + .tp-radv_b::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
  pointer-events: none;
}

/* a check row (lib/panes.js "check"): the system's Checkbox
   (components/check.js and check.css draw the box, its ladder, its
   ring under the keys, its touch band and its forced colours), standing
   in the row's unit (32, 48 under a finger) 8 from the rows beside it,
   as every row does; its words in the label column, dim, lit as a
   label is, a hand on them clicking the box; the box where every row's
   value starts */
.pane-host .tp-fldv_c > .tp-sprv[data-check-row]:not(.tp-v-fst),
.pane-host .tp-fldv_c > .tp-sprv[data-check-row] + *:not(.tp-v-hidden) {
  margin-top: var(--tp-container-unit-spacing);
}
.pane-host .pane-check {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  min-height: var(--tp-container-unit-size);
}
/* a check button in the lab's chrome (the panes, the Shows row): its
   rungs the chrome's radios' (round 6, iteration 16's follow-up: one
   look for a choice in a card), its ground the inactive one, chosen the
   line's with the words in ink at 500, the box the Checkbox's own */
.pane-host .ds-check-button {
  width: 100%;
}
/* a check row of a pane: the radios' row (32) and the chrome's small
   type, whatever the page's density, as the radios beside it (the
   visual audit, 2026-10-12: 16 at 500 among 14s, and 24 high in 32
   rows at Compact) */
.pane-host .pane-check .ds-check-button {
  --control: var(--chrome-row);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
/* a pane's list under its field as wide as the field (the visual audit:
   the least list of 192 hung 16 past a field of 176, onto the card's
   edge) */
.pane-host .ds-dropdown:not([data-side="over"]) .ds-dropdown__list {
  width: 100%;
}
/* its rungs are the chrome's check's (components/check.css: the box
   says on, the button the rest rung under the hand and held, as every
   control of the inspector; the critique of iteration 24: a check here
   answered the hand in its words alone and a checked one not at all,
   beside a Dropdown that took the tints) */
.pane-host .pane-check__label {
  min-width: 0;
  padding: 0 var(--ds-space-8) 0 0;
  overflow: hidden;
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
}
/* a check lit from elsewhere (a token's readers) says so in its words;
   under the hand its words are the hand's ink (iteration 18) */
.pane-host
  .pane-check[data-lit]
  .ds-check-button:not(:hover)
  .ds-check-button__words {
  color: var(--ds-color-measure);
}
.pane-host .pane-check[data-lit] .pane-check__label {
  color: var(--ds-color-measure);
}
/* the box's label takes the whole value column and the row's unit (32,
   48 under a finger), so a hand anywhere there is on the box, as the
   pane's checkbox was ("all of it the label") */
.pane-host .pane-check > .ds-check {
  align-self: stretch;
}
/* a swatch row (lib/panes.js "swatch", round 5: the Global tab's
   stroke colours): the role's chip (figures/swatches.css draws it, 48
   by 24) where every row's value starts; its words in the label column,
   lit as a label is, a hand on them pressing the page's own half */
.pane-host .pane-swatch {
  display: grid;
  grid-template-columns:
    calc(100% - var(--tp-blade-value-width))
    minmax(0, 1fr);
  align-items: center;
  min-height: var(--tp-container-unit-size);
}
.pane-host .pane-swatch[data-lit] .pane-check__label {
  color: var(--ds-color-measure);
}
/* a colour row (lib/panes.js "colour", round 6: the Global tab's
   Colour group): the words, the swatch (48 by 24: the half the Scheme
   shows filling it, or the pair with Both on), then its opacity, a
   field of the ladder 56 wide at the row's end, the mono 14 */
.pane-host .pane-colour {
  grid-template-columns:
    calc(100% - var(--tp-blade-value-width))
    minmax(0, 1fr)
    calc(var(--ds-grid-cell) * 14);
  column-gap: var(--ds-space-8);
}
/* a Colour row's chip takes the whole value column (owner, 2026-10-11:
   "use entire row responsive style"); its halves' shares slide, and a
   closing half fades, on the recolour's clock, inside it (owner, round
   6: "make it so colors animate when I toggle modes or 'both
   schemes'"; figures/swatches.css draws the chip) */
.pane-host .pane-colour .swatch__chip {
  width: 100%;
}
.pane-host .pane-swatch .swatch__half {
  transition:
    flex-grow var(--recolour-clock) var(--ds-motion-ease),
    opacity var(--recolour-clock) linear;
}
/* a pair's shares (a Stroke row's, or a Colour row's with Both on):
   the page's own half (html[data-own], lib/globals.js) two thirds of
   the chip, the other a third (owner, 2026-10-11: "currently active
   color should use 2/3 of the button"); while the other scheme is
   previewed (a picker open on its value, html[data-previewing]) the two
   are even, and back when the picker closes ("when im editing other
   theme animate it to fill 50/50"); the shares slide on the recolour's
   clock, inside the chip */
html[data-own="light"] .pane-host .pane-swatch .swatch__half[data-mode="light"],
html[data-own="dark"] .pane-host .pane-swatch .swatch__half[data-mode="dark"] {
  flex-grow: 2;
}
html[data-previewing] .pane-host .pane-swatch:not(.pane-colour) .swatch__half,
html[data-previewing] .pane-host .pane-colour[data-show="both"] .swatch__half {
  flex-grow: 1;
}
/* a Colour row with Both off: the half the Scheme does not show closes
   to nothing and fades, the other fills the chip */
.pane-host .pane-colour[data-show="light"] .swatch__half[data-mode="dark"],
.pane-host .pane-colour[data-show="dark"] .swatch__half[data-mode="light"] {
  flex-grow: 0;
  opacity: 0;
  pointer-events: none;
}
/* the opacity: its number in the dim mono, no ground and no edge at
   rest (owner: "i actually like as is"), dim at 100, ink below it; under
   the hand, scrubbed or edited it takes the value field's rungs (the
   Slider's, components/slider.css: the hover tint and edge, the held
   tint and edge while it scrubs and while the caret is in it, the ring
   where the keys brought it), so its edge, once it shows, stays on every
   rung (iteration 24's audit: a stroke at hover and none at focus, a
   ground at hover equal to the other field's rest, and 32 tall beside
   24); it stands the value fields' height. It takes the value field's
   gesture (lib/panes.js opacityField): a drag across it scrubs, a click
   puts the caret in it; a finger's swipe scrolls the drawer */
.pane-host .pane-colour__alpha {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: var(--ds-slider-height);
  margin: 0;
  padding: 0 var(--ds-space-8);
  border: 0;
  border-radius: min(var(--ds-radius-corner), var(--ds-slider-height) / 2);
  background: transparent;
  box-shadow: none;
  color: var(--ds-color-dim);
  font-family: var(--ds-font-mono);
  font-size: var(--mono-type, var(--ds-text-14));
  font-variant-numeric: tabular-nums;
  text-align: right;
  outline: none;
  cursor: ew-resize;
  touch-action: pan-y;
}
.pane-host .pane-colour__alpha:not([value="100%"]) {
  color: var(--ds-color-ink);
}
@media (hover: hover) {
  .pane-host .pane-colour__alpha:not([data-scrubbing]):not(:focus):hover {
    background: color-mix(
      in srgb,
      var(--ds-color-inactive),
      var(--ds-color-text) var(--ds-state-hover)
    );
    box-shadow: inset 0 0 0 var(--hover-edge-w) var(--ds-state-hover-edge);
    color: var(--ds-state-hover-text);
  }
}
.pane-host .pane-colour__alpha[data-scrubbing],
.pane-host .pane-colour__alpha:focus {
  background: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--ds-state-held)
  );
  box-shadow: inset 0 0 0 var(--held-edge-w) var(--ds-state-held-edge);
  color: var(--ds-state-held-text);
}
.pane-host .pane-colour__alpha[data-scrubbing] {
  user-select: none;
  -webkit-user-select: none;
}
.pane-host .pane-colour__alpha:focus {
  cursor: text;
}
html[data-kbd] .pane-host .pane-colour__alpha:focus {
  outline: var(--focus-ring-w) solid var(--ds-color-focus);
  outline-offset: var(--focus-ring-gap);
}
/* forced colours drop the shadows the rungs draw with: the field keeps
   an edge on every rung, its rest too, as the value field beside it
   does (the review of iteration 24: at rest its digits stood on no
   field; the owner's quiet rest is a look of normal colours) */
@media (forced-colors: active) {
  .pane-host .pane-colour__alpha {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  html[data-kbd] .pane-host .pane-colour__alpha:focus {
    outline: var(--focus-ring-forced-w) solid Highlight;
  }
}
/* a dropdown row (lib/panes.js "dropdown", round 6: the Type group's
   Family): the words, then the system's Dropdown, compact, across the
   value column, its own label for a reader only */
.pane-host .pane-dropdown {
  display: grid;
  grid-template-columns:
    calc(100% - var(--tp-blade-value-width))
    minmax(0, 1fr);
  align-items: center;
  min-height: var(--tp-container-unit-size);
}
/* its words and its field on the row's first line, whatever the list
   below it does: a list opening in the flow (the Global dock's) grows
   the row, and a centred label slid down to its middle (round 6,
   iteration 16) */
.pane-host .pane-dropdown {
  align-items: start;
}
.pane-host .pane-dropdown > .pane-check__label {
  line-height: var(--tp-container-unit-size);
}
.pane-host .pane-dropdown > .ds-dropdown {
  margin-top: calc(
    (
        var(--tp-container-unit-size) -
          var(--control, calc(var(--ds-grid-cell) * 8))
      ) /
      2
  );
}
.pane-host .pane-dropdown[data-lit] .pane-check__label {
  color: var(--ds-color-measure);
}
.pane-host .pane-dropdown .ds-dropdown {
  position: relative;
  grid-template-columns: minmax(0, 1fr);
  min-width: 0;
}
.pane-host .pane-dropdown .ds-dropdown__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* off as a row is (.tp-v-disabled above): the check button's own off
   rung (the dim words, no tint, its box at the off share: components/
   check.css), no hand; never a fade */
.pane-host .pane-check.tp-v-disabled {
  pointer-events: none;
}
.pane-host .pane-check.tp-v-disabled .pane-check__label {
  cursor: default;
}
@media (pointer: coarse) {
  .pane-host .tp-rotv {
    --tp-container-unit-size: calc(var(--ds-grid-cell) * 12);
    --pane-head: calc(var(--ds-grid-cell) * 12);
  }
  .pane-host [data-note] .tp-btnv_b {
    min-height: calc(var(--ds-grid-cell) * 12);
  }
}
/* a row whose words do not fit its value column together wraps
   (lib/panes.js fitWords): its label on a line of its own, the cells
   under it across the whole row, so every cell holds its word and, on a
   finger, is 48 or more */
.pane-host .tp-lblv[data-wide="fit"] {
  flex-wrap: wrap;
}
.pane-host .tp-lblv[data-wide="fit"] .tp-lblv_l {
  flex: 1 0 100%;
  padding-right: 0;
}
.pane-host .tp-lblv[data-wide="fit"] .tp-lblv_v {
  flex: 1 0 100%;
  width: 100%;
}
/* ---- below 960: one column; each section's controls follow its
        figure in the HTML already, so nothing moves. No sash. -------- */
@media (max-width: 959px) {
  .sec {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "card";
  }
  /* the inspector follows the sections in the flow, so the page's end
     and its foot room are the inspector's (.rail, above); a phone draws
     no inspector, so its sheet keeps its own (below) */
  .sheet {
    padding-bottom: 0;
  }
  /* the pane keeps a measure of three modules (288), never
     stretches */
  .pane-host {
    max-width: calc(var(--ds-grid-cell) * 72);
  }
  /* the Global card keeps the rail's card measure (336: the least
     rail, 384, less the page's gutter of 48 at its right), as at every
     width, so its rows keep their label column of 112 and value column
     of 192 */
  .globals {
    max-width: calc(var(--ds-grid-cell) * 84);
  }
  .split {
    display: none;
  }
  /* the column's one gap under the dock too, as from 960 (the review of
     the refinement: in the flow the dock stood flush on the first card) */
  .rail > .side__inner {
    padding-top: var(--rail-gap);
  }
}
/* a phone: the 16 gutter */
@media (max-width: 767px) {
  /* the column is the measure: every card spans it, as the cards under
     a figure do */
  .pane-host {
    max-width: none;
  }
  /* a section's end: 32 under its figure, then the next head's 24 (the
     refinement of iteration 24; the owner's "refine": the stage kept the
     card's 32 and its lattice pad, the section 48 more, so 128 stood
     dead between a figure and the next title, under a gap of 64 above
     the figure) */
  .sec {
    padding-bottom: calc(var(--ds-grid-cell) * 8);
  }
  .sec__stage {
    padding-bottom: var(--lattice-b);
  }
  /* no card on a phone: the words and the figure on the page; a press
     inks nothing either (the last pass, 2026-10-11: the selected rule
     outranked this one and drew a box edge to edge) */
  .sec__card,
  .sec[data-selected] > .sec__card {
    margin-inline: 0;
    box-shadow: none;
  }
  .sec__head {
    padding: calc(var(--ds-grid-cell) * 6) var(--ds-space-16)
      calc(var(--ds-grid-cell) * 4);
  }
  .sec__stage,
  .rail {
    padding-inline: var(--ds-space-16);
  }
}

/* ---- a finger: every target the touch unit, 48 ---------------------- */
@media (pointer: coarse) {
  /* Reset keeps its line in the hint; its reach grows to 48 high and
     4 past each side */
  .hint__reset::after {
    content: "";
    position: absolute;
    inset: calc((var(--ds-grid-cell) * 12 - 100%) / -2)
      calc(var(--ds-space-4) * -1);
  }
}

/* ---- a phone: only things to play with (the tool plan, §6) ----------
   Every debug or explanatory element carries data-chrome="debug" (the
   index's brand, its tools, the Proof grid's strip, the laws, the
   hints, every pane, the inspector and its dock, the Export drawer, the
   Inspect strip), and one rule (nav.css, every page's) hides them all.
   The panes are still built: they hold state, and a phone turned on its
   side may want them. The index keeps the section links, a control's
   section its one window; the foot band stays (an edge
   dissolve is neither debug nor explanatory), so the sheet ends a band
   lower than its last control */
@media (max-width: 767px) {
  .sheet {
    padding-bottom: calc(var(--ds-grid-cell) * 12);
  }
  /* a figure's foot holds only its hint */
  .preview__foot {
    margin-top: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation: none !important;
  }
}
/* forced colours drop every box-shadow and background this sheet draws
   states with: edges become outlines, a checked or pressed control
   takes Highlight, and every focus ring is Highlight */
@media (forced-colors: active) {
  .split:focus-visible::after,
  .split:hover::after,
  .split[data-dragging]::after {
    background: Highlight;
  }
  .globals {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  /* the frames drawn as shadows, which forced colours drop (iteration
     24's audit: the canvas cards had no edge, a firm selection showed
     only in its head's words, and a pinned head's ground covered its
     card's outline): each canvas card and each pinned head its own
     outline, a selection two in Highlight, on both sides */
  .sec__card,
  .rail .insp__head {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .sec[data-selected] > .sec__card,
  .insp__scope:has(> .insp__head[data-firm]) {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  /* a phone draws no card (above), forced or not */
  @media (max-width: 767px) {
    .sec__card,
    .sec[data-selected] > .sec__card {
      outline: none;
    }
  }
  /* the inside rings drawn as shadows, which forced colours drop: an
     inside ring of Highlight, as a cell's */
  html[data-kbd] .globals__reset:focus-visible,
  html[data-kbd] .hint__reset:focus-visible,
  html[data-kbd] .pane-host .tp-fldv_b:focus,
  html[data-kbd] .pane-host [data-note] .tp-btnv_b:focus {
    outline: var(--focus-ring-forced-w) solid Highlight;
    outline-offset: calc(var(--focus-ring-forced-w) * -1);
  }
  /* a note's way back: its hair is a shadow too, so it keeps an edge
     of its own (it had none, and no focus: review, 2026-10-08) */
  .pane-host [data-note] .tp-btnv_b {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .pane-host .tp-radv_b {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  /* the chosen cell Highlight under the hand and held too (its tints
     are the page's colours, which a cell that opts out would show) */
  .pane-host .tp-radv_i:checked + .tp-radv_b,
  .pane-host .tp-radv_l:is(:hover, :active) > .tp-radv_i:checked + .tp-radv_b {
    forced-color-adjust: none;
    background: Highlight;
  }
  .pane-host .tp-radv_i:checked + .tp-radv_b .tp-radv_t {
    forced-color-adjust: none;
    color: HighlightText;
  }
  html[data-kbd] .pane-host .tp-radv_i:focus + .tp-radv_b {
    outline: var(--focus-ring-forced-w) solid Highlight;
    outline-offset: calc(var(--focus-ring-forced-w) * -1);
  }
  /* on the checked cell's Highlight, the ring is HighlightText; the
     shadow ring is not drawn (the checked cell opts out of forcing, and
     its ::after would inherit that) */
  html[data-kbd] .pane-host .tp-radv_i:checked:focus + .tp-radv_b {
    outline-color: HighlightText;
  }
  html[data-kbd] .pane-host .tp-radv_i:focus + .tp-radv_b::after {
    display: none;
  }
}
