/* Built by kit/build.mjs from kit/src/core.css and kit/parts/*.css — edit those, not this. */
/*
 * Tactile UI Kit — Tactile Modernism.
 *
 * Interface parts made the way Braun made radios: bead-blasted aluminium and
 * soft-touch black, printing instead of decoration, and no brand colour at
 * all. Colour only means something — a lamp that is on, a display that is
 * lit. Everything is lit by one lamp, high and to the left.
 *
 * Two finishes: aluminium (light, the default) and graphite (dark). Put
 * data-finish="graphite" on any element to switch everything inside it.
 * Every class starts with tui-. No dependencies; kit.mjs adds behaviour to the
 * few parts that need it (knob, tabs, toasts, meters).
 */

@font-face { font-family: 'Instrument Sans'; src: url('./fonts/InstrumentSans-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Instrument Sans'; src: url('./fonts/InstrumentSans-Italic.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: 'Instrument Sans'; src: url('./fonts/InstrumentSans-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('./fonts/GeistMono-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('./fonts/GeistMono-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }

/* ------------------------------------------------------------------ tokens */

:root, [data-finish="aluminium"] {
  color-scheme: light;
  --tui-desk: #d8d7d2;        /* what the device stands on: the page */
  --tui-face: #e6e6e2;        /* bead-blasted aluminium: panels */
  --tui-face-hi: #f2f2ef;     /* raised parts: caps, knobs, thumbs */
  --tui-face-lo: #cbccc8;     /* slots, chamfers */
  --tui-well: #d3d4d0;        /* recessed: fields, tracks */
  --tui-skirt: #a4a5a1;       /* the side of a key, seen below its top */
  --tui-ink: #1b1c1e;         /* printing */
  --tui-ink-2: #4b4d51;       /* secondary printing, 5.5:1 on the face */
  --tui-ink-3: #6c6e72;       /* tertiary: scales and hints, 3.6:1 — never body text */
  --tui-rule: rgb(27 28 30 / 0.16);
  --tui-cap: #1e1f21;         /* the contrast key: the one action that matters */
  --tui-cap-hi: #2d2e31;
  --tui-cap-skirt: #070708;
  --tui-cap-ink: #efede8;
  --tui-hl: rgb(255 255 255 / 0.9);   /* the catch light on a top edge */
  --tui-sh: 24 25 28;                  /* shadow colour, as channels */
  --tui-sh-a: 0.24;
  --tui-grain: 0.5;
  --tui-focus: #1b1c1e;
  /* Metal and plastic that differ by finish: parts read these, never the
     finish of an ancestor, so a finish nested in another is exact. */
  --tui-cap-hl: rgb(255 255 255 / 0.14);
  --tui-rocker-hi: #f4f4f1; --tui-rocker-mid: #dedfdb; --tui-rocker-lo: #c4c5c1; --tui-rocker-sunk: #b1b2ae; --tui-rocker-wall: #8a8b87;
  --tui-rocker-mark: #2a2b2d; --tui-rocker-bezel: linear-gradient(#0c0d0e, #1d1e20);
  --tui-knob-hi: #fafaf8; --tui-knob-mid: #d9dad6; --tui-knob-lo: #a9aaa6;
  --tui-knob-cap-shadow: inset 0 1px 1px rgb(255 255 255 / 0.6), inset 0 -1px 2px rgb(0 0 0 / 0.3), 0 1px 2px rgb(0 0 0 / 0.35);
  --tui-cloth: #2a2b2d;
  --tui-backdrop: rgb(14 15 16 / 0.45);
  /* The floor of a recess darkens toward its upper wall. */
  --tui-well-fill: linear-gradient(to bottom, color-mix(in oklab, var(--tui-well) 86%, rgb(var(--tui-sh))), var(--tui-well) 55%);
}

[data-finish="graphite"] {
  color-scheme: dark;
  --tui-desk: #0e0f10;
  --tui-face: #1b1c1e;        /* soft-touch black */
  --tui-face-hi: #28292c;
  --tui-face-lo: #141516;
  --tui-well: #121315;
  --tui-skirt: #09090a;
  --tui-ink: #e8e6e1;
  --tui-ink-2: #a6a7a9;
  --tui-ink-3: #7a7c7f;
  --tui-rule: rgb(232 230 225 / 0.11);
  --tui-cap: #e9e7e2;
  --tui-cap-hi: #f6f4ef;
  --tui-cap-skirt: #a8a7a3;
  --tui-cap-ink: #17181a;
  --tui-hl: rgb(255 255 255 / 0.11);
  /* Black plastic: the floor of a recess is darkest under its upper wall
     and picks up the lamp again near the lower one. */
  --tui-well-fill: linear-gradient(to bottom, #070808, var(--tui-well) 45%, #17181a);
  --tui-sh: 0 0 0;
  --tui-sh-a: 0.55;
  --tui-grain: 0.35;
  --tui-focus: #e8e6e1;
  --tui-cap-hl: rgb(255 255 255 / 0.8);
  --tui-rocker-hi: #5b5c60; --tui-rocker-mid: #45464a; --tui-rocker-lo: #36373a; --tui-rocker-sunk: #2a2b2e; --tui-rocker-wall: #1a1b1d;
  --tui-rocker-mark: #e4e2dd; --tui-rocker-bezel: linear-gradient(#050506, #0d0e0f);
  --tui-knob-hi: #5a5b5f; --tui-knob-mid: #2c2d30; --tui-knob-lo: #141517;
  --tui-knob-cap-shadow: inset 0 1px 1px rgb(255 255 255 / 0.2), inset 0 -1px 2px rgb(0 0 0 / 0.5), 0 1px 2px rgb(0 0 0 / 0.6);
  --tui-cloth: #1f2022;
  --tui-backdrop: rgb(0 0 0 / 0.6);
}

:root, [data-finish] {
  /* Lamps and displays: the only colour in the kit, and always a signal. */
  --tui-green: #3fa34d;
  --tui-amber: #f29f05;
  --tui-red: #d93a2b;
  --tui-lcd: #b8bea9;
  --tui-lcd-ink: #1d2318;
  --tui-vfd-bg: #080b0b;
  --tui-vfd: #c6f3ea;

  --tui-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif;
  --tui-mono: 'Geist Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Type: a 1.25 scale from 13px. Labels are printed small and tracked. */
  --tui-t-label: 10.5px;
  --tui-t-small: 12px;
  --tui-t-body: 13.5px;
  --tui-t-lead: 16px;
  --tui-t-h3: 20px;
  --tui-t-h2: 26px;
  --tui-t-h1: clamp(34px, 5vw, 56px);
  --tui-track: 0.09em;

  /* A 4px grid. */
  --tui-1: 4px; --tui-2: 8px; --tui-3: 12px; --tui-4: 16px; --tui-5: 20px; --tui-6: 24px; --tui-8: 32px; --tui-10: 40px; --tui-12: 48px;
  --tui-r-s: 4px; --tui-r-m: 7px; --tui-r-l: 12px;
  --tui-ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* Light, from the lamp above left. */
  --tui-raised:
    inset 0 1px 0 var(--tui-hl),
    0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35)),
    0 1px 1.5px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.2)),
    0 5px 12px -5px rgb(var(--tui-sh) / var(--tui-sh-a));
  /* A recess, lit from above: the upper wall is in shadow, the lower wall
     catches the lamp, and so does the plate's lip below the cut. */
  --tui-inset:
    inset 0 3px 3px -2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.6)),
    inset 0 9px 12px -9px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.8)),
    inset 0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.45)),
    inset 0 -1px 0 color-mix(in oklab, var(--tui-hl) 60%, transparent),
    0 1px 0 var(--tui-hl),
    0 -1px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35));
  /* A pressed key sits below the plate, so the plate's edge shades its top. */
  --tui-pressed:
    inset 0 5px 5px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 3)),
    inset 4px 0 4px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)),
    inset -4px 0 4px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)),
    0 -1px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.3)),
    0 1px 0 var(--tui-hl);
  --tui-screw: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3CradialGradient id='g' cx='.38' cy='.32' r='.75'%3E%3Cstop offset='0' stop-color='%23fbfbf9'/%3E%3Cstop offset='1' stop-color='%239d9e9a'/%3E%3C/radialGradient%3E%3Ccircle cx='5' cy='5' r='4.3' fill='url(%23g)' stroke='%23000' stroke-opacity='.35' stroke-width='.5'/%3E%3Cpath d='M2.4 6.3 7.6 3.7' stroke='%23000' stroke-opacity='.55' stroke-width='.9' stroke-linecap='round'/%3E%3C/svg%3E");
  --tui-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0.28 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------------- base */

.tui {
  font: 400 var(--tui-t-body)/1.5 var(--tui-sans);
  color: var(--tui-ink);
  background: var(--tui-desk);
  font-feature-settings: 'tnum' 1;
  -webkit-font-smoothing: antialiased;
}
.tui *, .tui *::before, .tui *::after { box-sizing: border-box; }
/* hidden always wins over a part's own display. */
.tui [hidden] { display: none !important; }

/* Printed labels: the voice of a front panel. */
.tui-label {
  font: 500 var(--tui-t-label)/1.2 var(--tui-sans);
  letter-spacing: var(--tui-track);
  text-transform: uppercase;
  color: var(--tui-ink-2);
}
.tui-h1, .tui-h2, .tui-h3 { margin: 0; font-weight: 700; letter-spacing: -0.02em; line-height: 1.05; color: var(--tui-ink); }
.tui-h1 { font-size: var(--tui-t-h1); letter-spacing: -0.035em; line-height: 0.98; }
.tui-h2 { font-size: var(--tui-t-h2); }
.tui-h3 { font-size: var(--tui-t-h3); letter-spacing: -0.01em; }
.tui-lead { font-size: var(--tui-t-lead); line-height: 1.5; color: var(--tui-ink-2); max-width: 58ch; }
.tui-muted { color: var(--tui-ink-2); }
.tui-num { font-variant-numeric: tabular-nums; }

.tui :focus-visible { outline: 2px solid var(--tui-focus); outline-offset: 3px; }

/* ------------------------------------------------------------------ panel */

/* A face plate. The grain is the bead-blast; the edge catches the lamp. */
.tui-panel {
  position: relative;
  isolation: isolate;
  background: var(--tui-face);
  border-radius: var(--tui-r-l);
  box-shadow: var(--tui-raised);
  padding: var(--tui-5);
}
.tui-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--tui-noise), linear-gradient(170deg, rgb(255 255 255 / 0.06), transparent 40%);
  opacity: var(--tui-grain);
  pointer-events: none;
}
.tui-panel__head {
  display: flex;
  align-items: center;
  gap: var(--tui-2);
  margin: calc(var(--tui-1) * -1) 0 var(--tui-4);
  padding-bottom: var(--tui-3);
  border-bottom: 1px solid var(--tui-rule);
}
.tui-panel__head > :first-child { flex: 1; }
/* Four slotted screws, turned the way a fitter leaves them. */
.tui-panel--screws { padding: var(--tui-6); }
.tui-panel--screws::after {
  content: '';
  position: absolute;
  inset: 8px;
  pointer-events: none;
  --screw: var(--tui-screw);
  background: var(--screw) 0 0 / 9px 9px no-repeat, var(--screw) 100% 0 / 9px 9px no-repeat,
    var(--screw) 0 100% / 9px 9px no-repeat, var(--screw) 100% 100% / 9px 9px no-repeat;
  filter: drop-shadow(0 0.5px 0 var(--tui-hl));
}
/* A plain recessed tray that other parts sit in. */
.tui-tray {
  background: var(--tui-well-fill) var(--tui-well);
  border-radius: var(--tui-r-m);
  box-shadow: var(--tui-inset);
  padding: var(--tui-1);
}
.tui-rule { height: 1px; background: var(--tui-rule); border: 0; margin: var(--tui-4) 0; }

/* Perforated metal and speaker cloth: surfaces, not decoration. */
.tui-grille {
  border-radius: var(--tui-r-m);
  background: radial-gradient(circle, rgb(0 0 0 / 0.6) 1.1px, var(--tui-hl) 1.5px, transparent 1.9px) 0 0 / 7px 7px, var(--tui-face-lo);
  box-shadow: var(--tui-inset);
  min-height: 48px;
}
.tui-cloth {
  border-radius: var(--tui-r-m);
  background:
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.05) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgb(0 0 0 / 0.18) 0 1px, transparent 1px 3px),
    var(--tui-cloth);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.3), inset 0 8px 16px -8px rgb(0 0 0 / 0.5);
  min-height: 48px;
}

/* ------------------------------------------------------------------- keys */

/* A key: a cap on a skirt. Pressing it takes the skirt away. */
.tui-key {
  --h: 36px;
  --skirt: 2px;
  appearance: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tui-2);
  height: var(--h);
  padding: 0 var(--tui-4);
  border: 0;
  border-radius: var(--tui-r-m);
  font: 600 var(--tui-t-small)/1 var(--tui-sans);
  letter-spacing: 0.01em;
  color: var(--tui-ink);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  background:
    radial-gradient(120% 90% at 50% 0%, var(--tui-hl), transparent 60%),
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow:
    inset 0 1px 0 var(--tui-hl),
    0 var(--skirt) 0 var(--tui-skirt),
    0 calc(var(--skirt) + 1px) 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)),
    0 calc(var(--skirt) + 6px) 12px -6px rgb(var(--tui-sh) / var(--tui-sh-a));
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease);
  -webkit-tap-highlight-color: transparent;
}
.tui-key:hover { filter: brightness(1.03); }
/* A key whose menu or popover is open stays down until it closes. */
.tui-key:active, .tui-key[aria-pressed="true"], .tui-key[aria-expanded="true"], .tui-key.is-down {
  transform: translateY(var(--skirt));
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
}
.tui-key:disabled, .tui-key[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; }
.tui-key svg { width: 16px; height: 16px; flex: none; }

/* The contrast key: the one action on a surface that matters most. */
.tui-key--primary {
  color: var(--tui-cap-ink);
  background:
    radial-gradient(120% 90% at 50% 0%, rgb(255 255 255 / 0.1), transparent 60%),
    linear-gradient(var(--tui-cap-hi), var(--tui-cap));
  --tui-skirt: var(--tui-cap-skirt);
  --tui-hl: var(--tui-cap-hl);
}
/* Printed text that acts: no cap at all. */
.tui-key--flat {
  background: none;
  box-shadow: none;
  padding: 0 var(--tui-2);
  color: var(--tui-ink-2);
}
.tui-key--flat:hover { color: var(--tui-ink); filter: none; }
.tui-key--flat:active { transform: none; box-shadow: none; filter: none; color: var(--tui-ink); }
.tui-key--danger { color: var(--tui-red); }
.tui-key--sm { --h: 28px; --skirt: 1.5px; padding: 0 var(--tui-3); font-size: 11.5px; border-radius: 6px; }
.tui-key--lg { --h: 46px; --skirt: 3px; padding: 0 var(--tui-6); font-size: 14px; border-radius: 9px; }
.tui-key--icon { width: var(--h); padding: 0; }
.tui-key--round { border-radius: 999px; }
/* A key with its own lamp, set in the cap. */
.tui-key .tui-lamp { margin-left: calc(var(--tui-1) * -1); }

/* ------------------------------------------------------------------ lamps */

.tui-lamp {
  --c: var(--tui-green);
  display: inline-block;
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.25), transparent 55%), color-mix(in oklab, var(--c) 22%, var(--tui-face-lo));
  box-shadow: inset 0 1px 1.5px rgb(0 0 0 / 0.45), 0 1px 0 var(--tui-hl);
  vertical-align: middle;
}
.tui-lamp[data-lamp="amber"] { --c: var(--tui-amber); }
.tui-lamp[data-lamp="red"] { --c: var(--tui-red); }
.tui-lamp[data-on], .tui-lamp.is-on {
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.85), transparent 45%), var(--c);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.2), 0 0 6px 1px color-mix(in oklab, var(--c) 70%, transparent), 0 0 14px 2px color-mix(in oklab, var(--c) 30%, transparent);
}
.tui-lamp[data-blink] { animation: tui-blink 1.2s steps(1) infinite; }
@keyframes tui-blink { 50% { opacity: 0.25; } }

/* A status line: lamp, then printed words. */
.tui-status { display: inline-flex; align-items: center; gap: var(--tui-2); font-size: var(--tui-t-small); color: var(--tui-ink-2); }

/* A tag: a small printed plate. */
.tui-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 8px;
  border-radius: var(--tui-r-s);
  border: 1px solid var(--tui-rule);
  font: 600 10px/1 var(--tui-sans);
  letter-spacing: var(--tui-track);
  text-transform: uppercase;
  color: var(--tui-ink-2);
  background: color-mix(in oklab, var(--tui-face) 60%, transparent);
}
.tui-tag--solid { border: 0; color: var(--tui-cap-ink); background: var(--tui-cap); }

/* --------------------------------------------------------------- switches */

/* A slide switch, the grip ridged like a thumbwheel. The slot it reveals
   is green only because the thing is on. */
.tui-switch {
  appearance: none;
  position: relative;
  flex: none;
  width: 48px;
  height: 26px;
  margin: 0;
  border-radius: 999px;
  cursor: pointer;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  transition: background-color 180ms var(--tui-ease);
}
.tui-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 28px;
  height: 22px;
  border-radius: 999px;
  background:
    repeating-linear-gradient(90deg, transparent 0 2px, rgb(var(--tui-sh) / 0.22) 2px 3px, var(--tui-hl) 3px 4px) center / 11px 8px no-repeat,
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 90%, rgb(var(--tui-sh))));
  box-shadow: var(--tui-raised);
  transition: transform 180ms var(--tui-ease);
}
.tui-switch:checked { background: color-mix(in oklab, var(--tui-green) 75%, var(--tui-well)); box-shadow: inset 0 1.5px 3px rgb(0 0 0 / 0.3), 0 1px 0 var(--tui-hl), 0 0 10px -2px color-mix(in oklab, var(--tui-green) 60%, transparent); }
.tui-switch:checked::after { transform: translateX(16px); }
.tui-switch:disabled { opacity: 0.45; cursor: not-allowed; }

/* A rocker, printed with the IEC marks: | is on, O is off. A black bezel
   and a cap that pivots in it: the pressed half sinks into the bezel's
   shadow, the other half rises toward the lamp and shows its end wall. */
.tui-rocker {
  --cap-hi: var(--tui-rocker-hi);
  --cap-mid: var(--tui-rocker-mid);
  --cap-lo: var(--tui-rocker-lo);
  --cap-sunk: var(--tui-rocker-sunk);
  --cap-wall: var(--tui-rocker-wall);
  --mark: var(--tui-rocker-mark);
  /* A mark on the sunk half is further away: smaller, nearer the pivot, dimmer. */
  --mark-sunk: color-mix(in oklab, var(--mark) 72%, var(--cap-sunk));
  appearance: none;
  position: relative;
  flex: none;
  width: 60px;
  height: 32px;
  margin: 0;
  border-radius: 8px;
  cursor: pointer;
  background: var(--tui-rocker-bezel);
  box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.8), 0 1px 0 var(--tui-hl), 0 -1px 0 rgb(var(--tui-sh) / 0.25), 0 0 0 1px rgb(0 0 0 / 0.35);
}
.tui-rocker::before {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 5px;
  /* Off: the O half (right) is pressed; the | half (left) is raised. */
  background:
    linear-gradient(var(--mark), var(--mark)) calc(25% - 0.75px) 48.5% / 2px 9px no-repeat,
    radial-gradient(circle, transparent 2.7px, var(--mark-sunk) 2.9px 4px, transparent 4.2px) calc(75% - 0.75px) 51.5% / 11px 11px no-repeat,
    linear-gradient(to bottom, rgb(0 0 0 / 0.45), transparent 60%) 100% 0 / 50% 100% no-repeat,
    linear-gradient(to left, rgb(0 0 0 / 0.32), transparent 45%) 100% 0 / 50% 100% no-repeat,
    linear-gradient(rgb(255 255 255 / 0.75), rgb(255 255 255 / 0.75)) 0 0 / 50% 1px no-repeat,
    linear-gradient(90deg, var(--cap-wall) 0 5%, var(--cap-hi) 5% 14%, var(--cap-mid) 32%, var(--cap-lo) 49.6%, rgb(0 0 0 / 0.4) 49.6% 50.4%, var(--cap-sunk) 50.4%);
  box-shadow: -2px 2px 3px -1px rgb(0 0 0 / 0.6);
}
.tui-rocker:checked::before {
  /* On: the | half (left) is pressed; the O half (right) is raised. */
  background:
    linear-gradient(var(--mark-sunk), var(--mark-sunk)) calc(25% + 0.75px) 51.5% / 2px 8px no-repeat,
    radial-gradient(circle, transparent 3px, var(--mark) 3.2px 4.4px, transparent 4.6px) calc(75% + 0.75px) 48.5% / 12px 12px no-repeat,
    linear-gradient(to bottom, rgb(0 0 0 / 0.45), transparent 60%) 0 0 / 50% 100% no-repeat,
    linear-gradient(to right, rgb(0 0 0 / 0.32), transparent 45%) 0 0 / 50% 100% no-repeat,
    linear-gradient(rgb(255 255 255 / 0.75), rgb(255 255 255 / 0.75)) 100% 0 / 50% 1px no-repeat,
    linear-gradient(90deg, var(--cap-sunk) 0 49.6%, rgb(0 0 0 / 0.4) 49.6% 50.4%, var(--cap-lo) 50.4%, var(--cap-mid) 68%, var(--cap-hi) 86% 95%, var(--cap-wall) 95%);
  box-shadow: 2px 2px 3px -1px rgb(0 0 0 / 0.6);
}
.tui-rocker:focus-visible { outline: 2px solid var(--tui-focus); outline-offset: 3px; }

/* A check key: a small square key; checked, a tick is printed on it. */
.tui-check, .tui-radio {
  appearance: none;
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  cursor: pointer;
  border-radius: 5px;
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1.5px 0 var(--tui-skirt), 0 2px 3px rgb(var(--tui-sh) / 0.25);
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease);
}
.tui-radio { border-radius: 50%; }
.tui-check:checked, .tui-radio:checked {
  transform: translateY(1.5px);
  box-shadow: var(--tui-pressed);
}
.tui-check:checked::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 3px;
  width: 5px;
  height: 9px;
  border: solid var(--tui-ink);
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}
.tui-radio:checked::after {
  content: '';
  position: absolute;
  inset: 5.5px;
  border-radius: 50%;
  background: var(--tui-ink);
}
.tui-choice { display: inline-flex; align-items: center; gap: var(--tui-2); cursor: pointer; font-size: var(--tui-t-body); }

/* A row of latching keys, one down at a time: a band selector. */
.tui-seg {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: 9px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-seg > label { position: relative; display: block; }
.tui-seg input { position: absolute; opacity: 0; pointer-events: none; }
.tui-seg span {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 var(--tui-3);
  border-radius: 6px;
  font: 600 var(--tui-t-small)/1 var(--tui-sans);
  color: var(--tui-ink-2);
  cursor: pointer;
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1.5px 0 var(--tui-skirt), 0 2px 4px rgb(var(--tui-sh) / 0.2);
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease), color 70ms;
}
.tui-seg span::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--tui-amber) 20%, var(--tui-face-lo));
  box-shadow: inset 0 1px 1px rgb(0 0 0 / 0.35);
}
.tui-seg input:checked + span {
  transform: translateY(1.5px);
  color: var(--tui-ink);
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
}
.tui-seg input:checked + span::before {
  background: var(--tui-amber);
  box-shadow: 0 0 5px 1px color-mix(in oklab, var(--tui-amber) 60%, transparent);
}
.tui-seg input:focus-visible + span { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-seg--plain span::before { display: none; }

/* ------------------------------------------------------------------ fader */

/* A fader: a cap riding in a slot cut into the plate. */
.tui-fader {
  appearance: none;
  width: 100%;
  height: 32px;
  margin: 0;
  cursor: pointer;
  background: transparent;
}
.tui-fader::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: inset 0 1.5px 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2)), 0 1px 0 var(--tui-hl);
}
.tui-fader::-moz-range-track {
  height: 6px;
  border-radius: 3px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: inset 0 1.5px 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2)), 0 1px 0 var(--tui-hl);
}
.tui-fader::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 28px;
  margin-top: -11px;
  border-radius: 4px;
  background:
    linear-gradient(var(--tui-ink), var(--tui-ink)) center / 100% 1.5px no-repeat,
    linear-gradient(90deg, var(--tui-face-lo), var(--tui-face-hi) 30%, var(--tui-face-hi) 60%, var(--tui-face-lo));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 0 var(--tui-skirt), 0 4px 8px rgb(var(--tui-sh) / 0.35);
}
.tui-fader::-moz-range-thumb {
  width: 16px;
  height: 28px;
  border: 0;
  border-radius: 4px;
  background:
    linear-gradient(var(--tui-ink), var(--tui-ink)) center / 100% 1.5px no-repeat,
    linear-gradient(90deg, var(--tui-face-lo), var(--tui-face-hi) 30%, var(--tui-face-hi) 60%, var(--tui-face-lo));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 0 var(--tui-skirt), 0 4px 8px rgb(var(--tui-sh) / 0.35);
}
.tui-fader:focus-visible { outline: none; }
.tui-fader:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-fader:focus-visible::-moz-range-thumb { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
/* The scale printed under a fader: ticks every 10%, a longer one at each end. */
.tui-scale {
  height: 8px;
  margin: 0 8px;
  background:
    linear-gradient(90deg, var(--tui-ink-3) 1px, transparent 1px) 0 0 / 10% 5px repeat-x,
    linear-gradient(90deg, var(--tui-ink-2) 1px, transparent 1px) 0 0 / calc(100% - 1px) 8px repeat-x;
}
.tui-fader--v { writing-mode: vertical-lr; direction: rtl; width: 32px; height: 140px; }
.tui-fader--v::-webkit-slider-runnable-track { width: 6px; height: auto; }
.tui-fader--v::-webkit-slider-thumb { width: 28px; height: 16px; margin-top: 0; margin-left: -11px; background: linear-gradient(var(--tui-ink), var(--tui-ink)) center / 1.5px 100% no-repeat, linear-gradient(var(--tui-face-lo), var(--tui-face-hi) 30%, var(--tui-face-hi) 60%, var(--tui-face-lo)); }

/* ------------------------------------------------------------------- knob */

/* <tui-knob>: kit.mjs draws the ticks and turns it. The knurl and the
   pointer turn; the cap's sheen and every shadow stay still, because the
   lamp does not move. */
tui-knob {
  --size: 64px;
  --turn: 0deg;
  --k-hi: var(--tui-knob-hi);
  --k-mid: var(--tui-knob-mid);
  --k-lo: var(--tui-knob-lo);
  position: relative;
  display: inline-grid;
  place-items: center;
  width: calc(var(--size) * 1.45);
  height: calc(var(--size) * 1.45);
  touch-action: none;
  cursor: grab;
  user-select: none;
  outline: none;
}
/* A black knob on any finish. */
tui-knob[data-knob="black"] { --k-hi: #5a5b5f; --k-mid: #2c2d30; --k-lo: #141517; --tui-knob-cap-shadow: inset 0 1px 1px rgb(255 255 255 / 0.2), inset 0 -1px 2px rgb(0 0 0 / 0.5), 0 1px 2px rgb(0 0 0 / 0.6); }
tui-knob:active { cursor: grabbing; }
tui-knob .tui-knob__ticks { position: absolute; inset: 0; color: var(--tui-ink-2); }
tui-knob .tui-knob__body {
  position: relative;
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background: var(--k-mid);
  box-shadow: 0 1px 1.5px rgb(var(--tui-sh) / 0.45), 3px 7px 14px -6px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2));
}
tui-knob .tui-knob__knurl, tui-knob .tui-knob__sheen, tui-knob .tui-knob__cap, tui-knob .tui-knob__mark { position: absolute; border-radius: 50%; }
/* Ridges, turning with the knob. */
tui-knob .tui-knob__knurl {
  inset: 0;
  transform: rotate(var(--turn));
  background: repeating-conic-gradient(from 0deg, rgb(0 0 0 / 0.3) 0 2.2deg, rgb(255 255 255 / 0.35) 2.2deg 3deg, transparent 3deg 6deg);
}
/* Light on the skirt, fixed: bright toward the lamp, dark away from it. */
tui-knob .tui-knob__sheen {
  inset: 0;
  background: linear-gradient(150deg, rgb(255 255 255 / 0.45), transparent 42%, transparent 58%, rgb(0 0 0 / 0.35));
}
/* The spun cap: a fixed bow-tie highlight across the machining, the way
   light sits on turned aluminium whatever angle the knob is at. */
tui-knob .tui-knob__cap {
  inset: 13%;
  background:
    repeating-radial-gradient(circle, rgb(255 255 255 / 0.06) 0 0.6px, rgb(0 0 0 / 0.035) 0.6px 1.5px),
    conic-gradient(from 0deg, var(--k-mid) 0deg, var(--k-lo) 40deg, var(--k-mid) 80deg, var(--k-hi) 135deg, var(--k-mid) 180deg, var(--k-lo) 220deg, var(--k-mid) 260deg, var(--k-hi) 315deg, var(--k-mid) 360deg);
  box-shadow: var(--tui-knob-cap-shadow);
}
/* The pointer, engraved into the cap, turning. */
tui-knob .tui-knob__mark { inset: 13%; transform: rotate(var(--turn)); }
tui-knob .tui-knob__mark::after {
  content: '';
  position: absolute;
  left: calc(50% - 1px);
  top: 5%;
  width: 2px;
  height: 30%;
  border-radius: 1px;
  background: var(--tui-ink);
  box-shadow: 0 1px 0 rgb(255 255 255 / 0.35);
}
tui-knob:focus-visible .tui-knob__body { outline: 2px solid var(--tui-focus); outline-offset: 4px; }
.tui-control { display: inline-grid; justify-items: center; gap: var(--tui-1); }
.tui-control > .tui-label { text-align: center; }
.tui-control output { font: 500 var(--tui-t-small)/1 var(--tui-sans); font-variant-numeric: tabular-nums; color: var(--tui-ink); }

/* ----------------------------------------------------------------- fields */

.tui-field { display: grid; gap: 6px; min-width: 0; }
.tui-field > .tui-label { padding-left: 2px; }
.tui-hint { font-size: var(--tui-t-small); color: var(--tui-ink-2); padding-left: 2px; }
.tui-field[data-error] .tui-hint { color: var(--tui-red); }
.tui-input, .tui-select, .tui-textarea {
  appearance: none;
  width: 100%;
  min-width: 0;
  height: 38px;
  padding: 0 var(--tui-3);
  border: 0;
  border-radius: var(--tui-r-m);
  font: 400 var(--tui-t-body)/1 var(--tui-sans);
  color: var(--tui-ink);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-textarea { height: auto; min-height: 96px; padding: var(--tui-3); line-height: 1.5; resize: vertical; }
.tui-input::placeholder, .tui-textarea::placeholder { color: var(--tui-ink-3); }
.tui-input:focus-visible, .tui-select:focus-visible, .tui-textarea:focus-visible { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
/* An error is marked on the lip around the cut, so the upper wall's shadow cannot hide it. */
.tui-field[data-error] :is(.tui-input, .tui-select, .tui-textarea, .tui-combo) { box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--tui-red) 85%, transparent), 0 0 8px -2px color-mix(in oklab, var(--tui-red) 45%, transparent), var(--tui-inset); }
.tui-select {
  padding-right: 34px;
  cursor: pointer;
  background:
    linear-gradient(45deg, transparent 50%, var(--tui-ink-2) 50%) calc(100% - 17px) 50% / 5px 5px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--tui-ink-2) 50%) calc(100% - 12px) 50% / 5px 5px no-repeat,
    var(--tui-well);
  background-position: calc(100% - 17px) 55%, calc(100% - 12px) 55%, 0 0;
}
/* An input with a key beside it, sharing one well. */
.tui-combo { display: flex; gap: 4px; padding: 4px; border-radius: 11px; background: var(--tui-well-fill) var(--tui-well); box-shadow: var(--tui-inset); }
.tui-combo .tui-input { box-shadow: none; background: transparent; height: 36px; }
/* Focus rings the whole well, not the field inside it. */
.tui-combo .tui-input:focus-visible, .tui-stepper input:focus-visible { outline: none; }
.tui-combo:has(.tui-input:focus-visible), .tui-stepper:has(input:focus-visible) { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-combo .tui-key { --h: 36px; }
/* A number with − and + keys. */
.tui-stepper { display: inline-flex; align-items: center; gap: 3px; padding: 3px; border-radius: 9px; background: var(--tui-well-fill) var(--tui-well); box-shadow: var(--tui-inset); }
.tui-stepper input { width: 5ch; border: 0; background: transparent; text-align: center; font: 600 var(--tui-t-body)/1 var(--tui-sans); font-variant-numeric: tabular-nums; color: var(--tui-ink); -moz-appearance: textfield; }
.tui-stepper input::-webkit-inner-spin-button { display: none; }
.tui-stepper .tui-key { --h: 28px; --skirt: 1.5px; width: 28px; padding: 0; }

/* --------------------------------------------------------------- displays */

/* A liquid-crystal window: grey-green glass, dark segments, a ghost of the
   unlit ones behind (data-ghost: the same width as the value, digits as 8,
   e.g. "88:88" behind "02:52"). */
.tui-lcd, .tui-vfd {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  padding: 0.35em 0.6em;
  border-radius: var(--tui-r-s);
  font: 500 28px/1 var(--tui-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.tui-lcd {
  color: var(--tui-lcd-ink);
  background:
    linear-gradient(170deg, rgb(255 255 255 / 0.18), transparent 40%),
    var(--tui-lcd);
  box-shadow: inset 0 2px 4px rgb(0 0 0 / 0.28), inset 0 0 0 1px rgb(0 0 0 / 0.18), 0 1px 0 var(--tui-hl);
  text-shadow: 1px 1.5px 0 rgb(0 0 0 / 0.1);
}
.tui-vfd {
  color: var(--tui-vfd);
  background:
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.025) 0 1px, transparent 1px 3px),
    var(--tui-vfd-bg);
  box-shadow: inset 0 2px 6px rgb(0 0 0 / 0.8), inset 0 0 0 1px rgb(255 255 255 / 0.05), 0 1px 0 var(--tui-hl);
  text-shadow: 0 0 6px color-mix(in oklab, var(--tui-vfd) 55%, transparent), 0 0 18px color-mix(in oklab, var(--tui-vfd) 18%, transparent);
}
.tui-lcd[data-ghost]::before, .tui-vfd[data-ghost]::before {
  content: attr(data-ghost);
  position: absolute;
  left: 0.6em;
  top: 0.35em;
  opacity: 0.08;
  text-shadow: none;
}
.tui-lcd small, .tui-vfd small { font: 600 0.36em/1 var(--tui-sans); letter-spacing: var(--tui-track); text-transform: uppercase; opacity: 0.75; }
.tui-lcd--sm, .tui-vfd--sm { font-size: 16px; }
.tui-lcd--lg, .tui-vfd--lg { font-size: 44px; }

/* A readout: a printed label over a value, the way a panel names its dials. */
.tui-readout { display: grid; gap: 6px; }
.tui-readout__value { font: 600 var(--tui-t-h2)/1 var(--tui-sans); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.tui-readout__value small { font-size: 0.5em; font-weight: 500; color: var(--tui-ink-2); letter-spacing: 0; margin-left: 2px; }
.tui-delta { font: 600 var(--tui-t-small)/1 var(--tui-sans); color: var(--tui-ink-2); }
.tui-delta[data-dir="up"]::before { content: '▲ '; font-size: 0.7em; color: var(--tui-green); }
.tui-delta[data-dir="down"]::before { content: '▼ '; font-size: 0.7em; color: var(--tui-red); }

/* ----------------------------------------------------------------- meters */

/* An LED ladder: set --v from 0 to 1. Green, then amber, then red, the way
   a recording level has always been read. */
.tui-ladder {
  --v: 0.5;
  --n: 24;
  position: relative;
  height: 10px;
  border-radius: 2px;
  background: var(--tui-vfd-bg);
  box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.6), 0 1px 0 var(--tui-hl);
  overflow: hidden;
}
.tui-ladder::before, .tui-ladder::after {
  content: '';
  position: absolute;
  inset: 2px;
  background: linear-gradient(90deg, var(--tui-green) 0 70%, var(--tui-amber) 70% 88%, var(--tui-red) 88%);
  -webkit-mask: repeating-linear-gradient(90deg, #000 0 calc(100% / var(--n) - 2px), transparent calc(100% / var(--n) - 2px) calc(100% / var(--n)));
          mask: repeating-linear-gradient(90deg, #000 0 calc(100% / var(--n) - 2px), transparent calc(100% / var(--n) - 2px) calc(100% / var(--n)));
}
.tui-ladder::before { opacity: 0.14; }
.tui-ladder::after { clip-path: inset(0 calc((1 - var(--v)) * 100%) 0 0); filter: drop-shadow(0 0 3px rgb(255 255 255 / 0.25)); transition: clip-path 90ms linear; }
/* A progress slot: ink filling a groove, never a colour bar. */
.tui-progress {
  --v: 0.4;
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: inset 0 1.5px 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2)), 0 1px 0 var(--tui-hl);
  overflow: hidden;
}
.tui-progress::after {
  content: '';
  position: absolute;
  inset: 2px;
  right: auto;
  width: calc((100% - 4px) * var(--v));
  border-radius: 3px;
  background: var(--tui-ink);
  transition: width 300ms var(--tui-ease);
}

/* ------------------------------------------------------------- navigation */

/* Tabs: keys in a tray. kit.mjs gives them arrow keys. */
/* A tray wider than its container scrolls inside itself, never the page. */
.tui-tabs { display: inline-flex; max-width: 100%; overflow-x: auto; scrollbar-width: none; gap: 3px; padding: 3px; border-radius: 9px; background: var(--tui-well-fill) var(--tui-well); box-shadow: var(--tui-inset); }
.tui-tabs [role="tab"] {
  appearance: none;
  flex: none;
  white-space: nowrap;
  height: 30px;
  padding: 0 var(--tui-4);
  border: 0;
  border-radius: 6px;
  font: 600 var(--tui-t-small)/1 var(--tui-sans);
  color: var(--tui-ink-2);
  background: transparent;
  cursor: pointer;
}
.tui-tabs [role="tab"]:hover { color: var(--tui-ink); }
.tui-tabs [role="tab"][aria-selected="true"] {
  color: var(--tui-ink);
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1px 2px rgb(var(--tui-sh) / 0.3);
}

/* A bar across the top of a page: wordmark, keys, one action. */
.tui-bar {
  display: flex;
  align-items: center;
  gap: var(--tui-4);
  min-height: 56px;
  padding: 0 var(--tui-5);
}
.tui-bar__brand { display: flex; align-items: center; gap: var(--tui-2); font-weight: 700; letter-spacing: -0.01em; color: var(--tui-ink); text-decoration: none; }
.tui-bar__links { display: flex; gap: var(--tui-1); margin-left: auto; }
.tui-bar__links a { padding: 6px 10px; border-radius: 6px; font-size: var(--tui-t-small); font-weight: 500; color: var(--tui-ink-2); text-decoration: none; }
.tui-bar__links a:hover, .tui-bar__links a[aria-current] { color: var(--tui-ink); }

/* A side rail: the selected line lights its lamp. */
.tui-side { display: grid; gap: 2px; align-content: start; }
.tui-side > .tui-label { padding: var(--tui-4) var(--tui-3) var(--tui-2); }
.tui-side a {
  display: flex;
  align-items: center;
  gap: var(--tui-3);
  height: 34px;
  padding: 0 var(--tui-3);
  border-radius: var(--tui-r-m);
  font-size: var(--tui-t-body);
  font-weight: 500;
  color: var(--tui-ink-2);
  text-decoration: none;
}
.tui-side a::after { content: ''; width: 6px; height: 6px; margin-left: auto; border-radius: 50%; background: color-mix(in oklab, var(--tui-green) 18%, var(--tui-face-lo)); box-shadow: inset 0 1px 1px rgb(0 0 0 / 0.35); }
.tui-side a:hover { color: var(--tui-ink); background: color-mix(in oklab, var(--tui-face-hi) 50%, transparent); }
.tui-side a[aria-current="page"] {
  color: var(--tui-ink);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-side a[aria-current="page"]::after { background: var(--tui-green); box-shadow: 0 0 6px 1px color-mix(in oklab, var(--tui-green) 60%, transparent); }
.tui-side svg { width: 16px; height: 16px; flex: none; }

/* ------------------------------------------------------------------ table */

.tui-table { width: 100%; border-collapse: collapse; font-size: var(--tui-t-body); font-variant-numeric: tabular-nums; }
.tui-table th {
  padding: 0 var(--tui-3) var(--tui-2);
  text-align: left;
  font: 600 var(--tui-t-label)/1.2 var(--tui-sans);
  letter-spacing: var(--tui-track);
  text-transform: uppercase;
  color: var(--tui-ink-2);
  border-bottom: 1px solid var(--tui-rule);
}
.tui-table td { padding: 11px var(--tui-3); border-bottom: 1px solid var(--tui-rule); vertical-align: middle; }
.tui-table tr:last-child td { border-bottom: 0; }
.tui-table tbody tr:hover td { background: color-mix(in oklab, var(--tui-face-hi) 45%, transparent); }
.tui-table .is-num { text-align: right; }
.tui-table-wrap { overflow-x: auto; }

/* ---------------------------------------------------------- dialog, toast */

.tui-dialog {
  width: min(440px, calc(100vw - 32px));
  padding: var(--tui-6);
  border: 0;
  border-radius: 14px;
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 3px rgb(var(--tui-sh) / 0.3), 0 30px 60px -20px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.4));
}
.tui-dialog::backdrop { background: var(--tui-backdrop); }
.tui-dialog[open] { animation: tui-rise 220ms var(--tui-ease); }
.tui-dialog__actions { display: flex; justify-content: flex-end; gap: var(--tui-2); margin-top: var(--tui-6); }
@keyframes tui-rise { from { opacity: 0; transform: translateY(8px) scale(0.985); } }

/* Toasts: a small plate with a lamp, stacked bottom right. See kit.mjs. */
.tui-toasts { position: fixed; right: var(--tui-4); bottom: var(--tui-4); z-index: 50; display: grid; gap: var(--tui-2); justify-items: end; pointer-events: none; }
.tui-toast {
  display: flex;
  align-items: center;
  gap: var(--tui-3);
  max-width: 360px;
  padding: var(--tui-3) var(--tui-4);
  border-radius: 10px;
  font-size: var(--tui-t-body);
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 3px rgb(var(--tui-sh) / 0.25), 0 16px 32px -12px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2));
  pointer-events: auto;
  animation: tui-rise 220ms var(--tui-ease);
}
.tui-toast.is-leaving { opacity: 0; transform: translateY(6px); transition: opacity 200ms, transform 200ms; }

/* Plain-text tooltips on anything with data-tip. */
[data-tip] { position: relative; }
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  padding: 5px 8px;
  border-radius: 5px;
  white-space: nowrap;
  font: 500 11px/1 var(--tui-sans);
  letter-spacing: 0.01em;
  color: var(--tui-cap-ink);
  background: var(--tui-cap);
  box-shadow: 0 4px 10px -4px rgb(0 0 0 / 0.4);
  pointer-events: none;
  z-index: 10;
}

@media (prefers-reduced-motion: reduce) {
  .tui *, .tui *::before, .tui *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
  .tui-lamp[data-blink] { animation: none; }
}

/* ------------------------------------------------------------------- plot */

/* A plot on a display: gridlines printed faint, traces drawn in light.
   Put it inside .tui-glass (dark display glass) or any panel (ink traces). */
.tui-plot { display: block; width: 100%; height: auto; overflow: visible; }
.tui-plot .grid { stroke: var(--tui-rule); stroke-width: 1; }
.tui-plot .axis { fill: var(--tui-ink-3); font: 500 10px var(--tui-sans); letter-spacing: 0.04em; }
.tui-plot .trace { fill: none; stroke: var(--tui-ink); stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
.tui-plot .trace--2 { stroke: var(--tui-ink-3); stroke-dasharray: 3 3; }
.tui-plot .fill { fill: var(--tui-ink); opacity: 0.07; }
.tui-plot .now { stroke: var(--tui-red); stroke-width: 1; }
/* Dark glass for a plot or a readout, whatever the finish around it. */
.tui-glass {
  border-radius: var(--tui-r-m);
  padding: var(--tui-4);
  background:
    linear-gradient(165deg, rgb(255 255 255 / 0.06), transparent 35%),
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.018) 0 1px, transparent 1px 3px),
    var(--tui-vfd-bg);
  box-shadow: inset 0 2px 8px rgb(0 0 0 / 0.85), inset 0 0 0 1px rgb(255 255 255 / 0.05), 0 1px 0 var(--tui-hl);
  color: var(--tui-vfd);
  --tui-ink: var(--tui-vfd);
  --tui-ink-2: color-mix(in oklab, var(--tui-vfd) 70%, transparent);
  --tui-ink-3: color-mix(in oklab, var(--tui-vfd) 42%, transparent);
  --tui-rule: color-mix(in oklab, var(--tui-vfd) 10%, transparent);
}
.tui-glass .tui-plot .trace { filter: drop-shadow(0 0 3px color-mix(in oklab, var(--tui-vfd) 60%, transparent)); }
.tui-glass .tui-plot .fill { fill: var(--tui-vfd); opacity: 0.08; }
.tui-glass .tui-label { color: var(--tui-ink-2); }
/* A key/value list, printed like the plate on the back of a device. */
.tui-spec { display: grid; grid-template-columns: auto 1fr; gap: 0; margin: 0; font-size: var(--tui-t-body); }
.tui-spec dt, .tui-spec dd { margin: 0; padding: 9px 0; border-bottom: 1px solid var(--tui-rule); }
.tui-spec dt { color: var(--tui-ink-2); padding-right: var(--tui-4); }
.tui-spec dd { text-align: right; font-weight: 500; font-variant-numeric: tabular-nums; }
.tui-spec > :nth-last-child(-n+2) { border-bottom: 0; }

/* Forced states, for showing every state of a part at once (docs, specimens). */
.tui-key.is-hover { filter: brightness(1.03); }
.tui-key.is-focus, .tui-switch.is-focus, .tui-input.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 3px; }

/* ------------------------------------------------------------ forced states and disabled, for every part */

/* Forced states show a part's states side by side in documentation. */
.tui-seg label.is-down span, .tui-check.is-down, .tui-radio.is-down { transform: translateY(1.5px); box-shadow: var(--tui-pressed); }
.tui-seg label.is-hover span, .tui-check.is-hover, .tui-radio.is-hover, .tui-switch.is-hover, .tui-rocker.is-hover { filter: brightness(1.03); }
.tui-seg label.is-focus span, .tui-check.is-focus, .tui-radio.is-focus, .tui-rocker.is-focus, .tui-select.is-focus, .tui-textarea.is-focus,
.tui-tabs [role="tab"].is-focus, tui-knob.is-focus .tui-knob__body, .tui-fader.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 3px; }
.tui-tabs [role="tab"].is-hover { color: var(--tui-ink); }

/* Disabled: 45% and no movement, on every control. */
.tui-check:disabled, .tui-radio:disabled, .tui-rocker:disabled, .tui-fader:disabled, .tui-select:disabled, .tui-textarea:disabled, .tui-input:disabled,
.tui-seg input:disabled + span, .tui-tabs [role="tab"]:disabled, tui-knob[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.tui-check:disabled, .tui-radio:disabled, .tui-seg input:disabled + span { transform: none; }
tui-knob[aria-disabled="true"] { pointer-events: none; }

/* ---------------------------------------------------------------- part: accordion */
/* Accordion: printed sections, each with a small square key at the end of
   its head, printed +. Opening a section latches the key below the plate and
   its printing turns to −; the section's text slides out under the head.
   Native <details>: give them one name and only one opens at a time. */
.tui-accordion { display: grid; }
.tui-accordion__item { border-bottom: 1px solid var(--tui-rule); }
.tui-accordion__item:first-child { border-top: 1px solid var(--tui-rule); }
.tui-panel > .tui-accordion:first-child .tui-accordion__item:first-child,
.tui-accordion--flush .tui-accordion__item:first-child { border-top: 0; }
.tui-accordion--flush .tui-accordion__item:last-child { border-bottom: 0; }

.tui-accordion__item > summary {
  display: flex;
  align-items: center;
  gap: var(--tui-3);
  min-height: 52px;
  padding: var(--tui-2) 2px;
  list-style: none;
  font: 600 14px/1.35 var(--tui-sans);
  letter-spacing: -0.005em;
  color: var(--tui-ink);
  cursor: pointer;
  user-select: none;
  border-radius: var(--tui-r-m);
  -webkit-tap-highlight-color: transparent;
}
.tui-accordion__item > summary::-webkit-details-marker { display: none; }
.tui-accordion__item > summary::marker { content: ''; }
/* The key: a cap on a 1.5px skirt, printed + (the bar that makes it − drops away when open). */
.tui-accordion__item > summary::after {
  content: '';
  flex: none;
  width: 22px;
  height: 22px;
  margin-left: auto;
  border-radius: 6px;
  background:
    linear-gradient(var(--tui-ink), var(--tui-ink)) center / 8px 1.5px no-repeat,
    linear-gradient(var(--tui-ink), var(--tui-ink)) center / 1.5px 8px no-repeat,
    radial-gradient(120% 90% at 50% 0%, var(--tui-hl), transparent 60%),
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1.5px 0 var(--tui-skirt), 0 2.5px 3px rgb(var(--tui-sh) / 0.25);
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease);
}
.tui-accordion__item > summary:hover::after, .tui-accordion__item > summary.is-hover::after { filter: brightness(1.03); }
.tui-accordion__item > summary:active::after, .tui-accordion__item > summary.is-down::after,
.tui-accordion__item[open] > summary::after {
  transform: translateY(1.5px);
  filter: brightness(0.97);
  background:
    linear-gradient(var(--tui-ink), var(--tui-ink)) center / 8px 1.5px no-repeat,
    radial-gradient(120% 90% at 50% 0%, var(--tui-hl), transparent 60%),
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: var(--tui-pressed);
}
.tui-accordion__item > summary:focus-visible, .tui-accordion__item > summary.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 2px; }

/* An index number printed before the head, like a manual's sections. */
.tui-accordion__n {
  flex: none;
  width: 22px;
  font: 500 var(--tui-t-label)/1 var(--tui-sans);
  letter-spacing: var(--tui-track);
  color: var(--tui-ink-2);
}
.tui-accordion__meta { font: 500 var(--tui-t-small)/1 var(--tui-sans); color: var(--tui-ink-2); white-space: nowrap; }

.tui-accordion__body { padding: 0 2px var(--tui-5); color: var(--tui-ink-2); }
.tui-accordion__body > :first-child { margin-top: 0; }
.tui-accordion__body > :last-child { margin-bottom: 0; }
/* Numbered: the text lines up with the head's words, not with the number. */
.tui-accordion__item:has(> summary .tui-accordion__n) > .tui-accordion__body { padding-left: calc(22px + var(--tui-3) + 2px); }
.tui-accordion__item[open] > .tui-accordion__body { animation: tui-accordion-out 200ms var(--tui-ease); }
@keyframes tui-accordion-out { from { opacity: 0; transform: translateY(-6px); } }

/* ---------------------------------------------------------------- part: alert */
/* Alert: a message window let into the surface, with an annunciator — a
   small lit legend like the STEREO window on a receiver. The legend is the
   only colour: lit display-white for a note, green when done, amber to check,
   red for a fault. The words beside it say what happened and what to do. */
.tui-alert {
  --lit: var(--tui-vfd);
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--tui-2) var(--tui-3);
  padding: 10px 10px 10px 10px;
  border-radius: 9px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  font-size: var(--tui-t-body);
  line-height: 1.45;
  color: var(--tui-ink);
}
.tui-alert[data-alert="success"] { --lit: var(--tui-green); }
.tui-alert[data-alert="warning"] { --lit: var(--tui-amber); }
/* Red is lifted toward the display's white so the legend reads at 4.5:1. */
.tui-alert[data-alert="error"] { --lit: color-mix(in oklab, var(--tui-red) 78%, var(--tui-vfd)); }

/* The annunciator: dark glass, the legend lit behind it. */
.tui-alert__legend {
  flex: none;
  display: inline-grid;
  place-items: center;
  min-width: 64px;
  height: 24px;
  padding: 0 8px;
  border-radius: var(--tui-r-s);
  font: 700 10.5px/1 var(--tui-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lit);
  background:
    linear-gradient(170deg, rgb(255 255 255 / 0.07), transparent 45%),
    radial-gradient(80% 90% at 50% 55%, color-mix(in oklab, var(--lit) 16%, transparent), transparent 75%),
    var(--tui-vfd-bg);
  box-shadow: inset 0 1.5px 3px rgb(0 0 0 / 0.85), inset 0 0 0 1px rgb(255 255 255 / 0.05), 0 1px 0 var(--tui-hl);
  text-shadow: 0 0 5px color-mix(in oklab, var(--lit) 60%, transparent), 0 0 14px color-mix(in oklab, var(--lit) 25%, transparent);
}
.tui-alert__legend[data-blink] { animation: tui-blink 1.2s steps(1) infinite; }

.tui-alert:has(> .tui-alert__dismiss) { padding-right: 44px; }
.tui-alert__text { flex: 1 1 160px; min-width: 0; margin: 0; padding-top: 2px; color: var(--tui-ink-2); }
.tui-alert__text b, .tui-alert__text strong { font-weight: 700; color: var(--tui-ink); }
.tui-alert__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--tui-2); margin-left: auto; }
/* The ×: pinned top right, whatever wraps below it. */
.tui-alert__dismiss { position: absolute; top: 8px; right: 8px; color: var(--tui-ink-2); }
.tui-alert__dismiss svg { width: 14px; height: 14px; }
/* A long message puts its keys on their own line, under the words. */
.tui-alert--stacked .tui-alert__actions { flex-basis: 100%; margin-left: 0; padding-left: 76px; }

.tui-alert.is-leaving { opacity: 0; transform: translateY(-4px); transition: opacity 160ms var(--tui-ease), transform 160ms var(--tui-ease); }
@media (prefers-reduced-motion: reduce) { .tui-alert__legend[data-blink] { animation: none; } }

/* ---------------------------------------------------------------- part: avatar */
/* Avatar: a person's mark, struck like a coin. A raised rim catches the lamp;
   the field inside it sits a little lower, so the rim shades its upper edge
   and its lower edge is lit. Initials are stamped into the field; a photo is
   set under the rim like a print behind a bezel. A status lamp is mounted in
   the rim, in its own small bezel. */
.tui-avatar {
  --size: 40px;
  --field: calc(var(--size) * 0.075);
  position: relative;
  isolation: isolate;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  vertical-align: middle;
  font: 700 calc(var(--size) * 0.36)/1 var(--tui-sans);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--tui-ink-2);
  user-select: none;
  /* The rim: turned metal, brightest toward the lamp. */
  background:
    radial-gradient(90% 90% at 30% 22%, var(--tui-hl), transparent 60%),
    linear-gradient(150deg, var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 78%, rgb(var(--tui-sh))));
  box-shadow: var(--tui-raised);
}
/* The field, struck below the rim. */
.tui-avatar::before, .tui-avatar::after {
  content: '';
  position: absolute;
  inset: var(--field);
  border-radius: inherit;
  pointer-events: none;
}
.tui-avatar::before {
  z-index: -1;
  background: radial-gradient(130% 110% at 36% 24%, var(--tui-face-hi), var(--tui-face) 70%, color-mix(in oklab, var(--tui-face) 88%, rgb(var(--tui-sh))));
}
/* The rim's shadow on the field, over a photo too: dark under the upper wall, lit along the lower one. */
.tui-avatar::after {
  z-index: 2;
  box-shadow:
    inset 0 1.5px 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.9)),
    inset 1px 0 1.5px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.7)),
    inset 0 -1px 0 color-mix(in oklab, var(--tui-hl) 70%, transparent);
}
/* Stamped initials: the cut's upper wall is in shadow, its lower lip lit. */
.tui-avatar__mark {
  position: relative;
  z-index: 0;
  text-shadow: 0 1px 0 var(--tui-hl), 0 -0.5px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4));
}
.tui-avatar__mark svg { display: block; width: calc(var(--size) * 0.46); height: calc(var(--size) * 0.46); filter: drop-shadow(0 1px 0 var(--tui-hl)); }
/* A photo, set under the rim. If it fails to load (alt=""), the initials beneath show through. */
.tui-avatar > img {
  position: absolute;
  z-index: 1;
  inset: var(--field);
  width: calc(100% - var(--field) * 2);
  height: calc(100% - var(--field) * 2);
  border-radius: inherit;
  object-fit: cover;
}
/* The status lamp, mounted in the rim at five o'clock in a small bezel. */
.tui-avatar > .tui-lamp {
  --d: clamp(7px, calc(var(--size) * 0.2), 12px);
  position: absolute;
  z-index: 3;
  right: calc(var(--size) * 0.02);
  bottom: calc(var(--size) * 0.02);
  width: var(--d);
  height: var(--d);
  box-shadow: 0 0 0 max(1.5px, calc(var(--size) * 0.04)) var(--tui-face-hi), 0 0 0 max(2.5px, calc(var(--size) * 0.06)) rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.8)), inset 0 1px 1.5px rgb(0 0 0 / 0.45);
}
.tui-avatar > .tui-lamp:is([data-on], .is-on) {
  box-shadow: 0 0 0 max(1.5px, calc(var(--size) * 0.04)) var(--tui-face-hi), 0 0 0 max(2.5px, calc(var(--size) * 0.06)) rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.8)), 0 0 7px 1px color-mix(in oklab, var(--c) 70%, transparent);
}

.tui-avatar--sm { --size: 28px; letter-spacing: 0; }
.tui-avatar--lg { --size: 56px; }
.tui-avatar--xl { --size: 80px; }
/* A company or a team: a squared coin. */
.tui-avatar--square { border-radius: 26%; }
/* The count at the end of a stack: the field printed darker. */
.tui-avatar--more { font-size: calc(var(--size) * 0.3); letter-spacing: 0; color: var(--tui-ink); }
.tui-avatar--more::before { background: linear-gradient(var(--tui-face-lo), color-mix(in oklab, var(--tui-face-lo) 70%, var(--tui-face))); }

/* A stack: coins overlap from the left, each casting its shadow on the next
   (the lamp is to the left), so the first lies on top. */
.tui-avatar-group { display: inline-flex; align-items: center; isolation: isolate; }
.tui-avatar-group > .tui-avatar { box-shadow: var(--tui-raised), 3px 0 4px -1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.3)); }
.tui-avatar-group > .tui-avatar + .tui-avatar { margin-left: calc(var(--size) * -0.3); }
.tui-avatar-group > :nth-child(1) { z-index: 8; }
.tui-avatar-group > :nth-child(2) { z-index: 7; }
.tui-avatar-group > :nth-child(3) { z-index: 6; }
.tui-avatar-group > :nth-child(4) { z-index: 5; }
.tui-avatar-group > :nth-child(5) { z-index: 4; }
.tui-avatar-group > :nth-child(6) { z-index: 3; }
.tui-avatar-group > :nth-child(7) { z-index: 2; }
.tui-avatar-group > :nth-child(n+8) { z-index: 1; }
.tui-avatar-group--sm > .tui-avatar { --size: 28px; font-size: 10px; letter-spacing: 0; }
.tui-avatar-group--lg > .tui-avatar { --size: 56px; }

/* ---------------------------------------------------------------- part: calendar */
/* Calendar: a month on a plate. The month and the year are printed on two
   drums behind a window; paging rolls them. Days are printed; the chosen day
   is a latched contrast cap, a range a groove cut between two caps, events
   lamps under a day. kit/parts/calendar.mjs builds and wires it. */
tui-calendar {
  --tui-calendar-cell: 42px;
  container: tui-calendar / inline-size;
  display: grid;
  gap: var(--tui-3);
  width: min(100%, calc(var(--tui-calendar-cell) * 7 + 4px));
  font-variant-numeric: tabular-nums;
}
tui-calendar > data { display: none; }

/* Page keys either side of the drum window. */
.tui-calendar__head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--tui-2); }
.tui-calendar__head .tui-key { --h: 30px; }

/* The window: a recess with two drums behind it, month and year, a hairline between. */
.tui-calendar__window {
  --face: 26px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  height: 32px;
  border-radius: var(--tui-r-m);
  background: var(--tui-well);
  box-shadow: var(--tui-inset);
  overflow: hidden;
}
.tui-calendar__drum {
  position: relative;
  overflow: hidden;
  min-width: 0;
  /* The drum's printed face: a cylinder, brightest where it faces the window. */
  background: linear-gradient(to bottom, color-mix(in oklab, var(--tui-face-hi) 70%, rgb(var(--tui-sh))), var(--tui-face-hi) 38%, var(--tui-face-hi) 58%, color-mix(in oklab, var(--tui-face-hi) 62%, rgb(var(--tui-sh))));
  margin: 3px 0 3px 3px;
  border-radius: 5px 2px 2px 5px;
}
.tui-calendar__drum + .tui-calendar__drum { min-width: 58px; margin: 3px 3px 3px 2px; border-radius: 2px 5px 5px 2px; }
/* Curvature: the faces above and below turn away into shadow; the window's upper wall shades the top. */
.tui-calendar__drum::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.2)), transparent 34%, transparent 70%, rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)));
  box-shadow: inset 0 1px 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.6));
}
.tui-calendar__strip { position: absolute; left: 0; right: 0; top: 50%; translate: 0 -50%; display: grid; }
.tui-calendar__face {
  height: var(--face);
  padding: 0 10px;
  font: 600 var(--tui-t-body)/var(--face) var(--tui-sans);
  letter-spacing: 0.01em;
  color: var(--tui-ink);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The grid: printed weekday heads, then the days. */
.tui-calendar__grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
.tui-calendar__grid th { height: 22px; padding: 0 0 4px; font: 500 var(--tui-t-label)/1 var(--tui-sans); letter-spacing: var(--tui-track); text-transform: uppercase; color: var(--tui-ink-2); text-align: center; }
.tui-calendar__grid td { position: relative; height: var(--tui-calendar-cell); padding: 0; text-align: center; outline: none; cursor: pointer; }
.tui-calendar__grid td.is-blank { cursor: default; }
.tui-calendar__cap {
  position: relative;
  z-index: 1;
  display: inline-grid;
  place-items: center;
  width: min(34px, calc(100% - 4px));
  height: 34px;
  border-radius: var(--tui-r-m);
  font: 500 var(--tui-t-body)/1 var(--tui-sans);
  color: var(--tui-ink);
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease), background-color 70ms;
}
.tui-calendar__grid td:hover .tui-calendar__cap, .tui-calendar__grid td.is-hover .tui-calendar__cap { background: color-mix(in oklab, var(--tui-face-hi) 70%, transparent); box-shadow: inset 0 1px 0 var(--tui-hl), 0 1px 2px rgb(var(--tui-sh) / 0.2); }
.tui-calendar__grid td:focus-visible .tui-calendar__cap, .tui-calendar__grid td.is-focus .tui-calendar__cap { outline: 2px solid var(--tui-focus); outline-offset: 1px; }
/* Today: printed bold, boxed by a hairline — never a colour. */
.tui-calendar__grid td[aria-current="date"] .tui-calendar__cap { font-weight: 700; box-shadow: inset 0 0 0 1.5px var(--tui-ink-2); }
/* Events: lamps under the figure. */
.tui-calendar__lamps { position: absolute; left: 0; right: 0; bottom: 3px; display: flex; justify-content: center; gap: 2px; }
.tui-calendar__lamps .tui-lamp { width: 4px; height: 4px; box-shadow: 0 0 3px 0 color-mix(in oklab, var(--c) 70%, transparent); }
/* The chosen day: the contrast cap, latched below the plate. */
.tui-calendar__grid td.is-chosen .tui-calendar__cap, .tui-calendar__grid td.is-down .tui-calendar__cap {
  color: var(--tui-cap-ink);
  font-weight: 700;
  background: linear-gradient(var(--tui-cap-hi), var(--tui-cap));
  box-shadow: var(--tui-pressed), inset 0 -1px 0 color-mix(in oklab, var(--tui-cap-hl) 60%, transparent);
  transform: translateY(1px);
}
/* A range: a groove cut between its two caps, running under them to their centres. */
.tui-calendar__grid td.is-between::before, .tui-calendar__grid td.is-start::before, .tui-calendar__grid td.is-end::before {
  content: '';
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 0;
  right: 0;
  background: var(--tui-well);
  box-shadow: inset 0 3px 3px -2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.2)), inset 0 -1px 0 color-mix(in oklab, var(--tui-hl) 60%, transparent);
}
.tui-calendar__grid td.is-start::before { left: 50%; }
.tui-calendar__grid td.is-end::before { right: 50%; }
.tui-calendar__grid tr > td:first-child.is-between::before, .tui-calendar__grid td.is-between:has(+ td.is-blank)::before { border-radius: 6px 0 0 6px; }
.tui-calendar__grid tr > td:last-child.is-between::before { border-radius: 0 6px 6px 0; }
.tui-calendar__grid td.is-between .tui-calendar__cap { font-weight: 600; }
/* While the end is still being picked, the groove is drawn in outline only. */
tui-calendar.is-picking td:is(.is-between, .is-start, .is-end)::before { background: transparent; box-shadow: inset 0 1px 0 var(--tui-ink-3), inset 0 -1px 0 var(--tui-ink-3); }
.tui-calendar__grid td.is-tentative .tui-calendar__cap { box-shadow: inset 0 0 0 1.5px var(--tui-ink); }
/* Unavailable: printed at 45%, struck through, never pressed. */
.tui-calendar__grid td[aria-disabled="true"] { cursor: not-allowed; }
.tui-calendar__grid td[aria-disabled="true"] .tui-calendar__cap { opacity: 0.45; text-decoration: line-through; text-decoration-thickness: 1px; background: none; box-shadow: none; transform: none; }

/* The line under the grid: the focused day and its events, each lamp with its words. */
.tui-calendar__note { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; min-height: 30px; margin: 0; padding-top: var(--tui-3); border-top: 1px solid var(--tui-rule); }
/* Narrow plates: smaller drum faces so the month's whole name fits. */
@container tui-calendar (max-width: 250px) {
  .tui-calendar__face { padding: 0 6px; font-size: var(--tui-t-small); }
  .tui-calendar__drum + .tui-calendar__drum { min-width: 44px; }
  .tui-calendar__head { gap: 6px; }
}
.tui-calendar__note-day { font: 600 var(--tui-t-small)/1 var(--tui-sans); color: var(--tui-ink); }
/* A half groove with nothing to meet at the edge of a week is left out. */
.tui-calendar__grid tr > td:first-child.is-end::before, .tui-calendar__grid tr > td:last-child.is-start::before { display: none; }

/* ---------------------------------------------------------------- part: carousel */
/* Carousel: a viewer. Slides pass one at a time through a gate cut into the
   plate; under it, transport keys either side of a frame counter on an LCD,
   and a row of lamp keys, the one for the slide in the gate lit.
   kit/parts/carousel.mjs builds the gate and the bar around the slides. */
tui-carousel { display: grid; gap: var(--tui-3); width: min(100%, 640px); min-width: 0; }
tui-carousel:not(:defined) { overflow: hidden; }

/* The gate: a recess with a lip, the slides behind it. */
.tui-carousel__gate {
  position: relative;
  padding: 6px;
  border-radius: var(--tui-r-l);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
/* The gate's upper wall shades the top of whatever slide is in it. */
.tui-carousel__gate::after {
  content: '';
  position: absolute;
  inset: 6px;
  z-index: 1;
  border-radius: var(--tui-r-m);
  box-shadow: inset 0 6px 8px -6px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.4)), inset 0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.5));
  pointer-events: none;
}
.tui-carousel__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: var(--tui-r-m);
  outline: none;
}
.tui-carousel__track::-webkit-scrollbar { display: none; }
.tui-carousel__gate:has(.tui-carousel__track:focus-visible) { outline: 2px solid var(--tui-focus); outline-offset: 3px; }
.tui-carousel__slide {
  position: relative;
  display: grid;
  min-width: 0;
  margin: 0;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: var(--tui-face);
}

/* The bar: transport keys, the counter, the lamp keys. */
.tui-carousel__bar { display: flex; align-items: center; gap: var(--tui-2); min-width: 0; }
.tui-carousel__bar > .tui-key--round { --h: 34px; }
.tui-carousel__count { min-width: 0; }
.tui-carousel__picks { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0; margin-left: auto; }
/* Each lamp key is a 24px target with a 7px lamp; the slide in the gate lights its lamp. */
.tui-carousel__picks button {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}
.tui-carousel__picks button:hover .tui-lamp { filter: brightness(1.15); }
.tui-carousel__picks button:focus-visible, .tui-carousel__picks button.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 0; }
.tui-carousel__rotate { flex: none; }

/* A slide with a picture and a printed caption: the common case. */
.tui-carousel__picture { display: grid; place-items: center; min-height: 220px; padding: var(--tui-5); }
.tui-carousel__caption { display: grid; gap: 2px; padding: var(--tui-3) var(--tui-4) var(--tui-4); border-top: 1px solid var(--tui-rule); }
.tui-carousel__caption b { font-size: var(--tui-t-body); color: var(--tui-ink); }
.tui-carousel__caption span { font-size: var(--tui-t-small); color: var(--tui-ink-2); }

/* Narrow viewers: the counter and the transport keys are enough. */
tui-carousel { container: tui-carousel / inline-size; }
@container tui-carousel (max-width: 300px) {
  .tui-carousel__picks { display: none; }
  .tui-carousel__bar { justify-content: center; }
  .tui-carousel__picture { min-height: 150px; padding: var(--tui-3); }
}

/* ---------------------------------------------------------------- part: chat */
/* Chat: a teleprinter, with restraint. What you type sits in a recess, as it
   did in the composer; the assistant's answer is printed on a slip torn
   along a perforation, and an amber lamp blinks at the print head while it
   prints. Code comes up on display glass. kit/parts/chat.mjs builds the
   thread and the composer. */
tui-chat {
  --tui-chat-h: 540px;
  container-type: inline-size;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  height: var(--tui-chat-h);
  width: min(100%, 620px);
  min-width: 0;
  overflow: hidden;
  border-radius: var(--tui-r-l);
  background: var(--tui-face);
  box-shadow: var(--tui-raised);
}

/* The thread: the platen the slips feed onto. */
.tui-chat__thread {
  display: flex;
  flex-direction: column;
  gap: var(--tui-4);
  min-height: 0;
  padding: var(--tui-5) var(--tui-5) var(--tui-4);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  outline: none;
}
.tui-chat__thread:focus-visible { outline: 2px solid var(--tui-focus); outline-offset: -4px; border-radius: var(--tui-r-l); }
.tui-chat__msg { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; min-width: 0; max-width: min(100%, 520px); margin: 0; }
.tui-chat__body > * { margin: 0; }
.tui-chat__body > * + * { margin-top: var(--tui-2); }
.tui-chat__body p { line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }

/* Yours: typed into the machine, so it sits in a recess, to the right. */
.tui-chat__msg[data-from="user"] { align-self: flex-end; justify-items: end; max-width: min(84%, 440px); }
.tui-chat__msg[data-from="user"] .tui-chat__body {
  padding: 10px 14px;
  border-radius: var(--tui-r-m);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  color: var(--tui-ink);
}
.tui-chat__attached { display: flex; flex-wrap: wrap; gap: 4px; }

/* The assistant's: a printed slip, torn along its perforation. */
.tui-chat__msg[data-from="assistant"] {
  align-self: flex-start;
  width: 100%;
  padding: 16px 16px 14px;
  border-radius: 3px 3px var(--tui-r-m) var(--tui-r-m);
  background:
    radial-gradient(circle, var(--tui-face) 1.3px, rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.9)) 1.7px, transparent 2.1px) 2px 4px / 8px 8px repeat-x,
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 94%, rgb(var(--tui-sh))));
  box-shadow: var(--tui-raised);
}
.tui-chat__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--tui-2); min-height: 22px; margin: 0; }
.tui-chat__meta .tui-status, .tui-chat__meta > .tui-label { font: 500 var(--tui-t-label)/1.2 var(--tui-sans); letter-spacing: var(--tui-track); text-transform: uppercase; color: var(--tui-ink-2); }
.tui-chat__meta .tui-key { margin-right: -6px; }
.tui-chat__msg[aria-busy="true"] .tui-chat__meta .tui-key { display: none; }
/* The print head: a lamp at the end of the line being printed. */
.tui-chat__head { margin-left: 5px; vertical-align: 1px; }
.tui-chat__stopped { font-size: var(--tui-t-small); color: var(--tui-ink-2); }

/* Code, on display glass. */
.tui-chat__code { padding: 0; overflow: hidden; }
.tui-chat__code-bar { display: flex; align-items: center; justify-content: space-between; padding: 6px 6px 0 14px; }
.tui-chat__code-bar .tui-key { color: var(--tui-ink-2); }
.tui-chat__code pre { margin: 0; padding: 8px 14px 14px; overflow-x: auto; font: 400 12.5px/1.6 var(--tui-mono); white-space: pre; }

/* Empty: a tray with an unlit lamp, one sentence, suggestions to start with. */
.tui-chat__empty { display: grid; justify-items: center; align-content: center; gap: var(--tui-3); flex: 1; padding: var(--tui-6) var(--tui-4); text-align: center; }
.tui-chat__empty p { max-width: 36ch; margin: 0; color: var(--tui-ink-2); }
.tui-chat__suggest { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--tui-2); }
.tui-chat__thread:has(.tui-chat__msg) .tui-chat__empty { display: none; }

/* The composer: one well with the text, the attach key and the send key. */
.tui-chat__composer { display: grid; gap: 6px; padding: var(--tui-3) var(--tui-4) var(--tui-3); border-top: 1px solid var(--tui-rule); }
.tui-chat__files:empty { display: none; }
.tui-chat__files { display: flex; flex-wrap: wrap; gap: 4px; }
.tui-chat__file { text-transform: none; letter-spacing: 0.01em; font-weight: 500; font-size: 11.5px; }
.tui-chat__file button { display: grid; place-items: center; width: 16px; height: 16px; margin-right: -4px; padding: 0; border: 0; border-radius: 3px; background: none; color: var(--tui-ink-2); cursor: pointer; }
.tui-chat__file button:hover { color: var(--tui-ink); }
.tui-chat__file button svg { width: 10px; height: 10px; }
.tui-chat__well {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 5px 5px 5px 14px;
  border-radius: 12px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-chat__well:has(.tui-chat__input:focus-visible), .tui-chat__well.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-chat__input {
  flex: 1;
  min-width: 0;
  min-height: 34px;
  max-height: 140px;
  padding: 8px 0;
  border: 0;
  resize: none;
  field-sizing: content;
  font: 400 var(--tui-t-body)/1.4 var(--tui-sans);
  color: var(--tui-ink);
  background: transparent;
}
.tui-chat__input:focus-visible { outline: none; }
.tui-chat__input::placeholder { color: var(--tui-ink-3); }
.tui-chat__keys { display: flex; align-items: center; gap: 6px; }
.tui-chat__keys .tui-key--sm { --h: 32px; width: 32px; }
.tui-chat__send { --h: 34px; }
.tui-chat__help { margin: 0; padding-left: 4px; font-size: 11.5px; color: var(--tui-ink-2); }
@container (max-width: 380px) { .tui-chat__help { display: none; } }

/* ---------------------------------------------------------------- part: command */
/* Command palette: a modal plate whose entry line is a display. What you type
   glows in the vacuum-fluorescent window, with the count of matches beside
   it; the results are printed on the plate below, the chosen one pressed into
   it. Shortcuts are shown as the keys you would press. Native <dialog>. */
.tui-command {
  width: min(600px, calc(100vw - 24px));
  max-height: min(560px, calc(100dvh - 24px));
  margin: 12vh auto auto;
  padding: 0;
  border: 0;
  border-radius: 14px;
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 3px rgb(var(--tui-sh) / 0.3), 0 30px 60px -20px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.4));
  overflow: hidden;
}
.tui-command[open] { display: flex; flex-direction: column; animation: tui-rise 220ms var(--tui-ease); }
.tui-command::backdrop { background: var(--tui-backdrop); }
/* In a page (a specimen): a plate in the flow. */
.tui-command--inline { display: flex; flex-direction: column; position: static; margin: 0; width: 100%; }

/* The entry line: a VFD window, a prompt, the query, the count. */
.tui-command__display {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 54px;
  margin: 12px 12px 4px;
  padding: 0 14px 0 16px;
  border-radius: 8px;
  color: var(--tui-vfd);
  background:
    linear-gradient(170deg, rgb(255 255 255 / 0.06), transparent 40%),
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.025) 0 1px, transparent 1px 3px),
    var(--tui-vfd-bg);
  box-shadow: inset 0 2px 6px rgb(0 0 0 / 0.8), inset 0 0 0 1px rgb(255 255 255 / 0.05), 0 1px 0 var(--tui-hl);
  font: 400 17px/1 var(--tui-mono);
  text-shadow: 0 0 6px color-mix(in oklab, var(--tui-vfd) 55%, transparent), 0 0 18px color-mix(in oklab, var(--tui-vfd) 18%, transparent);
}
.tui-command__display::before { content: '›'; flex: none; font-size: 20px; opacity: 0.7; }
.tui-command__display:has(:focus-visible) { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-command__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  outline: none;
  font: inherit;
  letter-spacing: -0.01em;
  color: inherit;
  text-shadow: inherit;
  caret-color: var(--tui-vfd);
  background: none;
}
.tui-command__input:focus-visible { outline: none; }
.tui-command__input::placeholder { color: color-mix(in oklab, var(--tui-vfd) 55%, transparent); text-shadow: none; }
.tui-command__input::-webkit-search-cancel-button { display: none; }
.tui-command__count { flex: none; font: 500 11px/1 var(--tui-mono); letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.7; font-variant-numeric: tabular-nums; }

/* The results. */
.tui-command__list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 12px 10px; scrollbar-width: thin; }
.tui-command__group { display: grid; }
.tui-command__group + .tui-command__group { margin-top: 4px; }
.tui-command__heading {
  padding: 12px 10px 6px;
  font: 500 var(--tui-t-label)/1.2 var(--tui-sans);
  letter-spacing: var(--tui-track);
  text-transform: uppercase;
  color: var(--tui-ink-2);
}
.tui-command__item {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  min-height: 40px;
  padding: 0 10px 0 11px;
  border-radius: 8px;
  font-weight: 500;
  color: var(--tui-ink);
  cursor: pointer;
  user-select: none;
}
.tui-command__item > svg { width: 16px; height: 16px; color: var(--tui-ink-2); }
.tui-command__item > :not(svg, kbd, .tui-command__keys, .tui-lamp):not(:first-child) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tui-command__item small { margin-left: 8px; font-size: var(--tui-t-small); font-weight: 400; color: var(--tui-ink-2); }
.tui-command__item[aria-selected="true"], .tui-command__item.is-hover {
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-command__item[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

/* A shortcut is drawn as the keys to press: small caps on a skirt.
   (:nth-child(n) only lifts the rule over a page's own kbd styling.) */
:is(.tui-command__keys, .tui-command__foot) kbd:nth-child(n) {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 4px;
  font: 600 10.5px/1 var(--tui-sans);
  letter-spacing: 0;
  color: var(--tui-ink-2);
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1.5px 0 var(--tui-skirt), 0 2px 3px rgb(var(--tui-sh) / 0.2);
}
.tui-command__keys { display: inline-flex; gap: 4px; grid-column: 3; }

.tui-command__empty { display: grid; justify-items: center; gap: 8px; margin: 0; padding: 30px 16px 34px; text-align: center; color: var(--tui-ink-2); }
.tui-command__empty .tui-status { color: var(--tui-ink); font-weight: 600; font-size: var(--tui-t-body); }

.tui-command__foot {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  padding: 10px 16px 12px;
  border-top: 1px solid var(--tui-rule);
  font: 500 var(--tui-t-small)/1 var(--tui-sans);
  color: var(--tui-ink-2);
}
.tui-command__foot > span { display: inline-flex; align-items: center; gap: 6px; }
.tui-command__foot > :last-child { margin-left: auto; }

/* ---------------------------------------------------------------- part: commit */
/* Commit key: a kit key standing in its own cut in the plate. Pressed, it
   latches 2px deeper than a press — below the lip of the cut — and a 4×4 LED
   matrix in its face scans amber until the work is done: a green tick and
   the cap springs back, or a red cross and it pops back. The guarded version
   has a hinged smoked cover over the cut, lifted by the first press.
   commit.mjs builds the matrix and the legends and runs the states. */

tui-commit {
  position: relative;
  display: inline-grid;
  vertical-align: middle;
}

/* The cut: the key's own hole in the plate. Its lower lip sits where the
   skirt meets the plate, so a latched cap goes under it. */
.tui-commit__cut {
  display: inline-grid;
  align-self: start;
  justify-self: start;
  padding: 3px 3px 2px;
  border-radius: 10px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  overflow: hidden;
  min-width: max-content;
}
tui-commit:has(.tui-key--lg) .tui-commit__cut { padding-bottom: 3px; border-radius: 12px; }
tui-commit:has(.tui-key--sm) .tui-commit__cut { padding: 2px 2px 1.5px; border-radius: 8px; }
tui-commit:has(.tui-commit__key:focus-visible) .tui-commit__cut, tui-commit.is-focus .tui-commit__cut { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-commit__key:focus-visible { outline: none; }

.tui-commit__key { --m: 15px; padding-left: calc(var(--tui-4) - 3px); }
.tui-commit__key.tui-key--lg { --m: 18px; padding-left: calc(var(--tui-6) - 6px); }
.tui-commit__key.tui-key--sm { --m: 12px; padding-left: var(--tui-2); }

/* Busy: latched, a skirt and 2px down, shaded deep by the cut's upper wall. */
tui-commit[data-state="busy"] .tui-commit__key {
  transform: translateY(calc(var(--skirt) + 2px));
  filter: brightness(0.95);
  opacity: 1;
  cursor: progress;
  box-shadow:
    inset 0 7px 6px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 3.4)),
    inset 4px 0 4px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.6)),
    inset -4px 0 4px -4px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.6)),
    0 -1px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.3));
}
tui-commit[data-state="busy"] .tui-commit__key:hover { filter: brightness(0.95); }
/* Done: it springs back up past its rest by a pixel, and settles. Failed: it pops straight back. */
tui-commit[data-state="done"] .tui-commit__key { animation: tui-commit-spring 280ms var(--tui-ease); }
tui-commit[data-state="failed"] .tui-commit__key { animation: tui-commit-pop 120ms ease-out; }
@keyframes tui-commit-spring {
  from { transform: translateY(calc(var(--skirt) + 2px)); }
  55% { transform: translateY(-1px); }
  to { transform: none; }
}
@keyframes tui-commit-pop { from { transform: translateY(calc(var(--skirt) + 2px)); } }

/* The legends share one cell, so the key is always as wide as the longest
   and never moves when the words change. Printed beside the window. */
.tui-commit__legend { display: grid; }
.tui-commit__legend > span {
  grid-area: 1 / 1;
  text-align: left;
  visibility: hidden;
  opacity: 0;
  transition: opacity 110ms var(--tui-ease), visibility 0s linear 110ms;
}
tui-commit:not([data-state]) [data-for="idle"], tui-commit[data-state="idle"] [data-for="idle"],
tui-commit[data-state="busy"] [data-for="busy"], tui-commit[data-state="done"] [data-for="done"], tui-commit[data-state="failed"] [data-for="failed"] {
  visibility: visible;
  opacity: 1;
  transition: opacity 110ms var(--tui-ease) 60ms, visibility 0s;
}

/* The matrix: sixteen LEDs behind a small dark window in the cap. */
.tui-commit__matrix {
  flex: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 1px;
  width: var(--m);
  height: var(--m);
  padding: calc((var(--m) - 3px) * 0.14);
  border-radius: 3px;
  background:
    linear-gradient(160deg, rgb(255 255 255 / 0.09), transparent 45%),
    var(--tui-vfd-bg);
  box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.85), inset 0 0 0 0.5px rgb(255 255 255 / 0.06), 0 1px 0 var(--tui-hl);
}
.tui-commit__matrix i {
  --led: var(--tui-amber);
  position: relative;
  border-radius: 50%;
  background: color-mix(in oklab, var(--tui-vfd) 17%, var(--tui-vfd-bg));
  box-shadow: inset 0 0.5px 0.5px rgb(0 0 0 / 0.6);
}
.tui-commit__matrix i::after {
  content: '';
  position: absolute;
  inset: -0.25px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, rgb(255 255 255 / 0.75), transparent 55%), var(--led);
  box-shadow: 0 0 2.5px 0.5px color-mix(in oklab, var(--led) 75%, transparent);
  opacity: 0;
}
/* Busy: a wave of amber from the top left corner. */
tui-commit[data-state="busy"] .tui-commit__matrix i::after {
  animation: tui-commit-scan 1000ms linear calc(var(--d) * 90ms) infinite both;
}
@keyframes tui-commit-scan {
  0%, 100% { opacity: 0.12; }
  18% { opacity: 1; }
  48% { opacity: 0.3; }
}
/* Done: a tick drawn in green, stroke by stroke. Failed: a red cross. */
tui-commit[data-state="done"] .tui-commit__matrix i { --led: var(--tui-green); }
tui-commit[data-state="done"] .tui-commit__matrix :is(i:nth-child(8), i:nth-child(9), i:nth-child(11), i:nth-child(14))::after { opacity: 1; animation: tui-commit-on 160ms var(--tui-ease) both; }
tui-commit[data-state="done"] .tui-commit__matrix i:nth-child(14)::after { animation-delay: 50ms; }
tui-commit[data-state="done"] .tui-commit__matrix i:nth-child(11)::after { animation-delay: 100ms; }
tui-commit[data-state="done"] .tui-commit__matrix i:nth-child(8)::after { animation-delay: 150ms; }
tui-commit[data-state="failed"] .tui-commit__matrix i { --led: var(--tui-red); }
tui-commit[data-state="failed"] .tui-commit__matrix :is(i:nth-child(1), i:nth-child(4), i:nth-child(6), i:nth-child(7), i:nth-child(10), i:nth-child(11), i:nth-child(13), i:nth-child(16))::after { opacity: 1; }
@keyframes tui-commit-on { from { opacity: 0; } }

/* What failed, printed under the key; the live region says it too. Leave a line of room below a commit key. */
tui-commit[data-state="failed"][data-why]::after {
  content: attr(data-why);
  position: absolute;
  top: calc(100% + 6px);
  left: 3px;
  font: 500 var(--tui-t-small)/1.3 var(--tui-sans);
  color: var(--tui-ink-2);
  white-space: nowrap;
}

/* The guard: a smoked cover hinged along the top of the cut. The first
   press lifts it past upright; it drops again when the key goes idle. */
tui-commit[data-guard]::before {
  content: '';
  position: absolute;
  z-index: 2;
  top: -3px;
  left: 14px;
  right: 14px;
  height: 4px;
  border-radius: 2px;
  background:
    linear-gradient(90deg, transparent 0 22%, rgb(var(--tui-sh) / 0.35) 22% calc(22% + 1px), transparent calc(22% + 1px) calc(78% - 1px), rgb(var(--tui-sh) / 0.35) calc(78% - 1px) 78%, transparent 78%),
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 70%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1px 1.5px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4));
  pointer-events: none;
}
.tui-commit__cover {
  --rim: color-mix(in oklab, var(--tui-ink) 24%, transparent);
  position: absolute;
  z-index: 1;
  inset: -2px;
  border-radius: 13px;
  pointer-events: none;
  transform-origin: 50% 0;
  transform: perspective(420px) rotateX(0deg);
  transition: transform 260ms var(--tui-ease);
  /* Clear, lightly smoked polycarbonate: a tint, one soft reflection, and edges that catch. */
  background:
    linear-gradient(112deg, transparent 22%, color-mix(in oklab, var(--tui-hl) 38%, transparent) 34%, transparent 47%),
    linear-gradient(rgb(var(--tui-sh) / 0.07), rgb(var(--tui-sh) / 0.16));
  box-shadow:
    inset 0 0 0 1px var(--rim),
    inset 0 1.5px 0 var(--tui-hl),
    inset 0 -1px 0 color-mix(in oklab, var(--tui-hl) 50%, transparent),
    inset 0 0 0 2.5px color-mix(in oklab, var(--tui-hl) 25%, transparent),
    0 3px 5px -2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.2));
}
/* The finger tab. */
.tui-commit__cover::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 28px;
  height: 7px;
  transform: translateX(-50%);
  border-radius: 0 0 5px 5px;
  background: linear-gradient(rgb(var(--tui-sh) / 0.1), rgb(var(--tui-sh) / 0.2));
  box-shadow: inset 0 0 0 1px var(--rim), inset 0 -1px 0 var(--tui-hl), 0 2px 3px -1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.2));
  clip-path: inset(2px -4px -4px -4px);
}
tui-commit[data-cover="open"] .tui-commit__cover { transform: perspective(420px) rotateX(98deg); }
/* Covered, the key does not move: the first press goes into the cover. */
tui-commit[data-guard]:not([data-cover="open"]) .tui-commit__key:active {
  transform: none;
  filter: none;
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 var(--skirt) 0 var(--tui-skirt), 0 calc(var(--skirt) + 1px) 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4));
}
tui-commit[data-guard]:not([data-cover="open"]):has(.tui-commit__key:active) .tui-commit__cover { transform: perspective(420px) rotateX(-3deg); transition-duration: 70ms; }

/* Spoken, not shown. */
.tui-commit__said, .tui-commit__note { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  /* No scan and no spring: a steady amber matrix. Every state still shows. */
  tui-commit[data-state] .tui-commit__matrix i::after, tui-commit[data-state] .tui-commit__key { animation: none !important; }
  tui-commit[data-state="busy"] .tui-commit__matrix i::after { opacity: 0.85; }
  .tui-commit__cover, .tui-commit__legend > span { transition: none !important; }
}

/* ---------------------------------------------------------------- part: date-picker */
/* Date picker: a field whose calendar card slides out of a slot under the
   well. The field is the kit's recess with the calendar key set in it; the
   card is a plate that comes out top first, its upper edge still shaded by
   the slot it left. kit/parts/date-picker.mjs builds and wires it. */
tui-date-picker { position: relative; display: block; width: min(100%, 300px); }
.tui-date-picker__well {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 4px 0 0;
  border-radius: var(--tui-r-m);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-date-picker__well .tui-input { flex: 1; background: transparent; box-shadow: none; font-variant-numeric: tabular-nums; }
.tui-date-picker__well .tui-input:focus-visible { outline: none; }
.tui-date-picker__well:has(.tui-input:focus-visible), .tui-date-picker__well.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-date-picker__well .tui-key { --h: 30px; width: 30px; flex: none; }
.tui-date-picker__well .tui-key[aria-expanded="true"] { transform: translateY(var(--skirt)); box-shadow: var(--tui-pressed); }
.tui-date-picker__field[data-error] .tui-date-picker__well { box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--tui-red) 85%, transparent), 0 0 8px -2px color-mix(in oklab, var(--tui-red) 45%, transparent), var(--tui-inset); }

/* The card: a plate out of the slot, in the top layer (a popover) so nothing clips it. Placed by the script. */
.tui-date-picker__card:not(:popover-open) { display: none; }
.tui-date-picker__card {
  position: fixed;
  inset: auto;
  margin: 0;
  border: 0;
  overflow: visible;
  display: grid;
  gap: var(--tui-2);
  --tui-calendar-cell: 40px;
  width: min(calc(var(--tui-calendar-cell) * 7 + 36px), calc(100vw - 32px));
  max-width: calc(100vw - 32px);
  padding: var(--tui-4) var(--tui-4) var(--tui-2);
  border-radius: var(--tui-r-l);
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow:
    inset 0 1px 0 var(--tui-hl),
    /* The slot's lower lip still shades the card's top edge. */
    inset 0 10px 10px -10px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)),
    0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35)),
    0 2px 3px rgb(var(--tui-sh) / 0.3),
    0 24px 48px -18px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.2));
}
/* Placed above the field, the slot shades the card's lower edge instead. */
.tui-date-picker__card[data-side="above"] {
  box-shadow: inset 0 1px 0 var(--tui-hl), inset 0 -10px 10px -10px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.4)), 0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35)), 0 2px 3px rgb(var(--tui-sh) / 0.3), 0 24px 48px -18px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2.2));
}
.tui-date-picker__card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--tui-noise);
  opacity: var(--tui-grain);
  pointer-events: none;
}
.tui-date-picker__card tui-calendar { width: 100%; }
.tui-date-picker__foot { display: flex; align-items: center; gap: var(--tui-2); min-height: 32px; margin: 0; }
.tui-date-picker__say { flex: 1; font-size: var(--tui-t-small); color: var(--tui-ink-2); }

/* ---------------------------------------------------------------- part: empty-state */
/* Empty state: an empty tray with the outline of what goes in it printed on
   its floor, the way a tool board shows where each tool hangs. An unlit lamp
   names what is missing, one sentence says how it arrives, one key adds the
   first. Outlines: slots (default, one per <i>), a sheet, a plot. */
.tui-empty {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: var(--tui-3);
  padding: var(--tui-8) var(--tui-6) var(--tui-6);
  text-align: center;
  border-radius: var(--tui-r-l);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-empty .tui-status { color: var(--tui-ink); font-weight: 600; font-size: var(--tui-t-body); }
.tui-empty__text { max-width: 38ch; margin: 0; color: var(--tui-ink-2); text-wrap: balance; }
.tui-empty__text + * { margin-top: var(--tui-1); }

/* The printed outline: dashed, in the faint ink of a scale. */
.tui-empty__outline {
  --line: color-mix(in oklab, var(--tui-ink-3) 75%, transparent);
  display: grid;
  gap: 6px;
  width: min(100%, 196px);
  margin-bottom: var(--tui-2);
}
.tui-empty__outline > i {
  display: block;
  height: 22px;
  border: 1.5px dashed var(--line);
  border-radius: 6px;
  background: radial-gradient(circle, var(--line) 2.5px, transparent 3px) 9px 50% / 6px 6px no-repeat;
}
.tui-empty__outline > i:nth-child(2) { opacity: 0.7; }
.tui-empty__outline > i:nth-child(n + 3) { opacity: 0.45; }
/* A sheet: a page with its top corner turned, and three printed lines. */
.tui-empty__outline--sheet {
  position: relative;
  width: 64px;
  height: 80px;
  border: 1.5px dashed var(--line);
  border-radius: 5px 16px 5px 5px;
  background:
    linear-gradient(var(--line), var(--line)) 11px 30px / 34px 1.5px no-repeat,
    linear-gradient(var(--line), var(--line)) 11px 40px / 26px 1.5px no-repeat,
    linear-gradient(var(--line), var(--line)) 11px 50px / 30px 1.5px no-repeat;
}
.tui-empty__outline--sheet::after {
  content: '';
  position: absolute;
  top: -1.5px;
  right: -1.5px;
  width: 16px;
  height: 16px;
  border-left: 1.5px dashed var(--line);
  border-bottom: 1.5px dashed var(--line);
  border-radius: 0 0 0 5px;
}
/* A plot: axes printed, the trace still to come. */
.tui-empty__outline--plot {
  width: min(100%, 196px);
  height: 72px;
  border-left: 1.5px solid var(--line);
  border-bottom: 1.5px solid var(--line);
  background:
    repeating-linear-gradient(90deg, var(--line) 0 5px, transparent 5px 10px) 0 33% / 100% 1px no-repeat,
    repeating-linear-gradient(90deg, var(--line) 0 5px, transparent 5px 10px) 0 66% / 100% 1px no-repeat;
  opacity: 0.8;
}

/* Side by side when the tray is wide and short (under a table head): the
   words go in .tui-empty__words. Narrow, it folds into a left-aligned column. */
.tui-empty--row { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: var(--tui-4) var(--tui-5); padding: var(--tui-5); text-align: left; }
.tui-empty--row .tui-empty__outline { width: 104px; margin: 0; }
.tui-empty__words { display: grid; justify-items: center; gap: var(--tui-2); }
.tui-empty--row .tui-empty__words { flex: 1 1 200px; justify-items: start; }
.tui-empty--row .tui-empty__text { max-width: 52ch; }
.tui-empty--row > .tui-key { flex: none; margin: 0; }

/* ---------------------------------------------------------------- part: file-tree */
/* File tree: a WAI-ARIA tree printed like a wiring diagram. Guides are
   printed traces with an elbow into every item; a folder's chevron turns as
   it opens; the chosen item sits in a recess with its lamp lit, the way the
   side rail marks the current page. kit/parts/file-tree.mjs wires it. */
tui-file-tree { display: block; min-width: 0; font-size: var(--tui-t-body); }
tui-file-tree ul { margin: 0; padding: 0; list-style: none; }
tui-file-tree [role="group"] { position: relative; margin-left: 13px; padding-left: 10px; }
tui-file-tree [role="treeitem"] { position: relative; outline: none; }
/* The traces: a vertical run down each group, an elbow into each item; the last item's run stops at its elbow. */
tui-file-tree [role="group"] > [role="treeitem"]::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--tui-trace, color-mix(in oklab, var(--tui-ink-3) 55%, transparent));
}
tui-file-tree [role="group"] > [role="treeitem"]:last-child::before { bottom: auto; height: 15px; }
tui-file-tree [role="group"] > [role="treeitem"] > .tui-file-tree__row::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 15px;
  width: 8px;
  border-top: 1px solid var(--tui-trace, color-mix(in oklab, var(--tui-ink-3) 55%, transparent));
}

.tui-file-tree__row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px 0 6px;
  border-radius: 6px;
  color: var(--tui-ink-2);
  cursor: pointer;
  user-select: none;
}
[role="treeitem"]:not(.is-folder) > .tui-file-tree__row { padding-left: 22px; }
.tui-file-tree__row:hover, .tui-file-tree__row.is-hover { color: var(--tui-ink); background: color-mix(in oklab, var(--tui-face-hi) 55%, transparent); }
[role="treeitem"]:focus-visible > .tui-file-tree__row, .tui-file-tree__row.is-focus { outline: 2px solid var(--tui-focus); outline-offset: -1px; }
.tui-file-tree__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.is-folder > .tui-file-tree__row .tui-file-tree__name { font-weight: 600; color: var(--tui-ink); }
.tui-file-tree__meta { font-size: var(--tui-t-small); color: var(--tui-ink-2); font-variant-numeric: tabular-nums; }
/* The chosen item: a recess with its lamp lit. */
[role="treeitem"][aria-selected="true"] > .tui-file-tree__row, .tui-file-tree__row.is-down {
  color: var(--tui-ink);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-file-tree__row > .tui-lamp { width: 6px; height: 6px; opacity: 0; }
[role="treeitem"][aria-selected="true"] > .tui-file-tree__row > .tui-lamp, .tui-file-tree__row.is-down > .tui-lamp {
  opacity: 1;
  background: var(--tui-green);
  box-shadow: 0 0 6px 1px color-mix(in oklab, var(--tui-green) 60%, transparent);
}

/* Printed marks: a chevron that turns, a folder with its tab, a page with a folded corner. */
.tui-file-tree__chevron {
  flex: none;
  width: 12px;
  height: 12px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M4.2 2.6 8 6l-3.8 3.4z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M4.2 2.6 8 6l-3.8 3.4z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 120ms var(--tui-ease);
}
[aria-expanded="true"] > .tui-file-tree__row > .tui-file-tree__chevron { transform: rotate(90deg); }
.tui-file-tree__icon {
  flex: none;
  width: 16px;
  height: 16px;
  background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
          mask: var(--icon) center / contain no-repeat;
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.3' stroke-linejoin='round'%3E%3Cpath d='M4 1.8h5.2L12.5 5v9.2H4z'/%3E%3Cpath d='M9 1.8V5.2h3.5'/%3E%3C/svg%3E");
}
.is-folder > .tui-file-tree__row .tui-file-tree__icon {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.3' stroke-linejoin='round'%3E%3Cpath d='M1.8 3.4h4.4l1.4 1.6h6.6v8H1.8z'/%3E%3C/svg%3E");
}
[aria-expanded="true"] > .tui-file-tree__row .tui-file-tree__icon {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.3' stroke-linejoin='round'%3E%3Cpath d='M1.8 3.4h4.4l1.4 1.6h5.2v1.8'/%3E%3Cpath d='M1.8 3.4V13h10.6l2-6.2H4z'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------- part: list */
/* List: rows in a rack. Each row is printed on the plate — a mark, a title,
   a second line, a fact or a key at the end. Chosen rows sink into a recess
   with their check key latched; a row being moved lifts out of the rack on
   its skirt and slides past the others. kit/parts/list.mjs wires the
   selectable and reorderable kinds. */
.tui-list { display: grid; margin: 0; padding: 0; list-style: none; min-width: 0; }
.tui-list__row {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--tui-3);
  min-height: 56px;
  padding: 8px 10px;
  border-radius: var(--tui-r-m);
}
.tui-list__row:has(> :nth-child(4)) { grid-template-columns: auto minmax(0, 1fr) auto auto; }
/* Hairlines between rows, inset to the text, never under a lifted or chosen row. */
.tui-list__row + .tui-list__row::before { content: ''; position: absolute; top: 0; left: 10px; right: 10px; border-top: 1px solid var(--tui-rule); }
.tui-list__row:is([aria-selected="true"], .is-lifted, .is-down)::before, .tui-list__row:is([aria-selected="true"], .is-lifted, .is-down) + .tui-list__row::before { border-color: transparent; }
.tui-list__lead { display: grid; place-items: center; min-width: 24px; color: var(--tui-ink-2); }
.tui-list__lead svg { width: 18px; height: 18px; }
.tui-list__text { display: grid; gap: 2px; min-width: 0; }
.tui-list__title { font-weight: 600; color: var(--tui-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tui-list__sub { font-size: var(--tui-t-small); color: var(--tui-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tui-list__meta { font-size: var(--tui-t-small); color: var(--tui-ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.tui-list__row > .tui-key { justify-self: end; }
/* A row that is a link: hover brightens it, nothing moves. */
a.tui-list__row { color: inherit; text-decoration: none; }
a.tui-list__row:hover, .tui-list__row.is-hover { background: color-mix(in oklab, var(--tui-face-hi) 55%, transparent); }

/* Selectable: the list is one tab stop; the active row carries the ring; chosen rows sit in a recess. */
.tui-list[role="listbox"] { outline: none; }
.tui-list[role="listbox"] > [role="option"] { cursor: pointer; user-select: none; }
.tui-list[role="listbox"] > [role="option"]:hover { background: color-mix(in oklab, var(--tui-face-hi) 55%, transparent); }
.tui-list[role="listbox"]:focus-visible > .is-active, .tui-list__row.is-focus { outline: 2px solid var(--tui-focus); outline-offset: -2px; }
.tui-list__row[aria-selected="true"], .tui-list__row.is-down {
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
/* The check key at the lead: a small key that latches, with a tick printed on it. */
.tui-list__check {
  position: relative;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 92%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 1.5px 0 var(--tui-skirt), 0 2px 3px rgb(var(--tui-sh) / 0.25);
  transition: transform 70ms var(--tui-ease), box-shadow 70ms var(--tui-ease);
}
:is([aria-selected="true"], .is-down) > .tui-list__lead > .tui-list__check { transform: translateY(1.5px); box-shadow: var(--tui-pressed); }
:is([aria-selected="true"], .is-down) > .tui-list__lead > .tui-list__check::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 3px;
  width: 5px;
  height: 9px;
  border: solid var(--tui-ink);
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}

/* Reorderable: a running order, numbered by position; a knurled grip at the end of each row. */
.tui-list--reorder { counter-reset: tui-list-row; }
.tui-list--reorder > .tui-list__row { counter-increment: tui-list-row; grid-template-columns: auto minmax(0, 1fr) auto auto; transition: transform 120ms var(--tui-ease), box-shadow 120ms var(--tui-ease); }
.tui-list__num::before { content: counter(tui-list-row, decimal-leading-zero); font: 600 var(--tui-t-small)/1 var(--tui-sans); font-variant-numeric: tabular-nums; color: var(--tui-ink-2); }
.tui-list__grip {
  display: grid;
  place-items: center;
  width: 28px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  cursor: grab;
  touch-action: none;
  color: var(--tui-ink-2);
  /* Knurled ridges, like the grip of a slide switch. */
  background: repeating-linear-gradient(0deg, transparent 0 2px, rgb(var(--tui-sh) / 0.28) 2px 3px, var(--tui-hl) 3px 4px) center / 12px 14px no-repeat;
}
.tui-list__grip:hover { background-color: color-mix(in oklab, var(--tui-face-hi) 60%, transparent); }
.tui-list__grip:focus-visible, .tui-list__grip.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 1px; }
/* Lifted out of the rack: the row stands on a skirt, above the plate, while it moves. */
.tui-list__row.is-lifted {
  z-index: 1;
  background: linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 94%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 0 var(--tui-skirt), 0 10px 18px -8px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2));
  transform: translateY(-2px);
}
.is-lifted .tui-list__grip { cursor: grabbing; }

.tui-list__live { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------------------------------------------------------------- part: menu */
/* Menu: a card that slides out from under its key. The key stays down while
   the card is out; the line under the finger is pressed into the card; an
   option that is on lights its lamp (green for a setting, amber for the one
   chosen from a set). Native popover; menu.mjs gives it the keyboard. */

/* The key: a printed arrow says a card comes out of it. */
.tui-menu__trigger::after {
  content: '';
  flex: none;
  width: 7px;
  height: 4px;
  margin-right: -2px;
  background: currentColor;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  opacity: 0.8;
}
.tui-key.tui-menu__trigger[aria-expanded="true"][data-tip]::after { display: none; }
.tui-key.tui-menu__trigger[aria-expanded="true"], .tui-key.tui-menu__trigger.is-down {
  transform: translateY(var(--skirt));
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
}

/* The card. */
.tui-menu {
  position: fixed;
  inset: auto;
  margin: 0;
  border: 0;
  overflow: visible;
  min-width: 212px;
  max-width: min(320px, calc(100vw - 16px));
  padding: 5px;
  border-radius: 11px;
  font: 400 var(--tui-t-body)/1.2 var(--tui-sans);
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow:
    inset 0 1px 0 var(--tui-hl),
    0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35)),
    0 2px 3px rgb(var(--tui-sh) / 0.25),
    0 18px 36px -14px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2));
  outline: none;
  max-height: max(160px, var(--tui-room, 80vh));
  overflow-y: auto;
  scrollbar-width: thin;
}
.tui-menu:focus-visible { outline: none; }
.tui-menu:not([popover]) { position: relative; text-align: left; white-space: normal; }
.tui-menu:popover-open { animation: tui-menu-out 150ms var(--tui-ease); }
.tui-menu[data-placed="top"]:popover-open { animation-name: tui-menu-up; }
.tui-menu[data-placed="right"]:popover-open { animation-name: tui-menu-right; }
.tui-menu[data-placed="left"]:popover-open { animation-name: tui-menu-left; }
@keyframes tui-menu-out { from { opacity: 0; transform: translateY(-6px); } }
@keyframes tui-menu-up { from { opacity: 0; transform: translateY(6px); } }
@keyframes tui-menu-right { from { opacity: 0; transform: translateX(-6px); } }
@keyframes tui-menu-left { from { opacity: 0; transform: translateX(6px); } }

/* A line: a lamp or icon slot, the words, then a shortcut or an arrow. */
.tui-menu [role^="menuitem"] {
  appearance: none;
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 10px;
  width: 100%;
  min-height: 32px;
  margin: 0;
  padding: 0 10px 0 9px;
  border: 0;
  border-radius: 7px;
  font: 500 var(--tui-t-body)/1.2 var(--tui-sans);
  color: var(--tui-ink);
  text-align: left;
  text-decoration: none;
  background: none;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.tui-menu [role^="menuitem"]::before { content: ''; grid-area: 1 / 1; justify-self: center; }
.tui-menu [role^="menuitem"] > svg { grid-area: 1 / 1; width: 14px; height: 14px; color: var(--tui-ink-2); }
/* Under the finger, or the keyboard: pressed into the card. */
.tui-menu [role^="menuitem"]:focus, .tui-menu [role^="menuitem"].is-hover {
  outline: none;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-menu [role^="menuitem"]:focus-visible, .tui-menu [role^="menuitem"].is-focus { outline: 2px solid var(--tui-focus); outline-offset: 1px; }
.tui-menu [role^="menuitem"][aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.tui-menu__item--danger { color: var(--tui-red) !important; }
.tui-menu__item--danger > svg { color: currentColor; }

/* Checkable lines carry a lamp: off until the option is on. */
.tui-menu [role="menuitemcheckbox"]::before, .tui-menu [role="menuitemradio"]::before {
  --c: var(--tui-green);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.25), transparent 55%), color-mix(in oklab, var(--c) 22%, var(--tui-face-lo));
  box-shadow: inset 0 1px 1.5px rgb(0 0 0 / 0.45), 0 1px 0 var(--tui-hl);
}
.tui-menu [role="menuitemradio"]::before { --c: var(--tui-amber); }
.tui-menu [aria-checked="true"]::before {
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.85), transparent 45%), var(--c);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.2), 0 0 6px 1px color-mix(in oklab, var(--c) 70%, transparent), 0 0 14px 2px color-mix(in oklab, var(--c) 30%, transparent);
}

/* Shortcuts are printed, like the legend under a key. */
.tui-menu [role^="menuitem"] > kbd {
  grid-column: 3;
  padding: 0;
  background: none;
  box-shadow: none;
  font: 500 var(--tui-t-small)/1 var(--tui-sans);
  letter-spacing: 0.06em;
  color: var(--tui-ink-2);
  white-space: nowrap;
}
/* A line that opens another card: a printed arrow. */
.tui-menu [role="menuitem"][aria-haspopup]::after {
  content: '';
  grid-column: 3;
  width: 4px;
  height: 7px;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  opacity: 0.7;
}
.tui-menu [role="menuitem"][aria-expanded="true"] { background: var(--tui-well-fill) var(--tui-well); box-shadow: var(--tui-inset); }

.tui-menu [role="separator"], .tui-menu hr { height: 1px; margin: 5px 8px; border: 0; background: var(--tui-rule); }
.tui-menu [role="group"] { display: grid; }
.tui-menu__label {
  display: block;
  padding: 9px 10px 5px 33px;
  font: 500 var(--tui-t-label)/1.2 var(--tui-sans);
  letter-spacing: var(--tui-track);
  text-transform: uppercase;
  color: var(--tui-ink-2);
}

/* ---------------------------------------------------------------- part: notifications */
/* Notifications: a key with a counter window in its cap, and a card of
   messages hung from it. Each unread message has its amber lamp lit; reading
   it puts the lamp out and the counter steps down. "Mark all read" puts the
   lamps out one after another, top to bottom. The card is a .tui-popover. */

/* The key, and the LCD window set into its cap. */
.tui-notifications__trigger { gap: 7px; }
.tui-notifications__trigger:not(.tui-key--icon) { padding: 0 6px 0 11px; }
.tui-notifications__trigger svg { width: 16px; height: 16px; }
.tui-notifications__count {
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 3px 4px 3px;
  gap: 0;
  border-radius: 3px;
  letter-spacing: 0;
}
.tui-notifications__count[data-ghost]::before { left: 4px; top: 3px; }
.tui-key.tui-notifications__trigger[aria-expanded="true"], .tui-key.tui-notifications__trigger.is-down {
  transform: translateY(var(--skirt));
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
}
/* An icon key with only a lamp in the corner of its cap. */
.tui-notifications__trigger > .tui-lamp { position: absolute; top: 5px; right: 5px; width: 6px; height: 6px; margin: 0; }

/* The card: a .tui-popover, wider, its list scrolling inside the room it is given. */
.tui-popover.tui-notifications { display: none; flex-direction: column; width: min(372px, calc(100vw - 16px)); max-width: none; max-height: max(220px, var(--tui-room, 80vh)); padding: 0; }
.tui-popover.tui-notifications:is(:popover-open, :not([popover])) { display: flex; }
.tui-notifications__head {
  display: flex;
  align-items: center;
  gap: var(--tui-3);
  padding: 14px 12px 12px 18px;
  border-bottom: 1px solid var(--tui-rule);
}
.tui-notifications__head > :first-child { flex: 1; margin: 0; }
.tui-notifications__head > * { white-space: nowrap; }
.tui-notifications__list {
  display: grid;
  margin: 0;
  padding: 4px 6px;
  list-style: none;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.tui-notifications__item {
  display: grid;
  grid-template-columns: 7px minmax(0, 1fr) auto;
  column-gap: var(--tui-3);
  row-gap: 3px;
  padding: 12px 12px 13px;
}
.tui-notifications__item + .tui-notifications__item { border-top: 1px solid var(--tui-rule); }
.tui-notifications__item > .tui-lamp { grid-row: 1; margin-top: 5px; transition: background 90ms linear, box-shadow 90ms linear; }
.tui-notifications__title { margin: 0; font: 500 var(--tui-t-body)/1.35 var(--tui-sans); color: var(--tui-ink); }
.tui-notifications__item[data-unread] .tui-notifications__title { font-weight: 700; }
.tui-notifications__item time { grid-column: 3; grid-row: 1; padding-top: 1px; font-size: var(--tui-t-small); color: var(--tui-ink-2); white-space: nowrap; }
.tui-notifications__body { grid-column: 2 / 4; margin: 0; font-size: var(--tui-t-small); line-height: 1.45; color: var(--tui-ink-2); }
.tui-notifications__actions { grid-column: 2 / 4; display: flex; flex-wrap: wrap; gap: var(--tui-2); margin-top: var(--tui-2); }
.tui-notifications__empty { display: none; margin: 0; padding: 28px 18px; text-align: center; color: var(--tui-ink-2); }
.tui-notifications__list:not(:has(li)) { display: none; }
.tui-notifications__list:not(:has(li)) + .tui-notifications__empty { display: block; }
.tui-notifications__foot { display: flex; justify-content: center; padding: 8px; border-top: 1px solid var(--tui-rule); }

/* ---------------------------------------------------------------- part: onboarding */
/* Onboarding: stations along a groove, like the program track of a machine.
   A step that is done has its green lamp lit in its socket; the step you are
   on is a raised cap with its number; the rest are empty sockets. Ink runs
   along the groove as far as you have come. The setup checklist below it is
   check keys that stay down, a progress slot, and one key for the next task. */

/* ---------------------------------------------------------------- the steps */
.tui-onboarding__steps {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  margin: 0;
  padding: 0;
  list-style: none;
  container-type: inline-size;
}
.tui-onboarding__step { position: relative; display: grid; justify-items: center; align-content: start; gap: 9px; text-align: center; }
/* The groove from the station before to this one. */
.tui-onboarding__step + .tui-onboarding__step::before {
  content: '';
  position: absolute;
  top: 11px;
  left: calc(-50% + 17px);
  right: calc(50% + 17px);
  height: 5px;
  border-radius: 3px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: inset 0 1.5px 2px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2)), 0 1px 0 var(--tui-hl);
}
/* Ink along the groove, drawn out as far as you have come. */
.tui-onboarding__step + .tui-onboarding__step::after {
  content: '';
  position: absolute;
  top: 12.5px;
  left: calc(-50% + 18px);
  right: calc(50% + 18px);
  height: 2px;
  border-radius: 1px;
  background: var(--tui-ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 220ms var(--tui-ease);
}
.tui-onboarding__step:is([data-state="done"], [data-state="current"])::after { transform: none; }

/* A station: a socket, a lamp in it when done, a cap on it when current. */
.tui-onboarding__station {
  position: relative;
  display: grid;
  place-items: center;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  font: 600 11.5px/1 var(--tui-sans);
  font-variant-numeric: tabular-nums;
  color: var(--tui-ink-2);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  transition: transform 180ms var(--tui-ease), box-shadow 180ms var(--tui-ease);
}
[data-state="done"] > .tui-onboarding__station { color: transparent; }
[data-state="done"] > .tui-onboarding__station::after {
  content: '';
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.85), transparent 45%), var(--tui-green);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.2), 0 0 6px 1px color-mix(in oklab, var(--tui-green) 70%, transparent), 0 0 14px 2px color-mix(in oklab, var(--tui-green) 30%, transparent);
}
[data-state="current"] > .tui-onboarding__station {
  color: var(--tui-ink);
  font-weight: 700;
  transform: translateY(-1px);
  background:
    radial-gradient(120% 90% at 50% 0%, var(--tui-hl), transparent 60%),
    linear-gradient(var(--tui-face-hi), color-mix(in oklab, var(--tui-face-hi) 90%, rgb(var(--tui-sh))));
  box-shadow: inset 0 1px 0 var(--tui-hl), 0 2px 0 var(--tui-skirt), 0 3px 3px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.2)), 0 7px 12px -6px rgb(var(--tui-sh) / var(--tui-sh-a));
}
.tui-onboarding__name { max-width: 16ch; font: 600 var(--tui-t-small)/1.3 var(--tui-sans); color: var(--tui-ink-2); }
[data-state="current"] > .tui-onboarding__name { color: var(--tui-ink); }
.tui-onboarding__name small { display: block; margin-top: 2px; font-weight: 400; }
.tui-onboarding__state, .tui-onboarding__vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Narrow: every station stays, only the current one keeps its name. */
@container (max-width: 400px) {
  .tui-onboarding__step:not([data-state="current"]) > .tui-onboarding__name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .tui-onboarding__step[data-state="current"] > .tui-onboarding__name { width: max-content; max-width: 30cqi; }
}

/* ------------------------------------------------------------ the checklist */
.tui-onboarding { display: grid; gap: var(--tui-3); }
.tui-onboarding__head { display: flex; align-items: baseline; gap: var(--tui-3); flex-wrap: wrap; }
.tui-onboarding__title { flex: 1; margin: 0; font: 700 16px/1.25 var(--tui-sans); letter-spacing: -0.01em; color: var(--tui-ink); }
.tui-onboarding__count { font: 500 var(--tui-t-small)/1 var(--tui-sans); font-variant-numeric: tabular-nums; color: var(--tui-ink-2); }
.tui-onboarding__list { display: grid; margin: var(--tui-2) 0 0; padding: 0; list-style: none; }
.tui-onboarding__task {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: start;
  column-gap: var(--tui-3);
  padding: var(--tui-3) 0;
  border-top: 1px solid var(--tui-rule);
}
.tui-onboarding__task > .tui-check { margin-top: 1px; }
.tui-onboarding__task > label { display: grid; gap: 2px; cursor: pointer; }
.tui-onboarding__task > label > b { font-weight: 600; color: var(--tui-ink); }
.tui-onboarding__task > label > span { font-size: var(--tui-t-small); color: var(--tui-ink-2); }
.tui-onboarding__task:has(> .tui-check:checked) > label > b { font-weight: 500; color: var(--tui-ink-2); }
.tui-onboarding__action { align-self: center; }
.tui-onboarding__task:not([data-next]) > .tui-onboarding__action { display: none; }

/* ---------------------------------------------------------------- part: pagination */
/* Pagination: numbered keys in a tray; the current page's key is latched
   below the plate. Seven slots at most, so the row keeps its width. The
   compact version is a transport: back, a track counter in an LCD, on. */
.tui-pagination {
  position: relative; /* holds the screen-reader words, which are positioned */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tui-3) var(--tui-5);
  font-size: var(--tui-t-small);
  color: var(--tui-ink-2);
}
.tui-pagination__keys {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  border-radius: 9px;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-pagination__pages { display: flex; align-items: center; gap: 3px; margin: 0; padding: 0; list-style: none; }
.tui-pagination__pages > li { display: flex; }
.tui-pagination__keys .tui-key { --h: 30px; --skirt: 1.5px; min-width: 30px; padding: 0 7px; border-radius: 6px; font-size: var(--tui-t-small); font-variant-numeric: tabular-nums; }
.tui-pagination__keys .tui-key--icon { width: 30px; padding: 0; }
.tui-pagination__keys .tui-key svg { width: 14px; height: 14px; }
/* The page you are on: latched, its printing at full ink. */
.tui-pagination__keys .tui-key[aria-current="page"] {
  transform: translateY(var(--skirt));
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
  cursor: default;
}
.tui-pagination__keys .tui-key:not([aria-current]) { color: var(--tui-ink-2); }
.tui-pagination__keys .tui-key:not([aria-current]):hover, .tui-pagination__keys .tui-key.is-hover { color: var(--tui-ink); }
.tui-pagination__keys .tui-key[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: inset 0 1px 0 var(--tui-hl), 0 var(--skirt) 0 var(--tui-skirt); filter: none; }
.tui-pagination__gap { width: 18px; height: 30px; overflow: hidden; color: transparent; background: radial-gradient(circle, var(--tui-ink-2) 1.1px, transparent 1.5px) 0 50% / 6px 6px repeat-x; }

.tui-pagination__range { margin: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tui-pagination__size { display: inline-flex; align-items: center; gap: var(--tui-2); margin-left: auto; }
.tui-pagination__size .tui-select { width: auto; height: 32px; padding-left: 10px; font-size: var(--tui-t-small); }

/* Compact: a transport and a track counter. */
.tui-pagination__lcd { min-width: 0; font-size: 15px; padding: 0.4em 0.55em; }
.tui-pagination__lcd[data-ghost]::before { left: 0.55em; top: 0.4em; }
.tui-pagination--compact .tui-pagination__keys { gap: 6px; padding: 3px 4px; }

/* Words for screen readers only: the counter itself is hidden from them. */
.tui-pagination__said { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------------------------------------------------------------- part: popover */
/* Popover: a card hung from the key that opened it. A printed leader runs
   from the card to the key and ends in a dot on it, the way a manual points
   at a part. The key stays down while its card is out. Native popover;
   popover.mjs places it and moves the leader. */
.tui-popover {
  --tui-leader: 50%;
  --gap: 14px;
  position: fixed;
  inset: auto;
  margin: 0;
  border: 0;
  overflow: visible;
  width: max-content;
  max-width: min(300px, calc(100vw - 16px));
  padding: var(--tui-4);
  border-radius: var(--tui-r-l);
  font: 400 var(--tui-t-body)/1.5 var(--tui-sans);
  color: var(--tui-ink);
  background: var(--tui-face);
  box-shadow:
    inset 0 1px 0 var(--tui-hl),
    0 0 0 1px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.35)),
    0 2px 3px rgb(var(--tui-sh) / 0.25),
    0 18px 36px -14px rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 2));
}
/* Inside a page (a specimen, a docs cell) it sits in the flow. */
.tui-popover:not([popover]) { position: relative; }
.tui-popover:popover-open { animation: tui-popover-hang 160ms var(--tui-ease); }
.tui-popover[data-placed="top"]:popover-open { animation-name: tui-popover-hang-up; }
@keyframes tui-popover-hang { from { opacity: 0; transform: translateY(-5px); } }
@keyframes tui-popover-hang-up { from { opacity: 0; transform: translateY(5px); } }

/* The leader: a hairline across the gap and a dot where it touches the key. */
.tui-popover::before, .tui-popover::after {
  content: '';
  position: absolute;
  left: var(--tui-leader);
  pointer-events: none;
}
.tui-popover::before { bottom: 100%; width: 1px; height: calc(var(--gap) - 2px); margin-left: -0.5px; background: var(--tui-ink-2); }
.tui-popover::after { bottom: calc(100% + var(--gap) - 5px); width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: var(--tui-ink); box-shadow: 0 0 0 1.5px var(--tui-face-hi); }
.tui-popover[data-placed="top"]::before { top: 100%; bottom: auto; }
.tui-popover[data-placed="top"]::after { top: calc(100% + var(--gap) - 5px); bottom: auto; }
.tui-popover[data-placed="right"]::before, .tui-popover[data-placed="left"]::before { top: var(--tui-leader); left: auto; right: 100%; width: calc(var(--gap) - 2px); height: 1px; margin: -0.5px 0 0; }
.tui-popover[data-placed="right"]::after, .tui-popover[data-placed="left"]::after { top: var(--tui-leader); left: auto; right: calc(100% + var(--gap) - 5px); bottom: auto; margin: -2.5px 0 0; }
.tui-popover[data-placed="left"]::before { right: auto; left: 100%; }
.tui-popover[data-placed="left"]::after { right: auto; left: calc(100% + var(--gap) - 5px); }
/* A card with no leader, e.g. inside a page. */
.tui-popover--plain::before, .tui-popover--plain::after { display: none; }

.tui-popover__title { margin: 0 0 var(--tui-1); font: 700 var(--tui-t-body)/1.3 var(--tui-sans); }
.tui-popover p { margin: 0; }
.tui-popover__title ~ p { color: var(--tui-ink-2); }
.tui-popover > .tui-label:first-child { display: block; margin-bottom: var(--tui-2); }
.tui-popover__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--tui-2); margin-top: var(--tui-4); }

/* The key holding a card out stays down, and its tip keeps out of the card's way. */
.tui-popover__trigger[aria-expanded="true"][data-tip]::after { display: none; }
.tui-key.tui-popover__trigger[aria-expanded="true"], .tui-key.tui-popover__trigger.is-down {
  transform: translateY(var(--skirt));
  filter: brightness(0.97);
  box-shadow: var(--tui-pressed);
}

/* Open but not yet placed (the toggle event is asynchronous): unseen for that frame, still focusable. */
.tui-popover:popover-open:not([data-placed]) { opacity: 0; }

/* ---------------------------------------------------------------- part: profile-card */
/* Profile card: a person's ID plate. Their coin (.tui-avatar) sits in a
   countersunk socket cut into the plate; the facts are a rating plate pressed
   into the face, values engraved in tabular figures; one key to act. */
.tui-profile-card {
  container: tui-profile-card / inline-size;
  display: grid;
  gap: var(--tui-5);
  width: min(100%, 360px);
}
.tui-profile-card__who { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--tui-4); }
/* The socket: a round recess a little wider than the coin, so the coin's shadow falls into it. */
.tui-profile-card__socket {
  display: grid;
  place-items: center;
  padding: 5px;
  border-radius: 50%;
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-profile-card__name { margin: 0; font: 700 var(--tui-t-h3)/1.1 var(--tui-sans); letter-spacing: -0.015em; color: var(--tui-ink); overflow-wrap: anywhere; }
.tui-profile-card__role { margin: 4px 0 0; font-size: var(--tui-t-body); color: var(--tui-ink-2); }
.tui-profile-card__who .tui-status { margin-top: var(--tui-2); }
/* The rating plate: a recess with its facts engraved two by two, hairlines between. */
.tui-profile-card__plate {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  border-radius: var(--tui-r-m);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
}
.tui-profile-card__plate > div { display: grid; gap: 5px; padding: 11px 14px 12px; min-width: 0; }
.tui-profile-card__plate > div:nth-child(odd) { border-right: 1px solid var(--tui-rule); }
.tui-profile-card__plate > div:nth-child(n+3) { border-top: 1px solid var(--tui-rule); }
.tui-profile-card__plate dt { font: 500 var(--tui-t-label)/1.2 var(--tui-sans); letter-spacing: var(--tui-track); text-transform: uppercase; color: var(--tui-ink-2); }
.tui-profile-card__plate dd {
  margin: 0;
  font: 600 17px/1 var(--tui-sans);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--tui-ink);
  /* Engraved: the cut's lower lip catches the lamp. */
  text-shadow: 0 1px 0 var(--tui-hl);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tui-profile-card__plate dd small { margin-left: 3px; font-size: 0.66em; font-weight: 500; color: var(--tui-ink-2); letter-spacing: 0; }
.tui-profile-card__actions { display: flex; gap: var(--tui-2); }
.tui-profile-card__actions > .tui-key { flex: 1; }

/* Compact: one line — coin, name and role, one small key. For lists of people and panel heads. */
.tui-profile-card--compact { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--tui-3); width: min(100%, 420px); }
.tui-profile-card--compact .tui-profile-card__who { display: contents; }
.tui-profile-card--compact .tui-profile-card__socket { padding: 3px; }
.tui-profile-card--compact .tui-profile-card__name { font-size: var(--tui-t-body); font-weight: 700; letter-spacing: 0; }
.tui-profile-card--compact .tui-profile-card__role { margin-top: 2px; font-size: var(--tui-t-small); }
.tui-profile-card--compact .tui-profile-card__actions > .tui-key { flex: none; }

/* Narrow: the coin above the name, the plate still two by two. */
@container tui-profile-card (max-width: 260px) {
  .tui-profile-card__who { grid-template-columns: minmax(0, 1fr); justify-items: start; }
}

/* A latching key on a card lights its lamp only while it is down. */
.tui-profile-card .tui-key[aria-pressed="false"] > .tui-lamp {
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / 0.25), transparent 55%), color-mix(in oklab, var(--c) 22%, var(--tui-face-lo));
  box-shadow: inset 0 1px 1.5px rgb(0 0 0 / 0.45), 0 1px 0 var(--tui-hl);
}

/* ---------------------------------------------------------------- part: scrub */
/* Scrub field: a number in a well, with an engraved ruler along the well's
   floor. The ruler slides under a fixed index; the index is printed until
   you set the value, then its hairline lights amber. At min and max a
   printed stop meets the index. scrub.mjs builds the ruler and moves it. */

tui-scrub {
  position: relative;
  display: grid;
  min-width: 0;
  border-radius: var(--tui-r-m);
  background: var(--tui-well-fill) var(--tui-well);
  box-shadow: var(--tui-inset);
  -webkit-tap-highlight-color: transparent;
}
tui-scrub:hover, tui-scrub.is-hover { filter: brightness(1.03); }

/* The numerals, typed or read, and the unit printed after them. */
.tui-scrub__row {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 29px;
  padding: 2px var(--tui-3) 0;
  cursor: text;
}
.tui-scrub__input {
  flex: none;
  width: 4ch; /* as wide as its numerals, so the unit follows them (scrub.mjs where field-sizing is missing) */
  max-width: 100%;
  min-width: 1ch;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  font: 600 15px/1 var(--tui-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--tui-ink);
}
@supports (field-sizing: content) { .tui-scrub__input { field-sizing: content; width: auto; } }
tui-scrub .tui-scrub__input:focus-visible { outline: none; }
.tui-scrub__input::selection { background: color-mix(in oklab, var(--tui-ink) 18%, transparent); }
.tui-scrub__unit { flex: none; font: 500 var(--tui-t-small)/1 var(--tui-sans); color: var(--tui-ink-2); }

/* The strip: a window on the floor of the well. Its ends fall away, as a
   tape does over its drums. Drag it; the page still scrolls from anywhere else. */
.tui-scrub__window {
  position: relative;
  height: 27px;
  overflow: hidden;
  border-radius: 0 0 var(--tui-r-m) var(--tui-r-m);
  cursor: ew-resize;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-mask: linear-gradient(90deg, transparent, #000 24%, #000 76%, transparent);
          mask: linear-gradient(90deg, transparent, #000 24%, #000 76%, transparent);
}
/* The strip itself: a band of tape a shade lighter than the floor, its top
   edge just under the numerals. */
.tui-scrub__window::before {
  content: '';
  position: absolute;
  inset: 3px 0 0;
  background: linear-gradient(color-mix(in oklab, var(--tui-face-hi) 38%, transparent), color-mix(in oklab, var(--tui-face-hi) 14%, transparent));
  box-shadow: inset 0 1px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 0.5));
}
/* The printed label of the field is a grip too. */
.tui-scrub__grip { cursor: ew-resize; touch-action: none; user-select: none; -webkit-user-select: none; }

/* The ruler: fine ticks every step, a longer one halfway, a long numbered
   one at each major. Engraved and ink-filled: each cut has its lit wall on
   the right, toward the lamp's side of the groove. */
.tui-scrub__tape {
  --pos: 0;
  position: absolute;
  top: 4px;
  bottom: 0;
  left: calc(50% - 0.5px);
  width: calc(var(--span, 0px) + 1px);
  transform: translate3d(calc(var(--pos) * -1px), 0, 0);
  transition: transform 90ms var(--tui-ease);
  background:
    linear-gradient(90deg, var(--tui-ink) 0 1px, var(--tui-hl) 1px 2px, transparent 2px) var(--o-major, 0) 0 / var(--major, 80px) 10px repeat-x,
    linear-gradient(90deg, var(--tui-ink-2) 0 1px, var(--tui-hl) 1px 2px, transparent 2px) var(--o-mid, 0) 0 / var(--mid, 40px) 7px repeat-x,
    linear-gradient(90deg, color-mix(in oklab, var(--tui-ink-2) 70%, transparent) 0 1px, color-mix(in oklab, var(--tui-hl) 70%, transparent) 1px 2px, transparent 2px) var(--o-tick, 0) 0 / var(--tick, 8px) 4px repeat-x;
}
tui-scrub[data-scrubbing]:not([data-detent]) .tui-scrub__tape { transition: none; }
tui-scrub[data-detent] .tui-scrub__tape { transition-duration: 70ms; }
/* The stops, printed past each end: a heavy bar, then hatching where the
   scale runs out. */
.tui-scrub__tape::before, .tui-scrub__tape::after {
  content: '';
  position: absolute;
  top: 0;
  width: 44px;
  height: 12px;
  background:
    linear-gradient(var(--tui-ink), var(--tui-ink)) var(--stop-at) 0 / 2.5px 100% no-repeat,
    repeating-linear-gradient(-55deg, color-mix(in oklab, var(--tui-ink-3) 55%, transparent) 0 1px, transparent 1px 4px) 0 1px / 100% 9px no-repeat;
}
.tui-scrub__tape::before { right: 100%; --stop-at: 100%; }
.tui-scrub__tape::after { left: 100%; --stop-at: 0; }
.tui-scrub__n {
  position: absolute;
  top: 13px;
  left: var(--at);
  transform: translateX(calc(-50% + 0.5px));
  font: 500 9.5px/1 var(--tui-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--tui-ink-2);
  white-space: nowrap;
}

/* The index: a hairline behind a slit, under a printed pointer. It lights
   only while the value is being set. */
.tui-scrub__needle {
  position: absolute;
  z-index: 1;
  top: 0;
  left: calc(50% - 0.75px);
  width: 1.5px;
  height: 13px;
  border-radius: 0 0 1px 1px;
  background: var(--tui-ink);
  box-shadow: 1px 0 0 var(--tui-hl);
  transition: background-color 90ms var(--tui-ease), box-shadow 90ms var(--tui-ease);
}
.tui-scrub__needle::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 9px;
  height: 5px;
  transform: translateX(-50%);
  background: var(--tui-ink);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
tui-scrub:focus-within .tui-scrub__needle, tui-scrub[data-scrubbing] .tui-scrub__needle, tui-scrub.is-focus .tui-scrub__needle, tui-scrub.is-down .tui-scrub__needle {
  background: var(--tui-amber);
  box-shadow: 0 0 3px 0.5px color-mix(in oklab, var(--tui-amber) 75%, transparent), 0 0 9px 1px color-mix(in oklab, var(--tui-amber) 35%, transparent);
}

/* Focus rings the whole well; an error marks its lip, as on a field. */
tui-scrub:has(.tui-scrub__input:focus-visible), tui-scrub.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
tui-scrub[data-error], .tui-field[data-error] tui-scrub {
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--tui-red) 85%, transparent), 0 0 8px -2px color-mix(in oklab, var(--tui-red) 45%, transparent), var(--tui-inset);
}
tui-scrub:has(.tui-scrub__input:disabled) { opacity: 0.45; filter: none; }
tui-scrub:has(.tui-scrub__input:disabled) .tui-scrub__window, .tui-field:has(tui-scrub .tui-scrub__input:disabled) .tui-scrub__grip { cursor: not-allowed; pointer-events: none; }

/* Compact: for a table cell or a dense inspector. The ruler keeps its ticks
   and drops its numbers. */
.tui-scrub--compact .tui-scrub__row { height: 26px; padding: 1px var(--tui-2) 0; }
.tui-scrub--compact .tui-scrub__input { font-size: var(--tui-t-body); }
.tui-scrub--compact .tui-scrub__window { height: 11px; }
.tui-scrub--compact .tui-scrub__tape { top: 3px; }
.tui-scrub--compact .tui-scrub__n { display: none; }
.tui-scrub--compact .tui-scrub__needle { height: 9px; }
.tui-scrub--compact .tui-scrub__needle::before { width: 7px; height: 4px; }
.tui-scrub--compact .tui-scrub__tape::before, .tui-scrub--compact .tui-scrub__tape::after { height: 10px; }

/* An inspector row: the label printed on the left, the field on the right. */
.tui-field.tui-scrub-row { grid-template-columns: minmax(0, 8.5em) minmax(0, 1fr); align-items: center; gap: var(--tui-3); }
.tui-field.tui-scrub-row > .tui-label { padding-left: 0; }

/* ---------------------------------------------------------------- part: sign-in */
/* Sign-in: an entry plate. The providers' marks are stamped into their key
   caps; a two-way selector re-prints the plate between signing in and making
   an account; errors sit on the field's lip with a hint that says what to do.
   kit/parts/sign-in.mjs checks the fields and runs the switch. */
.tui-sign-in { display: grid; gap: var(--tui-4); width: min(100%, 380px); padding: var(--tui-6); }
.tui-sign-in__head { display: grid; gap: var(--tui-4); }
.tui-sign-in__title { margin: 0; font: 700 var(--tui-t-h3)/1.15 var(--tui-sans); letter-spacing: -0.015em; color: var(--tui-ink); }
.tui-sign-in__lead { margin: -8px 0 0; color: var(--tui-ink-2); }
.tui-sign-in__mode { display: grid; grid-template-columns: 1fr 1fr; }
.tui-sign-in__mode span { justify-content: center; }

/* Provider keys: full width, the mark stamped into the cap — its upper edge shaded, its lower lip lit. */
.tui-sign-in__providers { display: grid; gap: var(--tui-2); }
.tui-sign-in__provider { width: 100%; gap: 10px; }
.tui-sign-in__provider svg { width: 18px; height: 18px; color: var(--tui-ink); filter: drop-shadow(0 1px 0 var(--tui-hl)) drop-shadow(0 -0.6px 0 rgb(var(--tui-sh) / calc(var(--tui-sh-a) * 1.2))); }

/* "or with email": printed between two hairlines. */
.tui-sign-in__or { display: flex; align-items: center; gap: var(--tui-3); margin: 0; font: 500 var(--tui-t-label)/1 var(--tui-sans); letter-spacing: var(--tui-track); text-transform: uppercase; color: var(--tui-ink-2); }
.tui-sign-in__or::before, .tui-sign-in__or::after { content: ''; flex: 1; height: 1px; background: var(--tui-rule); }

.tui-sign-in__fields { display: grid; gap: var(--tui-4); }
.tui-sign-in .tui-hint:empty { display: none; }
/* The password well holds a flat Show key. */
.tui-sign-in__secret { display: flex; align-items: center; border-radius: var(--tui-r-m); background: var(--tui-well-fill) var(--tui-well); box-shadow: var(--tui-inset); }
.tui-sign-in__secret .tui-input { flex: 1; background: transparent; box-shadow: none; }
.tui-sign-in__secret .tui-input:focus-visible { outline: none; }
.tui-sign-in__secret:has(.tui-input:focus-visible), .tui-sign-in__secret.is-focus { outline: 2px solid var(--tui-focus); outline-offset: 2px; }
.tui-sign-in__secret .tui-key { margin-right: 4px; }
.tui-field[data-error] .tui-sign-in__secret { box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--tui-red) 85%, transparent), 0 0 8px -2px color-mix(in oklab, var(--tui-red) 45%, transparent), var(--tui-inset); }
.tui-field[data-error] .tui-sign-in__secret .tui-input { box-shadow: none; }

.tui-sign-in__go { width: 100%; }
.tui-sign-in__go .tui-lamp { display: none; }
.tui-sign-in[aria-busy="true"] .tui-sign-in__go .tui-lamp { display: inline-block; }
.tui-sign-in[aria-busy="true"] .tui-sign-in__go { pointer-events: none; }
.tui-sign-in__foot { margin: 0; font-size: var(--tui-t-small); color: var(--tui-ink-2); text-align: center; }
.tui-sign-in__foot a, .tui-sign-in__lead a { color: var(--tui-ink); text-underline-offset: 2px; }
.tui-sign-in__status:empty { display: none; }
.tui-sign-in__status { display: flex; align-items: center; gap: var(--tui-2); margin: 0; font-size: var(--tui-t-small); color: var(--tui-ink); }

/* The switch re-prints the plate: [data-up] shows only for a new account, [data-in] only for signing in. */
.tui-sign-in [data-up] { display: none; }
.tui-sign-in:has(.tui-sign-in__mode input[value="up"]:checked) [data-up] { display: revert; }
.tui-sign-in:has(.tui-sign-in__mode input[value="up"]:checked) .tui-field[data-up] { display: grid; }
.tui-sign-in:has(.tui-sign-in__mode input[value="up"]:checked) [data-in] { display: none; }
