/* GoRunner docs: the component system (R3). Built on direction "Manual", in the product's Paper look.
   Every value below comes from the product (frontend/src/styles/tokens.css, index.css, components/ui) unless a comment
   says otherwise. The spec is SYSTEM.md; the living gallery is components.html.

   Contents
     1  Tokens               colour (light-dark), type, space, radii, rules, depth, motion, layout
     2  Base                 page, text, selection, focus, links
     3  Scrollbars           thin, themed, no layout shift; the sidebar's appears on hover or scroll
     4  Keys                 buttons (primary, secondary, quiet, icon, ⋯), kbd, menus
     5  Chrome               top bar, sidebar, phone bar, breadcrumbs, prev/next, footer, back to top
     6  Reading              headings, anchors, prose, steps, "You should see"
     7  Code                 block, bar, tabs, wrap, highlight, diff, syntax, inline
     8  Content blocks       tables, callouts, folds, screenshot frame, lightbox, side panel
     9  Search               the ⌘K palette with Ask, and its states
    10  Small pieces         edition, app rows, HTTP methods, run states, toasts, skeletons, 404
    11  Motion preferences
    12  Print
*/

/* ═══ 1 · TOKENS ══════════════════════════════════════════════════════════════════════════════════════════════════
   Colour is written once with light-dark(): the theme is the element's color-scheme. The root follows the system
   ("light dark"); [data-theme] on the root (the reader's pick) or on any element (a gallery pane) forces one. */
:root {
  color-scheme: light dark;

  /* Materials (tokens.css 6-26 / 106-127) */
  --gr-paper:       light-dark(#f4f2f0, #161513);  /* the page */
  --gr-card:        light-dark(#fcfbf9, #1e1d1b);  /* a sheet, the side panel, a menu, a dialog */
  --gr-well:        light-dark(#eceae7, #12110f);  /* a sunk field, a code block */
  --gr-hover:       light-dark(#e9e7e4, #272624);  /* row hover, the chosen item */
  --gr-desk:        light-dark(#e2e1de, #0c0b0a);  /* behind a frame (the gallery's stage) */
  --gr-ink:         light-dark(#2b2926, #e5e3e0);  /* text, primary key, focus, link, selection */
  --gr-ink-2:       light-dark(#494744, #c2c0bd);  /* sentences in UI, column heads */
  --gr-muted:       light-dark(#5b5956, #a7a5a2);  /* meta, nav at rest, placeholders */
  --gr-on-ink:      light-dark(#f4f2f0, #161513);  /* text on the ink */
  --gr-rule-subtle: light-dark(#e7e5e1, #33322f);  /* between rows */
  --gr-rule:        light-dark(#d8d6d2, #3d3c39);  /* the default rule */
  --gr-rule-strong: light-dark(#bfbdb9, #4e4c49);  /* a sheet's frame, a scrollbar thumb */
  --gr-rule-emph:   light-dark(#969491, #6d6b68);  /* a sheet's top edge, a link's underline */
  --gr-control:     light-dark(#878582, #716f6c);  /* a control's hairline and keycap edge */
  --gr-edge:        light-dark(#7c7a77, #8d8c89);  /* the primary key's edge */
  --gr-wash:        color-mix(in srgb, var(--gr-ink) 4.5%, transparent); /* the search well */
  --gr-chosen:      color-mix(in srgb, var(--gr-ink) 10%, transparent);
  --gr-select:      color-mix(in srgb, var(--gr-ink) 24%, transparent);   /* ::selection (index.css 614) */

  /* Sheets (the product's option C: index.css 380-388, components/ui/sheet-group-variants.ts). A group of rows is a
     sheet on the page's paper: the card, its own 1px edge on four sides, dividers inside it wall to wall. */
  --sheet:       var(--gr-card);                  /* --color-sheet (card) */
  --sheet-edge:  var(--gr-rule);                  /* --color-sheet-edge (rule) */
  --sheet-rule:  var(--gr-rule-subtle);           /* --color-sheet-rule (rule-subtle): a divider inside */
  --sheet-hover: light-dark(#f1efec, #252422);    /* --color-sheet-hover (card-hover) */
  --sheet-x: 16px;                                /* SHEET_ROW: 16px at the sides */
  --sheet-y: 12px;                                /*            12px above and below */

  /* Run states: the only hues (tokens.css 27-38 / 128-139). A word uses -text; a fill is for ticks and rules. */
  --gr-ok:        light-dark(#16603e, #84c8a1);  --gr-ok-fill:   light-dark(#1f6e49, #5ea47b);  --gr-ok-soft:   light-dark(#e6ede5, #293024);
  --gr-warn:      light-dark(#7a5309, #e0b265);  --gr-warn-fill: light-dark(#a4700f, #e3ad4c);  --gr-warn-soft: light-dark(#f3eddf, #3b311e);
  --gr-bad:       light-dark(#841d12, #f7a591);  --gr-bad-fill:  light-dark(#841d12, #cb5d47);  --gr-bad-soft:  light-dark(#f0e5df, #37251c);
  --gr-run:       light-dark(#26456f, #9bbde7);  --gr-run-fill:  light-dark(#2c4f86, #7fa6d9);  --gr-run-soft:  light-dark(#e7eaeb, #2d3031);

  /* Code: a quiet syntax palette on the well. Ink carries structure; two low-chroma hues (umber for strings, plum for
     literals and placeholders) that no run state uses. Every pair is 4.5:1 or better on the well (SYSTEM.md §7). */
  --syn-text:  var(--gr-ink);
  --syn-punc:  var(--gr-muted);
  --syn-com:   var(--gr-muted);
  --syn-kw:    var(--gr-ink);                    /* keywords, flags: ink at 600 */
  --syn-str:   light-dark(#6c4527, #d8b48e);     /* strings: umber */
  --syn-lit:   light-dark(#683f63, #d2a7cb);     /* numbers, true/false/null, $VARS, {placeholders}: plum */
  --syn-key:   light-dark(#38352f, #dedad3);     /* object keys, attribute names */
  --syn-hl:    color-mix(in srgb, var(--gr-ink) 7%, transparent);

  /* Type: two families, five sizes, two weights. Code is Plex Mono 15/24 (14/20 inside small text). */
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --t-h1: 600 32px/40px var(--sans);
  --t-h2: 600 22px/30px var(--sans);
  --t-h3: 600 18px/26px var(--sans);
  --t-body: 400 17px/27px var(--sans);
  --t-small: 400 14px/20px var(--sans);
  --t-code: 400 15px/24px var(--mono);
  --t-code-small: 400 14px/20px var(--mono);
  --w-regular: 400;
  --w-strong: 600;

  /* Space: the product's 4px step */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px;
  --s-10: 40px; --s-12: 48px; --s-14: 56px; --s-18: 72px; --s-24: 96px;

  /* Corners are roles: a control is 2px, a sheet and a dialog 0. Only a status dot is round. */
  --r-control: 2px;
  --r-sheet: 0;

  /* Depth: nothing on the page casts a shadow. What floats has a hard offset, never a blur. */
  --shadow-overlay: 3px 3px 0 0 light-dark(rgb(26 24 20 / .16), rgb(0 0 0 / .5));
  --shadow-dialog:  6px 6px 0 0 light-dark(rgb(26 24 20 / .18), rgb(0 0 0 / .45));
  --edge: 2px;                                              /* the keycap edge, and how far a pressed key sinks */
  --shadow-key:     0 var(--edge) 0 0 var(--gr-control);
  --shadow-primary: 0 var(--edge) 0 0 var(--gr-edge);
  --shadow-row-key: 0 var(--edge) 0 0 var(--gr-rule-strong);
  --shadow-selected: inset 2px 0 0 var(--gr-ink);           /* the current item's rule */
  --scrim: light-dark(rgb(26 24 20 / .32), rgb(8 7 5 / .6));

  /* Motion: one curve, three durations. Exits run at two thirds and only fade. */
  --ease: cubic-bezier(.2, 0, 0, 1);
  --dur-quick: 120ms;
  --dur-base: 180ms;
  --dur-slow: 240ms;
  --dur-exit-base: 120ms;
  --dur-exit-slow: 160ms;
  --rise: 8px;                                              /* new content rises at most this far */

  /* Layout */
  --top-h: 56px;
  --side-w: 256px;
  --col: 680px;           /* pictures, tables, code */
  --break: 880px;         /* one block that breaks out of the column */
  --wide: 1080px;         /* the Wide frame: catalogues, galleries, the home */
  --lane-l: 520px;        /* the Split frame's text lane */
  --gap-split: 32px;
  --prose: 576px;         /* sentences: about 75 characters */
  --gutter: 24px;
  --panel-w: 480px;
}
:root[data-theme="light"], [data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"],  [data-theme="dark"]  { color-scheme: dark; }

/* The scrollbar thumb is a registered colour so it can fade in (the sidebar's). */
@property --sb-thumb { syntax: "<color>"; inherits: true; initial-value: transparent; }

/* ═══ 2 · BASE ════════════════════════════════════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  scroll-padding-top: calc(var(--top-h) + var(--s-6));
  background: var(--gr-paper);
}
body {
  margin: 0; background: var(--gr-paper); color: var(--gr-ink);
  font: var(--t-body); font-variant-numeric: tabular-nums; font-kerning: normal;
  -webkit-font-smoothing: auto; -moz-osx-font-smoothing: auto;   /* Plex draws thinner antialiased on paper */
  overflow-x: clip;
  -webkit-tap-highlight-color: transparent;
  accent-color: var(--gr-ink); caret-color: var(--gr-ink);
}
:root[data-theme="dark"] body, [data-theme="dark"] { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
  :root [data-theme="light"] { -webkit-font-smoothing: auto; -moz-osx-font-smoothing: auto; }
}
img, svg, video { display: block; max-width: 100%; }
svg { flex: none; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { touch-action: manipulation; }
[hidden] { display: none !important; }
.vh { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Selection: the ink, thinned over the paper (index.css 614). Same in code. */
::selection { background: var(--gr-select); color: inherit; }

/* Focus is for the keyboard only: a 2px paper gap, then 2px of ink. The gap is the outline's offset, so it shows the
   ground under the control. Inside a clipping row, tab or cell the ink is drawn inside the edge (.ring-in). */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--gr-ink); outline-offset: 2px; border-radius: var(--r-control); }
.ring-in:focus-visible, .ring-in.is-focus { outline-offset: -2px; }
.is-focus { outline: 2px solid var(--gr-ink); outline-offset: 2px; }

.skip { position: fixed; left: var(--s-4); top: -64px; z-index: 90; padding: 6px 12px; background: var(--gr-card); border: 1px solid var(--gr-rule-strong); box-shadow: var(--shadow-overlay); font: var(--t-small); text-decoration: none; }
.skip:focus-visible { top: 12px; }

/* Links. Ink, never coloured; a quiet underline that turns ink under the pointer. Visited links look the same:
   colour is spent on run states, and a docs reader re-opens pages on purpose. */
a { color: inherit; }
a:not([class]), .link {
  text-decoration-line: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
  text-decoration-color: var(--gr-rule-emph); text-decoration-skip-ink: auto;
  transition: text-decoration-color var(--dur-quick) var(--ease);
}
a:not([class]):hover, .link:hover, .link.is-hover { text-decoration-color: var(--gr-ink); }
a:not([class]):active, .link:active, .link.is-active { text-decoration-thickness: 2px; text-decoration-color: var(--gr-ink); }
/* External: a small ↗ after the last word, never alone on a line. The page adds "(opens in a new tab)" for a new tab. */
a.ext, a[href^="http"]:not([class]) { }
.ext::after {
  content: ""; display: inline-block; width: 12px; height: 12px; margin-left: 3px; vertical-align: 1px;
  background: currentColor; opacity: .7;
  -webkit-mask: var(--i-ext) center / 12px no-repeat; mask: var(--i-ext) center / 12px no-repeat;
}
:root { --i-ext: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 6h10v10M18 6 6 18' fill='none' stroke='black' stroke-width='2' stroke-linecap='square'/%3E%3C/svg%3E");
        --i-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m9 6 6 6-6 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='square'/%3E%3C/svg%3E");
        --i-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 12h15m-6-6 6 6-6 6' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='square'/%3E%3C/svg%3E");
        --i-link: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 14a4 4 0 0 0 5.66 0l3-3a4 4 0 0 0-5.66-5.66l-1 1M14 10a4 4 0 0 0-5.66 0l-3 3a4 4 0 0 0 5.66 5.66l1-1' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='square'/%3E%3C/svg%3E"); }
/* Nav links (sidebar, crumbs, footer, top tabs) carry a class and no underline: their place says they are links. */

/* ═══ 3 · SCROLLBARS ══════════════════════════════════════════════════════════════════════════════════════════════
   The paper's own: a thin thumb in the strong rule, no track, no arrows. Standard properties first; the
   ::-webkit-scrollbar rules serve engines without them. Every scroller sets its thumb on itself, so a dark pane inside
   a light page gets a dark thumb. scrollbar-gutter keeps the width a scrollbar would take, so nothing shifts when
   one appears (or when an overlay locks the page). */
html, .sb, .sb-reveal, pre, .tbl, .side, .side-body, .panel, .pal-body, .menu, .zoom-body, .shot, .tabs {
  --sb-thumb: var(--gr-rule-strong);
  scrollbar-width: thin;
  scrollbar-color: var(--sb-thumb) transparent;
}
html { scrollbar-gutter: stable; }
.sb, .sb-reveal, .side-body, .panel, .pal-body { scrollbar-gutter: stable; overscroll-behavior: contain; }
.pal-body { scrollbar-gutter: auto; } /* its group dividers run wall to wall */
.sb:hover, .pal-body:hover, .panel:hover, pre:hover, .tbl:hover, .shot:hover { --sb-thumb: var(--gr-control); }
/* The sidebar (and any .sb-reveal): no thumb at rest. It fades in while the pointer is over it, while it scrolls
   (.is-scrolling, set by docs.js for 900ms after the last scroll), or while a key has focus inside it; then fades out.
   At rest a thumb is the quiet strong rule; while the reader is using it, the control tone (3:1 or more). */
.side-body, .sb-reveal { --sb-thumb: transparent; transition: --sb-thumb var(--dur-slow) var(--ease); }
.side-body:hover, .side-body:has(:focus-visible), .sb-reveal:hover, .sb-reveal:has(:focus-visible) { --sb-thumb: var(--gr-rule-strong); transition-duration: var(--dur-quick); }
.side-body.is-scrolling, .sb-reveal.is-scrolling, .side-body.is-scrolling:hover { --sb-thumb: var(--gr-control); transition-duration: var(--dur-quick); }
/* Fallback (Safari before scrollbar-color, older Chromium): 10px hit area, a 4px thumb inset by a clear border that
   widens to 6px under the pointer. Square corners, like a control. */
::-webkit-scrollbar { width: 10px; height: 10px; background: transparent; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background-color: var(--sb-thumb, var(--gr-rule-strong)); border: 3px solid transparent; background-clip: padding-box; border-radius: 5px; min-height: 32px; }
::-webkit-scrollbar-thumb:hover { background-color: var(--gr-control); border-width: 2px; }
::-webkit-scrollbar-button { display: none; }
/* A strip that scrolls sideways by design (tabs) shows no bar: the edge fade says there is more. */
.no-sb { scrollbar-width: none; }
.no-sb::-webkit-scrollbar { display: none; }

/* ═══ 4 · KEYS ════════════════════════════════════════════════════════════════════════════════════════════════════
   The product's keycap: a 1px hairline (always present, so a variant never changes size), and a 2px edge under it.
   Pressed, the key sinks onto its edge. Busy keeps the label and swaps the icon for the spinner; it stays focusable.
   Disabled is 50% and leaves the tab order; "not yet" (aria-disabled) stays focusable, with the reason beside it. */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: 32px; padding: 0 var(--s-3); border: 1px solid transparent; border-radius: var(--r-control);
  font: var(--t-small); color: var(--gr-ink); white-space: nowrap; text-decoration: none; cursor: pointer; user-select: none;
  background: transparent;
  transition-property: background-color, border-color, color, box-shadow, transform, opacity;
  transition-duration: var(--dur-quick); transition-timing-function: var(--ease);
}
.btn svg { width: 16px; height: 16px; }
.btn-primary   { background: var(--gr-ink); color: var(--gr-on-ink); box-shadow: var(--shadow-primary); }
.btn-primary:hover, .btn-primary.is-hover { background: var(--gr-ink-2); }
.btn-secondary { background: var(--gr-card); border-color: var(--gr-control); box-shadow: var(--shadow-key); }
.btn-secondary:hover, .btn-secondary.is-hover { background: var(--gr-hover); }
.btn-quiet     { color: var(--gr-ink-2); }
.btn-quiet:hover, .btn-quiet.is-hover { background: var(--gr-hover); color: var(--gr-ink); }
.btn-icon      { width: 32px; padding: 0; }
.btn-sm        { height: 28px; padding: 0 10px; }
.btn-sm.btn-icon { width: 28px; padding: 0; }
.btn-row       { background: var(--gr-card); border-color: var(--gr-control); box-shadow: var(--shadow-row-key); height: 28px; padding: 0 10px; }
.btn-row:hover, .btn-row.is-hover { background: var(--gr-hover); }
/* ⋯ : borderless at rest; under the pointer, or with its menu open, it becomes a framed key with its edge. */
.btn-more { width: 32px; padding: 0; color: var(--gr-ink-2); }
.btn-more:hover, .btn-more.is-hover, .btn-more[aria-expanded="true"] { background: var(--gr-card); border-color: var(--gr-control); box-shadow: var(--shadow-key); color: var(--gr-ink); }
.btn-more[aria-expanded="true"] { border-color: var(--gr-rule-emph); background: var(--gr-hover); }
/* Pressed (sinks) */
.btn:not([aria-disabled="true"]):not([aria-busy="true"]):not(:disabled):active, .btn.is-active { transform: translateY(var(--edge)); box-shadow: none; }
/* Held on: a toggle (aria-pressed) keeps the hover tone, a secondary also takes the emphasis frame. */
.btn[aria-pressed="true"] { background: var(--gr-hover); color: var(--gr-ink); }
.btn-secondary[aria-pressed="true"], .btn-secondary[aria-expanded="true"] { border-color: var(--gr-rule-emph); background: var(--gr-hover); }
.btn-primary[aria-pressed="true"] { background: var(--gr-ink); color: var(--gr-on-ink); }
/* Busy: the label stays, the spinner takes the icon's place; presses are ignored by docs.js. */
.btn[aria-busy="true"] { cursor: progress; }
.btn[aria-busy="true"] > svg:not(.spin) { display: none; }
.btn:not([aria-busy="true"]) > .spin { display: none; }
/* Not yet (aria-disabled): outline, no fill, muted, focusable. Disabled: 50%, out of the tab order. */
.btn[aria-disabled="true"] { cursor: default; background: transparent; color: var(--gr-muted); border-color: var(--gr-control); box-shadow: none; }
.btn:disabled { opacity: .5; cursor: default; pointer-events: none; }
@media (pointer: coarse) { .btn { min-height: 44px; } .btn-icon, .btn-more { min-width: 44px; } .btn-sm, .btn-row { min-height: 36px; } }

/* The spinner: 900ms, linear; it keeps turning under reduced motion because it is the information. */
.spin { animation: gr-spin 900ms linear infinite; }
@keyframes gr-spin { to { transform: rotate(360deg); } }

/* Keyboard hints: a keycap with a 1px rule and no fill, mono, muted. Hidden on touch screens. */
kbd, .kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 5px;
  border: 1px solid var(--gr-rule); border-bottom-color: var(--gr-rule-strong); border-radius: var(--r-control);
  font: var(--t-code-small); color: var(--gr-muted); background: transparent; vertical-align: 1px; white-space: nowrap;
}
p kbd, li kbd, td kbd { height: 22px; }
kbd + kbd { margin-left: 2px; }
@media (pointer: coarse) { .kbd-hint, kbd.hint { display: none; } }

/* Menus: what floats. The card, the strong frame, the 3px print offset. Enter: fade and rise; exit: fade, faster. */
.menu {
  position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; min-width: 100%; max-height: min(360px, 60vh); overflow-y: auto;
  padding: var(--s-1) 0; background: var(--gr-card); border: 1px solid var(--gr-rule-strong); box-shadow: var(--shadow-overlay);
  transform-origin: top left;
}
.menu:not([hidden]) { animation: gr-rise var(--dur-base) var(--ease) both; }
.menu.is-leaving { animation: gr-fade-out var(--dur-exit-base) var(--ease) both; }
.menu-r { left: auto; right: 0; min-width: 220px; transform-origin: top right; }
.menu [role^="menuitem"] { white-space: nowrap; }
.menu [role^="menuitem"] {
  display: flex; align-items: center; gap: var(--s-3); width: 100%; min-height: 36px; padding: 0 var(--s-3); border: 0; background: none;
  font: var(--t-small); color: var(--gr-ink-2); text-align: left; text-decoration: none; cursor: pointer;
}
.menu [role^="menuitem"] svg { width: 16px; height: 16px; color: var(--gr-muted); }
.menu [role^="menuitem"]:hover, .menu [role^="menuitem"]:focus-visible, .menu [role^="menuitem"].is-hover { background: var(--gr-hover); color: var(--gr-ink); outline: none; }
.menu [role^="menuitem"]:focus-visible { box-shadow: inset 0 0 0 2px var(--gr-ink); }
.menu [aria-checked="true"] { color: var(--gr-ink); font-weight: var(--w-strong); box-shadow: var(--shadow-selected); }
.menu [aria-checked="true"]:focus-visible { box-shadow: inset 0 0 0 2px var(--gr-ink); }
.menu .menu-sep { height: 1px; margin: var(--s-1) 0; background: var(--gr-rule-subtle); }
.menu .menu-meta { margin-left: auto; color: var(--gr-muted); }
@keyframes gr-rise { from { opacity: 0; transform: translateY(calc(var(--rise) * -.5)); } }
@keyframes gr-arrive { from { opacity: 0; transform: translateY(var(--rise)); } }
@keyframes gr-fade-in { from { opacity: 0; } }
@keyframes gr-fade-out { to { opacity: 0; } }

/* ═══ 5 · CHROME ══════════════════════════════════════════════════════════════════════════════════════════════════ */
/* Top bar: 56px, paper, one rule. Brand, the six sections, then search and the theme key. */
.top {
  position: sticky; top: 0; z-index: 30; height: var(--top-h);
  display: flex; align-items: center; gap: var(--s-8); padding: 0 var(--gutter);
  background: var(--gr-paper); border-bottom: 1px solid var(--gr-rule);
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: var(--w-strong); text-decoration: none; white-space: nowrap; border-radius: var(--r-control); }
.brand svg { width: 22px; height: 22px; }
/* Section tabs. One ink bar under the current tab; it glides to a newly chosen tab (240ms, the one curve) and, between
   pages, through a cross-document view transition. Hover only darkens the word. Without JS the bar is the tab's own
   inset rule. */
.secs { position: relative; display: flex; gap: var(--s-1); align-self: stretch; }
.secs a {
  display: flex; align-items: center; padding: 0 10px; font: var(--t-small); color: var(--gr-muted); text-decoration: none;
  box-shadow: inset 0 -2px 0 transparent; transition: color var(--dur-quick) var(--ease);
}
.secs a:hover, .secs a.is-hover { color: var(--gr-ink); }
.secs a[aria-current] { color: var(--gr-ink); box-shadow: inset 0 -2px 0 var(--gr-ink); }
.secs a:focus-visible { outline-offset: -2px; }
.ink { position: absolute; left: 0; bottom: 0; height: 2px; width: var(--ink-w, 0); transform: translateX(var(--ink-x, 0)); background: var(--gr-ink); pointer-events: none; view-transition-name: gr-tab-ink; }
.ink.is-ready { transition: transform var(--dur-slow) var(--ease), width var(--dur-slow) var(--ease); }
.js [data-ink] > [aria-current], .js [data-ink] > [aria-selected="true"] { box-shadow: none !important; }
.top-end { margin-left: auto; display: flex; align-items: center; gap: var(--s-2); }
.search-btn {
  text-decoration: none;
  display: flex; align-items: center; gap: var(--s-2); width: 248px; height: 32px; padding: 0 5px 0 10px;
  background: var(--gr-wash); border: 1px solid transparent; border-radius: var(--r-control); cursor: pointer;
  font: var(--t-small); color: var(--gr-muted); text-align: left;
  transition: border-color var(--dur-quick) var(--ease), background-color var(--dur-quick) var(--ease);
}
.search-btn svg { width: 16px; height: 16px; }
.search-btn > span { flex: 1; }
.search-btn:hover, .search-btn.is-hover { border-color: var(--gr-rule); }
.search-btn:active { background: var(--gr-hover); }

/* Cross-document view transition: the page swaps at once; only the section's ink bar glides. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
  ::view-transition-group(gr-tab-ink) { animation-duration: var(--dur-slow); animation-timing-function: var(--ease); }
}

/* Frame: the sidebar and one column (two columns, at most). */
.frame { display: flex; align-items: flex-start; }
.col { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: calc(100vh - var(--top-h)); container: doc / inline-size; }

/* Sidebar */
.side {
  position: sticky; top: var(--top-h); flex: none; width: var(--side-w); height: calc(100vh - var(--top-h)); height: calc(100dvh - var(--top-h));
  display: flex; flex-direction: column; overflow: hidden;
  border-right: 1px solid var(--gr-rule-subtle);
  font: var(--t-small);
}
.side a { text-decoration: none; }
/* Three bands (the product's docked panel: head, body, foot). The head holds "Steps for" (on a phone, the sheet's
   Contents and ×) above its boundary rule, wall to wall; it never scrolls, so nothing passes beneath it. Only the
   list (.side-body) scrolls, and it fades out over its last 24px above the foot instead of being cut. A head with
   nothing in it takes no room. */
.side-head { flex: none; position: relative; z-index: 2; padding: var(--s-4) var(--s-3) var(--s-4) var(--gutter); border-bottom: 1px solid var(--gr-rule-subtle); }
.side-head:not(:has(.ed)) { display: none; }
.side-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--s-6) var(--s-3) var(--s-6) var(--gutter);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--s-6)), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - var(--s-6)), transparent); }
.side-sec { display: block; padding: 6px 0 10px; font-weight: var(--w-strong); color: var(--gr-ink); border-radius: var(--r-control); }
/* A group: its label folds the list below with a height animation (grid rows 0fr → 1fr), the chevron turns. */
.grp { display: grid; grid-template-rows: auto 0fr; transition: grid-template-rows var(--dur-exit-base) var(--ease); }
.grp.open { grid-template-rows: auto 1fr; transition-duration: var(--dur-base); }
.grp > ul { overflow: hidden; min-height: 0; list-style: none; margin: 0; padding: 0; visibility: hidden; transition: visibility 0s var(--dur-exit-base); }
.grp.open > ul { visibility: visible; transition-delay: 0s; }
.grp > ul > li:last-child { margin-bottom: var(--s-2); }
/* While the sidebar takes its first state (docs.js), nothing animates: the scroll to the current page is measured on
   the final layout. */
.side.is-settling .grp, .side.is-settling .grp > ul, .side.is-settling .grp-btn .chev { transition: none !important; }
.grp-btn {
  display: flex; align-items: center; gap: 6px; width: calc(100% + 20px); min-height: 36px; margin-left: -20px; padding: 0;
  background: none; border: 0; border-radius: var(--r-control); cursor: pointer; text-align: left; font: var(--t-small); color: var(--gr-ink-2);
  transition: color var(--dur-quick) var(--ease);
}
.grp-btn .chev { width: 14px; height: 14px; color: var(--gr-rule-emph); transition: transform var(--dur-base) var(--ease), color var(--dur-quick) var(--ease); }
.grp-btn:hover, .grp-btn.is-hover { color: var(--gr-ink); }
.grp-btn:hover .chev { color: var(--gr-muted); }
.grp.open > .grp-btn { color: var(--gr-ink); }
/* An item with something at its side: an app's 16px tile or an AI app's mark at the left, an endpoint's method at
   the right (Mono 12, the one exception to the type scale the sitemap allows). Labels wrap to 2 lines, hanging. */
:is(.grp, .grp-plain) li > a.has-mark { display: grid; grid-template-columns: 16px 1fr; column-gap: 8px; align-items: start; }
:is(.grp, .grp-plain) li > a.has-mark > .tile, :is(.grp, .grp-plain) li > a.has-mark > .mk { width: 16px; height: 16px; margin-top: 2px; }
:is(.grp, .grp-plain) li > a.has-method { display: grid; grid-template-columns: 1fr auto; column-gap: 8px; align-items: baseline; }
:is(.grp, .grp-plain) li > a .m { font: var(--t-code-small); font-size: 13px; color: var(--gr-muted); }
:is(.grp, .grp-plain) li > a[aria-current="page"] .m { color: var(--gr-ink); }
:is(.grp, .grp-plain) li.deprecated > a { color: var(--gr-muted); }
.mk { display: inline-flex; color: currentColor; }
.mk svg { width: 100%; height: 100%; }
:is(.grp, .grp-plain) li > a.more::after { content: " ›"; }
.side-back { display: block; margin: 0 0 4px; padding: 6px 0; color: var(--gr-muted); }
.side-back:hover { color: var(--gr-ink); }
.grp-plain > ul { list-style: none; margin: 0 0 var(--s-2); padding: 0; }
.grp-plain li { margin: 0; }
.grp.open > .grp-btn .chev { transform: rotate(90deg); }
.grp-btn:focus-visible { outline-offset: -2px; }
/* Items hang from one 1px guide; the current item's 2px ink rule sits on it (no fill, no pill). */
:is(.grp, .grp-plain) li { margin: 0; }
:is(.grp, .grp-plain) li > a { display: block; padding: 8px 8px 8px 12px; color: var(--gr-ink-2); box-shadow: inset 1px 0 0 var(--gr-rule); border-radius: 0; transition: color var(--dur-quick) var(--ease), box-shadow var(--dur-quick) var(--ease); }
:is(.grp, .grp-plain) li > a:hover, :is(.grp, .grp-plain) li > a.is-hover { color: var(--gr-ink); box-shadow: inset 1px 0 0 var(--gr-rule-emph); }
:is(.grp, .grp-plain) li > a:focus-visible, :is(.grp, .grp-plain) li > a.is-focus { outline-offset: -2px; }
:is(.grp, .grp-plain) li.cur > a, :is(.grp, .grp-plain) li > a[aria-current="page"] { color: var(--gr-ink); font-weight: var(--w-strong); box-shadow: var(--shadow-selected); }
/* The current page's contents, with the scroll-spy marker: a 2px ink bar that slides along the guide to the section
   in view. docs.js sets --mark-y and --mark-h; the bar fades in once a section is reached. */
.toc { position: relative; list-style: none; margin: 0 0 var(--s-1); padding: 0; }
.toc::after { content: ""; position: absolute; left: 0; top: 0; width: 2px; height: var(--mark-h, 0); transform: translateY(var(--mark-y, 0)); background: var(--gr-ink); opacity: var(--mark-o, 0); pointer-events: none; transition: transform var(--dur-base) var(--ease), height var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease); }
.toc a { display: grid !important; grid-template-columns: 20px 1fr; padding: 4px 8px 4px 24px !important; font-weight: var(--w-regular) !important; }
.toc a:not(:has(.n)) { grid-template-columns: 1fr; }
.toc:has(.n) a:not(:has(.n)) { padding-left: 44px !important; }
.toc a[aria-current="true"], .toc a.is-current { color: var(--gr-ink); }
.toc .n { color: var(--gr-muted); transition: color var(--dur-quick) var(--ease); }
.toc a[aria-current="true"] .n { color: var(--gr-ink); }
.side-foot { flex: none; padding: var(--s-2) var(--s-3) var(--s-4) var(--gutter); }
/* Back to top: in the sidebar's foot, never floating over the text. It appears after the first screen. */
.to-top { display: inline-flex; align-items: center; gap: 6px; color: var(--gr-muted); text-decoration: none; border-radius: var(--r-control); opacity: 0; visibility: hidden; transform: translateY(4px); transition: opacity var(--dur-base) var(--ease), transform var(--dur-base) var(--ease), visibility 0s var(--dur-base), color var(--dur-quick) var(--ease); }
.to-top svg { width: 14px; height: 14px; }
.to-top:hover { color: var(--gr-ink); }
.to-top.is-shown, .to-top:focus-visible { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.side-all { display: none; }
.side-phone { display: none; }

/* Breadcrumbs: parents only; the h1 is the current page. Muted, no underline, ink on hover. */
.crumbs { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 32px; margin-bottom: var(--s-2); }
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; list-style: none; margin: 0; padding: 0; font: var(--t-small); color: var(--gr-muted); }
.crumbs li { display: flex; align-items: center; gap: 6px; margin: 0; }
.crumbs li + li::before { content: ""; width: 12px; height: 12px; background: var(--gr-rule-strong); -webkit-mask: var(--i-chev) center / 12px no-repeat; mask: var(--i-chev) center / 12px no-repeat; }
.crumbs a { text-decoration: none; border-radius: var(--r-control); transition: color var(--dur-quick) var(--ease); }
.crumbs a:hover, .crumbs a.is-hover { color: var(--gr-ink); }

/* The page's ⋯ menu sits at the right of the crumbs row. */
.pm { position: relative; }

/* Tab strip (the product's tabs): 44px, sentence case, a rule under the strip, the ink bar under the chosen tab.
   Arrow keys move; on a phone the strip scrolls sideways with no bar. */
.tabs { position: relative; display: flex; gap: var(--s-1); max-width: var(--col); margin: var(--s-2) 0 0; border-bottom: 1px solid var(--gr-rule); overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs [role="tab"] { flex: none; height: 44px; padding: 0 var(--s-3); border: 0; background: none; cursor: pointer; font: var(--t-small); color: var(--gr-muted); box-shadow: inset 0 -2px 0 transparent; transition: color var(--dur-quick) var(--ease); }
.tabs [role="tab"]:hover, .tabs [role="tab"].is-hover { color: var(--gr-ink); }
.tabs [role="tab"][aria-selected="true"] { color: var(--gr-ink); box-shadow: inset 0 -2px 0 var(--gr-ink); }
.tabs [role="tab"]:focus-visible { outline-offset: -2px; }
.tabs .ink { view-transition-name: none; }
.tabs .count { color: var(--gr-muted); margin-left: 4px; }

/* Previous / next (SITEMAP §2.4): one row at the end of the page, plain underlined links, no cards. "← Previous: …" at
   the left, "Next: … →" at the right; each title wraps to at most 2 lines. On a phone they stack, Next first. No rule
   above it: the gap sets it apart, and the footer's own rule is the only line near it. */
.pn { display: flex; justify-content: space-between; gap: var(--s-6); max-width: var(--col); margin: var(--s-14) 0 0; }
.pn a { max-width: 48%; text-decoration-line: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: var(--gr-rule-emph); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; transition: text-decoration-color var(--dur-quick) var(--ease); }
.pn a:hover, .pn a.is-hover { text-decoration-color: var(--gr-ink); }
.pn .dir { color: var(--gr-muted); }
.pn .next { margin-left: auto; text-align: right; }

/* Footer: one row, at most six links and the version. */
.foot { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-6); min-height: 72px; padding: var(--s-5) var(--gutter); border-top: 1px solid var(--gr-rule-subtle); font: var(--t-small); color: var(--gr-muted); }
.foot nav { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.foot a { text-decoration: none; border-radius: var(--r-control); }
.foot a:hover { color: var(--gr-ink); }
.foot .ver { margin-left: auto; }

/* Phone bar (≤900): the section and page; opens the sidebar as a sheet. */
.phonebar { display: none; }
.side-scrim { position: fixed; inset: 0; z-index: 34; background: var(--scrim); animation: gr-fade-in var(--dur-base) var(--ease) both; }

/* ═══ 6 · READING ═════════════════════════════════════════════════════════════════════════════════════════════════ */
.doc { width: 100%; max-width: calc(var(--col) + 2 * var(--gutter)); margin: 0 auto; padding: var(--s-8) var(--gutter) var(--s-24); flex: 1; }
.doc > * { max-width: var(--col); }
/* FRAMES (PRESENTATION §1.1). Every page picks one: Read (the 680 column, centred), Wide (one 1080 box) or Split (Wide in
   two lanes, the text and the code that belongs to it). Decided by the container, so opening the panel behaves like a
   narrower screen. */
.doc[data-frame="wide"], .doc[data-frame="split"] { max-width: calc(var(--wide) + 2 * var(--gutter)); }
.doc[data-frame="wide"] > *, .doc[data-frame="split"] > * { max-width: none; }
.doc[data-frame="wide"] > :is(h1, .lede, .meta, p), .doc[data-frame="split"] > :is(h1, .lede, .meta, p) { max-width: var(--prose); }
/* Break out: one block grows past 680, centred on the column. */
.breakout { width: min(var(--break), (100cqw + min(var(--col), 100cqw - 2 * var(--gutter))) / 2 - var(--gutter)); max-width: none !important; margin-left: 0; }
.breakout > * { max-width: none; }
/* Split: an L lane (text) and an R lane (its code). The R lane sticks inside its pair, never over the next section. */
.pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
@container doc (min-width: 960px) {
  .pair { grid-template-columns: minmax(0, min(var(--lane-l), (100% - var(--gap-split)) / 2)) minmax(0, 1fr); column-gap: var(--gap-split); align-items: start; }
  .pair > .r { position: sticky; top: calc(var(--top-h) + var(--s-6)); }
  .pair > .r.is-tall { position: static; }
}
@container doc (max-width: 727px) { .doc { padding-left: 16px; padding-right: 16px; } }
.doc p, .doc ul, .doc ol:not(.steps), .doc dl { max-width: var(--prose); }
h1, h2, h3 { color: var(--gr-ink); text-wrap: balance; } /* the page's scroll-padding-top clears the bar */
h1 { font: var(--t-h1); margin: 0 0 var(--s-3); }
h2 { font: var(--t-h2); margin: var(--s-14) 0 var(--s-3); }
h3 { font: var(--t-h3); margin: var(--s-8) 0 var(--s-2); }
p { margin: 0 0 var(--s-4); text-wrap: pretty; hanging-punctuation: first; }
ul, ol { margin: 0 0 var(--s-4); padding-left: var(--s-6); }
li { margin: 0 0 6px; }
li::marker { color: var(--gr-muted); }
strong, b { font-weight: var(--w-strong); }
.lede { color: var(--gr-ink-2); margin-bottom: var(--s-2); }
.meta { font: var(--t-small); color: var(--gr-muted); margin: 0 0 var(--s-8); }
.small { font: var(--t-small); }
.muted { color: var(--gr-muted); }
h2 + p, h2 + ol, h2 + ul, h3 + p { margin-top: 0; }
hr { border: 0; border-top: 1px solid var(--gr-rule-subtle); margin: var(--s-10) 0; }

/* Heading anchors: the heading's own text is the link to itself. A link glyph appears beside it under the pointer or
   keyboard focus (always, faintly, on touch). Pressing it also copies the address and says "Link copied.". */
.h-link { color: inherit; text-decoration: none; border-radius: var(--r-control); }
.h-glyph { display: inline-block; width: 18px; height: 18px; margin-left: 8px; vertical-align: -2px; background: var(--gr-muted); opacity: 0; -webkit-mask: var(--i-link) center / 18px no-repeat; mask: var(--i-link) center / 18px no-repeat; transition: opacity var(--dur-quick) var(--ease); }
h3 .h-glyph { width: 16px; height: 16px; -webkit-mask-size: 16px; mask-size: 16px; vertical-align: -1px; }
.h-link:hover .h-glyph, .h-link:focus-visible .h-glyph, .h-link.is-hover .h-glyph { opacity: 1; }
.h-link:hover .h-glyph { background: var(--gr-ink-2); }
@media (hover: none) { .h-link:focus-within .h-glyph, .h-link:focus .h-glyph { opacity: .55; } }

/* Tutorial steps: the number hangs muted in a gutter left of the column; the step being read turns it ink. */
.step :is(h2, h3) { position: relative; }
.step :is(h2, h3) .n { position: absolute; right: 100%; width: 44px; padding-right: var(--s-3); text-align: right; color: var(--gr-muted); transition: color var(--dur-base) var(--ease); }
.step.cur :is(h2, h3) .n, .step.is-current :is(h2, h3) .n { color: var(--gr-ink); }
/* "You should see": one muted line after the step, the product's logbook voice, coloured only where the product would. */
.see { position: relative; font: var(--t-small); color: var(--gr-muted); margin: calc(-1 * var(--s-2)) 0 0; padding-left: 22px; }
/* the words "You should see" are text (screen readers and the Markdown twins keep them); the eye only marks the line */
.see::before { content: ""; position: absolute; left: 0; top: 3px; width: 14px; height: 14px; background: var(--gr-muted); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7S2 12 2 12Z' fill='none' stroke='black' stroke-width='1.8'/%3E%3Ccircle cx='12' cy='12' r='3' fill='none' stroke='black' stroke-width='1.8'/%3E%3C/svg%3E") center / 14px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7S2 12 2 12Z' fill='none' stroke='black' stroke-width='1.8'/%3E%3Ccircle cx='12' cy='12' r='3' fill='none' stroke='black' stroke-width='1.8'/%3E%3C/svg%3E") center / 14px no-repeat; }
.see b { color: var(--gr-ink-2); }
.shot + .see { margin-top: calc(-1 * var(--s-3)); }
/* A procedure inside a section: one action per item; the numbers hang the same way. */
ol.steps { list-style: none; counter-reset: st; padding: 0; margin: 0 0 var(--s-5); max-width: var(--prose); }
ol.steps > li { position: relative; counter-increment: st; margin: 0 0 var(--s-2); }
ol.steps > li::before { content: counter(st) "."; position: absolute; right: 100%; width: 44px; padding-right: var(--s-3); text-align: right; color: var(--gr-muted); }
/* Inside a tutorial step the actions indent under the heading, so their numbers never compete with the step's. */
.step ol.steps > li { padding-left: 28px; }
.step ol.steps > li::before { right: auto; left: 0; width: auto; padding: 0; text-align: left; }

/* ═══ 7 · CODE ════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* Inline: Plex Mono at 15px in body (0.88em), no chip, as the product sets it. */
code, kbd, samp, pre { font-variant-numeric: normal; font-variant-ligatures: none; }
code { font: var(--t-code); }
.small code, td code, th code, .see code, .meta code, .callout.small code { font: var(--t-code-small); }
h2 code, h3 code { font-family: var(--mono); font-size: 15px; font-weight: var(--w-strong); } /* --t-code's size, never em */
a > code { text-decoration: inherit; }
/* Block: the well, one rule, a 36px bar (language left; wrap and Copy right), the body in Mono 15/24. */
.code { position: relative; margin: var(--s-4) 0 var(--s-5); border: 1px solid var(--gr-rule); background: var(--gr-well); border-radius: var(--r-sheet); }
.code-bar { display: flex; align-items: center; gap: var(--s-2); min-height: 40px; padding: 0 var(--s-1) 0 var(--s-4); border-bottom: 1px solid var(--gr-rule); font: var(--t-small); color: var(--gr-muted); }
.code-bar .lang { margin-right: auto; }
.code-bar .file { margin-right: auto; font: var(--t-code-small); color: var(--gr-ink-2); }
/* Language tabs in the bar: the product's tabs, with the gliding ink bar. */
.code-tabs { position: relative; display: flex; align-self: stretch; margin: 0 auto 0 calc(-1 * var(--s-2)); overflow-x: auto; }
.code-tabs [role="tab"] { flex: none; padding: 0 var(--s-2); border: 0; background: none; cursor: pointer; font: var(--t-small); color: var(--gr-muted); box-shadow: inset 0 -2px 0 transparent; transition: color var(--dur-quick) var(--ease); }
.code-tabs [role="tab"]:hover { color: var(--gr-ink); }
.code-tabs [role="tab"][aria-selected="true"] { color: var(--gr-ink); box-shadow: inset 0 -2px 0 var(--gr-ink); }
.code-tabs [role="tab"]:focus-visible { outline-offset: -2px; }
.code-tabs .ink { view-transition-name: none; }
/* Copy: a quiet key whose label turns to "Copied" with a check for 1.6s; a polite live region says it too. */
.copy .i-done { display: none; }
.copy[data-state="copied"] .i-copy { display: none; }
.copy[data-state="copied"] .i-done { display: block; animation: gr-pop var(--dur-base) var(--ease) both; }
.copy[data-state="copied"] { color: var(--gr-ink); }
@keyframes gr-pop { from { opacity: 0; transform: scale(.6); } }
pre { margin: 0; padding: 14px var(--s-4) var(--s-4); overflow-x: auto; font: var(--t-code); color: var(--syn-text); tab-size: 2; background: none; }
pre code { font: inherit; display: block; min-width: max-content; white-space: pre; }
pre[data-wrap="true"] code { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.code pre[hidden] { display: none; }
/* Lines: highlighted, added, removed. Markers are drawn, never copied. */
pre .line { display: inline-block; min-width: calc(100% + 2 * var(--s-4)); margin: 0 calc(-1 * var(--s-4)); padding: 0 var(--s-4); }
pre[data-wrap="true"] .line, pre.lined .line { display: block; min-width: 0; min-height: 24px; }
pre .line.hl  { background: var(--syn-hl); box-shadow: var(--shadow-selected); }
pre .line.add { background: var(--gr-ok-soft); }
pre .line.del { background: var(--gr-bad-soft); }
pre.diff .line { padding-left: calc(var(--s-4) + 20px); position: relative; }
pre.diff .line::before { content: " "; position: absolute; left: var(--s-4); width: 14px; color: var(--gr-muted); user-select: none; }
pre.diff .line.add::before { content: "+"; color: var(--gr-ok); }
pre.diff .line.del::before { content: "−"; color: var(--gr-bad); }
pre[data-ln] { counter-reset: ln; }
pre[data-ln] .line { padding-left: calc(var(--s-4) + 32px); position: relative; counter-increment: ln; }
pre[data-ln] .line::before { content: counter(ln); position: absolute; left: var(--s-4); width: 20px; text-align: right; color: var(--gr-muted); user-select: none; }
/* Syntax (quiet) */
.t-k { color: var(--syn-kw); font-weight: var(--w-strong); }
.t-s { color: var(--syn-str); }
.t-n, .t-v { color: var(--syn-lit); }
.t-p { color: var(--syn-punc); }
.t-c { color: var(--syn-com); }
.t-a { color: var(--syn-key); }
.t-f { color: var(--syn-text); }

/* ═══ 8 · CONTENT BLOCKS ══════════════════════════════════════════════════════════════════════════════════════════ */
/* Tables: the Keel markdown table at docs size. 14/20; a strong rule under the head, subtle rules between rows.
   .tbl scrolls sideways when the table is wider than the column; .tbl-wrap draws a fade on the edge that has more.
   .tall gives the table its own height so the head can stick inside it. */
.tbl-wrap { position: relative; margin: var(--s-4) 0 var(--s-6); --fade-bg: var(--sheet); }
/* A table is a sheet: its own edge, the head's boundary rule wall to wall, subtle dividers, none under the last row. */
.tbl { overflow-x: auto; overflow-y: hidden; background: var(--sheet); border: 1px solid var(--sheet-edge); border-radius: var(--r-sheet); }
.tbl th:first-child, .tbl td:first-child { padding-left: var(--sheet-x); }
.tbl th:last-child, .tbl td:last-child { padding-right: var(--sheet-x); }
.tbl tbody:last-child > tr:last-child > td { border-bottom: 0; }
.tbl.tall { max-height: 420px; overflow-y: auto; }
.tbl-wrap::before, .tbl-wrap::after { content: ""; position: absolute; top: 1px; bottom: 10px; width: 32px; pointer-events: none; opacity: 0; transition: opacity var(--dur-base) var(--ease); z-index: 2; }
.tbl-wrap::before { left: 1px; background: linear-gradient(to right, var(--fade-bg), transparent); }
.tbl-wrap::after { right: 1px; background: linear-gradient(to left, var(--fade-bg), transparent); }
.tbl-wrap[data-more~="start"]::before, .tbl-wrap[data-more~="end"]::after { opacity: 1; }
table { width: 100%; border-collapse: separate; border-spacing: 0; font: var(--t-small); }
th { position: sticky; top: 0; z-index: 1; text-align: left; vertical-align: bottom; padding: 10px var(--s-4) 8px 0; font-weight: var(--w-regular); color: var(--gr-muted); background: var(--fade-bg, var(--gr-paper)); border-bottom: 1px solid var(--sheet-edge); white-space: nowrap; }
td { padding: 10px var(--s-4) 10px 0; vertical-align: top; color: var(--gr-ink-2); border-bottom: 1px solid var(--sheet-rule); }
th:last-child, td:last-child { padding-right: 0; }
td:first-child { color: var(--gr-ink); }
td.nowrap, td:first-child:has(> code:only-child) { white-space: nowrap; }
.wrap-first td:first-child { white-space: normal; }
/* identifiers in cells break only where the build put <wbr> (after _ . /), never mid-word */
.doc td code, .doc th code { overflow-wrap: normal; word-break: normal; }
td.nowrap code { white-space: nowrap; }
td strong { color: var(--gr-ink); }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.rows tbody tr { transition: background-color var(--dur-quick) var(--ease); }
table.rows tbody tr:hover, table.rows tbody tr.is-hover { background: var(--sheet-hover); }
/* Sortable head: the whole head is the key; ↕ at rest (muted), ↑ or ↓ in ink once sorted. aria-sort says it. */
th .sort { display: inline-flex; align-items: center; gap: 6px; margin: -4px 0; padding: 4px 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer; border-radius: var(--r-control); }
th .sort:hover { color: var(--gr-ink); }
th .sort svg { width: 12px; height: 12px; color: var(--gr-rule-emph); }
th[aria-sort="ascending"] .sort, th[aria-sort="descending"] .sort { color: var(--gr-ink); }
th[aria-sort] .sort svg .up, th[aria-sort] .sort svg .dn { opacity: .35; }
th[aria-sort="ascending"] .sort svg .up, th[aria-sort="descending"] .sort svg .dn { opacity: 1; }
th[aria-sort="ascending"] .sort svg, th[aria-sort="descending"] .sort svg { color: var(--gr-ink); }
th.num .sort { flex-direction: row-reverse; }
/* Filter: one field above the table, the count beside it, an empty line in place of rows. */
.tbl-filter { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); margin: var(--s-4) 0 0; }
.tbl-filter .field { flex: 1 1 240px; max-width: 360px; }
.tbl-count { font: var(--t-small); color: var(--gr-muted); }
.tbl-empty td { color: var(--gr-muted); padding: var(--s-4) var(--sheet-x); }

/* Fields (the filter, the search box) */
.field { height: 36px; padding: 0 var(--s-3); background: var(--gr-well); color: var(--gr-ink); border: 1px solid var(--gr-control); border-radius: var(--r-control); font: var(--t-small); transition: border-color var(--dur-quick) var(--ease); }
.field::placeholder { color: var(--gr-muted); opacity: 1; }
.field:hover { border-color: var(--gr-muted); }
.field:focus-visible, .field:focus { outline: 2px solid var(--gr-ink); outline-offset: 0; border-color: var(--gr-ink); }
@media (pointer: coarse) { .field { font-size: 16px; height: 44px; } }

/* Callouts: three, and only three. Note is ink with a rule; Warning wears Held; Danger wears Failed. A glyph says the
   kind without colour. No blue info, no green tip: those hues mean Running and Worked. */
.callout { display: grid; grid-template-columns: auto 1fr; column-gap: var(--s-3); max-width: var(--col); margin: var(--s-6) 0; padding: var(--s-3) var(--s-4); border-left: 2px solid var(--gr-rule-strong); color: var(--gr-ink); }
.callout > svg { width: 16px; height: 16px; margin-top: 5px; }
.callout > :not(svg) { grid-column: 2; }
.callout.note { grid-template-columns: 1fr; padding: 2px 0 2px var(--s-4); }
.callout.note > * { grid-column: 1; }
.callout p { margin: 0; max-width: none; }
.callout p + p { margin-top: var(--s-2); }
.callout .label { font-weight: var(--w-strong); }
.callout.note .label { color: var(--gr-ink-2); }
.callout.warn { background: var(--gr-warn-soft); border-left-color: var(--gr-warn-fill); }
.callout.warn > svg, .callout.warn .label { color: var(--gr-warn); }
.callout.danger { background: var(--gr-bad-soft); border-left-color: var(--gr-bad-fill); }
.callout.danger > svg, .callout.danger .label { color: var(--gr-bad); }

/* Folds: <details>, the product's Collapsible (variant "sheet"). A fold is a sheet whose first row is its summary:
   the chevron first, turning 90° (never a glyph swap), the title after it. Folds that follow one another stack into
   one sheet, a divider between them. Open, a divider sits under the summary and the body follows inside the same
   sheet. The body opens with a height animation (docs.js), and a fold with an id opens when the address points at it
   (or at anything inside it). */
details { margin: var(--s-6) 0; max-width: var(--col); background: var(--sheet); border: 1px solid var(--sheet-edge); border-radius: var(--r-sheet); }
details:has(+ details) { margin-bottom: 0; border-bottom: 0; }
details + details { margin-top: 0; border-top-color: var(--sheet-rule); }
summary { list-style: none; display: flex; gap: 10px; align-items: flex-start; min-height: 48px; padding: 10px var(--sheet-x); cursor: pointer; color: var(--gr-ink); border-radius: var(--r-sheet); transition: background-color var(--dur-quick) var(--ease); }
summary:hover, summary.is-hover { background: var(--sheet-hover); }
summary::-webkit-details-marker { display: none; }
summary::before { content: ""; flex: none; width: 16px; height: 27px; background: var(--gr-ink-2); -webkit-mask: var(--i-chev) center / 16px no-repeat; mask: var(--i-chev) center / 16px no-repeat; transition: transform var(--dur-base) var(--ease); }
details[open] > summary::before { transform: rotate(90deg); }
details[open] > summary { border-bottom: 1px solid var(--sheet-rule); }
summary:focus-visible { outline-offset: -2px; }
/* The body's inset is on its children, not on the body, so a list inside a fold is one of the fold's rows: no box of
   its own, its dividers wall to wall (no sheet inside a sheet), and no negative margins. Prose and code keep the inset. */
.fold-body { padding: var(--s-3) 0 var(--s-4); overflow: hidden; }
.fold-body > :not(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list) { margin-left: calc(var(--sheet-x) + 26px); margin-right: var(--sheet-x); }
.fold-body.fold-body > :is(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list) { border-width: 1px 0; border-color: var(--sheet-rule); border-radius: 0; background: none; margin: var(--s-3) 0; max-width: none; }
.fold-body.fold-body > :is(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list):first-child { border-top-width: 0; margin-top: 0; }
.fold-body.fold-body > :is(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list):last-child { border-bottom-width: 0; margin-bottom: 0; }
.fold-body:has(> :is(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list):first-child) { padding-top: 0; }
.fold-body:has(> :is(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list):last-child) { padding-bottom: 0; }
.fold-body > .params > div { padding-left: calc(var(--sheet-x) + 26px); }
html:not(.js) details > :not(summary) { margin-left: calc(var(--sheet-x) + 26px); margin-right: var(--sheet-x); }
.fold-body > :last-child { margin-bottom: 0; }
details:target > summary, details.is-target > summary { color: var(--gr-ink); }
details.is-target { animation: gr-target 1.2s var(--ease) both; }
@keyframes gr-target { 0%, 30% { background: var(--gr-chosen); } 100% { background: transparent; } }

/* "What if…": questions that open in the side panel. Those next to each other are one sheet (layout.mjs wraps them in
   .q-sheet); each is a row whose words lead and whose arrow trails (it goes somewhere: the panel), the whole row the key. */
.doc .q-sheet { margin: var(--s-5) 0 var(--s-6); max-width: var(--col); }
.doc .q { max-width: none; margin: 0; }
.q a { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); min-height: 48px; padding: 10px var(--sheet-x); text-decoration: none; color: var(--gr-ink); transition: background-color var(--dur-quick) var(--ease); }
.q a:hover, .q a.is-hover { background: var(--sheet-hover); }
.q a::after { content: ""; flex: none; width: 16px; height: 16px; background: var(--gr-muted); -webkit-mask: var(--i-arrow) center / 16px no-repeat; mask: var(--i-arrow) center / 16px no-repeat; transition: transform var(--dur-base) var(--ease); }
.q a:hover::after { transform: translateX(2px); }
.q a[aria-current] { font-weight: var(--w-strong); }
.q a[aria-current]::after { background: var(--gr-ink); }
.q a:focus-visible { outline-offset: -2px; }
/* A term peek: a 320px card under the dotted word, with the definition, what the screen says, and one link. */
.peek, .ed-pop { position: absolute; z-index: 45; width: min(320px, calc(100vw - 32px)); padding: var(--s-3) var(--s-4) var(--s-4); background: var(--gr-card); border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); box-shadow: var(--shadow-overlay); font: var(--t-small); color: var(--gr-ink-2); animation: gr-rise var(--dur-base) var(--ease) both; }
.peek.is-leaving, .ed-pop.is-leaving { animation: gr-fade-out var(--dur-exit-base) var(--ease) both; }
.peek h2 { font: var(--t-small); font-weight: var(--w-strong); color: var(--gr-ink); margin: 0 0 var(--s-1); }
.peek p { margin: 0 0 var(--s-2); max-width: none; }
.peek p:last-child { margin: 0; }
.peek:focus { outline: none; }
[data-ed].is-changed { animation: gr-target 0.9s var(--ease) both; }
/* A first-use term: a dotted rule, solid and ink on hover. At most two per paragraph. */
.term { text-decoration: underline dotted var(--gr-rule-emph); text-underline-offset: 4px; text-decoration-thickness: 1px; cursor: pointer; }
.term:hover, .term[aria-current] { text-decoration-style: solid; text-decoration-color: var(--gr-ink); }

/* Screenshot frame: the product's sheet (strong rule, emph top edge), 1:1 at 2x, flush left. The ring is the
   product's focus ring drawn in CSS (2px paper gap, 2px ink), so light and dark always match. One short label at most.
   When the column is narrower than the picture the frame scrolls sideways, starting at the ring. */
.shot { position: relative; margin: var(--s-5) -6px var(--s-6); padding: 6px; max-width: calc(100% + 12px); overflow-x: auto; overflow-y: hidden; }
.shot .frame { position: relative; width: max-content; max-width: none; border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); background: var(--gr-card); }
.shot img { display: block; height: auto; background: var(--gr-well); }
/* A crop whose product element draws its own border shows no frame of its own (no doubled lines). */
.shot.bare .frame { border-color: transparent; background: transparent; }
/* A crop cut short in CSS (to end on a row boundary): the frame's height, the rest hidden. */
.shot .frame.clip { overflow: hidden; }
.shot .frame.clip img { height: auto; }
.shot .d { display: none; }
:root[data-theme="dark"] .shot .l, [data-theme="dark"] .shot .l { display: none; }
:root[data-theme="dark"] .shot .d, [data-theme="dark"] .shot .d { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .shot .l { display: none; }
  :root:not([data-theme="light"]) .shot .d { display: block; }
  :root [data-theme="light"] .shot .l { display: block; }
  :root [data-theme="light"] .shot .d { display: none; }
}
.ring { position: absolute; border-radius: var(--r-control); box-shadow: 0 0 0 2px var(--gr-paper), 0 0 0 4px var(--gr-ink); pointer-events: none; }
/* A ring with no room outside (at a crop's edge, or beside a separator) is drawn inside its control. */
.ring.in { box-shadow: inset 0 0 0 2px var(--gr-ink); }
.ring-label { position: absolute; transform: translateY(calc(-100% - 10px)); padding: 1px 6px; background: var(--gr-ink); color: var(--gr-on-ink); font: var(--t-small); border-radius: var(--r-control); white-space: nowrap; pointer-events: none; }
.ring-label.below { transform: translateY(10px); }
/* Zoom: a key over the picture's corner, shown on hover or focus; the picture itself is the target. */
.shot-zoom { all: unset; display: block; cursor: zoom-in; }
.shot-zoom:focus-visible { outline: 2px solid var(--gr-ink); outline-offset: 2px; }
.shot .zoom-hint { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px; background: var(--gr-card); border: 1px solid var(--gr-control); border-radius: var(--r-control); box-shadow: var(--shadow-key); font: var(--t-small); color: var(--gr-ink); opacity: 0; transform: translateY(-2px); transition: opacity var(--dur-quick) var(--ease), transform var(--dur-quick) var(--ease); pointer-events: none; }
.shot .zoom-hint svg { width: 14px; height: 14px; }
.shot-zoom:hover .zoom-hint, .shot-zoom:focus-visible .zoom-hint, .shot.is-hover .zoom-hint { opacity: 1; transform: none; }
.shot figcaption { margin-top: var(--s-2); font: var(--t-small); color: var(--gr-muted); }
/* Lightbox: a modal <dialog>. The picture at its full 2x size on the desk ground, scrollable; Esc, the key or a click
   outside the picture closes it and focus goes back to the picture. */
.zoom { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; color: var(--gr-ink); overflow: hidden; }
.zoom::backdrop { background: var(--scrim); }
.zoom[open] { display: flex; flex-direction: column; animation: gr-fade-in var(--dur-slow) var(--ease) both; }
.zoom[open]::backdrop { animation: gr-fade-in var(--dur-slow) var(--ease) both; }
.zoom.is-leaving, .zoom.is-leaving::backdrop { animation: gr-fade-out var(--dur-exit-slow) var(--ease) both; }
.zoom-bar { display: flex; align-items: center; gap: var(--s-3); height: var(--top-h); padding: 0 var(--s-3) 0 var(--gutter); background: var(--gr-card); border-bottom: 1px solid var(--gr-rule-strong); font: var(--t-small); color: var(--gr-ink-2); }
.zoom-bar .alt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zoom-body { flex: 1; overflow: auto; display: grid; place-items: center; padding: var(--s-8); background: var(--gr-desk); }
.zoom-body img { max-width: none; border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); animation: gr-arrive var(--dur-slow) var(--ease) both; cursor: zoom-out; }
.zoom-body .frame { position: relative; }

/* Side panel: a docked column on the card ground, one rule from the page. Not a modal on a desktop (no scrim, the page
   stays usable); full screen, modal and focus-trapped on a phone. It lives in the URL as ?panel=. Opening slides its
   content 12px in with a fade; a phone's page slides in from the right; closing fades. */
.panel {
  position: sticky; top: var(--top-h); flex: none; width: var(--panel-w); height: calc(100vh - var(--top-h)); height: calc(100dvh - var(--top-h));
  overflow-y: auto; background: var(--gr-card); border-left: 1px solid var(--gr-rule); --fade-bg: var(--gr-card);
}
.panel { position: fixed; top: var(--top-h); right: 0; bottom: 0; z-index: 28; height: auto; }
.panel.over { box-shadow: var(--shadow-dialog); border-left-color: var(--gr-rule-strong); }
.panel:focus, .panel h2:focus { outline: none; }
.q a[aria-current] { background: var(--sheet-hover); }
.panel.is-opening > * { animation: gr-panel-in var(--dur-slow) var(--ease) both; }
.panel.is-leaving { animation: gr-fade-out var(--dur-exit-slow) var(--ease) both; }
@keyframes gr-panel-in { from { opacity: 0; transform: translateX(12px); } }
@keyframes gr-panel-page { from { transform: translateX(100%); } }
.panel-head { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: var(--s-3); min-height: 64px; padding: var(--s-3) var(--s-3) var(--s-3) var(--s-5); background: var(--gr-card); border-bottom: 1px solid var(--gr-rule); }
.panel-head h2 { flex: 1; margin: 0; font: var(--t-h3); }
.panel-body { padding: var(--s-4) var(--s-5) var(--s-10); }
.panel-body > :last-child { margin-bottom: 0; }
.panel-body p, .panel-body ul, .panel-body ol { max-width: none; }
.panel-body .shot .ring { box-shadow: 0 0 0 2px var(--gr-card), 0 0 0 4px var(--gr-ink); }
body.panel-open .side { display: flex; }
/* The page steps aside for the docked panel (SYSTEM §8): the column gives up the panel's width, so the doc container
   narrows and every form re-fits; below 1680 the sidebar steps aside too. .over (with its shadow) is only the
   leftover case where the text still can't fit. */
@media (min-width: 1024px) {
  body.panel-open .col { padding-right: var(--panel-w); }
}
@media (min-width: 1024px) and (max-width: 1679px) {
  body.panel-open .side { display: none; }
}
@media (min-width: 1024px) and (max-width: 1279px) { :root { --panel-w: 400px; } }
@media (min-width: 1920px) { :root { --panel-w: 520px; } }

/* ═══ 8a · SHARED FORMS, ROUND 4 (one form per kind of information; the kit is forms.mjs / h.mjs) ══════════════════
   The code lane's height, the example response's fold, pictures on a phone, catalogues, comparisons, landings, keys,
   titled sheets, aliases, edition run-ins. */
/* The code lane: every block at most a screen tall (it scrolls inside), so the lane stays beside its text. */
@container doc (min-width: 960px) {
  .pair > .r pre { max-height: min(calc(100vh - 160px), 34rem); overflow: auto; }
  .pair > .r .resp-fold pre { max-height: min(calc(100vh - 220px), 28rem); }
}
details.resp-fold { margin: var(--s-4) 0 0; border: 0; background: none; border-radius: 0; max-width: none; }
details.resp-fold > summary { list-style: none; display: flex; align-items: center; gap: 6px; padding: 0; min-height: 0; cursor: pointer; }
details.resp-fold > summary::-webkit-details-marker { display: none; }
details.resp-fold > summary::before { content: ""; width: 12px; height: 12px; flex: none; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m9 6 6 6-6 6' fill='none' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center / 12px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m9 6 6 6-6 6' fill='none' stroke='black' stroke-width='2'/%3E%3C/svg%3E") center / 12px no-repeat; transition: transform var(--dur-quick) var(--ease); }
details.resp-fold[open] > summary::before { transform: rotate(90deg); }
details.resp-fold > .fold-body { padding: 0; }
details.resp-fold > .fold-body > * { margin-left: 0 !important; margin-right: 0 !important; }
details.resp-fold > .fold-body > .code { margin-top: var(--s-2); }
/* Pictures on a phone: below a 728px column a capture fits the column (rings are percentages, so they stay on their
   control); Enlarge is always shown and opens it at 1:1. */
@container doc (max-width: 727px) {
  .shot { overflow: visible; margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; max-width: 100%; }
  .shot .shot-zoom { width: 100%; } /* a button sizes to its content: give it the column */
  .shot .frame { max-width: 100%; height: auto; }
  .shot .frame img { width: 100%; height: auto; }
  .shot .zoom-hint { opacity: 1; transform: none; }
}
/* The "You should see" words */
.see-k { color: var(--gr-muted); }
.see .st, .see kbd, .see .kbd { text-indent: 0; }
/* Old ids kept as anchors */
.alias, .ba-alias, .sh-alias, .em-alias { display: block; height: 0; overflow: hidden; }
/* Edition run-ins on a page without "Steps for": "Self-hosted: …", "In Embed: …" */
.ed-aside .ri { font-weight: var(--w-strong); color: var(--gr-ink); }
/* A titled sheet that isn't "You need" (the roles, a backup's contents, a group of keys) */
.doc .sheet.titled { margin: var(--s-6) 0; max-width: var(--col); }
/* Tables: fixed column widths (the same across a catalogue's bands) */
table.fixed { table-layout: fixed; width: 100%; }
.nm-cell a { color: inherit; text-decoration: none; }
.nm-cell a:hover { text-decoration: underline; }
/* A comparison: ✓ Yes / — No in ink (colour is for run states only), then the recommendation */
.compare .yes { color: var(--gr-ink); font-weight: var(--w-strong); white-space: nowrap; }
.compare .no { color: var(--gr-muted); white-space: nowrap; }
.compare-say { margin-top: var(--s-4); }
/* A catalogue's filter: a short placeholder, the example under it */
.filter-hint { margin: calc(-1 * var(--s-2)) 0 var(--s-4); font: var(--t-small); color: var(--gr-muted); }
.filter-row .field::-webkit-search-cancel-button, .field::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
/* The landing (PRESENTATION §2.23) */
.landing > h2#start-here { margin-top: var(--s-8); }
.landing .rows-2 { max-width: var(--col); }
.doc[data-frame="wide"] .landing .rows-2 { max-width: none; }
/* Keys: the Mac / Windows control (a two-key segmented control) */
.seg { display: inline-flex; border: 1px solid var(--gr-control); border-radius: var(--r-control); overflow: hidden; margin: var(--s-2) 0 var(--s-4); }
.seg button { all: unset; box-sizing: border-box; height: 32px; padding: 0 var(--s-3); font: var(--t-small); color: var(--gr-ink-2); cursor: pointer; }
.seg button + button { border-left: 1px solid var(--gr-control); }
.seg button[aria-checked="true"] { background: var(--gr-hover); color: var(--gr-ink); font-weight: var(--w-strong); }
.seg button:focus-visible { outline: 2px solid var(--gr-ink); outline-offset: -2px; }
@media (pointer: coarse) { .seg button { height: 44px; } }
/* "Steps for": every page of a section that has it keeps its band, so the sidebar never jumps between pages */
.side-head.is-reserved { display: block; border-bottom-color: transparent; }
.side-head.is-reserved .ed-home { min-height: 28px; } /* the height of .ed */
@media (max-width: 1023px) { .side-head.is-reserved .ed-home { min-height: 0; } }
/* The sections, first in the phone's sheet (a compact line); the desktop has them in the top bar */
.side-secs { display: none; }
@media (max-width: 1023px) {
  .side-secs { display: flex; flex-wrap: wrap; gap: 0 var(--s-4); margin: 0 0 var(--s-6); padding-bottom: var(--s-4); border-bottom: 1px solid var(--gr-rule-subtle); }
  .side-secs a { display: flex; align-items: center; min-height: 40px; color: var(--gr-ink-2); }
  .side-secs a[aria-current] { color: var(--gr-ink); font-weight: var(--w-strong); }
}

/* ═══ 8b · PAGE FORMS (PRESENTATION §2, generalised from the section builds) ════════════════════════════════════
   "You need" and definition rows (.defs), the run-state legend (.legend-states), a workflow as text (.outline), a
   sheet's rows in HTML (.html-sheet), troubleshooting (.symptoms, .cause), expression anatomy (.anatomy), the
   endpoint pieces (.ep-sig, .params, .resp, .ep-sec, .code-cap, .related-line), command steps in Split (.cmd-step),
   output blocks (.output), the still sequence diagram (.seq), line diagrams (.line-fig) and the settings catalogue
   (.catalogue). The kit that writes them is site/_src/lib/forms.mjs (ctx.h.*). */
/* ── Long addresses and file names never push the page sideways ── */
.doc p code, .doc li code { overflow-wrap: anywhere; }
.code-bar .file { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Build: "You need" and definition rows (PRESENTATION §2.4) */
.doc .defs { max-width: var(--col); margin: var(--s-4) 0 var(--s-6); }
.doc .defs { display: grid; grid-template-columns: fit-content(40%) minmax(0, 1fr); column-gap: var(--s-6); }
.defs > div { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; padding: var(--sheet-y) var(--sheet-x); }
.defs dt { font-weight: var(--w-strong); }
.defs dd { margin: 0; color: var(--gr-ink-2); max-width: var(--prose); }
.defs-code dt { font-weight: var(--w-regular); }
.doc .defs-code { grid-template-columns: fit-content(30%) minmax(0, 1fr); }
.anatomy .defs dd { color: var(--gr-ink); }
@container doc (max-width: 727px) { .doc .defs, .doc .defs-code { grid-template-columns: minmax(0, 1fr); } .defs > div { row-gap: 2px; } .defs dd { font: var(--t-small); } }

/* Build: the run-state legend (PRESENTATION §2.8) */
.doc .legend-states { list-style: none; padding: 0; margin: var(--s-4) 0 var(--s-6); max-width: var(--col); }
.legend-states li { display: grid; grid-template-columns: 128px minmax(0, 1fr) auto; column-gap: var(--s-4); align-items: baseline; margin: 0; padding: var(--sheet-y) var(--sheet-x); }
.legend-states .m { color: var(--gr-ink-2); }
.legend-states .api { font: var(--t-code-small); color: var(--gr-muted); text-align: right; }
@container doc (max-width: 727px) { .legend-states li { grid-template-columns: 112px minmax(0, 1fr); } .legend-states .api { grid-column: 2; text-align: left; } }

/* Build: the workflow as text (PRESENTATION §2.7) */
.outline { max-width: var(--col); margin: var(--s-4) 0 var(--s-6); padding: var(--s-3) var(--s-4); background: var(--gr-well); font: var(--t-code-small); overflow-x: auto; }
.outline .r { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; column-gap: var(--s-3); padding: 3px 0; white-space: nowrap; }
.outline .r .nm { padding-left: calc(var(--d) * 24px); }
.outline .r .n { color: var(--gr-muted); }
.outline .r .ap { color: var(--gr-muted); text-align: right; }
.outline .r.arm .nm { color: var(--gr-ink-2); }
.outline .r.arm .nm { padding-left: calc((var(--d) - 1) * 24px); }
.outline .r.arm .nm::before { content: "└ "; color: var(--gr-muted); }

/* Build: a sheet's rows, in HTML (PRESENTATION §2.3) */
.html-sheet { margin: var(--s-5) 0 var(--s-6); max-width: 100%; overflow-x: auto; }
.html-sheet .frame { width: max-content; border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); background: var(--gr-card); }
.html-sheet table { border-collapse: collapse; font: var(--t-small); }
.html-sheet th, .html-sheet td { border: 1px solid var(--gr-rule-subtle); padding: 6px 12px; height: 32px; text-align: left; white-space: nowrap; }
.html-sheet thead th { font-weight: var(--w-regular); color: var(--gr-muted); text-align: center; background: var(--gr-well); }
.html-sheet tbody th { font-weight: var(--w-regular); color: var(--gr-muted); width: 36px; text-align: center; background: var(--gr-well); }
.html-sheet td { min-width: 160px; }
.html-sheet tbody tr:first-child td { font-weight: var(--w-strong); }
.html-sheet tr.is-ring td { position: relative; background: var(--gr-wash); }
.html-sheet tr.is-ring td::after { content: ""; position: absolute; inset: -1px; border: 2px solid var(--gr-ink); border-left-width: 0; border-right-width: 0; pointer-events: none; }
.html-sheet tr.is-ring td:first-of-type::after { border-left-width: 2px; }
.html-sheet tr.is-ring td:last-of-type::after { border-right-width: 2px; }
.html-sheet figcaption { margin-top: var(--s-2); font: var(--t-small); color: var(--gr-muted); }

/* Build: troubleshooting (PRESENTATION §2.18) */
.doc .symptoms { list-style: none; padding: 0; margin: var(--s-4) 0 var(--s-8); max-width: var(--col); }
.symptoms li { margin: 0; }
.symptoms a { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s-6); padding: var(--sheet-y) var(--sheet-x); text-decoration: none; color: var(--gr-ink); transition: background-color var(--dur-quick) var(--ease); }
.symptoms a:hover { background: var(--sheet-hover); }
.symptoms a:focus-visible { outline-offset: -2px; }
.symptoms .pg { color: var(--gr-ink-2); text-decoration: underline; text-decoration-color: var(--gr-rule-emph); text-underline-offset: 3px; text-decoration-thickness: 1px; }
@container doc (max-width: 727px) { .symptoms a { grid-template-columns: 1fr; row-gap: 2px; } .symptoms .pg { font: var(--t-small); } }
.cause { display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: var(--s-3); max-width: calc(var(--prose) + 52px); }
.cause .ri { font-weight: var(--w-strong); }
.cause p { margin: 0 0 var(--s-3); }
.doc .cause ol.steps { margin: 0; }
.cause ol.steps > li { padding-left: 28px; }
.cause ol.steps > li::before { right: auto; left: 0; width: auto; padding: 0; text-align: left; }
/* In the side panel there is no margin for hanging numbers: they sit inside, as in a step. */
.panel-body ol.steps > li { padding-left: 28px; }
.panel-body ol.steps > li::before { right: auto; left: 0; width: auto; padding: 0; text-align: left; }

/* Build: expression anatomy (PRESENTATION §2.9) */
.anatomy .ex { margin: var(--s-4) 0 var(--s-2); }
.anatomy .ex code { font: var(--t-code); }
.anatomy .ex code span { border-bottom: 1px solid var(--gr-rule-emph); }

/* Build: one-line facts under a picture */
.shot-cap { font: var(--t-small); color: var(--gr-muted); margin-top: calc(-1 * var(--s-3)); }


/* Endpoint signature: the method as a word, the path in Mono, breakable after slashes (SITEMAP §3.6). */
.sig.ep-sig { display: block; margin: 0 0 var(--s-4); text-align: start; }
.ep-sig .method { display: inline; min-width: 0; margin-right: 10px; font: var(--t-code); font-weight: var(--w-strong); }
.ep-sig code { font: var(--t-code); color: var(--gr-ink); }
.ep-needs { color: var(--gr-ink-2); }
/* Split sections of an endpoint page: each L section and its R block are one pair. No rule between pairs (a free
   hairline between blocks is the C law's "no"): the gap and the h2 carry the break. */
.ep-sec { margin-top: var(--s-12); }
.ep-sec:first-of-type { margin-top: var(--s-6); }
.ep-sec h2 { margin-top: var(--s-4); }
.ep-sec .r > .code:first-child, .ep-sec .r > .code-cap:first-child + .code { margin-top: var(--s-4); }
.code-cap { font: var(--t-small); color: var(--gr-muted); margin: var(--s-4) 0 calc(-1 * var(--s-2)); }
@container doc (max-width: 959px) { .ep-first .pair > .r { order: -1; } .ep-first .pair > .r > .code:first-child { margin-top: 0; } }
@container doc (max-width: 727px) { .doc .pair > .r .code { margin-left: -16px; margin-right: -16px; border-left: 0; border-right: 0; } }
/* Parameter rows */
.params { margin: var(--s-3) 0 var(--s-4); max-width: none !important; }
.params > div { padding: var(--sheet-y) var(--sheet-x); scroll-margin-top: calc(var(--top-h) + var(--s-6)); }
.params dt { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-3); }
.params dt code { font: var(--t-code); color: var(--gr-ink); overflow-wrap: anywhere; }
.params dt span { font: var(--t-small); color: var(--gr-muted); white-space: nowrap; }
.params dd { margin: 4px 0 0; }
.params dd p { margin: 0 0 var(--s-2); max-width: var(--prose); }
.params dd p:last-child { margin: 0; }
.doc .params + h3 { margin-top: var(--s-6); }
.ep-sec h3 { font: var(--t-small); font-weight: var(--w-strong); color: var(--gr-ink-2); margin: var(--s-6) 0 var(--s-2); }
.ep-sec h2 + h3 { margin-top: var(--s-3); }
/* Responses inside L: the error rows, a little tighter */
.doc .resp { max-width: none; margin: var(--s-3) 0 var(--s-4); }
.resp .err-head { grid-template-columns: 40px minmax(0, 1fr) auto; }
.resp p { margin-left: 52px !important; }
.resp .resp-ok { color: var(--gr-ink-2); }
.resp .err-head code { font-size: 14px; }
.related-line { margin-top: var(--s-10); color: var(--gr-ink-2); }
.folds { margin-top: var(--s-10); }
/* Output blocks: no Copy; check marks in their state's word colour */
.output .code-bar { min-height: 36px; }
.out-m { font-weight: var(--w-strong); }
.out-m.ok { color: var(--gr-ok); } .out-m.warn { color: var(--gr-warn); } .out-m.bad { color: var(--gr-bad); }
/* Command steps in Split (§2.2): number in L at h2 size, nothing sticky. No rule between steps: the gap, the number
   and the h2 carry the break. */
.cmd-step { padding: var(--s-10) 0 var(--s-2); }
.cmd-step:first-of-type { margin-top: var(--s-6); padding-top: 0; }
.cmd-step h2 { margin: 0 0 var(--s-3); scroll-margin-top: calc(var(--top-h) + var(--s-6)); }
.cmd-step h2 .n { position: static; display: inline; width: auto; padding: 0 .35em 0 0; }
.cmd-step .pair > .r { position: static; max-height: none; overflow: visible; }
.cmd-step .pair > .r > .code:first-child { margin-top: 0; }
@container doc (min-width: 960px) { .cmd-step .pair > .r { padding-top: 2px; } }
.cmd-step .r:empty { display: none; }
.cmd-step .tbl-wrap { margin: var(--s-3) 0 var(--s-4); }
/* The still sequence diagram */
.seq-fig { margin-top: var(--s-6); margin-bottom: var(--s-8); }
.seq { --lane: calc(100% / var(--L)); position: relative; border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); background: var(--gr-card); padding: 0 0 0; }
.seq-lanes { display: grid; grid-template-columns: repeat(var(--L), minmax(0, 1fr)); position: relative; z-index: 1; }
.seq-lanes span { margin: var(--s-3) var(--s-2); padding: var(--s-2) var(--s-2); text-align: center; font: var(--t-small); font-weight: var(--w-strong); color: var(--gr-ink); background: var(--gr-card); border: 1px solid var(--gr-rule-strong); }
.seq-rows { list-style: none; margin: 0; padding: var(--s-2) 0 var(--s-6); max-width: none !important; position: relative; background-image: linear-gradient(to right, transparent calc(50% - .5px), var(--gr-rule-strong) calc(50% - .5px), var(--gr-rule-strong) calc(50% + .5px), transparent calc(50% + .5px)); background-size: var(--lane) 100%; background-repeat: repeat-x; }
.seq-rows > li { display: grid; grid-template-columns: repeat(var(--L), minmax(0, 1fr)); margin: 0; padding: var(--s-2) 0 var(--s-3); position: relative; }
.seq-msg .seq-t, .seq-msg .seq-arrow { grid-column: var(--a) / var(--b); grid-row: 1; }
.seq-msg .seq-t { align-self: end; justify-self: center; text-align: center; margin: 0 var(--s-6) 12px; padding: 0 var(--s-2); background: var(--gr-card); font: var(--t-small); color: var(--gr-ink); max-width: calc(100% - 2 * var(--s-6)); position: relative; z-index: 1; }
.seq-sub { display: block; font: var(--t-code-small); color: var(--gr-muted); overflow-wrap: anywhere; }
.seq-arrow { align-self: end; position: relative; height: 9px; margin: 0 calc(100% / (2 * var(--k))); border-bottom: 1px solid var(--gr-ink-2); }
.seq-msg.dashed .seq-arrow { border-bottom-style: dashed; }
.seq-arrow::after { content: ""; position: absolute; right: -1px; bottom: -5px; width: 9px; height: 9px; border-top: 1px solid var(--gr-ink-2); border-right: 1px solid var(--gr-ink-2); transform: rotate(45deg); transform-origin: center; box-sizing: border-box; translate: -3px 0; }
.seq-msg.back .seq-arrow::after { right: auto; left: -1px; transform: rotate(-135deg); translate: 3px 0; }
.seq-n { position: absolute; left: var(--s-3); top: var(--s-2); font: var(--t-small); font-variant-numeric: tabular-nums; color: var(--gr-muted); }
.seq-note .seq-t { grid-column: var(--a); justify-self: center; text-align: center; font: var(--t-small); color: var(--gr-ink-2); background: var(--gr-well); border: 1px solid var(--gr-rule); padding: var(--s-1) var(--s-3); margin: 0 var(--s-2); }
.seq-list { display: none; }
@container doc (max-width: 727px) {
  .seq { display: none; }
  .seq-list { display: block; list-style: none; counter-reset: sq; padding: 0; margin: 0; }
  .seq-list li { counter-increment: sq; position: relative; padding: var(--sheet-y) var(--sheet-x) var(--sheet-y) 48px; margin: 0; }
  .seq-list li::before { content: counter(sq); position: absolute; left: var(--sheet-x); color: var(--gr-muted); font-variant-numeric: tabular-nums; }
  .seq-list b { display: block; font: var(--t-small); font-weight: var(--w-strong); color: var(--gr-ink-2); }
}
/* Diagrams drawn in 1px lines (landings) */
.line-fig { margin-top: var(--s-6); margin-bottom: var(--s-8); }
.line-fig .fig-wide, .line-fig .fig-tall { display: block; max-width: 100%; height: auto; }
.line-fig .fig-tall { display: none; }
@container doc (max-width: 927px) { .line-fig .fig-wide { display: none; } .line-fig .fig-tall { display: block; margin: 0 auto; } }
.line-fig svg text { font: var(--t-small); fill: var(--gr-ink); }
.line-fig svg text.m { fill: var(--gr-muted); }
.line-fig svg text.mono { font: var(--t-code-small); fill: var(--gr-muted); }
.line-fig svg text.b { font-weight: 600; }
.line-fig svg .box { fill: var(--gr-card); stroke: var(--gr-rule-strong); stroke-width: 1; }
.line-fig svg .box.emph { stroke: var(--gr-rule-emph); }
.line-fig svg .well { fill: var(--gr-well); stroke: var(--gr-rule); stroke-width: 1; }
.line-fig svg .dash { fill: none; stroke: var(--gr-rule-emph); stroke-width: 1; stroke-dasharray: 4 4; }
.line-fig svg .ln { fill: none; stroke: var(--gr-ink-2); stroke-width: 1; }
.line-fig svg .hd { fill: var(--gr-ink-2); }
.line-fig figcaption { font: var(--t-small); color: var(--gr-muted); margin-top: var(--s-2); max-width: var(--prose); }
/* Settings catalogue (§2.12) */
.catalogue { width: 100%; border-collapse: collapse; font: var(--t-small); }
.catalogue thead th { text-align: left; font-weight: var(--w-regular); color: var(--gr-ink-2); padding: 10px var(--s-3) 8px 0; border-bottom: 1px solid var(--sheet-edge); }
.catalogue thead th:first-child { padding-left: var(--sheet-x); }
.catalogue td { vertical-align: top; padding: 12px var(--s-3) 12px 0; border-bottom: 1px solid var(--sheet-rule); }
.catalogue td:first-child { width: 300px; padding-left: var(--sheet-x); }
.catalogue td:last-child { padding-right: var(--sheet-x); }
.catalogue .wd details { background: none; }
.catalogue .wd details[open] > summary { border-bottom: 0; }
.catalogue .wd details > summary { min-height: 0; }
.catalogue .wd details > summary:hover { background: none; }
.catalogue .wd .fold-body { padding: 0; }
.catalogue .wd .fold-body > * { margin-left: 0; margin-right: 0; }
.catalogue td:nth-child(2) { width: 180px; }
.catalogue .nm { display: flex; align-items: flex-start; gap: var(--s-1); }
.catalogue .nm code { font: var(--t-code-small); color: var(--gr-ink); overflow-wrap: anywhere; padding-top: 2px; }
.catalogue .nm a { text-decoration: none; }
.catalogue .nm a:hover { text-decoration: underline; text-decoration-color: var(--gr-rule-emph); text-underline-offset: 3px; }
.catalogue .cp { flex: none; margin-left: auto; opacity: 0; transition: opacity var(--dur-quick) var(--ease); }
.catalogue tr:hover .cp, .catalogue .cp:focus-visible, .catalogue tr:focus-within .cp { opacity: 1; }
@media (hover: none) { .catalogue .cp { opacity: 1; } }
.catalogue .df code { font: var(--t-code-small); color: var(--gr-ink); overflow-wrap: anywhere; }
.catalogue .df .w { color: var(--gr-muted); }
.catalogue .wd p { margin: 0; max-width: var(--prose); }
.catalogue .wd details { margin: 2px 0 0 !important; border: 0 !important; max-width: none; }
.catalogue .wd details > summary { font: var(--t-small); color: var(--gr-muted); padding: 2px 0; gap: 4px; display: inline-flex; }
.catalogue .wd details > summary::before { height: 20px; }
.catalogue .wd details[open] > summary { color: var(--gr-ink-2); }
.catalogue .wd details > :not(summary) { margin: 2px 0 var(--s-1); }
.catalogue .wd .callout { margin: var(--s-2) 0 0; font: var(--t-small); }
.catalogue tr.bandrow td { background: var(--gr-well); padding: 0 var(--sheet-x); height: 44px; vertical-align: middle; border-bottom: 1px solid var(--sheet-rule); }
.catalogue tr.bandrow b { font-weight: var(--w-strong); color: var(--gr-ink); }
.catalogue tr.bandrow span { color: var(--gr-muted); margin-left: var(--s-2); }
.catalogue tr[id] { scroll-margin-top: calc(var(--top-h) + var(--s-8)); }
.catalogue tr.is-target td { animation: gr-target 1.6s var(--ease) both; }
.catalogue tr[hidden] { display: none; }
@container doc (max-width: 727px) {
  .catalogue, .catalogue tbody, .catalogue tr, .catalogue td { display: block; width: auto !important; }
  .catalogue thead { display: none; }
  .catalogue tr:not(.bandrow) { padding: var(--sheet-y) var(--sheet-x); }
  .catalogue tr + tr:not([hidden]), .catalogue tbody + tbody:not([hidden]) { border-top: 1px solid var(--sheet-rule); }
  .catalogue tr.bandrow + tr { border-top: 0; }
  .catalogue td, .catalogue tr:not(.bandrow) > td { padding: 0; border: 0; }
  .catalogue .nm code { font: var(--t-code); }
  .catalogue .df { margin: 2px 0 4px; color: var(--gr-muted); }
  .catalogue .df[data-label]:not(:empty)::before { content: attr(data-label) " "; }
  .catalogue tr.bandrow td { display: flex; align-items: center; height: 44px; }
}
.env-block { max-width: var(--col) !important; }
/* Endpoint lists on the landings */
.ep-list .band { font: var(--t-h3); }
.ep-list .ref-list .v .method { font-weight: var(--w-strong); color: var(--gr-ink); }
.ep-list section[hidden] { display: none; }
/* Small things */
.lookup-line { margin-top: var(--s-10); }
.shot-cap { font: var(--t-small); color: var(--gr-muted); margin: calc(-1 * var(--s-3)) 0 var(--s-6); }
.choose-table td:first-child { white-space: nowrap; }

/* A task grid filling its breakout (PRESENTATION §2.23) */
.tasks-grid .rows { max-width: none; }
.doc .tasks-grid { margin-bottom: var(--s-8); }
/* The canvas from a container of 728; its text outline below that (PRESENTATION §2.7) */
.canvas-or-outline .outline { display: none; }
@container doc (max-width: 727px) { .canvas-or-outline .breakout { display: none; } .canvas-or-outline .outline { display: block; } .wide-only { display: none; } }

/* ═══ 8c · PRODUCT REPLAYS (MOTION.md; R3/motion, moved here) ═══════════════════════════════════════════════════
   A short replay of the product, rebuilt in HTML: <figure class="rp" data-replay> with .rp-frame > .rp-stage
   (aria-hidden: the steps under it are its text), .rp-steps and one .rp-key. docs.js plays it. Manual's Paper tokens
   are mapped onto the system's inside .rp only. On a phone (a container under 728) it starts as a compact poster with
   Play, so the steps after it stay near the top of the page. */
.rp { --paper: var(--gr-paper); --card: var(--gr-card); --well: var(--gr-well); --hover: var(--gr-hover); --ink: var(--gr-ink); --ink-2: var(--gr-ink-2); --muted: var(--gr-muted); --rule-subtle: var(--gr-rule-subtle); --rule: var(--gr-rule); --rule-strong: var(--gr-rule-strong); --rule-emph: var(--gr-rule-emph); --control: var(--gr-control); --ok: var(--gr-ok); --bad: var(--gr-bad); --run: var(--gr-run);
  --rp-info: var(--gr-run); --rp-dot: light-dark(rgb(43 41 38 / .16), rgb(229 227 224 / .14)); --rp-edge: var(--gr-edge); --rp-tile: light-dark(rgb(43 41 38 / .14), rgb(229 227 224 / .16)); --rp-wire: var(--gr-rule-strong); }
.doc figure.rp { margin: var(--s-6) 0 var(--s-8); }
.doc .rp-steps { max-width: var(--prose); }
.doc .rp-steps li { margin: 0 0 6px; }
.doc .rp-steps li::marker { content: none; }

.rp { margin: 20px 0 28px; max-width: 680px; }
.rp-frame {
  position: relative; height: var(--rp-h, 400px); overflow: hidden; cursor: pointer;
  border: 1px solid var(--rule-strong); border-top-color: var(--rule-emph); background: var(--paper);
  -webkit-tap-highlight-color: transparent;
}
.rp-stage {
  position: absolute; inset: 0; font-size: 15px; line-height: 22px; letter-spacing: .16px; color: var(--ink);
  transition: opacity 180ms var(--ease);
}
.rp-stage.rp-out { opacity: 0; transition-duration: 120ms; }
.rp-stage * { box-sizing: border-box; }
.rp-instant .rp-stage, .rp-instant .rp-stage * { transition: none !important; animation: none !important; }
.rp-foot { display: grid; grid-template-columns: 1fr auto; align-items: start; column-gap: 16px; margin-top: 12px; }
.rp-steps { list-style: none; margin: 0; padding: 0; counter-reset: rp; font-size: 14px; line-height: 20px; max-width: 576px; }
.rp-steps li { counter-increment: rp; display: grid; grid-template-columns: 20px 1fr; margin: 0 0 6px; color: var(--muted); transition: color 120ms var(--ease); }
.rp-steps li::before { content: counter(rp) "."; color: var(--muted); }
.rp-steps li[aria-current] { color: var(--ink); }
.rp-steps li[aria-current]::before { color: var(--ink); }
.rp-steps b { font-weight: 600; color: inherit; }
.rp-steps code { font-size: 14px; line-height: 20px; }
.rp-steps button { all: unset; cursor: pointer; }
.rp-steps button:hover { text-decoration: underline; text-decoration-color: var(--rule-emph); text-underline-offset: 3px; }
.rp-steps button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rp-reduced .rp-steps li, .rp-reduced .rp-steps li::before { color: var(--ink-2); }
.rp-key {
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px 0 8px; cursor: pointer;
  background: var(--card); color: var(--ink); border: 1px solid var(--control); border-radius: 2px;
  box-shadow: 0 2px 0 0 var(--control); font: 400 14px/20px var(--sans); white-space: nowrap;
  transition: transform 120ms var(--ease), box-shadow 120ms var(--ease);
}
.rp-key:active { transform: translateY(2px); box-shadow: none; }
.rp-key svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: square; stroke-linejoin: miter; }
.rp-key[data-k="play"] svg { fill: currentColor; stroke: none; }
.rp-scene { position: absolute; inset: 0; opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 120ms var(--ease), transform 0s linear 120ms, visibility 0s linear 120ms; }
.rp-scene.is-on { opacity: 1; visibility: visible; transform: none;
  transition: opacity 180ms var(--ease), transform 180ms var(--ease), visibility 0s; }
.rp-in { opacity: 0; transform: translateY(4px); transition: opacity 120ms var(--ease), transform 120ms var(--ease); }
.rp-in.is-on { opacity: 1; transform: none; transition-duration: 180ms; }
.rp-ring { position: absolute; border-radius: 2px; pointer-events: none; opacity: 0; box-shadow: inset 0 0 0 2px var(--ink); transition: opacity 180ms var(--ease); }
.rp-ring.is-on { opacity: 1; }
.rp-ic { display: block; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: square; stroke-linejoin: miter; }
.rp-ic * { vector-effect: non-scaling-stroke; }
@keyframes rp-spin { to { transform: rotate(360deg); } }
.rp-spin { animation: rp-spin 900ms linear infinite; }
.rp-paused .rp-spin { animation-play-state: paused; }
.rp-bar { position: relative; z-index: 1; display: flex; align-items: center; gap: 12px; height: 48px; padding: 0 16px; background: var(--paper); border-bottom: 1px solid var(--rule); white-space: nowrap; overflow: hidden; }
.rp-bar .rp-back { color: var(--ink-2); }
.rp-bar-name { font-size: 16px; line-height: 22px; font-weight: 600; letter-spacing: 0; }
.rp-bar-state { position: relative; display: flex; align-items: center; min-width: 0; font-size: 14px; line-height: 20px; color: var(--ink-2); }
.rp-bar-state .rp-st { display: inline-flex; align-items: center; gap: 6px; }
.rp-bar-state .rp-st + .rp-st { position: absolute; left: 0; top: 0; }
.rp-st { opacity: 0; transition: opacity 120ms var(--ease); }
.rp-st.is-on { opacity: 1; transition-duration: 180ms; }
.rp-st .w-run { color: var(--rp-info); font-weight: 600; }
.rp-st .w-ok { color: var(--ink-2); }
.rp-st .w-bad { color: var(--bad); font-weight: 600; }
.t-ok { color: var(--ok); } .t-bad { color: var(--bad); } .t-run { color: var(--rp-info); }
.rp-canvas { position: absolute; inset: 48px 0 0; background-color: var(--paper); background-image: radial-gradient(var(--rp-dot) .7px, transparent 1.15px); background-size: 22px 22px; background-position: 11px 11px; }
.rp-canvas.is-full { inset: 0; }
.rp-flow { position: absolute; left: 50%; width: min(384px, calc(100% - 32px)); transform: translateX(-50%); display: flex; flex-direction: column; }
.rp-card {
  position: relative; z-index: 1; display: flex; align-items: center; gap: 12px; height: 70px; padding: 0 16px 0 14px;
  background: var(--card); border: 1px solid var(--rule-strong); border-radius: 2px;
  transition: border-color 120ms var(--ease), box-shadow 120ms var(--ease);
}
.rp-card.is-running { border-color: var(--ink); }
.rp-card.is-selected { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.rp-tile { width: 32px; height: 32px; flex: none; display: grid; place-items: center; background: var(--card); border-radius: 2px; box-shadow: inset 0 0 0 1px var(--rp-tile); color: var(--ink); }
.rp-tile img { width: 19px; height: 19px; display: block; }
:root[data-theme="dark"] .rp-tile.is-logo { background: #f4f2ea; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .rp-tile.is-logo { background: #f4f2ea; } }
.rp-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rp-title { font-size: 14px; line-height: 20px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-meta { font-size: 13px; line-height: 18px; letter-spacing: .25px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-meta .n { color: var(--muted); }
.rp-lens { position: relative; flex: none; width: 92px; height: 38px; }
.rp-out-s { position: absolute; right: 0; top: 0; display: grid; grid-template-columns: auto auto; grid-template-rows: 20px 18px; column-gap: 6px; align-items: center; justify-items: end;
  font-size: 14px; line-height: 20px; opacity: 0; transition: opacity 120ms var(--ease); }
.rp-out-s.is-on { opacity: 1; transition-duration: 180ms; }
.rp-out-s .w { grid-column: 2; color: var(--ink-2); white-space: nowrap; }
.rp-out-s .tm { grid-column: 2; justify-self: start; font-size: 13px; line-height: 18px; color: var(--ink-2); }
.rp-out-s.is-bad .w { color: var(--bad); font-weight: 600; }
.rp-out-s.is-run .w { color: var(--ink); }
.rp-out-s.is-run { color: var(--ink-2); }
.rp-out-s.is-not .w { color: var(--muted); }
.rp-fault { position: absolute; top: 100%; left: -1px; right: -1px; margin: 0; padding: 7px 14px 9px 58px; background: var(--card);
  border: 1px solid var(--rule-strong); border-top: 0; color: var(--bad); font-size: 12px; line-height: 16px;
  opacity: 0; transition: opacity 120ms var(--ease); }
.rp-fault.is-on { opacity: 1; transition-duration: 180ms; }
.rp-wire { position: relative; height: 56px; }
.rp-wire::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; margin-left: -.75px; border-left: 1.5px solid var(--rp-wire); transition: border-color 180ms var(--ease); }
.rp-wire.is-taken::before { border-left-color: var(--ink); }
.rp-wire.is-off::before { border-left-style: dashed; border-left-color: var(--rule-emph); }
.rp-wire .sq { position: absolute; left: 50%; top: 50%; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; background: var(--ink-2); }
.rp-pub { position: absolute; left: 50%; top: 24px; width: min(420px, calc(100% - 32px)); transform: translateX(-50%); }
.rp-pub-top { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; font-size: 15px; line-height: 24px; font-weight: 600; letter-spacing: 0; }
.rp-pub-top svg { width: 20px; height: 20px; fill: currentColor; }
.rp-panel { background: var(--card); border: 1px solid var(--rule); border-radius: 2px; padding: 24px; transition: opacity 120ms var(--ease); }
.rp-panel h3 { margin: 0; font-size: 24px; line-height: 32px; font-weight: 600; letter-spacing: -.01em; }
.rp-panel label { display: block; margin: 16px 0 6px; font-size: 14px; line-height: 20px; font-weight: 600; }
.rp-field { position: relative; height: 44px; padding: 10px 12px; background: var(--card); border: 1px solid var(--control); border-radius: 2px; font-size: 16px; line-height: 22px; letter-spacing: .01em; white-space: nowrap; overflow: hidden; transition: border-color 120ms var(--ease); }
.rp-field.is-focus { border-color: var(--ink); }
.rp-caret { display: inline-block; width: 1px; height: 20px; margin-left: 1px; vertical-align: -4px; background: var(--ink); opacity: 0; }
.rp-field.is-focus .rp-caret { opacity: 1; }
.rp-submit { display: flex; align-items: center; justify-content: center; gap: 8px; height: 44px; margin-top: 22px; border-radius: 2px;
  background: var(--ink); color: var(--paper); font-size: 15px; line-height: 20px; font-weight: 600; box-shadow: 0 2px 0 0 var(--rp-edge);
  transition: transform 120ms var(--ease), box-shadow 120ms var(--ease); }
.rp-submit.is-down { transform: translateY(1px); box-shadow: 0 1px 0 0 var(--rp-edge); }
.rp-submit .rp-busy { display: none; width: 14px; height: 14px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--paper) 35%, transparent); border-top-color: var(--paper); }
.rp-submit.is-busy .rp-busy { display: block; animation: rp-spin 900ms linear infinite; }
.rp-pub.is-busy .rp-panel label, .rp-pub.is-busy .rp-field { opacity: .55; }
.rp-sheet { position: absolute; left: 50%; top: 50%; width: min(520px, calc(100% - 32px)); transform: translate(-50%, -50%);
  border: 1px solid var(--rule); background: var(--card); font-size: 14px; line-height: 20px; }
.rp-sheet table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 14px; }
.rp-sheet th, .rp-sheet td { height: 34px; padding: 0 10px; border: 1px solid var(--rule-subtle); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); vertical-align: middle; }
.rp-sheet thead th { height: 26px; background: var(--well); color: var(--muted); font-weight: 400; text-align: center; font-size: 13px; }
.rp-sheet tbody th { width: 40px; background: var(--well); color: var(--muted); font-weight: 400; text-align: center; font-size: 13px; padding: 0; }
.rp-sheet .hd td { font-weight: 600; }
.rp-sheet td span { display: inline-block; opacity: 0; transform: translateY(4px); transition: opacity 120ms var(--ease), transform 120ms var(--ease); }
.rp-sheet tr.is-on td span { opacity: 1; transform: none; transition-duration: 180ms; }
.rp-sheet tr.is-on td:not(.blank) { background: color-mix(in srgb, var(--ink) 4.5%, transparent); }
.rp-sheet td { transition: background-color 240ms var(--ease); }
.rp-sheet-name { position: absolute; left: 0; right: 0; bottom: 100%; padding: 0 0 8px; font-size: 13px; line-height: 18px; color: var(--muted); }
.rp-split { position: absolute; inset: 0; display: grid; grid-template-columns: 248px 1fr; background: var(--card); }
.rp-data { display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--rule); background: var(--card); }
.rp-data-head { display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 12px; border-bottom: 1px solid var(--rule); font-size: 13px; line-height: 18px; font-weight: 600; flex: none; }
.rp-data-head .rp-ic { color: var(--ink-2); }
.rp-data-search { padding: 8px 12px; border-bottom: 1px solid var(--rule); flex: none; }
.rp-data-search div { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; background: var(--well); border: 1px solid var(--control); border-radius: 2px; font-size: 14px; color: var(--muted); }
.rp-band { height: 0; overflow: hidden; flex: none; background: color-mix(in srgb, var(--ink) 6%, transparent); font-size: 12px; line-height: 16px; color: var(--ink-2); opacity: 0;
  transition: height 180ms var(--ease), opacity 120ms var(--ease); border-bottom: 0 solid var(--rule); }
.rp-band p { margin: 0; padding: 8px 12px; }
.rp-band b { font-weight: 600; color: var(--ink); }
.rp-band.is-on { height: 33px; opacity: 1; border-bottom-width: 1px; }
.rp-tree { flex: 1; min-height: 0; overflow: hidden; padding: 6px; font-size: 12px; line-height: 16px; }
.rp-sec { display: flex; align-items: center; gap: 8px; padding: 8px; font-size: 13px; line-height: 18px; }
.rp-sec .rp-tile { width: 20px; height: 20px; }
.rp-sec .rp-tile img { width: 12px; height: 12px; }
.rp-chev { color: var(--muted); }
.rp-kids { margin-left: 20px; padding-left: 10px; border-left: 1px solid var(--rule); }
.rp-kids .rp-kids { margin-left: 8px; padding-left: 8px; border-left-color: color-mix(in srgb, var(--rule) 50%, transparent); }
.rp-row { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 2px; white-space: nowrap; transition: background-color 120ms var(--ease); }
.rp-row .k { font-weight: 600; color: var(--ink); flex: none; }
.rp-row .v { color: var(--ink); overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.rp-row .ty { color: var(--muted); }
.rp-row .ins { color: var(--ink); opacity: 0; transition: opacity 120ms var(--ease); flex: none; }
.rp-row.is-hover { background: color-mix(in srgb, var(--ink) 5%, transparent); }
.rp-row.is-hover .ins { opacity: 1; }
.rp-row.is-down { background: color-mix(in srgb, var(--ink) 10%, transparent); }
.rp-row.is-down .ins { opacity: 1; }
.rp-data-foot { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-top: 1px solid var(--rule); font-size: 12px; line-height: 16px; color: var(--ink-2); flex: none; white-space: nowrap; overflow: hidden; }
.rp-data-foot i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink); flex: none; }
.rp-form { padding: 16px 16px 16px 20px; min-width: 0; overflow: hidden; }
.rp-lbl { display: flex; gap: 8px; align-items: baseline; font-size: 14px; line-height: 20px; font-weight: 600; }
.rp-lbl span { font-weight: 400; color: var(--muted); }
.rp-hint { margin: 4px 0 8px; font-size: 13px; line-height: 18px; color: var(--ink-2); }
.rp-input { height: 40px; padding: 9px 12px; background: var(--card); border: 1px solid var(--control); border-radius: 2px; font-size: 15px; line-height: 20px; margin-bottom: 18px; white-space: nowrap; overflow: hidden; }
.rp-expr { position: relative; min-height: 88px; padding: 10px 12px; background: var(--card); border: 1px solid var(--control); border-radius: 2px;
  font: 400 13px/30px var(--mono); transition: border-color 120ms var(--ease); }
.rp-expr.is-focus { border-color: var(--ink); }
.rp-expr .jk { color: var(--ink-2); } .rp-expr .jp { color: var(--muted); }
.rp-expr .line { display: block; white-space: nowrap; }
.rp-slot { position: relative; display: inline-block; vertical-align: middle; }
.rp-pill { display: inline-flex; align-items: center; padding: 2px 8px; margin: 0 1px; line-height: 22px; font: 600 12px/22px var(--mono);
  color: var(--ink); background: color-mix(in srgb, var(--ink) 8%, transparent); border: 1px solid color-mix(in srgb, var(--ink) 25%, transparent); border-radius: 2px;
  opacity: 0; transform: translateY(4px); transition: opacity 120ms var(--ease), transform 120ms var(--ease); max-width: 0; overflow: hidden; padding-left: 0; padding-right: 0; border-width: 0; }
.rp-pill.is-on { opacity: 1; transform: none; max-width: 240px; padding: 2px 8px; border-width: 1px; transition: opacity 240ms var(--ease), transform 240ms var(--ease); }
.rp-expr .rp-caret { height: 16px; vertical-align: -3px; margin: 0; }
.rp-cslot { display: inline-block; width: 1px; }
.rp-cslot .rp-caret { opacity: 0; }
.rp-cslot.is-on .rp-caret { opacity: 1; }
.rp-preview { display: flex; align-items: baseline; gap: 6px; margin-top: 10px; padding: 0 4px; font: 400 12px/16px var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; }
.rp-preview .eq { color: color-mix(in srgb, var(--ink) 70%, transparent); flex: none; }
.rp-preview .pv { overflow: hidden; text-overflow: ellipsis; color: var(--ink-2); }
.rp-row-ring { left: 41px; top: 61px; height: 34px; width: calc((100% - 42px) * 2 / 3); }
.rp-data-fig { --rp-h: 400px; }
.rp-preview { position: relative; overflow: visible; }
.rp-preview .pv { white-space: nowrap; }
@media (max-width: 600px) {
  .rp-when { display: none; }
  .rp-sheet .c3 { display: none; }
  .rp-row-ring { width: calc(100% - 42px); }
  .rp-foot { grid-template-columns: 1fr; row-gap: 12px; }
  .rp-key { justify-self: start; }
  .rp-split { grid-template-columns: 1fr; grid-template-rows: 218px 1fr; }
  .rp-data-fig { --rp-h: 456px; }
  .rp-data-search, .rp-data-foot, .rp-ctx, .rp-more { display: none; }
  .rp-form { padding: 14px 16px; }
  .rp-preview .pv { white-space: normal; }
  .rp-data { border-right: 0; border-bottom: 1px solid var(--rule); }
  .rp-lens { width: 78px; }
  .rp-card { padding-right: 12px; gap: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .rp-spin, .rp-submit.is-busy .rp-busy { animation: none; }
}
@media print { .rp-key { display: none; } }

.rp-poster { display: none; }
@container doc (max-width: 727px) {
  .js .rp:not(.is-open) .rp-frame, .js .rp:not(.is-open) .rp-key { display: none; }
  .js .rp:not(.is-open) .rp-poster { display: flex; }
  .js .rp:not(.is-open) .rp-foot { margin-top: var(--s-2); }
}
.rp-poster { align-items: center; gap: var(--s-3); width: 100%; min-height: 52px; padding: var(--s-2) var(--s-3); border: 1px solid var(--gr-rule-strong); border-top-color: var(--gr-rule-emph); border-radius: var(--r-sheet); background: var(--gr-card); color: var(--gr-ink); font: var(--t-small); text-align: left; cursor: pointer; }
.rp-poster:hover { background: var(--gr-hover); }
.rp-poster:focus-visible { outline-offset: 2px; }
.rp-poster .pi { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 1px solid var(--gr-control); border-radius: var(--r-control); box-shadow: var(--shadow-key); background: var(--gr-card); }
.rp-poster .pi svg { width: 14px; height: 14px; fill: currentColor; }
.rp-poster .pt { flex: 1; min-width: 0; }
.rp-poster .pl { color: var(--gr-muted); white-space: nowrap; }

/* ═══ 8c · SHEETS ═════════════════════════════════════════════════════════════════════════════════════════════════
   The product's option C (qa/separators/C-PLAN.md §1; components/ui/sheet-group*.ts). Every group of rows is a SHEET:
   the card, its own 1px edge on all four sides (never a free rule above and below), square in Paper. Dividers between
   its rows are the subtle rule, wall to wall: the sheet has no side padding and each row carries 12px 16px. There is
   never a rule above the first row or below the last, and never a sheet inside a sheet (a list inside a titled sheet
   gives up its own box). A titled sheet's title is its first row (.sheet-title). Rows that are links fill with the
   sheet's hover tone; their focus ring is drawn inside. The list below is every form that is a sheet; a new form
   either joins it or uses .sheet. Specificity is zero (:where), so a form's own rule can always say more.
   (.ag-grid on a phone and .sections-grid draw the same sheet in site.css; tables are sheets in §8.) */
:where(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list, .sheet-row) {
  background: var(--sheet); border: 1px solid var(--sheet-edge); border-radius: var(--r-sheet);
}
/* The divider: above every shown row but the first shown. Rows hidden by a filter carry [hidden]. Edition-only rows
   at the head of a sheet are alternatives for one place (only one shows), so none of them draws a divider. */
:where(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list) > :where(:not([hidden]) ~ :not([hidden])) { border-top: 1px solid var(--sheet-rule); }
:where(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list) > [data-ed]:not(:not([data-ed]) ~ *) { border-top: 0; }
.sheet { max-width: var(--col); margin: var(--s-4) 0 var(--s-6); }
.sheet-title { margin: 0; padding: var(--sheet-y) var(--sheet-x); font: var(--t-body); font-weight: var(--w-strong); color: var(--gr-ink); }
/* No sheet inside a sheet: a list in a titled sheet is its rows; a fold in a sheet is one of its rows. */
.sheet.sheet > :where(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list, details) { border-width: 0; background: none; margin: 0; max-width: none; }
.sheet > :not([hidden]) ~ :where(.sheet, .rows, .defs, .legend-states, .symptoms, .params, .err-list, .app-list, .am, .af, .ref-list, .gl-list, .seq-list, details):not([hidden]) { border-top: 1px solid var(--sheet-rule); }
.need { margin-top: var(--s-8); }
/* In Wide and Split a sheet of text rows keeps the Read column's measure; lists of pages and endpoints span the frame. */
.doc[data-frame] > :is(.need, .q-sheet, .defs, .legend-states, .symptoms, details) { max-width: var(--col); }
/* The list's own rows lose the side margins they used to borrow (no negative-margin breakouts: the A law). */
.doc .err-list > li { padding: var(--sheet-y) var(--sheet-x) var(--s-4); }
.af > div { padding: var(--sheet-y) var(--sheet-x); }

/* ═══ 9 · SEARCH (⌘K) ═════════════════════════════════════════════════════════════════════════════════════════════
   A modal <dialog>: 640px at 13vh, the paper ground, no radius, the 3px offset. A 52px input; groups in sentence
   case; 44px rows with the matched letters in 600 ink and the machine value right-aligned in Mono. Ask is always
   the last row. A phone gets a bottom sheet with a grab handle. */
.pal { width: min(640px, calc(100vw - 32px)); max-width: none; max-height: min(560px, 74vh); margin: 13vh auto auto; padding: 0; border: 1px solid var(--gr-rule-strong); background: var(--gr-paper); color: var(--gr-ink); box-shadow: var(--shadow-overlay); overflow: hidden; }
.pal[open] { display: flex; flex-direction: column; animation: gr-arrive var(--dur-base) var(--ease) both; }
.pal::backdrop { background: var(--scrim); }
.pal[open]::backdrop { animation: gr-fade-in var(--dur-base) var(--ease) both; }
.pal.is-leaving, .pal.is-leaving::backdrop { animation: gr-fade-out var(--dur-exit-base) var(--ease) both; }
.pal-in { flex: none; display: flex; align-items: center; gap: 10px; height: 52px; padding: 0 var(--s-2) 0 var(--s-4); border-bottom: 1px solid var(--gr-rule); color: var(--gr-muted); }
.pal-in > svg { width: 18px; height: 18px; }
.pal-in input { flex: 1; min-width: 0; height: 100%; border: 0; background: none; color: var(--gr-ink); font: var(--t-body); outline: none; }
.pal-in input::placeholder { color: var(--gr-muted); opacity: 1; }
.pal-in input::-webkit-search-cancel-button { display: none; }
.pal-in .pal-x { display: none; }
.pal-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--s-1) 0 var(--s-2); }
.pal-g { padding: var(--s-3) var(--s-4) var(--s-1); font: var(--t-small); color: var(--gr-muted); }
.pal-grp + .pal-grp, .pal-grp + .pal-g { border-top: 1px solid var(--gr-rule-subtle); }
.pal-i { display: flex; align-items: center; gap: var(--s-3); min-height: 44px; padding: 6px var(--s-4); margin: 0 var(--s-1); border-radius: var(--r-control); text-decoration: none; color: var(--gr-ink-2); cursor: pointer; font: var(--t-small); }
.pal-i > svg { width: 16px; height: 16px; color: var(--gr-muted); }
.pal-i .pt { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.pal-i .pt > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-i .pt b { font-weight: var(--w-strong); color: var(--gr-ink); }
.pal-i .ps { color: var(--gr-muted); }
.pal-i .pm { flex: 0 1 auto; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-code-small); color: var(--gr-muted); text-align: right; }
.pal-i[aria-selected="true"], .pal-i.is-hover { background: var(--gr-hover); color: var(--gr-ink); }
.pal-i[aria-selected="true"] .pm, .pal-i[aria-selected="true"] > svg { color: var(--gr-ink-2); }
.pal-i .enter { visibility: hidden; }
.pal-i[aria-selected="true"] .enter { visibility: visible; }
.pal-i.pal-ask .pt > span:first-child { color: var(--gr-ink); }
.pal-i[aria-disabled="true"] { cursor: default; }
.pal-empty { padding: var(--s-3) var(--s-4) var(--s-1); font: var(--t-small); color: var(--gr-ink-2); }
/* The answer (B's layout): "Answer", 1-3 sentences with bold UI words, then source rows with a page glyph and →. */
.answer { padding: var(--s-1) var(--s-4) var(--s-2); font: var(--t-body); color: var(--gr-ink); animation: gr-arrive var(--dur-slow) var(--ease) both; }
.answer p { margin: 0 0 var(--s-3); max-width: none; }
.answer p:last-child { margin-bottom: 0; }
.answer .working { display: flex; align-items: center; gap: var(--s-2); font: var(--t-small); color: var(--gr-muted); }
.answer .working svg { width: 14px; height: 14px; }
.pal-back { padding: var(--s-2) var(--s-4) var(--s-1); margin: 0; font: var(--t-small); }
.linkbtn { padding: 0; border: 0; background: none; cursor: pointer; font: inherit; color: var(--gr-ink); text-decoration: underline; text-decoration-color: var(--gr-rule-emph); text-underline-offset: 3px; text-decoration-thickness: 1px; border-radius: var(--r-control); }
.linkbtn:hover { text-decoration-color: var(--gr-ink); }
.pal-foot { flex: none; display: flex; flex-wrap: wrap; gap: var(--s-4); padding: 10px var(--s-4); border-top: 1px solid var(--gr-rule); font: var(--t-small); color: var(--gr-muted); }
.pal-foot span { display: inline-flex; align-items: center; gap: 6px; }
.pal-foot .off { margin-left: auto; }
/* States */
.pal-skel { padding: var(--s-2) var(--s-4); }
.pal-skel .skel { height: 14px; margin: 10px 0; }
.pal-skel .skel:nth-child(2n) { width: 62%; }
.pal-skel .skel:nth-child(3n) { width: 78%; }
.pal-note { display: flex; align-items: flex-start; gap: var(--s-2); padding: var(--s-3) var(--s-4); font: var(--t-small); color: var(--gr-ink-2); }
.pal-note svg { width: 16px; height: 16px; margin-top: 2px; color: var(--gr-muted); }
/* A static copy of the palette, for the gallery */
.pal.is-static { display: flex; flex-direction: column; position: static; margin: 0; width: 100%; max-height: none; animation: none; }
.pal.is-static .pal-body { overflow: visible; }

/* ═══ 10 · SMALL PIECES ═══════════════════════════════════════════════════════════════════════════════════════════ */
/* Edition: the one setting in the chrome. "Steps for: Cloud", a secondary key with its menu of three. */
.ed { position: relative; display: flex; align-items: center; gap: var(--s-2); }
/* One line: the label, a small select key, a "?" (what the three words mean, in a popover). */
.ed-label { flex: none; font: var(--t-small); color: var(--gr-muted); white-space: nowrap; }
.ed-pick { position: relative; flex: 1; min-width: 0; display: flex; }
.ed-btn { flex: 1; min-width: 0; justify-content: space-between; padding: 0 var(--s-2) 0 10px; color: var(--gr-ink); }
.ed-btn b { font-weight: var(--w-strong); overflow: hidden; text-overflow: ellipsis; }
.ed-btn .chev { width: 14px; height: 14px; color: var(--gr-muted); transition: transform var(--dur-base) var(--ease); }
.ed-btn[aria-expanded="true"] .chev, .ed-btn.is-open .chev { transform: rotate(180deg); }
.ed-help { flex: none; color: var(--gr-muted); }
.ed-help[aria-expanded="true"] { color: var(--gr-ink); background: var(--gr-hover); }
.ed .menu { min-width: 100%; }
.ed-pop { top: calc(100% + 6px); left: 0; width: 100%; min-width: 220px; }
.ed-pop p { margin: 0 0 var(--s-2); }
.ed-pop dl { margin: 0; }
.ed-pop dl > div + div { margin-top: var(--s-1); }
.ed-pop dt { display: inline; font-weight: var(--w-strong); color: var(--gr-ink); }
.ed-pop dt::after { content: ": "; }
.ed-pop dd { display: inline; margin: 0; }
/* Edition-only content hides only where its edition isn't chosen; a shown block keeps its own display (a grid row
   stays a grid row). */
:root:not([data-edition]) [data-ed]:not([data-ed~="cloud"]), :root[data-edition="cloud"] [data-ed]:not([data-ed~="cloud"]),
:root[data-edition="self"] [data-ed]:not([data-ed~="self"]), :root[data-edition="embed"] [data-ed]:not([data-ed~="embed"]) { display: none !important; }

/* App rows and logos: every app sits on one tile (the card, a 1px inset hairline, 2px corners). A vendor logo keeps
   its colours at 58% of the tile and stands on the brand's paper in dark; our own apps are an ink glyph. */
.tile { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: var(--r-control); background: var(--gr-card); color: var(--gr-ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gr-ink) 14%, transparent); }
.tile img { width: 60%; height: 60%; object-fit: contain; }
.tile svg { width: 50%; height: 50%; stroke-width: 1.75; }
.tile.logo { background: light-dark(var(--gr-card), #f4f2ea); box-shadow: inset 0 0 0 1px light-dark(rgb(43 41 38 / .14), rgb(0 0 0 / .2)); }
.tile.lg { width: 40px; height: 40px; }
.tile.sm { width: 24px; height: 24px; }
.app-list { list-style: none; margin: 0; padding: 0; max-width: var(--col); }
.app-list li { margin: 0; }
.app-list a { display: flex; align-items: center; gap: 14px; min-height: 64px; padding: var(--sheet-y) var(--sheet-x); text-decoration: none; transition: background-color var(--dur-quick) var(--ease); }
.app-list a:hover, .app-list a.is-hover { background: var(--sheet-hover); }
.app-list a:focus-visible { outline-offset: -2px; }
.app-list .an { display: block; font-weight: var(--w-strong); }
.app-list .ad { display: block; font: var(--t-small); color: var(--gr-muted); }
.app-list .am { margin-left: auto; font: var(--t-small); color: var(--gr-muted); white-space: nowrap; }

/* HTTP method marks: the one chip the docs allow besides a run state. Mono 600, neutral (a method is not a state),
   a fixed width so paths line up. */
.method { display: inline-block; min-width: 4.2em; color: var(--gr-ink); font: var(--t-code-small); font-weight: var(--w-strong); }
.method.sm { min-width: 0; }
.sig { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 var(--s-4); }
.sig code { overflow-wrap: anywhere; }

/* Run states: a glyph and a word, in the state's word colour, no pill. Running turns; Queued is a dashed ring. */
.st { display: inline-flex; align-items: center; gap: 6px; font: var(--t-small); font-weight: var(--w-strong); white-space: nowrap; vertical-align: -1px; }
.st svg { width: 14px; height: 14px; stroke-width: 1.5; stroke-linecap: square; stroke-linejoin: miter; fill: none; stroke: currentColor; }
.st .at { font-weight: var(--w-regular); color: var(--gr-muted); }
.st-ok { color: var(--gr-ok); }
.st-bad { color: var(--gr-bad); }
.st-held { color: var(--gr-warn); }
.st-run { color: var(--gr-run); }
.st-off, .st-queued { color: var(--gr-muted); }
.st-run svg { animation: gr-spin 900ms linear infinite; }
.st.in-text { font-size: inherit; line-height: inherit; }

/* Toasts: what floats. The card, the emphasis frame, the print offset; a glyph, a short sentence ending in a full
   stop. Bottom-right on a desktop, under the top bar on a phone. At most three; each leaves after 4s (paused under
   the pointer). Enter: rise 8px; exit: fade. */
.toasts { position: fixed; z-index: 100; right: var(--s-6); bottom: var(--s-6); display: flex; flex-direction: column; align-items: flex-end; gap: var(--s-2); pointer-events: none; }
.toast { display: flex; align-items: center; gap: 10px; min-height: 44px; max-width: 360px; padding: 10px var(--s-3) 10px var(--s-4); background: var(--gr-card); border: 1px solid var(--gr-rule-emph); box-shadow: var(--shadow-overlay); font: var(--t-small); color: var(--gr-ink); pointer-events: auto; animation: gr-arrive var(--dur-base) var(--ease) both; }
.toast svg { width: 16px; height: 16px; }
.toast.is-leaving { animation: gr-fade-out var(--dur-exit-base) var(--ease) both; }
.toast.is-static { animation: none; }

/* Skeletons: the hover tone in the control's corner, breathing at 1.4s; still under reduced motion. Shapes match
   what will arrive, so nothing jumps when it does. */
.skel { display: block; height: 1em; border-radius: var(--r-control); background: var(--gr-hover); animation: gr-breathe 1.4s var(--ease) infinite; }
.skel.h1 { height: 32px; width: 60%; margin: 4px 0 16px; }
.skel.line { height: 14px; margin: 8px 0; }
.skel.line:last-child { width: 70%; }
.skel.block { height: 160px; }
@keyframes gr-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* 404: left-aligned, never centred. A title, one sentence, the search box, three ways on. */
.nf h1 { margin-bottom: var(--s-2); }
.nf .path { font: var(--t-code); color: var(--gr-ink-2); overflow-wrap: anywhere; }
.nf .ask { margin: var(--s-6) 0 var(--s-8); }
.ask { display: flex; align-items: center; gap: var(--s-3); width: 100%; max-width: var(--col); height: 52px; padding: 0 var(--s-3) 0 var(--s-4); background: var(--gr-card); border: 1px solid var(--gr-control); border-radius: var(--r-control); text-align: left; font: var(--t-body); color: var(--gr-muted); cursor: text; transition: border-color var(--dur-quick) var(--ease); }
.ask svg { width: 18px; height: 18px; }
.ask > span { flex: 1; }
.ask:hover { border-color: var(--gr-muted); }
.rows { list-style: none; margin: var(--s-4) 0 var(--s-6); padding: 0; max-width: var(--col); }
.rows li { margin: 0; }
.rows a { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: var(--s-4); padding: var(--sheet-y) var(--sheet-x); text-decoration: none; transition: background-color var(--dur-quick) var(--ease); }
.rows a:hover, .rows a.is-hover { background: var(--sheet-hover); }
.rows a::after { content: ""; grid-row: 1 / span 2; grid-column: 2; width: 16px; height: 16px; background: var(--gr-muted); -webkit-mask: var(--i-arrow) center / 16px no-repeat; mask: var(--i-arrow) center / 16px no-repeat; transition: transform var(--dur-base) var(--ease); }
.rows a:hover b { text-decoration: underline; text-decoration-color: var(--gr-rule-emph); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.rows a:hover::after { transform: translateX(2px); }
.rows a:focus-visible { outline-offset: -2px; }
.rows b { font-weight: var(--w-strong); }
.rows span { font: var(--t-small); color: var(--gr-muted); }

/* ═══ PHONE AND TABLET ════════════════════════════════════════════════════════════════════════════════════════════ */
@container doc (max-width: 823px) {
  .step :is(h2, h3) .n { position: static; display: inline-block; width: auto; min-width: 1.4em; padding: 0; text-align: left; }
  ol.steps > li { padding-left: 28px; }
  ol.steps > li::before { right: auto; left: 0; width: auto; padding: 0; text-align: left; }
}
/* The top bar by width (SITEMAP §2.1): 1440 a 240px well; 1024 a 160px "Search" well; below 1024 an icon key;
   below 760 the six sections leave the bar for the phone menu. */
.search-btn .sb-short { display: none; }
@media (max-width: 1279px) {
  .search-btn { width: 160px; }
  .search-btn .sb-long { display: none; }
  .search-btn .sb-short { display: inline; }
  .secs a { padding: 0 8px; }
}
@media (max-width: 759px) { .secs { display: none; } }
@media (max-width: 1023px) {
  :root { --gutter: 16px; }
  html { scroll-padding-top: calc(var(--top-h) + 44px + var(--s-4)); } /* the bar and the phone bar */
  .top { gap: var(--s-3); }
  .search-btn { width: 32px; height: 32px; padding: 0; justify-content: center; background: transparent; }
  .search-btn > span, .search-btn .sb-short, .search-btn .sb-long, .search-btn kbd { display: none; }
  .top { gap: var(--s-4); }
  .crumbs nav { display: none; }
  .crumbs { position: absolute; right: var(--gutter); margin: 0; min-height: 0; }
  .doc { position: relative; }
  .doc > h1 { padding-right: 44px; }
  .phonebar { display: block; position: sticky; top: var(--top-h); z-index: 25; background: var(--gr-paper); border-bottom: 1px solid var(--gr-rule-subtle); }
  .phonebar > div { display: flex; align-items: center; }
  .phonebar .pb-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 var(--gutter); border: 0; background: none; cursor: pointer; font: var(--t-small); color: var(--gr-muted); text-align: left; }
  .phonebar .pb-open:focus-visible { outline-offset: -2px; }
  .phonebar .chev { width: 14px; height: 14px; color: var(--gr-rule-emph); }
  .phonebar .pb-page { min-width: 0; color: var(--gr-ink); font-weight: var(--w-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .phonebar .pb-down { width: 14px; height: 14px; margin-left: auto; }
  .phonebar .to-top { flex: none; justify-content: center; width: 44px; height: 44px; }
  .side {
    position: fixed; z-index: 35; top: 0; left: 0; bottom: 0; height: auto; width: min(320px, 86vw);
    background: var(--gr-paper); border-right: 1px solid var(--gr-rule);
    transform: translateX(-102%); visibility: hidden; --sb-thumb: var(--gr-rule-strong);
    transition: transform var(--dur-exit-slow) var(--ease), visibility 0s var(--dur-exit-slow);
  }
  .side.open { transform: none; visibility: visible; box-shadow: var(--shadow-overlay); transition: transform var(--dur-slow) var(--ease), visibility 0s; }
  .side-head, .side-head:not(:has(.ed)) { display: block; padding: var(--s-2) var(--s-2) var(--s-2) 36px; }
  .side-body { padding: var(--s-4) var(--s-4) var(--s-8) 36px; }
  .side-foot { display: none; }
  .side-phone { display: flex; align-items: center; justify-content: space-between; color: var(--gr-muted); }
  .side-all { display: block; margin-top: var(--s-8); } /* no rule: the gap and the muted label set it apart */
  .side-all span { display: block; padding: 6px 0; color: var(--gr-muted); }
  .side-all a { display: block; padding: 8px 0; color: var(--gr-ink-2); }
  .side-all a[aria-current] { color: var(--gr-ink); font-weight: var(--w-strong); }
  .side-all + .side-all { margin-top: var(--s-4); }
  :is(.grp, .grp-plain) li > a, .grp-btn { min-height: 40px; display: flex; align-items: center; }
  .toc a { display: grid !important; align-items: center; }
  .doc { padding: var(--s-5) var(--gutter) var(--s-18); }
  h2 { margin-top: 44px; }
  .foot { gap: var(--s-2) var(--s-4); padding: var(--s-4) var(--gutter); min-height: 0; }
  .foot nav { gap: var(--s-2) var(--s-4); }
  .foot .ver { margin-left: 0; }
  .pn { flex-direction: column-reverse; gap: var(--s-3); }
  .pn a { max-width: none; }
  .pn .next { margin-left: 0; text-align: left; }
  .panel { position: fixed; inset: 0; z-index: 40; width: auto; height: auto; border-left: 0; }
  .panel.is-opening { animation: gr-panel-page var(--dur-slow) var(--ease) both; }
  .panel.is-opening > * { animation: none; }
  .panel-head { padding-left: var(--s-4); }
  .panel-body { padding: var(--s-4) var(--s-4) var(--s-10); }
  .zoom-body { padding: var(--s-4); place-items: start; }
}
/* A phone: search is a bottom sheet with a grab handle; toasts sit under the bars. */
@media (max-width: 759px) {
  .search-btn, .top .btn-icon { width: 44px; height: 44px; }
  .pal { width: 100%; max-width: none; max-height: 88dvh; margin: auto 0 0; border-left: 0; border-right: 0; border-bottom: 0; padding-top: var(--s-3); }
  .pal[open] { animation: gr-sheet-up var(--dur-slow) var(--ease) both; }
  .pal::before { content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: var(--gr-rule-strong); }
  .pal-foot { display: none; }
  .pal-in .pal-x { display: inline-flex; }
  .pal.is-static { padding-top: var(--s-3); position: relative; }
  .toasts { left: var(--s-4); right: var(--s-4); bottom: auto; top: calc(var(--top-h) + var(--s-2)); align-items: stretch; }
  .toast { max-width: none; }
}
@media (pointer: coarse) { .pal-foot { display: none; } }
@keyframes gr-sheet-up { from { transform: translateY(100%); } }

/* ═══ 11 · MOTION PREFERENCES ═════════════════════════════════════════════════════════════════════════════════════
   Reduced motion: every transition and animation goes to its end state at once, except the spinner (the information)
   and a 120ms fade where something would otherwise pop (the panel, the palette, the lightbox). Smooth scrolling off. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: 0s !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .spin, .st-run svg { animation-duration: 900ms !important; animation-iteration-count: infinite !important; }
  .panel.is-opening, .pal[open], .zoom[open], .toast { animation: gr-fade-in 120ms linear both !important; }
  .skel { animation: none !important; }
}
@media (prefers-reduced-motion: no-preference) { html:focus-within { scroll-behavior: smooth; } }

/* ═══ 12 · PRINT ══════════════════════════════════════════════════════════════════════════════════════════════════
   Light, ink on white, the reading column only. Chrome, keys and anchors go; folds print open; links to elsewhere
   print their address; code wraps; nothing splits a picture, a table row or a code block. */
@media print {
  :root { color-scheme: light; --gr-paper: #fff; --gr-card: #fff; --gutter: 0; }
  @page { margin: 18mm 16mm; }
  html, body { background: #fff; }
  body { font-size: 11pt; line-height: 1.55; }
  .top, .phonebar, .side, .panel, .foot, .pn, .crumbs, .copy, .code-bar .btn, .h-glyph, .skip, .toasts, .pal, .zoom, .zoom-hint, .to-top, .q, .ed, [data-noprint] { display: none !important; }
  .frame, .col { display: block; }
  .doc { max-width: none; padding: 0; }
  .doc p, .doc ul, .doc ol { max-width: none; }
  a:not([class]) { text-decoration: underline; }
  a[href^="http"]:not([class])::after { content: " (" attr(href) ")"; font: var(--t-code-small); color: #5b5956; overflow-wrap: anywhere; }
  .ext::after { display: none; }
  details > :not(summary) { display: block !important; }
  details { break-inside: avoid; }
  summary::before { transform: rotate(90deg); }
  pre code, pre { white-space: pre-wrap !important; overflow-wrap: anywhere; overflow: visible; min-width: 0; }
  .code, .shot, figure, tr, .callout, .step h2 { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
  .shot { overflow: visible; }
  .shot .l { display: block !important; } .shot .d { display: none !important; }
  .tbl { overflow: visible; max-height: none !important; }
  .tbl-wrap::before, .tbl-wrap::after { display: none; }
  th { position: static; }
  .step h2 .n { position: static; width: auto; padding-right: 6px; color: #5b5956; }
}

/* Rhythm: a picture's caption, a table or a list of rows ends with 24px before the text that follows */
.see + p, .shot-cap + p, .tbl-wrap + p, .defs + p { margin-top: var(--s-6); }
/* Without JavaScript: groups are open, so are their chevrons; a replay shows its still and steps, no key */
html:not(.js) .grp .chev { transform: rotate(90deg); }
html:not(.js) .rp-key { display: none; }
