/* ===========================================================================
   Showcase — co-located styling for the /showcase dev route (pages/Showcase.tsx).

   Two kinds of value live here, and the distinction is the honest claim:

   1. DEMONSTRATION reads — every colour reads a token or surface-role context,
      and the token-scale demos read var(--mc-*) directly (that read IS the
      demonstration). These are the subject of the page.
   2. DEMO CHROME — the frame the subject is shown in: swatch box sizes, the
      compose rail's width, the scrim boxes. These carry raw px, because they
      size a display case, not a component. A --mc-* token for "how big is a
      radius swatch" would be a token the design system does not own.

   So: the page is not literal-free, and does not claim to be. It is free of
   literal PAINT — nothing here defines a token or hardcodes a colour, which
   keeps the page a pure viewer of the production design system.
   =========================================================================== */

.sc-root {
  min-height: 100vh;
}

.sc-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: var(--mc-space-3) var(--mc-space-4);
  border-bottom-width: 1px;
  border-bottom-style: solid;
  /* border-color comes from the page surface-role applicator */
}

.sc-body {
  display: grid;
  gap: var(--mc-space-7);
  max-width: 1100px;
  padding: var(--mc-space-5);
}

.sc-h2 {
  font-size: var(--mc-text-lead);
  font-weight: 600;
}


.sc-stack {
  display: grid;
  gap: var(--mc-space-4);
}

/* Accent-seam probe — renders the app-shell filter-chip vocabulary
   (--pill-active-*, --pill-inactive-text) exactly as the home toolbar chips
   read it, so an accent re-point that misses the seam shows up here as a
   washed-out active chip. */
.sc-chip {
  padding: var(--mc-space-1) var(--mc-space-3);
  border-radius: var(--mc-radius-pill);
  font-size: var(--mc-text-body);
  border: 1px solid var(--pill-active-border);
  background: var(--pill-active-bg);
  color: var(--pill-active-text);
}

.sc-chip--inactive {
  border-color: var(--border);
  background: transparent;
  color: var(--pill-inactive-text);
}

/* Surface-role swatches — 3-up grid. SurfaceRole is a closed set of FIVE
   (page/panel/modal/field/frame); the same grid also holds panel's three
   elevation steps and the two hover-state swatches. */
.sc-role-grid {
  display: grid;
  gap: var(--mc-space-3);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.sc-role {
  min-height: 80px;
  padding: var(--mc-space-5);
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-md);
}

.sc-role-name {
  font-weight: 600;
}

.sc-role-sub {
  font-size: var(--mc-text-body);
}

/* "Surfaces compose" — a frame rail + page + panel/field/console. */
/* raw-layout-ok: grid track list — two-column rail+main split; Grid is not modeled by Stack/Cluster. */
.sc-compose {
  display: grid;
  grid-template-columns: auto 1fr;
  height: 360px;
  overflow: hidden;
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-lg);
}

.sc-rail {
  width: 180px;
  padding: var(--mc-space-4);
}

.sc-rail-title {
  font-weight: 700;
}

.sc-rail-item {
  padding: var(--mc-space-1-5) 0;
}



.sc-main {
  flex: 1;
  display: grid;
  align-content: start;
  gap: var(--mc-space-3);
  padding: var(--mc-space-5);
}

.sc-card {
  padding: var(--mc-space-4);
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-md);
}

/* Verification: the card reads its PANEL surface's own ink ramp. Under a
   mixed-polarity theme (meadow) the panel is a dark island in a light page, so
   these role vars resolve to LIGHT ink — the card shows correct contrast with
   no per-component change. Reading the role's own ink var (not the global
   Tier-1 --text-*) is the two-tier-correct move. */
.sc-card-title {
  color: var(--surface-panel-ink-strong);
  font-weight: 600;
}

.sc-card-sub {
  color: var(--surface-panel-ink-dim);
  font-size: var(--mc-text-body);
}

.sc-inline-field {
  padding: var(--mc-space-2-5) var(--mc-space-3);
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-md);
}

.sc-console {
  padding: var(--mc-space-4);
  border-radius: var(--mc-radius-md);
  font-family: var(--mc-font-mono);
  font-size: var(--mc-text-body);
}

.sc-form {
  display: grid;
  gap: var(--mc-space-3-5);
  max-width: 420px;
  padding: var(--mc-space-4);
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-md);
  /* border-color comes from the panel surface-role applicator */
}

/* Controls panel — the honest home of Button/Badge/Pill/form controls. They
   never sit on the bare page; under a mixed-polarity theme the panel is a dark
   island, which is where their tone/tint choices must actually be judged. */
.sc-controls-panel {
  display: grid;
  gap: var(--mc-space-6);
  padding: var(--mc-space-5);
  border-width: 1px;
  border-style: solid;
  border-radius: var(--mc-radius-lg);
  /* bg + border-color from the panel surface-role applicator */
}

.sc-controls-caption {
  font-size: var(--mc-text-caption);
  color: var(--text-dim);
}

/* Secondary text on this page takes a real ink STEP, never an opacity. An
   opacity multiplies the ramp step it sits on, so the rendered colour is not a
   step at all: no theme can re-point it, the contrast gate reads a value that
   exists in no stylesheet, and the ramp's whole point — that dimness is a
   choosable rung — is bypassed. Measured before this changed: three 0.6 rules
   here dimmed #2c2a25 (the body step) to #7a7872 / #7c7a75 and accounted for 64
   of the 79 nodes failing the colour-contrast gate.
   The three remaining `opacity` rules in this file are all `:disabled` states,
   which is the conventional affordance and which WCAG 1.4.3 exempts. */

/* Per-row axis label — names the closed-set member the row demonstrates. */
.sc-cell-label {
  min-width: 92px;
  font-size: var(--mc-text-caption);
  color: var(--text-dim);
}

/* Scrim box — stands in for the image ground the `overlay` tones and
   OverlayAction are painted for. Not a token read: a demo prop for a context
   (a photo) the design system does not own.
   A stand-in for a PHOTOGRAPH: nothing about the gradient is a design
   decision — it exists so the overlay tones have something busy to sit on, and
   a derived token would imply this ground is one the system owns. */
.sc-scrim {
  padding: var(--mc-space-3);
  border-radius: var(--mc-radius-md);
  /* hue-alias-ok: stands in for a photograph, not a ground the system owns. */
  background: linear-gradient(135deg, var(--violet), var(--info));
}

/* The Label primitive's base carries Tailwind's `block`, which is emitted
   AFTER this file in the bundle — so the row's flex layout rides utilities on
   the element (Tailwind orders `flex` after `block`) and this rule keeps only
   the non-conflicting paint. */
.sc-toggle-row {
  cursor: pointer;
  font-size: var(--mc-text-body);
}

/* raw-layout-ok: inline control affordance (column flow) — grid, not sibling rhythm. */
.sc-upload {
  display: inline-grid;
  grid-auto-flow: column;
  align-items: center;
  height: var(--mc-control-sm);
  padding: 0 var(--mc-space-3);
  border: 1px solid var(--surface-panel-border);
  border-radius: var(--mc-radius-md);
  font-size: var(--mc-text-body);
}

/* Fields in the states row sit inline beside their label. The width lives on
   this WRAPPER, not the field: Input/Select carry Tailwind's `w-full`, emitted
   after this file, so a width here would lose at equal specificity. */
.sc-state-field {
  width: 200px;
}

/* InlineLink flows as text, so its demo must be a real paragraph. */
.sc-prose {
  font-size: var(--mc-text-body);
  line-height: var(--mc-leading-relaxed);
}

.sc-option {
  padding: var(--mc-space-3);
  background: var(--surface-panel-bg);
}

.sc-option-title {
  font-weight: 600;
}

.sc-option-sub {
  font-size: var(--mc-text-caption);
  color: var(--text-dim);
}

/* raw-layout-ok: inline control affordance (column flow) — grid, not sibling rhythm. */
.sc-menu-trigger {
  display: inline-grid;
  grid-auto-flow: column;
  align-items: center;
  gap: var(--mc-space-2);
  height: var(--mc-control-sm);
  padding: 0 var(--mc-space-3);
  border: 1px solid var(--surface-panel-border);
  border-radius: var(--mc-radius-md);
  font-size: var(--mc-text-body);
}

.sc-menu {
  min-width: 180px;
  padding: var(--mc-space-1);
  border: 1px solid var(--surface-modal-border);
  border-radius: var(--mc-radius-md);
  background: var(--surface-modal-bg);
  box-shadow: var(--mc-shadow-lg);
}

.sc-menu-item {
  padding: var(--mc-space-2) var(--mc-space-3);
  border-radius: var(--mc-radius-sm);
  font-size: var(--mc-text-body);
}

.sc-menu-item:disabled {
  opacity: 0.5;
}

.sc-rows {
  display: grid;
  border: 1px solid var(--surface-panel-border);
  border-radius: var(--mc-radius-md);
  overflow: hidden;
}

.sc-list-row {
  padding: var(--mc-space-2) var(--mc-space-3);
  font-size: var(--mc-text-body);
  border-left-width: var(--mc-border-thick);
  border-left-style: solid;
  border-left-color: transparent;
}

.sc-list-row--active {
  border-left-color: rgb(var(--accent));
  background: var(--surface-panel-bg);
}

.sc-list-row:disabled {
  opacity: 0.5;
}

.sc-disclosure-body {
  padding: var(--mc-space-3);
  font-size: var(--mc-text-body);
  color: var(--text-mid);
}

/* OverlayAction covers its parent, so the host needs a size + `relative`. */
/* raw-layout-ok: single-item centering box — grid, not sibling rhythm. */
.sc-overlay-host {
  position: relative;
  display: grid;
  place-items: center;
  width: 140px;
  height: 72px;
  overflow: hidden;
  border-radius: var(--mc-radius-md);
  /* hue-alias-ok: the same photograph stand-in as .sc-scrim above — the host an
     OverlayAction is demonstrated over, not a ground the system owns. */
  background: linear-gradient(135deg, var(--violet), var(--info));
}

.sc-overlay-glyph {
  font-size: var(--mc-text-caption);
  font-weight: 600;
  /* Declared here and then read, the two-tier form. The IconButton alias this
     used to borrow is now a socket on that primitive, which this probe is not
     one of — so the probe binds its own name to the on-colour role. */
  --sc-overlay-glyph-ink: var(--text-oncolor);
  color: var(--sc-overlay-glyph-ink);
}


/* Colour-token swatches — the value IS var(--<token>), applied inline. */
.sc-color {
  text-align: center;
  font-size: var(--mc-text-caption);
}

.sc-color-chip {
  width: 56px;
  height: 56px;
  border-radius: var(--mc-radius-md);
  border: 1px solid var(--surface-page-border);
}

.sc-color-name {
  color: var(--text-dim);
}

/* Identity palette — one column per slot. The disc is the avatar geometry at
   swatch scale (a circle sized to match .sc-color-chip so the two token
   galleries scan as one rhythm); the caption below it carries the same hue as
   INK, which is a different pair with a different failure mode. */
.sc-identity-disc {
  width: 56px;
  height: 56px;
  border-radius: var(--mc-radius-pill);
  display: grid;
  place-items: center;
  font-size: var(--mc-text-lead);
  font-weight: 600;
}

.sc-identity-ink {
  font-size: var(--mc-text-caption);
  font-weight: 500;
}

/* Scale demos — space / radius / type / shadow. */
.sc-scale {
  display: grid;
  gap: var(--mc-space-5);
}

.sc-scale-label {
  font-size: var(--mc-text-caption);
  color: var(--text-dim);
}


.sc-space-bar {
  height: 40px;
  border-radius: var(--mc-radius-xs);
  /* FORM: --accent is a bare "R G B" triplet — it must be rgb()-wrapped or
     the declaration is invalid and the bars render nothing. */
  background: rgb(var(--accent));
  /* width is set inline to the demonstrated var(--mc-space-N) */
}

/* raw-layout-ok: single-item centering box — grid, not sibling rhythm. */
.sc-radius-box {
  width: 56px;
  height: 40px;
  display: grid;
  place-items: center;
  font-size: var(--mc-text-caption);
  border: 1px solid var(--surface-panel-border);
  background: var(--surface-panel-bg);
  /* border-radius is set inline to the demonstrated var(--mc-radius-X) */
}

/* raw-layout-ok: single-item centering box — grid, not sibling rhythm. */
.sc-shadow-box {
  width: 72px;
  height: 48px;
  display: grid;
  place-items: center;
  font-size: var(--mc-text-caption);
  border-radius: var(--mc-radius-md);
  background: var(--surface-panel-bg);
  /* box-shadow is set inline to the demonstrated var(--mc-shadow-X) */
}

/* Line-height needs multi-line text to show anything, so the sample is a
   paragraph with a width that forces a wrap. */
.sc-leading-sample {
  max-width: 420px;
  font-size: var(--mc-text-body);
}

/* raw-layout-ok: control-height demo box (column flow, start) — grid, not sibling rhythm. */
.sc-control-box {
  display: grid;
  grid-auto-flow: column;
  justify-content: start;
  align-items: center;
  padding: 0 var(--mc-space-3);
  border: 1px solid var(--surface-panel-border);
  border-radius: var(--mc-radius-md);
  background: var(--surface-panel-bg);
  font-size: var(--mc-text-caption);
  /* height is set inline to the demonstrated var(--mc-control-X) */
}

/* raw-layout-ok: single-item centering box — grid, not sibling rhythm. */
.sc-border-box {
  display: grid;
  place-items: center;
  width: 72px;
  height: 40px;
  border-style: solid;
  border-color: var(--surface-panel-border);
  border-radius: var(--mc-radius-md);
  font-size: var(--mc-text-caption);
  /* border-width is set inline to the demonstrated var(--mc-border-X) */
}

.sc-font-line {
  font-size: var(--mc-text-body);
  /* font-family is set inline to the demonstrated var(--mc-font-X) */
}

/* Motion — a fixed-length track the dot crosses, so every duration/easing is
   compared over the same distance. */

.sc-motion-dot {
  width: 20px;
  height: 20px;
  border-radius: var(--mc-radius-pill);
  background: rgb(var(--accent));
  transform: translateX(0);
  transition-property: transform;
  /* duration + timing-function are set inline to the demonstrated token */
}

.sc-motion-dot--moved {
  transform: translateX(240px);  /* layout-literal-ok: motion offset — a distance travelled, not a layout dimension; the --mc-* scale describes layout */
}

/* Z-ladder — a relative host so the boxes stack against each other. The
   offsets are inline (they read --mc-space-*); only the frame is here. */
.sc-zstack {
  position: relative;
  height: 200px;
}

/* raw-layout-ok: single-item centering box — grid, not sibling rhythm. */
.sc-zbox {
  position: absolute;
  display: grid;
  place-items: center;
  width: 132px;
  height: 44px;
  border: 1px solid var(--surface-modal-border);
  border-radius: var(--mc-radius-md);
  background: var(--surface-modal-bg);
  box-shadow: var(--mc-shadow-md);
  font-size: var(--mc-text-caption);
  /* z-index + offsets are set inline to the demonstrated var(--z-X) */
}

.sc-type-line {
  line-height: 1.3;
  /* font-size is set inline to the demonstrated var(--mc-text-X) */
}

/* Layout demos. A layout primitive paints nothing, so the demo supplies the
   surfaces around it and what you judge is the space between them. */
.sc-layout-demo {
  padding: var(--mc-space-3);
  border-radius: var(--mc-radius-md);
  min-width: var(--mc-space-10);
}
.sc-layout-demo-wide { width: 100%; }
.sc-layout-chip {
  padding: var(--mc-space-1) var(--mc-space-2);
  border-radius: var(--mc-radius-xs);
  font-size: var(--mc-text-body);
}
/* A second height so Cluster's align (center / start / end / baseline) has
   something to align AGAINST — equal-height children would make every value
   look identical and the demo would assert nothing. */
.sc-layout-chip-tall { padding-block: var(--mc-space-4); }
/* Mobile (< 768px) ActivityCard tweaks */
@media (max-width: 767px) {
  .activity-card {
    padding: 12px 14px !important;
    min-height: 44px;
  }
}

/* The delete control's reveal.
 *
 * Hover-revealed on a FINE pointer: an irreversible action on every card in a
 * long feed is noise until someone reaches for it, and a mouse can ask for it.
 *
 * Simply PRESENT on a coarse one, because a touch device has no hover to reveal
 * it with. The control used to live in the card header on `opacity-0
 * group-hover:opacity-100`, which meant it held its full width on every card —
 * on the one platform that could never make it appear, and in the one row with
 * no width to spare. It sits with the turn's other actions now, in a row that
 * wraps.
 *
 * Pointer, not viewport: reachability is a property of the input device, and
 * `--mc-control-*` already takes its 44px touch bump from the same question
 * (design-tokens.css). A component may not ask how wide the viewport is
 * (docs/claude/layout.md → Adaptation); it may ask what is pointing at it.
 */
@media (pointer: fine) {
  .activity-card__delete {
    opacity: 0;
  }

  .group:hover .activity-card__delete,
  .activity-card__delete:focus-visible {
    opacity: 1;
  }
}
/* Generated-media asset tiles (MediaAssetTile.tsx) — shared by the feed's
   inline asset strips and the workspace AssetsGalleryModal grid.

   Tier-2 component vars are bound at the sheet's component root from the
   feed-card family (defined at :root in index.css), then consumed below —
   the two-tier css convention, so a theme re-point of --feedcard-* reaches
   every tile without touching this sheet. Dimensions live here (not inline
   styles) because a tile's width/aspect are bespoke to this component, not
   steps on the --mc-* rhythm scale. */

.mat-tile {
  --mat-border: var(--feedcard-border);
  --mat-media-bg: color-mix(in srgb, var(--feedcard-border) 45%, transparent);
  --mat-shimmer-ink: color-mix(in srgb, var(--text-faint) 25%, transparent);
  --mat-caption-ink: var(--text-dim);
  --mat-tile-w: 148px;

  width: var(--mat-tile-w);
  border: 1px solid var(--mat-border);
  border-radius: var(--mc-radius-md);
  overflow: hidden;
}

.mat-tile--clickable {
  cursor: zoom-in;
}

.mat-tile__media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--mat-media-bg);
  overflow: hidden;
}

.mat-tile__img,
.mat-tile__video {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  display: block;
}

/* Generated speech / music. The tile box is sized for a visual frame, so the
   transport sits centred in it rather than being stretched to fill — an <audio>
   element scaled to a 4:3 box renders its controls at unusable proportions. */
.mat-tile__audio {
  position: absolute;
  inset: 0;
  margin: auto;
  width: calc(100% - var(--mc-space-3));
  height: var(--mc-control-lg);
}

/* Centered play-glyph overlay on video tiles. Grid centring — a container
   arrangement the layout primitives deliberately do not model. */
.mat-tile__overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}

.mat-tile__play {
  display: grid;
  place-items: center;
  width: var(--mc-control-md, 32px);
  height: var(--mc-control-md, 32px);
  border-radius: var(--mc-radius-pill);
}

.mat-tile__failed {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

/* Generating state: a slow shimmer sweep over the media box. The cadence
   composes the motion-token scale (calc over --mc-motion-duration-slow), so
   reduced-motion zeroing the tokens stills it too; the explicit media block
   below removes the loop entirely for good measure. */
.mat-tile__shimmer {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, var(--mat-shimmer-ink) 50%, transparent 80%);
  background-size: 200% 100%;
  animation: mat-shimmer calc(var(--mc-motion-duration-slow) * 4) linear infinite;
}

@keyframes mat-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .mat-tile__shimmer {
    animation: none;
  }
}

.mat-tile__caption {
  padding: var(--mc-space-1) var(--mc-space-1-5);
  color: var(--mat-caption-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Status rail (StatusRail.tsx) — the step narration's ink.

   The rail's ink is not a fixed rank inside the card, it is a function of the
   turn's lifetime, and that is why it is a stylesheet rather than an inline
   style: the value is selected by state, and a state selector cannot be
   written inline.

   WHILE RUNNING the rail is the only thing on the card that is current. The
   prompt is what the user already typed and the conclusion does not exist
   yet, so the step message is what a reader is actually reading — it belongs
   at the reading baseline, alongside the prompt, not below it.

   ONCE SETTLED the turn has a conclusion, and the narration of how it got
   there is no longer the subject. It recedes to --text-dim, which is where a
   finished rail already sat and is why the settled state needs no rule of its
   own — the rest position IS the resting value.

   Rank inside the card's text band stays ink alone: both bands are at the
   reading baseline, and nothing here drops a step to the chrome floor.

   Tier-2 socket, declared at this component's root and nowhere else, so a
   theme re-point of --text / --text-dim reaches the rail without an edit
   here, and no other component inherits a rail's ink decision. */

.mc-rail {
  --rail-step-ink: var(--text-dim);
}

.mc-rail[data-state='running'] {
  --rail-step-ink: var(--text);
}

.mc-rail__step {
  color: var(--rail-step-ink);
}

/* Step narration wraps; it never runs past the card.

   A separate class from .mc-rail__step on purpose: ink is state-bound and a
   failed step opts OUT of it (it keeps the status ink that says so), while
   wrapping is unconditional — every message wears this one, failed or not.

   `anywhere` rather than `break-word`, which is the distinction that actually
   decides the bug. Both break a too-long token once a line is being laid out,
   but only `anywhere` counts toward the element's intrinsic min-content
   width. Without it a single unbroken token — a URL, a long identifier — sets
   a min-content floor that the flex row cannot shrink below, so the row grows
   wider than the card and the shell's `overflow: hidden` (.main in
   globals.css) clips it flush with no scrollbar and no ellipsis. Ordinary
   prose is unaffected: `anywhere` still prefers a space when there is one.

   The row's other half of that fix is the text column releasing its
   `min-width: auto` floor, which it does through Stack's `grow` — see
   StatusRail.tsx. Both halves are needed: a floor of zero with no way to
   break the token still overflows, and a breakable token under an
   unshrinkable floor still overflows. */
.mc-rail__msg {
  overflow-wrap: anywhere;
}

/* The verification round's check panel, nested inside its rail step.

   A hairline and nothing else: the panel groups the round's rows so a reader
   can see where one pass ends and the next begins, but it sits on the card's
   own ground and does not claim a surface role of its own — a second role here
   would paint a panel-on-panel edge that appears nowhere else in the rail.
   Declared at the rail's root scope for the same reason the ink socket is. */
.mc-rail__checks {
  border: 1px solid var(--border-soft);
}
/* CreateProjectModal — provisioning step list (fixed-viewport, auto-following).
   The step list lives in a FIXED-height scroll viewport so the modal keeps one
   size for the whole run instead of growing with every step. These rules exist
   because none are expressible as utilities: the soft fade masks at the
   viewport's edges (an alpha ramp, not a paint — hence the keyword colors),
   the thin token-tinted scrollbar, and the in-flight row's accent inset edge. */

.create-provision-scroll {
  /* Tier-2 binding at the component scope root (two-tier form) — consumers
     below read the component var, never the role token directly. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
  /* Top ramp (12px) stays inside the viewport's own top padding so the first
     row renders at full opacity when the list is short; the deeper bottom
     ramp is the "more below" affordance while scrolled. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 12px, black calc(100% - 20px), transparent);
  mask-image: linear-gradient(to bottom, transparent, black 12px, black calc(100% - 20px), transparent);
}
.create-provision-scroll::-webkit-scrollbar { width: 5px; }
.create-provision-scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}

.create-provision-now {
  /* --accent is a Tier-1 R G B triplet, never a complete <color> — the rgb()
     wrap is load-bearing (a bare var() here is malformed and silently drops
     the declaration). */
  box-shadow: inset 2px 0 0 rgb(var(--accent));
}
/* ChoiceOptions — the concierge's clickable answers. Paint + hover only; the
   arrangement lives in the .tsx.

   STATE RIDES THE BORDER AND THE CHECK, NEVER A HEAVY FILL. An earlier draft
   washed the chosen pill in 32% success and it fought the capability glyphs in
   the proposal card below it — two saturated blocks in one column, neither of
   which is the thing being read. So: an identical neutral rest for every
   option, colour only once the user acts, and the acted-on state announced by a
   1.5× border and a leading check rather than by area.

   The hue is --success, the theme's own emerald, read as a HUE and not as a
   status claim: nothing has succeeded, the user has chosen. Clay/terracotta and
   peach were both tried and both read as errors down a stacked column — the
   same failure the try-next chips recorded before they went confetti.

   The three values ride --cc-option-* variables rather than being set inline,
   because Button spreads the caller's inline style last: an inline background
   would win over these state rules instead of resolving through them. */
/* Every pill DECLARES data-surface="field" (the same role the agent's own chat
   bubble declares, which is what "the bubble's card white" means here), so
   --surface-bg below is the field ground and --text / --text-dim are that
   ground's inks. Painting the ground without declaring the role would split the
   two on a mixed-polarity theme — meadow's dark field under the page's dark
   ink — which is the split the role layer exists to prevent. */
.cc-option {
  --cc-option-bg: var(--surface-bg);
  --cc-option-border: var(--border-soft);
  --cc-option-border-width: var(--mc-border-thin);
  --cc-option-ink: var(--text);
  transition:
    background var(--mc-motion-duration-fast),
    border-color var(--mc-motion-duration-fast),
    transform var(--mc-motion-duration-fast);
}

/* Hover — barely tinted, a green hairline, and a 1px lift. The tint sits well
   under the tone family's own --tone-bg-mix on purpose: the pill is saying it
   is pressable, not reporting a state. */
.cc-option:hover:enabled {
  --cc-option-bg: color-mix(in srgb, var(--success) 7%, var(--surface-bg));
  --cc-option-border: color-mix(in srgb, var(--success) 48%, transparent);
  transform: translateY(calc(-1 * var(--mc-space-0-5) / 2));
}

/* Chosen — the answer the user gave, frozen (the component renders it disabled;
   changing an answer is done by typing). The ink is the validated per-surface
   success ink, so the label clears its own tint on every theme. */
.cc-option[data-state='chosen'] {
  --cc-option-bg: color-mix(in srgb, var(--success) 12%, var(--surface-bg));
  --cc-option-border: color-mix(in srgb, var(--success) 72%, transparent);
  --cc-option-border-width: calc(var(--mc-border-thin) * 1.5);
  --cc-option-ink: var(--tone-success-text);
}

/* Turned down — kept, readable, and out of the way. Transparent rather than a
   grey fill: the row is history now, and history should not draw a second block
   of colour beside the answer that was actually given. */
.cc-option[data-state='passed'] {
  --cc-option-bg: transparent;
  --cc-option-border: var(--border-soft);
  --cc-option-ink: var(--text-dim);
}

.cc-option-note {
  font-size: var(--mc-text-caption);
  color: var(--text-faint);
}
/* Inside a chosen or passed pill the note takes that pill's own ink — a
   --text-faint note in a green pill reads as a second, unrelated element. */
.cc-option[data-state='chosen'] .cc-option-note,
.cc-option[data-state='passed'] .cc-option-note {
  color: currentColor;
  opacity: 0.8;
}

@media (prefers-reduced-motion: reduce) {
  .cc-option {
    transition: none;
  }
  .cc-option:hover:enabled {
    transform: none;
  }
}
/* Rotating showcase-prompt overlay for the homepage build box. Painted as a
   ghost layer behind a transparent-placeholder textarea (the native
   `placeholder` attribute can't type char-by-char or carry a caret). Geometry
   MUST mirror the Textarea primitive's own padding / font / line-height so the
   ghost text sits exactly where the user's typed text will. */
.rpp-ghost {
  position: absolute;
  inset: 0;
  pointer-events: none;
  padding: var(--mc-space-2) var(--mc-space-3);
  font-size: var(--mc-text-lead);
  line-height: var(--mc-leading-normal);
  color: var(--text-mid);
  white-space: pre-wrap;
  word-break: break-word;
  overflow: hidden;
}

/* The faint "Try:" lead-in reads the rotating text as a suggestion, not
   pre-filled input. */
.rpp-lead {
  color: var(--text-faint);
}

/* Typewriter caret — a thin accent bar that blinks while typing/holding. */
.rpp-caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  vertical-align: -2px;
  background: rgb(var(--accent));
  /* ~1s caret pulse — a repeating cadence, not a UI transition, so its period
     is the slow transition token (500ms) doubled rather than a raw 1s, and it
     eases with the standard token (a soft blink instead of a hard toggle). */
  animation: rpp-blink calc(var(--mc-motion-duration-slow) * 2) var(--mc-motion-ease-standard) infinite;
}

@keyframes rpp-blink {
  50% { opacity: 0; }
}

/* Motion-sensitive visitors get instant swaps, no typing, no blink. */
@media (prefers-reduced-motion: reduce) {
  .rpp-caret { animation: none; }
}
/* ShowcaseCarousel — the auto-rotating "Others are doing it!" project rail on
   the public homepage. Motion is CSS-only here; the auto-advance timer + the
   pause-on-hover state live in ShowcaseCarousel.tsx.

   All timings/easings/elevation read the --mc-* motion + shadow tokens, so the
   `@media (prefers-reduced-motion: reduce)` block in design-tokens.css already
   collapses every transition to 0ms. The component ADDITIONALLY renders a
   static, non-animated fallback under reduced motion (no timer, no scale), so
   this sheet only ever styles the motion path. */

/* Clips the sliding track horizontally. Vertical padding gives a hovered card
   room to lift + cast its shadow without a scrollbar or a clipped edge. */
.hp-carousel-viewport {
  overflow: hidden;
  padding-block: var(--mc-space-2);
}

/* The card lift. A gentle scale + soft elevation on a spring ease — premium,
   not a pop. `position: relative` + a local z-index (< 30, in-flow, ungoverned
   by the --z-* ladder) lifts the hovered card above its neighbours. */
.hp-carousel-card {
  position: relative;
  z-index: 0;
  border-radius: var(--mc-radius-xl);
  transition:
    transform var(--mc-motion-duration-medium) var(--mc-motion-ease-spring),
    box-shadow var(--mc-motion-duration-medium) var(--mc-motion-ease-standard);
  will-change: transform;
}

.hp-carousel-card:hover {
  transform: scale(1.04);
  box-shadow: var(--mc-shadow-lg);
  z-index: 1;
}
/* ─── Multicode mobile shell ───
   The sticky top bar + fixed bottom nav that MobileLayout.tsx renders. The CSS
   variables (var(--surface-page-bg), var(--text-strong), …) resolve to the `:root` tokens in
   web/src/index.css, so this sheet inherits the design-token system.

   Only the classes MobileLayout ACTUALLY renders live here. This file was
   originally a verbatim port of a static mobile mock, most of which — a full
   content vocabulary (cards / feed / profile / sheet / forms / toasts / pills)
   plus its @keyframes — was never wired to any component and was removed as
   dead CSS. `scripts/check-no-orphan-mobile-css.sh` keeps it that way: every
   `.m-*` class here must have a rendered consumer in web/src. */

body.mobile { max-width: 480px; margin: 0 auto;
  border-left: 1px solid var(--border-soft);
  border-right: 1px solid var(--border-soft);
  font-size: var(--mc-text-body); min-height: 100vh; overscroll-behavior: none; }

/* Top bar — chrome only. The horizontal arrangement (brand · title · action)
   is a <Cluster> in MobileLayout.tsx; this rule owns sticky/border/padding and
   the data-surface="frame" ground, never the flex row. */
.m-topbar { position: sticky; top: 0; z-index: var(--z-sticky);
  border-bottom: 1px solid var(--border-soft);
  padding: 14px 18px 12px; }
/* raw-layout-ok: single-glyph centering box (28×28 brand mark) — grid, not
   sibling rhythm; rungs 1-2 (Stack/Cluster) model multi-child rhythm only. */
.m-logo { width: 28px; height: 28px; border-radius: 7px;
  background: linear-gradient(135deg, var(--mobileshell-accent), var(--mobileshell-accent-alt));
  display: grid; place-items: center;
  font-weight: 700; color: var(--mobileshell-oncolor); font-size: var(--mc-text-lead); flex-shrink: 0; }
.m-title { flex: 1; min-width: 0; }
.m-title .t { font-size: var(--mc-text-lead); font-weight: 600; color: var(--text-strong); }

.m-main { padding-bottom: 96px; }

/* Lift the fixed-bottom UpdateAvailableBanner above the bottom nav on mobile:
   both sit on the bottom edge at --z-banner, so equal z-index makes the
   later-in-DOM nav paint over the banner. Matches .m-main's reserved nav
   footprint (96px). Desktop has no nav → the banner's 0px fallback applies. */
body.mobile { --updatebanner-bottom: 96px; }

/* Bottom nav */
/* role-ground-ok: translucent page SCRIM, not a page region — the bar is 92%
   page over whatever scrolls beneath it and the backdrop blur is the effect;
   an opaque ground would erase both. Same disposition as MaintenanceOverlay's
   viewport scrim. The rail's ink comes from the shell it sits in. */
.m-nav { position: fixed; bottom: 0; left: 0; right: 0; z-index: var(--z-banner);
  max-width: 480px; margin: 0 auto;
  background: color-mix(in srgb, var(--surface-page-bg) 92%, transparent); backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0px); }
/* raw-layout-ok: grid track list — five equal-width nav cells, distribution not
   gap rhythm; Grid is deliberately not modeled by Stack/Cluster (rung 4). */
.m-nav-row { display: grid; grid-template-columns: repeat(5, 1fr); }
/* Chrome only. Each item holds its single child — the icon+label <Stack> in
   MobileLayout.tsx owns the vertical rhythm. `place-items: start center` keeps
   the content top-aligned (as the prior flex-column justify-content:start did),
   so a taller sibling (the raised [+]) never re-centers the shorter cells.
   raw-layout-ok: single-child placement (grid place-items) — not sibling rhythm. */
.m-nav-item { background: none; border: none;
  padding: 10px 0 12px; display: grid; place-items: start center;
  color: var(--text-dim);
  text-decoration: none; font-family: inherit; cursor: pointer; }
.m-nav-item.on { color: var(--text-strong); }
/* raw-layout-ok: single-glyph centering box — grid, not sibling rhythm. */
.m-nav-item .ic { width: 28px; height: 28px;
  display: grid; place-items: center; font-size: var(--mc-text-lead); }
.m-nav-item.on .ic { color: var(--mobileshell-accent); }
.m-nav-item .lbl { font-size: var(--mc-text-caption); }
.m-nav-item.on .lbl { font-weight: 600; }
/* raw-layout-ok: single-glyph centering box (raised FAB) — grid, not rhythm. */
/* The negative offset lifts the FAB out of the nav bar so it reads as raised. */
/* margin-ok: self-positioning claim on its own box, like an auto margin. */
.m-nav-plus { width: 46px; height: 46px; margin-top: -22px;
  border-radius: 50%; background: var(--mobileshell-accent); color: var(--mobileshell-oncolor);
  display: grid; place-items: center;
  font-size: var(--mc-text-title); font-weight: 700; text-decoration: none;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--mobileshell-accent) 35%, transparent), 0 0 0 4px var(--surface-page-bg); }
/* MC-317 — floating direct-chat windows. Colors come from the design theme
   variables only (the avatar background is the sole exception, set inline from
   avatarColorFor, matching the Online Now rail convention). */

.chat-window-container {
  position: fixed;
  bottom: 0;
  right: 16px;
  /* raw-layout-ok: fixed floating-window rail — row-reverse, viewport-edge-anchored (runtime overlay position); Cluster models neither reverse nor the fixed anchor (rung 4 ruled out) */
  display: flex;
  flex-direction: row-reverse;
  align-items: flex-end;
  gap: 8px;
  z-index: var(--z-modal);
  pointer-events: none;
}

/* The header's height is a socket rather than a literal because it has to track
   the close button inside it. That control is an `IconButton`, so it reads
   `--mc-control-sm`, which the coarse-pointer block in design-tokens.css raises
   to the 44px touch floor — a header pinned at 40px would clip it. One value,
   declared here, consumed by both the header and the minimized window, so the
   two cannot drift apart. */
.chat-window {
  --directchat-header-h: 40px;
  pointer-events: auto;
  width: 240px;
  height: 320px;
  /* raw-layout-ok: shell column — header + grow scroll region + input meet with no inter-child rhythm gap; SpaceStep has no 0 (rungs 1–2 ruled out) */
  display: flex;
  flex-direction: column;
  background: var(--surface-panel-bg);
  border: 1px solid var(--border);
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  box-shadow: var(--directchat-shadow);
  overflow: hidden;
  font-size: var(--mc-text-body);
}

.chat-window.minimized {
  height: var(--directchat-header-h);
}

/* A thumb needs a bigger box than a mouse, and the window is only reachable by
   thumb since the container started mounting on both shells. The primitives
   inside already grow — Button/IconButton/Input all read `--mc-control-*`,
   which design-tokens.css raises to 44px under `pointer: coarse`. What did NOT
   grow was the header they sit in, so the bump alone would have clipped the
   close button rather than enlarging it. */
@media (pointer: coarse) {
  .chat-window {
    --directchat-header-h: 52px;
  }
}

/* Narrow viewports get the same windows, fitted rather than redesigned.
   Three 240px windows side by side need 736px, so on a 390px screen the stack
   renders two of them off the left edge — present in the DOM, unreachable to a
   thumb. Under the shell breakpoint the newest conversation takes the full
   width and its siblings are hidden; they are still open, and re-appear one at
   a time as each is closed.

   The bottom offset clears MobileLayout's fixed .m-nav rail, which the desktop
   shell has no equivalent of — a window flush to `bottom: 0` would bury its own
   input row under the nav.

   This is a fit, not the answer. A full-screen chat route is the right shape
   for a phone; until that exists, a usable floating window is the difference
   between a reachable feature and none. */
@media (max-width: 767px) {
  .chat-window-container {
    left: 0;
    right: 0;
    bottom: 56px;
    padding: 0 8px;
  }

  .chat-window-container > :not(:last-child) {
    display: none;
  }

  .chat-window {
    width: 100%;
    height: min(60vh, 420px);
  }
}

.chat-window-header {
  height: var(--directchat-header-h);
  min-height: var(--directchat-header-h);
  padding: 0 8px;
  background: var(--surface-field-bg);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

.chat-window-name {
  flex: 1;
  font-size: var(--mc-text-body);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-window-unread {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--directchat-unread-bg);
  color: var(--directchat-unread-ink);
  font-size: var(--mc-text-caption);
  font-weight: 600;
  /* raw-layout-ok: single-glyph centring box — the unread count badge, one child centred, not sibling rhythm (rungs 1–4 ruled out) */
  display: flex;
  align-items: center;
  justify-content: center;
}

.chat-window-messages {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.chat-message {
  max-width: 80%;
  padding: 5px 9px;
  border-radius: 12px;
  font-size: var(--mc-text-body);
  line-height: 1.3;
  word-break: break-word;
}

/* A GROUND token as ink is correct only for a NEUTRAL fill, whose fill is a
   ramp rung — theme-schema.ts says exactly that, and omits `neutral` from the
   oncolor family for it. The accent is not a ramp rung, so reading the page
   ground here tracked the PAGE rather than the fill underneath: fine on a dark
   theme where the two agree, 1.83:1 on meadow, whose page is a light mint and
   whose accent is pink.

   The bubble is a coloured FILL — not a control, not a surface — which is the
   domain the theme files give --on-accent: "imagery or coloured fills, not
   surfaces". It is theme-constant by design and graded against --accent by
   accentGroundPairs. Its sibling --tone-brand-oncolor is the CONTROL ink and
   is per-theme declarable; both are black today, and theme-pairs.ts records
   that a theme is free to declare them differently, so picking by what the
   element IS rather than by today's value is what keeps this correct after a
   theme moves one of them. Reached through a --directchat-* handle, the way
   the unread badge already does. */
.chat-message.own {
  align-self: flex-end;
  background: var(--directchat-accent);
  color: var(--directchat-own-ink);
}

.chat-message.peer {
  align-self: flex-start;
  background: var(--surface-panel-bg-2);
  color: var(--text);
}

.chat-message.pending {
  opacity: 0.6;
}

.chat-window-empty {
  margin: auto;
  font-size: var(--mc-text-caption);
  color: var(--text-dim);
}

.chat-window-input-row {
  padding: 8px;
  border-top: 1px solid var(--border);
}

.chat-window-input {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  /* No font-size: this class rides the `Input` primitive, whose inline style
     sets `lead` and always wins over a stylesheet rule. A declaration here
     would render nothing and read as though the chat field were a step
     smaller than every other field, which is worse than silence. */
  background: var(--surface-page-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
}

.chat-window-input:focus {
  outline: none;
  border-color: var(--directchat-accent);
}

/* MC-412 — design-token (`--mc-*`) layer. MUST stay first: `@import` rules
   precede all other statements, and any `var(--mc-*)` consumer needs the
   tokens defined before it cascades. */
/* ===========================================================================
   MC-412 — Design-token foundation (`--mc-*`).

   The single source of truth for tunable UI *dimensions* — typography scale,
   line-heights, letter-spacing, spacing, control sizes, border radii, border
   widths, font families, motion (duration + easing), and elevation (shadow
   ramp). COLOUR tokens are intentionally NOT here: those live in
   `web/src/index.css` (`--shade-*` palette, roles, semantics). The `--mc-`
   prefix is reserved exclusively for this dimension layer — never reuse an
   existing colour-tier name, and never add a colour LITERAL to this file
   (the shadow ramp's ink is a `var(--shade-*)` reference, which is allowed —
   the literal stays in the palette). See `docs/claude/design-tokens.md` for
   the full catalog + the rules for adding / changing / removing a token.

   This file is imported FIRST by `web/src/index.css` (before `@tailwind base`)
   so every `var(--mc-*)` consumer resolves against a defined value.
   =========================================================================== */

:root {
  /* ── Typography scale (font-size) ──
     Six ROLE steps, reached by scale key (`text-body`) — theme.fontSize is a
     closed replace-key backed 1:1 by these tokens, so a name outside the set
     emits no CSS. Roles, not t-shirt sizes: a role name states where the text
     sits in the reading hierarchy, so an author cannot reflexively reach for
     "small" on body copy. The scale a role name replaces cannot be chosen by
     reflex — that is the point of the vocabulary, and the reason a nine-step
     t-shirt ramp collapsed to six.

     The ratio widens as it climbs (caption→body 1.17, title→heading 1.30,
     heading→display 1.38) — fine distinction in the dense band, coarse in the
     display band, which is what a UI scale needs and an editorial
     constant-ratio scale does not give.

     REM, NOT PX, and this is the whole point of the unit: a px type scale is
     inert against the browser's text-size preference, which is the setting
     assistive-technology guidance actually points low-vision users to. Zoom
     scales layout too and introduces horizontal scroll on a fixed-width
     design; the text-size preference scales only glyphs, which is what a
     reader asking for bigger text is asking for. Spacing, control, radius and
     border tokens deliberately stay px — a 32px control height is a density
     decision the app owns, while glyph size is one the reader owns.

     The baseline is 14px (0.875rem), which is not a judgement call: Primer,
     Carbon, Polaris, Material's body-medium and Tailwind's own `text-sm` all
     land on exactly 0.875rem for body copy. */
  --mc-text-caption: 0.75rem;    /* 12px — dense chrome; the floor */
  --mc-text-body: 0.875rem;      /* 14px — the reading baseline */
  --mc-text-lead: 1rem;          /* 16px — section + card titles */
  --mc-text-title: 1.25rem;      /* 20px — page headings */
  --mc-text-heading: 1.625rem;   /* 26px — above a page heading, below display */
  --mc-text-display: 2.25rem;    /* 36px — largest display type */

  /* NOT a step on the scale above, and px on purpose while every step is rem.
     This is WCAG 1.4.3's large-text threshold — the size at or above which an
     ink is graded at 3:1 instead of 4.5:1 — and the provision is defined in
     absolute terms, so a rem value could not express it.

     It exists because the display register makes a claim the register itself
     cannot check. `registerFor` in utils/theme-schema.ts returns `display` for
     a token, not for a call site, and DISPLAY_MIN_RATIO's contract is that a
     rung enters that register "only when it is large BY CONSTRUCTION at every
     site that reads it". A rem size does not satisfy that on its own: the root
     is `font-size: 100%`, so a reader's text-size preference can carry any
     step below 24px and silently move the ink to a bar it does not meet.

     A display-register site therefore floors its size against this token —
     `max(var(--mc-text-heading), var(--mc-text-large-floor))` — which clamps
     DOWNWARD only. A reader enlarging text is untouched and the size grows
     normally; the floor binds solely below a ~14.77px root, where the register
     would otherwise break. That is a deliberate bound on the reader-owns-glyph
     -size principle stated above, taken only where it collides with the
     contrast contract and only in the direction that carries no access need.

     Kept equal to DISPLAY_MIN_RATIO's stated threshold by hand: CSS cannot
     import the TS constant, the same restatement tailwind.config.js makes for
     SHELL_BREAKPOINT_PX. */
  --mc-text-large-floor: 24px;


  /* ── Line heights ── */
  --mc-leading-tight: 1.2;
  --mc-leading-normal: 1.4;
  --mc-leading-relaxed: 1.6;

  /* ── Letter spacing ── */
  --mc-tracking-tight: -0.01em;
  --mc-tracking-normal: 0;
  /* Mild spread on running text (banner copy, a pill label). 0.025em is
     Tailwind's own `wide`, and it is what the old 0.3px already rendered at the
     12px caption these sites cluster on — so the value is the published one and
     the pixel result is unchanged where it was tuned. In em for the same reason
     as `-label` below: the spread tracks the size it separates. */
  --mc-tracking-wide: 0.025em;
  /* All-caps micro-label spread (e.g. "STARTER", "STOREFRONT API
     PERMISSIONS"). The role was already in the tree twice: 29 sites reached it
     through Tailwind's `wider` (0.05em) and 7 through this token (2px), four
     times apart. Converged on the majority rendering, and on em, so the spread
     tracks the size it separates instead of staying fixed while the type moves. */
  --mc-tracking-label: 0.05em;

  /* ── Spacing scale (base-4 grid) ── */
  --mc-space-1: 4px;
  --mc-space-2: 8px;
  --mc-space-3: 12px;
  --mc-space-4: 16px;
  --mc-space-5: 20px;
  --mc-space-6: 24px;
  --mc-space-7: 28px;
  --mc-space-8: 32px;
  --mc-space-9: 36px;
  --mc-space-10: 40px;
  /* Half-steps — the app also uses a 2px sub-grid (6/10/14/18px are heavily
     used for dense card/feed chrome). Named as .5 steps between the base-4
     stops so the grid stays legible. */
  --mc-space-0-5: 2px;
  --mc-space-1-5: 6px;
  --mc-space-2-5: 10px;
  --mc-space-3-5: 14px;
  --mc-space-4-5: 18px;

  /* ── Control heights (button / input) ── */
  --mc-control-xs: 20px;
  --mc-control-sm: 28px;
  --mc-control-md: 32px;
  --mc-control-lg: 36px;

  /* ── Icon glyph sizes ──
     The closed size scale for the Icon primitive — a glyph's own box, distinct
     from --mc-control-* (the button/input box an icon sits INSIDE). Seeded from
     the pre-Icon inline-SVG population's dominant w-/h- cluster, whose values
     resolve through the --mc-space-* scale: w-3=12, w-3.5=14, w-4=16, w-5=20,
     w-6=24. The Icon primitive reads these inline (like IconButton's control
     box), so there is no tailwind utility for them — the closed IconSize union
     is the only door. */
  --mc-icon-xs: 12px;
  --mc-icon-sm: 14px;
  --mc-icon-md: 16px;
  --mc-icon-lg: 20px;
  --mc-icon-xl: 24px;

  /* ── Border radii ── */
  --mc-radius-xs: 4px;
  --mc-radius-sm: 6px;
  --mc-radius-md: 10px;
  --mc-radius-lg: 12px;
  --mc-radius-xl: 14px;
  --mc-radius-pill: 9999px;

  /* ── Border widths ── */
  --mc-border-thin: 1px;
  --mc-border-thick: 3px;

  /* ── Motion: durations ──
     The four-step timing scale every transition/animation resolves through.
     `fast` deliberately equals Tailwind's default transition duration (150ms)
     so the tailwind.config.js repoint is value-identical for the default-timed
     `transition-*` utilities. The root `prefers-reduced-motion` rule zeros
     these four tokens — that single override is how the whole app dampens; a
     timing that must survive reduced motion (spin/pulse progress indicators)
     must NOT read these tokens. */
  --mc-motion-duration-instant: 0ms;
  --mc-motion-duration-fast: 150ms;
  --mc-motion-duration-medium: 300ms;
  --mc-motion-duration-slow: 500ms;

  /* ── Motion: easings ──
     `standard` is Tailwind's default ease (their `ease-in-out`); `decelerate`
     is their `ease-out` (entrances), `accelerate` their `ease-in` (exits).
     `spring` is the overshoot curve the mobile bottom-sheet already used —
     promoted from a hand-rolled literal to the named token. */
  --mc-motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --mc-motion-ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
  --mc-motion-ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
  --mc-motion-ease-spring: cubic-bezier(0.22, 1, 0.36, 1);

  /* ── Elevation: shadow ramp ──
     Four z-axis steps. Geometry is seeded from Tailwind's default md/lg/xl/2xl
     boxShadow values (the de-facto ramp the app already rendered), shifted
     down one name: our sm=their md … our xl=their 2xl, because the app's
     elevated surfaces start at their lg. Ink is `rgb(var(--shade-black) / a)`
     — palette-derived, so the values are var()-carrying and the DesignOverlay
     surfaces them read-only (elevation retunes by re-pointing, not text
     editing). Rings and glows (--shadow-focus-ring, --shadow-feed-glow in
     index.css) are NOT elevation and stay outside the ramp. */
  --mc-shadow-sm: 0 4px 6px -1px rgb(var(--shade-black) / 0.1), 0 2px 4px -2px rgb(var(--shade-black) / 0.1);
  --mc-shadow-md: 0 10px 15px -3px rgb(var(--shade-black) / 0.1), 0 4px 6px -4px rgb(var(--shade-black) / 0.1);
  --mc-shadow-lg: 0 20px 25px -5px rgb(var(--shade-black) / 0.1), 0 8px 10px -6px rgb(var(--shade-black) / 0.1);
  --mc-shadow-xl: 0 25px 50px -12px rgb(var(--shade-black) / 0.25);

  /* ── Component dimensions ──
     Off-grid sizes that are still tunable parameters of a specific surface. */
  /* MC-426 — AdminPanel + AdminConsole off-grid layout constraints (formerly
     `min-w-[800px]` / `max-w-[200px]` / `max-h-[80vh]` arbitrary Tailwind
     values + an inline `minHeight: 180px`). Component-coupled per the
     design-tokens convention for one-off dimensions. */
  --mc-admin-table-min-w-lg: 800px;
  --mc-admin-table-min-w-md: 700px;
  --mc-admin-table-min-w-sm: 500px;
  --mc-admin-truncate-max-w: 200px;
  --mc-admin-modal-max-h: 80vh;
  --mc-admin-console-textarea-min-h: 180px;
  /* MC-510 — height of the Agents page's fixed-bottom "Save changes" banner.
     The Projects config table reserves exactly this as bottom padding while the
     banner is visible, so the last row is never occluded. One token keeps the
     two in lockstep. */
  --mc-admin-save-banner-h: 68px;
  /* Page content-column max width (FriendsPage and sibling list pages cap their
     content at this width for readable line lengths). A structural constant, not
     a spacing step. */
  --mc-page-content-max-w: 1120px;
  /* App-shell content-column max width — the single centered container the
     DesktopLayout Outlet + TopBar inner row share, so every routed page (home,
     explore, trending, …) and the header line up to the same left/right edges.
     Wider than the list-page column above (roughly half the side margins). */
  --mc-app-content-max-w: 1520px;
  /* ProjectCard's empty-state minimum height — keeps a card without a preview
     the same height as its populated siblings in the grid. */
  --mc-card-min-h: 280px;
  /* HomeToolbar search-input max width. Same pixel value as --mc-card-min-h but
     a distinct role — never share the token across the two. */
  --mc-toolbar-search-max-w: 280px;
  /* "Start something new" card's plus-glyph display size — a decorative glyph
     between the `title` and `display` roles, deliberately outside the ramp
     because a "+" mark is not text. In px, and staying px, for the same
     reason: it is a drawing sized to its card, not a size a reader has a
     preference about. */
  --mc-newcard-glyph: 30px;
  /* Desktop sidebar fixed width + its two nav-icon box sizes. */
  --mc-sidebar-width: 220px;
  --mc-sidebar-icon: 30px;
  --mc-sidebar-icon-sm: 26px;
  /* Slide-over workspace panel widths (sm breakpoint / lg breakpoint). The lg
     width is the DESKTOP reading width for the toolbar-opened panels (Settings,
     Services, Team, Activity) + the Test-the-app modal — wide enough that plan
     text and feature descriptions don't wrap every few words. It's a max-width
     paired with w-full, so it clamps to the viewport on smaller laptops and the
     mobile bottom sheet (below sm) stays full-width. */
  --mc-panel-w-sm: 420px;
  --mc-panel-w-lg: 760px;
  /* Scrollable log/diff region caps shared by the deploy modal, sync, and
     publish cards. */
  --mc-scroll-region-max-h: 400px;
  --mc-log-view-min-h: 200px;
  --mc-env-key-min-w: 140px;

  /* ── Font families ──
     --mc-font-mono is the identity/default face (self-hosted JetBrains Mono,
     loaded via web/src/styles/fonts.css). --mc-font-sans is the prose companion
     (self-hosted Hanken Grotesk), loaded but applied per-surface by ui-shell;
     the system-sans stack trails as the swap fallback. */
  --mc-font-sans: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mc-font-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
}

/* ===========================================================================
   Overlay z-index ladder (`--z-*`) — the single stacking-order authority.

   Every viewport-level overlay reads its band from this ladder; a raw z-index
   in a component is banned by scripts/check-no-raw-z.sh + the ESLint
   `raw-literals/no-raw-z-index` rule (mirrors the raw-colour floor). Bands are
   a STRICT TOTAL ORDER, low → high; a higher band always paints over a lower
   one. See docs/claude/overlays.md for the family taxonomy this ladder serves.

   IN scope: things that escape normal flow to the viewport (banners, menus,
   toasts, drawers, coach-marks, modals, the dev overlay, the maintenance
   ceiling). OUT of scope: in-flow LOCAL stacking scoped to a positioned parent
   (explore-card decorations, sticky sub-headers, preview-pane layers, dropdowns
   anchored inside a card) — those keep small raw z-index values (< the sticky
   band) and are exempt from the lint.

   The JS modal stack (shared/Modal.tsx) keeps its own numeric MODAL_BASE /
   MODAL_Z_CEILING constants — it needs arithmetic (base + depth·step) a CSS var
   can't express — pinned to `--z-modal` / `--z-maintenance` by comment there.

   Coach-mark note: `--z-coach` sits ABOVE `--z-modal` (its settled "coach
   commands the site" design — raised by overlay-input-system alongside the
   coach's pointer-through + always-exit behaviour), and below `--z-devtool` so
   the design inspector can still inspect the coach.
   =========================================================================== */
:root {
  --z-sticky: 30;      /* app-shell sticky chrome (mobile topbar) */
  --z-banner: 40;      /* persistent edge strips (health / non-admin / notice banners, mobile nav, sticky action footers) */
  --z-menu: 50;        /* anchored popovers / dropdown menus at viewport level */
  --z-toast: 60;       /* transient notifications (above menus — a confirmation never hides behind a dropdown) */
  --z-drawer: 70;      /* slide-overs / bottom sheets + their backdrops */
  --z-modal: 1000;     /* blocking dialog base; Modal climbs +MODAL_TIER_STEP per stack depth */
  --z-coach: 8500;     /* tutorial coach-mark — above modal (commands the site), below the dev/maintenance ceiling */
  --z-devtool-capture: 8999;  /* DesignOverlay inspect capture layer (just under its panel) */
  --z-devtool: 9000;   /* DesignOverlay panel (above the app, below maintenance, so it can inspect any overlay) */
  --z-maintenance: 9999;      /* MaintenanceOverlay — the ceiling; nothing paints at or above it */
}

/* ── Tier 2: component variables (dimensions) ──────────────────────────────
   MC-417 — the dimension half of the two-tier convention. Same rule as the
   colour component vars in index.css: each aliases a Tier-1 `--mc-*` token,
   and the RHS is ALWAYS a `var(--mc-*)` reference, never a raw px/unit
   literal. A component reads its own variable (`border-radius:
   var(--card-radius)`) so the overlay can retune one surface (individual edit)
   or the whole `--mc-*` scale (group edit). Purely additive — no component
   consumes these yet. See docs/claude/design-tokens.md → "Two-tier model". */
:root {
  --btn-radius: var(--mc-radius-sm);
  --card-radius: var(--mc-radius-md);
  --card-padding: var(--mc-space-4);
  --input-radius: var(--mc-radius-sm);
  --select-radius: var(--mc-radius-sm);
}

/* ===========================================================================
   Per-scope overrides — `data-design-scope="<name>"`.

   A container marks itself `data-design-scope="<name>"`; the rules below
   re-point one or more `--mc-*` tokens for that subtree only. CSS custom
   properties inherit, so the override applies to ALL descendants of the
   scoped element (including modals/portals rendered inside it) — keep scope
   markers on leaf-level containers where possible. Catalog each scope in
   `docs/claude/design-tokens.md`.

   Scopes in use:
   - explore — the /explore page (`<main className="main" data-design-scope=
     "explore">` in ExplorePage.tsx). Demonstrates the override mechanism with
     a softer card radius. No descendant currently consumes `--mc-radius-md`
     directly (the explore cards hardcode their radius in index.css), so this
     override is presently presentational-neutral and exists to anchor the
     mechanism + its AC.
   =========================================================================== */
[data-design-scope="explore"] {
  --mc-radius-md: 20px;
}

/* ===========================================================================
   Touch-target override — `@media (pointer: coarse)`.

   The primary input on the device is a fingertip (phone / tablet / touch
   laptop), which cannot land on a 32px control as reliably as a mouse cursor.
   Raise the control-height scale to a >=44px floor so every primitive that
   reads `--mc-control-*` (Button/IconButton/Input) grows under a thumb — no
   per-component edit. `pointer: fine` (mouse/trackpad) never matches this
   block, so desktop keeps the dense 28/32/36 scale above; the swap is input-
   driven, not viewport-driven, and reverts by deleting this block.

   Enforced by the responsive spec (docs/claude/responsive-spec.md): >=44px on
   coarse, <=40px on fine — 36 is where this scale tops out, and the sweep's
   ceiling carries sub-pixel tolerance above it. Placed last so it wins by
   source order when matched.
   =========================================================================== */
@media (pointer: coarse) {
  :root {
    --mc-control-xs: 44px;
    --mc-control-sm: 44px;
    --mc-control-md: 44px;
    --mc-control-lg: 48px;
  }
}

/* ===========================================================================
   Reduced-motion override — `@media (prefers-reduced-motion: reduce)`.

   Honors the OS-level motion preference by zeroing the duration tokens, so
   every transition and every token-keyed animation collapses to an instant
   state change in ONE place — no per-component media queries. Same
   token-override pattern as the touch-target block above.

   Deliberate carve-out: timings that do NOT read the duration tokens keep
   animating — the spin / pulse progress indicators (Tailwind's baked 1s / 2s
   values) and the literal-timed status-pulse cadences. Those convey ongoing
   work, not decoration; an agent that looks frozen mid-deploy is worse for a
   motion-sensitive user than a slow pulse. A new animation joins the
   carve-out by NOT reading `--mc-motion-duration-*` — and forfeits the token
   scale to do so, which keeps the trade explicit.

   scripts/check-no-raw-style-literals.sh fails the build if this block
   disappears (the reduced-motion floor).
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  :root {
    --mc-motion-duration-instant: 0ms;
    --mc-motion-duration-fast: 0ms;
    --mc-motion-duration-medium: 0ms;
    --mc-motion-duration-slow: 0ms;
  }
}
/* Self-hosted brand faces (@font-face for JetBrains Mono + Hanken Grotesk). Must
   precede @tailwind so the families are defined before any consumer cascades. */
/*
 * Self-hosted brand typefaces. The app named JetBrains Mono + Hanken Grotesk in
 * its font stacks but shipped neither — no @font-face, no bundled woff2 — so a
 * visitor without the font installed fell through to their OS default. These
 * rules load both faces from web/public/fonts/ (served at /fonts/*; stable URLs
 * so web/index.html can rel=preload the first-paint weights).
 *
 * Vendored from @fontsource 5.2.8 (via `npm pack`, not a runtime dep): latin
 * subset, weights 400/500/700, normal style. Both families are SIL OFL 1.1 —
 * license text is committed as OFL-HankenGrotesk.txt / OFL-JetBrainsMono.txt
 * beside the woff2s. `font-display: swap` shows the fallback immediately and
 * swaps in the real face on load (no invisible-text flash).
 *
 * JetBrains Mono is the identity/default face. Hanken Grotesk is the prose
 * companion: loaded here, but applied to surfaces by ui-shell — not this file.
 */

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-500.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-700.woff2') format('woff2');
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/hanken-grotesk-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/hanken-grotesk-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/hanken-grotesk-700.woff2') format('woff2');
}

*, ::before, ::after {
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}

::backdrop {
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}

/* ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com *//*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/

*,
::before,
::after {
  box-sizing: border-box; /* 1 */
  border-width: 0; /* 2 */
  border-style: solid; /* 2 */
  border-color: #e5e7eb; /* 2 */
}

::before,
::after {
  --tw-content: '';
}

/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/

html,
:host {
  line-height: 1.5; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
  -moz-tab-size: 4; /* 3 */
  -o-tab-size: 4;
     tab-size: 4; /* 3 */
  font-family: var(--mc-font-sans); /* 4 */
  font-feature-settings: normal; /* 5 */
  font-variation-settings: normal; /* 6 */
  -webkit-tap-highlight-color: transparent; /* 7 */
}

/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/

body {
  margin: 0; /* 1 */
  line-height: inherit; /* 2 */
}

/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/

hr {
  height: 0; /* 1 */
  color: inherit; /* 2 */
  border-top-width: 1px; /* 3 */
}

/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/

abbr:where([title]) {
  -webkit-text-decoration: underline dotted;
          text-decoration: underline dotted;
}

/*
Remove the default font size and weight for headings.
*/

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

/*
Reset links to optimize for opt-in styling instead of opt-out.
*/

a {
  color: inherit;
  text-decoration: inherit;
}

/*
Add the correct font weight in Edge and Safari.
*/

b,
strong {
  font-weight: bolder;
}

/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
*/

code,
kbd,
samp,
pre {
  font-family: var(--mc-font-mono); /* 1 */
  font-feature-settings: normal; /* 2 */
  font-variation-settings: normal; /* 3 */
  font-size: 1em; /* 4 */
}

/*
Add the correct font size in all browsers.
*/

small {
  font-size: 80%;
}

/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/

table {
  text-indent: 0; /* 1 */
  border-color: inherit; /* 2 */
  border-collapse: collapse; /* 3 */
}

/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-feature-settings: inherit; /* 1 */
  font-variation-settings: inherit; /* 1 */
  font-size: 100%; /* 1 */
  font-weight: inherit; /* 1 */
  line-height: inherit; /* 1 */
  letter-spacing: inherit; /* 1 */
  color: inherit; /* 1 */
  margin: 0; /* 2 */
  padding: 0; /* 3 */
}

/*
Remove the inheritance of text transform in Edge and Firefox.
*/

button,
select {
  text-transform: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/

button,
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
  -webkit-appearance: button; /* 1 */
  background-color: transparent; /* 2 */
  background-image: none; /* 2 */
}

/*
Use the modern Firefox focus style for all focusable elements.
*/

:-moz-focusring {
  outline: auto;
}

/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/

:-moz-ui-invalid {
  box-shadow: none;
}

/*
Add the correct vertical alignment in Chrome and Firefox.
*/

progress {
  vertical-align: baseline;
}

/*
Correct the cursor style of increment and decrement buttons in Safari.
*/

::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
  height: auto;
}

/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/

[type='search'] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/*
Remove the inner padding in Chrome and Safari on macOS.
*/

::-webkit-search-decoration {
  -webkit-appearance: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/*
Add the correct display in Chrome and Safari.
*/

summary {
  display: list-item;
}

/*
Removes the default spacing and border for appropriate elements.
*/

blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}

fieldset {
  margin: 0;
  padding: 0;
}

legend {
  padding: 0;
}

ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

/*
Reset default styling for dialogs.
*/
dialog {
  padding: 0;
}

/*
Prevent resizing textareas horizontally by default.
*/

textarea {
  resize: vertical;
}

/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/

input::-moz-placeholder, textarea::-moz-placeholder {
  opacity: 1; /* 1 */
  color: rgb(var(--shade-gray-400) / 1); /* 2 */
}

input::placeholder,
textarea::placeholder {
  opacity: 1; /* 1 */
  color: rgb(var(--shade-gray-400) / 1); /* 2 */
}

/*
Set the default cursor for buttons.
*/

button,
[role="button"] {
  cursor: pointer;
}

/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
  cursor: default;
}

/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
   This can trigger a poorly considered lint error in some tools but is included by design.
*/

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block; /* 1 */
  vertical-align: middle; /* 2 */
}

/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/

img,
video {
  max-width: 100%;
  height: auto;
}

/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden]:where(:not([hidden="until-found"])) {
  display: none;
}
.\!container {
  width: 100% !important;
}
.container {
  width: 100%;
}
@media (min-width: 640px) {

  .\!container {
    max-width: 640px !important;
  }

  .container {
    max-width: 640px;
  }
}
@media (min-width: 768px) {

  .\!container {
    max-width: 768px !important;
  }

  .container {
    max-width: 768px;
  }
}
@media (min-width: 1024px) {

  .\!container {
    max-width: 1024px !important;
  }

  .container {
    max-width: 1024px;
  }
}
@media (min-width: 1280px) {

  .\!container {
    max-width: 1280px !important;
  }

  .container {
    max-width: 1280px;
  }
}
@media (min-width: 1536px) {

  .\!container {
    max-width: 1536px !important;
  }

  .container {
    max-width: 1536px;
  }
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.pointer-events-none {
  pointer-events: none;
}
.visible {
  visibility: visible;
}
.invisible {
  visibility: hidden;
}
.collapse {
  visibility: collapse;
}
.static {
  position: static;
}
.fixed {
  position: fixed;
}
.absolute {
  position: absolute;
}
.relative {
  position: relative;
}
.sticky {
  position: sticky;
}
.inset-0 {
  inset: 0px;
}
.inset-y-0 {
  top: 0px;
  bottom: 0px;
}
.-bottom-0\.5 {
  bottom: calc(var(--mc-space-0-5) * -1);
}
.-left-1 {
  left: calc(var(--mc-space-1) * -1);
}
.-right-0\.5 {
  right: calc(var(--mc-space-0-5) * -1);
}
.-right-1 {
  right: calc(var(--mc-space-1) * -1);
}
.-top-1 {
  top: calc(var(--mc-space-1) * -1);
}
.-top-2\.5 {
  top: calc(var(--mc-space-2-5) * -1);
}
.bottom-0 {
  bottom: 0px;
}
.bottom-2 {
  bottom: var(--mc-space-2);
}
.bottom-4 {
  bottom: var(--mc-space-4);
}
.bottom-full {
  bottom: 100%;
}
.left-0 {
  left: 0px;
}
.left-1\/2 {
  left: 50%;
}
.left-2 {
  left: var(--mc-space-2);
}
.left-4 {
  left: var(--mc-space-4);
}
.right-0 {
  right: 0px;
}
.right-1 {
  right: var(--mc-space-1);
}
.right-2 {
  right: var(--mc-space-2);
}
.right-4 {
  right: var(--mc-space-4);
}
.top-0 {
  top: 0px;
}
.top-1 {
  top: var(--mc-space-1);
}
.top-1\/2 {
  top: 50%;
}
.top-2 {
  top: var(--mc-space-2);
}
.top-4 {
  top: var(--mc-space-4);
}
.top-6 {
  top: var(--mc-space-6);
}
.top-7 {
  top: var(--mc-space-7);
}
.z-10 {
  z-index: 10;
}
.z-20 {
  z-index: 20;
}
.z-\[var\(--z-banner\)\] {
  z-index: var(--z-banner);
}
.z-\[var\(--z-maintenance\)\] {
  z-index: var(--z-maintenance);
}
.z-\[var\(--z-menu\)\] {
  z-index: var(--z-menu);
}
.z-\[var\(--z-toast\)\] {
  z-index: var(--z-toast);
}
.m-0 {
  margin: 0px;
}
.m-2 {
  margin: var(--mc-space-2);
}
.-mx-1 {
  margin-left: calc(var(--mc-space-1) * -1);
  margin-right: calc(var(--mc-space-1) * -1);
}
.mx-0\.5 {
  margin-left: var(--mc-space-0-5);
  margin-right: var(--mc-space-0-5);
}
.mx-auto {
  margin-left: auto;
  margin-right: auto;
}
.-mr-1\.5 {
  margin-right: calc(var(--mc-space-1-5) * -1);
}
.-mt-0\.5 {
  margin-top: calc(var(--mc-space-0-5) * -1);
}
.mb-1 {
  margin-bottom: var(--mc-space-1);
}
.mb-2 {
  margin-bottom: var(--mc-space-2);
}
.mb-3 {
  margin-bottom: var(--mc-space-3);
}
.ml-1 {
  margin-left: var(--mc-space-1);
}
.ml-1\.5 {
  margin-left: var(--mc-space-1-5);
}
.ml-2 {
  margin-left: var(--mc-space-2);
}
.ml-5 {
  margin-left: var(--mc-space-5);
}
.ml-\[148px\] {
  margin-left: 148px;
}
.ml-auto {
  margin-left: auto;
}
.mr-1 {
  margin-right: var(--mc-space-1);
}
.mr-auto {
  margin-right: auto;
}
.mt-0\.5 {
  margin-top: var(--mc-space-0-5);
}
.mt-1 {
  margin-top: var(--mc-space-1);
}
.mt-1\.5 {
  margin-top: var(--mc-space-1-5);
}
.mt-2 {
  margin-top: var(--mc-space-2);
}
.mt-3 {
  margin-top: var(--mc-space-3);
}
.mt-auto {
  margin-top: auto;
}
.mt-px {
  margin-top: 1px;
}
.line-clamp-2 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.block {
  display: block;
}
.inline-block {
  display: inline-block;
}
.inline {
  display: inline;
}
.flex {
  display: flex;
}
.inline-flex {
  display: inline-flex;
}
.table {
  display: table;
}
.table-column {
  display: table-column;
}
.grid {
  display: grid;
}
.inline-grid {
  display: inline-grid;
}
.contents {
  display: contents;
}
.list-item {
  display: list-item;
}
.hidden {
  display: none;
}
.h-1 {
  height: var(--mc-space-1);
}
.h-1\.5 {
  height: var(--mc-space-1-5);
}
.h-10 {
  height: var(--mc-space-10);
}
.h-12 {
  height: 48px;
}
.h-14 {
  height: 56px;
}
.h-16 {
  height: 64px;
}
.h-2 {
  height: var(--mc-space-2);
}
.h-2\.5 {
  height: var(--mc-space-2-5);
}
.h-3 {
  height: var(--mc-space-3);
}
.h-3\.5 {
  height: var(--mc-space-3-5);
}
.h-4 {
  height: var(--mc-space-4);
}
.h-5 {
  height: var(--mc-space-5);
}
.h-6 {
  height: var(--mc-space-6);
}
.h-7 {
  height: var(--mc-space-7);
}
.h-8 {
  height: var(--mc-space-8);
}
.h-84 {
  height: 336px;
}
.h-full {
  height: 100%;
}
.h-px {
  height: 1px;
}
.max-h-48 {
  max-height: 192px;
}
.max-h-56 {
  max-height: 224px;
}
.max-h-60 {
  max-height: 240px;
}
.max-h-96 {
  max-height: 384px;
}
.max-h-\[60vh\] {
  max-height: 60vh;
}
.max-h-\[70vh\] {
  max-height: 70vh;
}
.max-h-\[80vh\] {
  max-height: 80vh;
}
.max-h-\[85vh\] {
  max-height: 85vh;
}
.max-h-\[90vh\] {
  max-height: 90vh;
}
.max-h-\[var\(--mc-admin-modal-max-h\)\] {
  max-height: var(--mc-admin-modal-max-h);
}
.max-h-\[var\(--mc-scroll-region-max-h\)\] {
  max-height: var(--mc-scroll-region-max-h);
}
.min-h-0 {
  min-height: 0px;
}
.min-h-\[2rem\] {
  min-height: 2rem;
}
.min-h-\[50vh\] {
  min-height: 50vh;
}
.min-h-\[var\(--mc-control-sm\)\] {
  min-height: var(--mc-control-sm);
}
.min-h-\[var\(--mc-log-view-min-h\)\] {
  min-height: var(--mc-log-view-min-h);
}
.min-h-screen {
  min-height: 100vh;
}
.w-1 {
  width: var(--mc-space-1);
}
.w-1\.5 {
  width: var(--mc-space-1-5);
}
.w-10 {
  width: var(--mc-space-10);
}
.w-12 {
  width: 48px;
}
.w-14 {
  width: 56px;
}
.w-16 {
  width: 64px;
}
.w-2 {
  width: var(--mc-space-2);
}
.w-2\.5 {
  width: var(--mc-space-2-5);
}
.w-20 {
  width: 80px;
}
.w-3 {
  width: var(--mc-space-3);
}
.w-3\.5 {
  width: var(--mc-space-3-5);
}
.w-36 {
  width: 144px;
}
.w-4 {
  width: var(--mc-space-4);
}
.w-40 {
  width: 160px;
}
.w-44 {
  width: 176px;
}
.w-48 {
  width: 192px;
}
.w-5 {
  width: var(--mc-space-5);
}
.w-56 {
  width: 224px;
}
.w-6 {
  width: var(--mc-space-6);
}
.w-7 {
  width: var(--mc-space-7);
}
.w-72 {
  width: 288px;
}
.w-8 {
  width: var(--mc-space-8);
}
.w-80 {
  width: 320px;
}
.w-9 {
  width: var(--mc-space-9);
}
.w-\[28rem\] {
  width: 28rem;
}
.w-auto {
  width: auto;
}
.w-full {
  width: 100%;
}
.w-px {
  width: 1px;
}
.min-w-0 {
  min-width: 0px;
}
.min-w-4 {
  min-width: var(--mc-space-4);
}
.min-w-\[18rem\] {
  min-width: 18rem;
}
.min-w-\[var\(--mc-admin-table-min-w-lg\)\] {
  min-width: var(--mc-admin-table-min-w-lg);
}
.min-w-\[var\(--mc-admin-table-min-w-md\)\] {
  min-width: var(--mc-admin-table-min-w-md);
}
.min-w-\[var\(--mc-admin-table-min-w-sm\)\] {
  min-width: var(--mc-admin-table-min-w-sm);
}
.min-w-\[var\(--mc-env-key-min-w\)\] {
  min-width: var(--mc-env-key-min-w);
}
.max-w-2xl {
  max-width: 672px;
}
.max-w-5xl {
  max-width: 1024px;
}
.max-w-6xl {
  max-width: 1152px;
}
.max-w-\[12rem\] {
  max-width: 12rem;
}
.max-w-\[90vw\] {
  max-width: 90vw;
}
.max-w-\[var\(--mc-admin-truncate-max-w\)\] {
  max-width: var(--mc-admin-truncate-max-w);
}
.max-w-full {
  max-width: 100%;
}
.max-w-lg {
  max-width: 512px;
}
.max-w-md {
  max-width: 448px;
}
.max-w-sm {
  max-width: 384px;
}
.max-w-xl {
  max-width: 576px;
}
.max-w-xs {
  max-width: 320px;
}
.flex-1 {
  flex: 1 1 0%;
}
.flex-none {
  flex: none;
}
.flex-shrink {
  flex-shrink: 1;
}
.flex-shrink-0 {
  flex-shrink: 0;
}
.shrink {
  flex-shrink: 1;
}
.shrink-0 {
  flex-shrink: 0;
}
.flex-grow {
  flex-grow: 1;
}
.grow {
  flex-grow: 1;
}
.-translate-x-1\/2 {
  --tw-translate-x: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-x-full {
  --tw-translate-x: -100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2 {
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-full {
  --tw-translate-y: -100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-0 {
  --tw-translate-x: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-1 {
  --tw-translate-x: var(--mc-space-1);
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-5 {
  --tw-translate-x: var(--mc-space-5);
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-full {
  --tw-translate-x: 100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-0 {
  --tw-translate-y: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-full {
  --tw-translate-y: 100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-rotate-90 {
  --tw-rotate: -90deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-180 {
  --tw-rotate: 180deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-90 {
  --tw-rotate: 90deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-105 {
  --tw-scale-x: 1.05;
  --tw-scale-y: 1.05;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.animate-\[statusPulse_2s_ease-in-out_infinite\] {
  animation: statusPulse 2s ease-in-out infinite;
}
@keyframes ping {

  75%, 100% {
    transform: scale(2);
    opacity: 0;
  }
}
.animate-ping {
  animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes pulse {

  50% {
    opacity: .5;
  }
}
.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes spin {

  to {
    transform: rotate(360deg);
  }
}
.animate-spin {
  animation: spin 1s linear infinite;
}
.cursor-col-resize {
  cursor: col-resize;
}
.cursor-default {
  cursor: default;
}
.cursor-grab {
  cursor: grab;
}
.cursor-grabbing {
  cursor: grabbing;
}
.cursor-not-allowed {
  cursor: not-allowed;
}
.cursor-pointer {
  cursor: pointer;
}
.cursor-wait {
  cursor: wait;
}
.select-none {
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.select-text {
  -webkit-user-select: text;
     -moz-user-select: text;
          user-select: text;
}
.select-all {
  -webkit-user-select: all;
     -moz-user-select: all;
          user-select: all;
}
.resize-none {
  resize: none;
}
.resize-y {
  resize: vertical;
}
.resize {
  resize: both;
}
.list-inside {
  list-style-position: inside;
}
.list-disc {
  list-style-type: disc;
}
.grid-flow-col {
  grid-auto-flow: column;
}
.grid-cols-1 {
  grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-cols-\[1fr_100px_80px_80px_80px_80px_80px_80px_80px_40px\] {
  grid-template-columns: 1fr 100px 80px 80px 80px 80px 80px 80px 80px 40px;
}
.grid-cols-\[80px_120px_70px_100px_80px\] {
  grid-template-columns: 80px 120px 70px 100px 80px;
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(15rem\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(15rem,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(18rem\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(18rem,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(220px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(220px,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(22rem\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(22rem,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(240px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(240px,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(8rem\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(8rem,1fr));
}
.grid-cols-\[repeat\(auto-fill\2c minmax\(9rem\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(9rem,1fr));
}
.flex-col {
  flex-direction: column;
}
.flex-wrap {
  flex-wrap: wrap;
}
.place-items-center {
  place-items: center;
}
.items-start {
  align-items: flex-start;
}
.items-end {
  align-items: flex-end;
}
.items-center {
  align-items: center;
}
.items-baseline {
  align-items: baseline;
}
.items-stretch {
  align-items: stretch;
}
.justify-start {
  justify-content: flex-start;
}
.justify-end {
  justify-content: flex-end;
}
.justify-center {
  justify-content: center;
}
.justify-between {
  justify-content: space-between;
}
.justify-items-start {
  justify-items: start;
}
.justify-items-end {
  justify-items: end;
}
.justify-items-center {
  justify-items: center;
}
.gap-0\.5 {
  gap: var(--mc-space-0-5);
}
.gap-1 {
  gap: var(--mc-space-1);
}
.gap-1\.5 {
  gap: var(--mc-space-1-5);
}
.gap-10 {
  gap: var(--mc-space-10);
}
.gap-2 {
  gap: var(--mc-space-2);
}
.gap-2\.5 {
  gap: var(--mc-space-2-5);
}
.gap-3 {
  gap: var(--mc-space-3);
}
.gap-3\.5 {
  gap: var(--mc-space-3-5);
}
.gap-4 {
  gap: var(--mc-space-4);
}
.gap-4\.5 {
  gap: var(--mc-space-4-5);
}
.gap-5 {
  gap: var(--mc-space-5);
}
.gap-6 {
  gap: var(--mc-space-6);
}
.gap-7 {
  gap: var(--mc-space-7);
}
.gap-8 {
  gap: var(--mc-space-8);
}
.gap-9 {
  gap: var(--mc-space-9);
}
.gap-x-3 {
  -moz-column-gap: var(--mc-space-3);
       column-gap: var(--mc-space-3);
}
.gap-y-0\.5 {
  row-gap: var(--mc-space-0-5);
}
.-space-x-1\.5 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-x-reverse: 0;
  margin-right: calc(calc(var(--mc-space-1-5) * -1) * var(--tw-space-x-reverse));
  margin-left: calc(calc(var(--mc-space-1-5) * -1) * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-1 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(var(--mc-space-1) * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(var(--mc-space-1) * var(--tw-space-y-reverse));
}
.divide-y > :not([hidden]) ~ :not([hidden]) {
  --tw-divide-y-reverse: 0;
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
}
.divide-theme-border > :not([hidden]) ~ :not([hidden]) {
  --tw-divide-opacity: 1;
  border-color: rgb(var(--line-panel) / var(--tw-divide-opacity, 1));
}
.self-start {
  align-self: flex-start;
}
.self-center {
  align-self: center;
}
.overflow-auto {
  overflow: auto;
}
.overflow-hidden {
  overflow: hidden;
}
.overflow-clip {
  overflow: clip;
}
.overflow-x-auto {
  overflow-x: auto;
}
.overflow-y-auto {
  overflow-y: auto;
}
.overflow-x-hidden {
  overflow-x: hidden;
}
.scroll-smooth {
  scroll-behavior: smooth;
}
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.whitespace-normal {
  white-space: normal;
}
.whitespace-nowrap {
  white-space: nowrap;
}
.whitespace-pre-wrap {
  white-space: pre-wrap;
}
.break-words {
  overflow-wrap: break-word;
}
.break-all {
  word-break: break-all;
}
.rounded {
  border-radius: 4px;
}
.rounded-2xl {
  border-radius: 16px;
}
.rounded-\[var\(--mc-radius-md\)\] {
  border-radius: var(--mc-radius-md);
}
.rounded-\[var\(--mc-radius-sm\)\] {
  border-radius: var(--mc-radius-sm);
}
.rounded-\[var\(--mc-radius-xs\)\] {
  border-radius: var(--mc-radius-xs);
}
.rounded-full {
  border-radius: 9999px;
}
.rounded-lg {
  border-radius: 8px;
}
.rounded-md {
  border-radius: 6px;
}
.rounded-sm {
  border-radius: 2px;
}
.rounded-xl {
  border-radius: 12px;
}
.rounded-b-lg {
  border-bottom-right-radius: 8px;
  border-bottom-left-radius: 8px;
}
.rounded-b-none {
  border-bottom-right-radius: 0px;
  border-bottom-left-radius: 0px;
}
.rounded-l-lg {
  border-top-left-radius: 8px;
  border-bottom-left-radius: 8px;
}
.rounded-l-none {
  border-top-left-radius: 0px;
  border-bottom-left-radius: 0px;
}
.rounded-r-lg {
  border-top-right-radius: 8px;
  border-bottom-right-radius: 8px;
}
.rounded-r-none {
  border-top-right-radius: 0px;
  border-bottom-right-radius: 0px;
}
.rounded-t-2xl {
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
}
.rounded-t-lg {
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
}
.rounded-t-none {
  border-top-left-radius: 0px;
  border-top-right-radius: 0px;
}
.border {
  border-width: 1px;
}
.border-0 {
  border-width: 0px;
}
.border-2 {
  border-width: 2px;
}
.border-\[1\.5px\] {
  border-width: 1.5px;
}
.border-\[length\:var\(--mc-border-thick\)\] {
  border-width: var(--mc-border-thick);
}
.border-b {
  border-bottom-width: 1px;
}
.border-b-0 {
  border-bottom-width: 0px;
}
.border-b-2 {
  border-bottom-width: 2px;
}
.border-l {
  border-left-width: 1px;
}
.border-l-0 {
  border-left-width: 0px;
}
.border-l-2 {
  border-left-width: 2px;
}
.border-l-4 {
  border-left-width: 4px;
}
.border-r-0 {
  border-right-width: 0px;
}
.border-t {
  border-top-width: 1px;
}
.border-t-0 {
  border-top-width: 0px;
}
.border-dashed {
  border-style: dashed;
}
.\!border-mark-danger {
  border-color: var(--danger-on-ground) !important;
}
.\!border-mark-warning {
  border-color: var(--warning-on-ground) !important;
}
.\!border-status-warning\/50 {
  border-color: rgb(var(--status-warning) / 0.5) !important;
}
.border-accent {
  --tw-border-opacity: 1;
  border-color: rgb(var(--accent) / var(--tw-border-opacity, 1));
}
.border-accent\/20 {
  border-color: rgb(var(--accent) / 0.2);
}
.border-accent\/30 {
  border-color: rgb(var(--accent) / 0.3);
}
.border-accent\/40 {
  border-color: rgb(var(--accent) / 0.4);
}
.border-mark-danger {
  border-color: var(--danger-on-ground);
}
.border-mark-info {
  border-color: var(--info-on-ground);
}
.border-mark-success {
  border-color: var(--success-on-ground);
}
.border-mark-warning {
  border-color: var(--warning-on-ground);
}
.border-status-danger\/20 {
  border-color: rgb(var(--status-danger) / 0.2);
}
.border-status-danger\/30 {
  border-color: rgb(var(--status-danger) / 0.3);
}
.border-status-danger\/40 {
  border-color: rgb(var(--status-danger) / 0.4);
}
.border-status-info\/30 {
  border-color: rgb(var(--status-info) / 0.3);
}
.border-status-success\/20 {
  border-color: rgb(var(--status-success) / 0.2);
}
.border-status-success\/30 {
  border-color: rgb(var(--status-success) / 0.3);
}
.border-status-success\/50 {
  border-color: rgb(var(--status-success) / 0.5);
}
.border-status-warning\/20 {
  border-color: rgb(var(--status-warning) / 0.2);
}
.border-status-warning\/30 {
  border-color: rgb(var(--status-warning) / 0.3);
}
.border-status-warning\/40 {
  border-color: rgb(var(--status-warning) / 0.4);
}
.border-status-warning\/50 {
  border-color: rgb(var(--status-warning) / 0.5);
}
.border-theme-border {
  --tw-border-opacity: 1;
  border-color: rgb(var(--line-panel) / var(--tw-border-opacity, 1));
}
.border-theme-border-alt {
  --tw-border-opacity: 1;
  border-color: rgb(var(--line-panel-alt) / var(--tw-border-opacity, 1));
}
.border-theme-border\/30 {
  border-color: rgb(var(--line-panel) / 0.3);
}
.border-theme-border\/40 {
  border-color: rgb(var(--line-panel) / 0.4);
}
.border-theme-border\/50 {
  border-color: rgb(var(--line-panel) / 0.5);
}
.border-theme-panel {
  --tw-border-opacity: 1;
  border-color: rgb(var(--surface-panel-bg-rgb) / var(--tw-border-opacity, 1));
}
.border-transparent {
  border-color: transparent;
}
.border-l-amber-500 {
  --tw-border-opacity: 1;
  border-left-color: rgb(var(--shade-amber-500) / var(--tw-border-opacity, 1));
}
.border-l-blue-500 {
  --tw-border-opacity: 1;
  border-left-color: rgb(var(--shade-blue-500) / var(--tw-border-opacity, 1));
}
.border-l-emerald-500 {
  --tw-border-opacity: 1;
  border-left-color: rgb(var(--shade-emerald-500) / var(--tw-border-opacity, 1));
}
.border-l-gray-500 {
  --tw-border-opacity: 1;
  border-left-color: rgb(var(--shade-gray-500) / var(--tw-border-opacity, 1));
}
.border-l-purple-500 {
  --tw-border-opacity: 1;
  border-left-color: rgb(var(--shade-purple-500) / var(--tw-border-opacity, 1));
}
.border-t-accent {
  --tw-border-opacity: 1;
  border-top-color: rgb(var(--accent) / var(--tw-border-opacity, 1));
}
.border-t-current {
  border-top-color: currentColor;
}
.border-t-mark-success {
  border-top-color: var(--success-on-ground);
}
.border-t-mark-warning {
  border-top-color: var(--warning-on-ground);
}
.border-t-transparent {
  border-top-color: transparent;
}
.bg-accent {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--accent) / var(--tw-bg-opacity, 1));
}
.bg-accent\/10 {
  background-color: rgb(var(--accent) / 0.1);
}
.bg-accent\/20 {
  background-color: rgb(var(--accent) / 0.2);
}
.bg-accent\/30 {
  background-color: rgb(var(--accent) / 0.3);
}
.bg-accent\/5 {
  background-color: rgb(var(--accent) / 0.05);
}
.bg-accent\/90 {
  background-color: rgb(var(--accent) / 0.9);
}
.bg-accent\/\[0\.03\] {
  background-color: rgb(var(--accent) / 0.03);
}
.bg-black {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--shade-black) / var(--tw-bg-opacity, 1));
}
.bg-black\/0 {
  background-color: rgb(var(--shade-black) / 0);
}
.bg-black\/20 {
  background-color: rgb(var(--shade-black) / 0.2);
}
.bg-black\/30 {
  background-color: rgb(var(--shade-black) / 0.3);
}
.bg-black\/40 {
  background-color: rgb(var(--shade-black) / 0.4);
}
.bg-black\/50 {
  background-color: rgb(var(--shade-black) / 0.5);
}
.bg-black\/60 {
  background-color: rgb(var(--shade-black) / 0.6);
}
.bg-black\/70 {
  background-color: rgb(var(--shade-black) / 0.7);
}
.bg-black\/80 {
  background-color: rgb(var(--shade-black) / 0.8);
}
.bg-green-900\/30 {
  background-color: rgb(var(--shade-green-900) / 0.3);
}
.bg-mark-danger {
  background-color: var(--danger-on-ground);
}
.bg-mark-info {
  background-color: var(--info-on-ground);
}
.bg-mark-stopped {
  background-color: var(--stopped-on-ground);
}
.bg-mark-success {
  background-color: var(--success-on-ground);
}
.bg-mark-warning {
  background-color: var(--warning-on-ground);
}
.bg-status-attention\/10 {
  background-color: rgb(var(--status-attention) / 0.1);
}
.bg-status-danger\/10 {
  background-color: rgb(var(--status-danger) / 0.1);
}
.bg-status-danger\/20 {
  background-color: rgb(var(--status-danger) / 0.2);
}
.bg-status-danger\/5 {
  background-color: rgb(var(--status-danger) / 0.05);
}
.bg-status-danger\/\[0\.08\] {
  background-color: rgb(var(--status-danger) / 0.08);
}
.bg-status-info\/10 {
  background-color: rgb(var(--status-info) / 0.1);
}
.bg-status-info\/20 {
  background-color: rgb(var(--status-info) / 0.2);
}
.bg-status-progress\/10 {
  background-color: rgb(var(--status-progress) / 0.1);
}
.bg-status-stopped\/10 {
  background-color: rgb(var(--status-stopped) / 0.1);
}
.bg-status-success\/10 {
  background-color: rgb(var(--status-success) / 0.1);
}
.bg-status-success\/15 {
  background-color: rgb(var(--status-success) / 0.15);
}
.bg-status-success\/20 {
  background-color: rgb(var(--status-success) / 0.2);
}
.bg-status-success\/5 {
  background-color: rgb(var(--status-success) / 0.05);
}
.bg-status-success\/60 {
  background-color: rgb(var(--status-success) / 0.6);
}
.bg-status-success\/80 {
  background-color: rgb(var(--status-success) / 0.8);
}
.bg-status-warning\/10 {
  background-color: rgb(var(--status-warning) / 0.1);
}
.bg-status-warning\/15 {
  background-color: rgb(var(--status-warning) / 0.15);
}
.bg-status-warning\/20 {
  background-color: rgb(var(--status-warning) / 0.2);
}
.bg-status-warning\/5 {
  background-color: rgb(var(--status-warning) / 0.05);
}
.bg-theme-border {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--line-panel) / var(--tw-bg-opacity, 1));
}
.bg-theme-border-alt {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--line-panel-alt) / var(--tw-bg-opacity, 1));
}
.bg-theme-hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-hover-bg-rgb) / var(--tw-bg-opacity, 1));
}
.bg-theme-hover\/10 {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.1);
}
.bg-theme-hover\/20 {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.2);
}
.bg-theme-hover\/30 {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.3);
}
.bg-theme-hover\/50 {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.5);
}
.bg-theme-hover\/60 {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.6);
}
.bg-theme-input {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-field-bg-rgb) / var(--tw-bg-opacity, 1));
}
.bg-theme-page {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-page-bg-rgb) / var(--tw-bg-opacity, 1));
}
.bg-theme-page\/40 {
  background-color: rgb(var(--surface-page-bg-rgb) / 0.4);
}
.bg-theme-page\/50 {
  background-color: rgb(var(--surface-page-bg-rgb) / 0.5);
}
.bg-theme-page\/95 {
  background-color: rgb(var(--surface-page-bg-rgb) / 0.95);
}
.bg-theme-panel {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-panel-bg-rgb) / var(--tw-bg-opacity, 1));
}
.bg-theme-panel\/50 {
  background-color: rgb(var(--surface-panel-bg-rgb) / 0.5);
}
.bg-transparent {
  background-color: transparent;
}
.bg-white {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--shade-white) / var(--tw-bg-opacity, 1));
}
.bg-white\/20 {
  background-color: rgb(var(--shade-white) / 0.2);
}
.fill-current {
  fill: currentColor;
}
.object-contain {
  -o-object-fit: contain;
     object-fit: contain;
}
.object-cover {
  -o-object-fit: cover;
     object-fit: cover;
}
.object-top {
  -o-object-position: top;
     object-position: top;
}
.p-0 {
  padding: 0px;
}
.p-1 {
  padding: var(--mc-space-1);
}
.p-2 {
  padding: var(--mc-space-2);
}
.p-2\.5 {
  padding: var(--mc-space-2-5);
}
.p-3 {
  padding: var(--mc-space-3);
}
.p-4 {
  padding: var(--mc-space-4);
}
.p-5 {
  padding: var(--mc-space-5);
}
.p-6 {
  padding: var(--mc-space-6);
}
.p-8 {
  padding: var(--mc-space-8);
}
.px-0 {
  padding-left: 0px;
  padding-right: 0px;
}
.px-1 {
  padding-left: var(--mc-space-1);
  padding-right: var(--mc-space-1);
}
.px-1\.5 {
  padding-left: var(--mc-space-1-5);
  padding-right: var(--mc-space-1-5);
}
.px-2 {
  padding-left: var(--mc-space-2);
  padding-right: var(--mc-space-2);
}
.px-2\.5 {
  padding-left: var(--mc-space-2-5);
  padding-right: var(--mc-space-2-5);
}
.px-3 {
  padding-left: var(--mc-space-3);
  padding-right: var(--mc-space-3);
}
.px-3\.5 {
  padding-left: var(--mc-space-3-5);
  padding-right: var(--mc-space-3-5);
}
.px-4 {
  padding-left: var(--mc-space-4);
  padding-right: var(--mc-space-4);
}
.px-5 {
  padding-left: var(--mc-space-5);
  padding-right: var(--mc-space-5);
}
.px-6 {
  padding-left: var(--mc-space-6);
  padding-right: var(--mc-space-6);
}
.px-8 {
  padding-left: var(--mc-space-8);
  padding-right: var(--mc-space-8);
}
.py-0\.5 {
  padding-top: var(--mc-space-0-5);
  padding-bottom: var(--mc-space-0-5);
}
.py-1 {
  padding-top: var(--mc-space-1);
  padding-bottom: var(--mc-space-1);
}
.py-1\.5 {
  padding-top: var(--mc-space-1-5);
  padding-bottom: var(--mc-space-1-5);
}
.py-10 {
  padding-top: var(--mc-space-10);
  padding-bottom: var(--mc-space-10);
}
.py-2 {
  padding-top: var(--mc-space-2);
  padding-bottom: var(--mc-space-2);
}
.py-2\.5 {
  padding-top: var(--mc-space-2-5);
  padding-bottom: var(--mc-space-2-5);
}
.py-3 {
  padding-top: var(--mc-space-3);
  padding-bottom: var(--mc-space-3);
}
.py-4 {
  padding-top: var(--mc-space-4);
  padding-bottom: var(--mc-space-4);
}
.py-5 {
  padding-top: var(--mc-space-5);
  padding-bottom: var(--mc-space-5);
}
.py-6 {
  padding-top: var(--mc-space-6);
  padding-bottom: var(--mc-space-6);
}
.py-8 {
  padding-top: var(--mc-space-8);
  padding-bottom: var(--mc-space-8);
}
.py-px {
  padding-top: 1px;
  padding-bottom: 1px;
}
.pb-1 {
  padding-bottom: var(--mc-space-1);
}
.pb-1\.5 {
  padding-bottom: var(--mc-space-1-5);
}
.pb-2 {
  padding-bottom: var(--mc-space-2);
}
.pb-3 {
  padding-bottom: var(--mc-space-3);
}
.pb-3\.5 {
  padding-bottom: var(--mc-space-3-5);
}
.pb-4 {
  padding-bottom: var(--mc-space-4);
}
.pb-5 {
  padding-bottom: var(--mc-space-5);
}
.pb-6 {
  padding-bottom: var(--mc-space-6);
}
.pl-2 {
  padding-left: var(--mc-space-2);
}
.pl-4 {
  padding-left: var(--mc-space-4);
}
.pl-5 {
  padding-left: var(--mc-space-5);
}
.pl-6 {
  padding-left: var(--mc-space-6);
}
.pl-7 {
  padding-left: var(--mc-space-7);
}
.pr-1 {
  padding-right: var(--mc-space-1);
}
.pr-2 {
  padding-right: var(--mc-space-2);
}
.pr-3 {
  padding-right: var(--mc-space-3);
}
.pr-5 {
  padding-right: var(--mc-space-5);
}
.pt-0\.5 {
  padding-top: var(--mc-space-0-5);
}
.pt-1 {
  padding-top: var(--mc-space-1);
}
.pt-1\.5 {
  padding-top: var(--mc-space-1-5);
}
.pt-2 {
  padding-top: var(--mc-space-2);
}
.pt-2\.5 {
  padding-top: var(--mc-space-2-5);
}
.pt-3 {
  padding-top: var(--mc-space-3);
}
.pt-4 {
  padding-top: var(--mc-space-4);
}
.pt-8 {
  padding-top: var(--mc-space-8);
}
.text-left {
  text-align: left;
}
.text-center {
  text-align: center;
}
.text-right {
  text-align: right;
}
.align-top {
  vertical-align: top;
}
.font-mono {
  font-family: var(--mc-font-mono);
}
.font-sans {
  font-family: var(--mc-font-sans);
}
.text-body {
  font-size: var(--mc-text-body);
  line-height: var(--mc-leading-normal);
}
.text-caption {
  font-size: var(--mc-text-caption);
  line-height: var(--mc-leading-normal);
}
.text-display {
  font-size: var(--mc-text-display);
  line-height: var(--mc-leading-tight);
}
.text-lead {
  font-size: var(--mc-text-lead);
  line-height: var(--mc-leading-normal);
}
.text-title {
  font-size: var(--mc-text-title);
  line-height: var(--mc-leading-tight);
}
.font-bold {
  font-weight: 700;
}
.font-medium {
  font-weight: 500;
}
.font-normal {
  font-weight: 400;
}
.font-semibold {
  font-weight: 600;
}
.uppercase {
  text-transform: uppercase;
}
.lowercase {
  text-transform: lowercase;
}
.capitalize {
  text-transform: capitalize;
}
.normal-case {
  text-transform: none;
}
.italic {
  font-style: italic;
}
.tabular-nums {
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}
.leading-\[1\.5\] {
  line-height: 1.5;
}
.leading-\[1\.6\] {
  line-height: 1.6;
}
.leading-\[var\(--mc-leading-normal\)\] {
  line-height: var(--mc-leading-normal);
}
.leading-none {
  line-height: 1;
}
.leading-normal {
  line-height: var(--mc-leading-normal);
}
.leading-relaxed {
  line-height: var(--mc-leading-relaxed);
}
.tracking-label {
  letter-spacing: var(--mc-tracking-label);
}
.tracking-wide {
  letter-spacing: var(--mc-tracking-wide);
}
.\!text-status-danger {
  color: var(--tone-danger-text) !important;
}
.text-accent {
  color: var(--accent-ink-on-ground);
}
.text-accent-display {
  --tw-text-opacity: 1;
  color: rgb(var(--accent-ink-display) / var(--tw-text-opacity, 1));
}
.text-green-300 {
  --tw-text-opacity: 1;
  color: rgb(var(--shade-green-300) / var(--tw-text-opacity, 1));
}
.text-on-accent {
  --tw-text-opacity: 1;
  color: rgb(var(--on-accent-rgb) / var(--tw-text-opacity, 1));
}
.text-red-300 {
  --tw-text-opacity: 1;
  color: rgb(var(--shade-red-300) / var(--tw-text-opacity, 1));
}
.text-status-attention {
  color: var(--tone-attention-text);
}
.text-status-danger {
  color: var(--tone-danger-text);
}
.text-status-info {
  color: var(--tone-info-text);
}
.text-status-progress {
  color: var(--tone-progress-text);
}
.text-status-stopped {
  color: var(--tone-stopped-text);
}
.text-status-success {
  color: var(--tone-success-text);
}
.text-status-warning {
  color: var(--tone-warning-text);
}
.text-theme-faint {
  --tw-text-opacity: 1;
  color: rgb(var(--text-faint-rgb) / var(--tw-text-opacity, 1));
}
.text-theme-muted {
  --tw-text-opacity: 1;
  color: rgb(var(--text-dim-rgb) / var(--tw-text-opacity, 1));
}
.text-theme-primary {
  --tw-text-opacity: 1;
  color: rgb(var(--text-strong-rgb) / var(--tw-text-opacity, 1));
}
.text-theme-secondary {
  --tw-text-opacity: 1;
  color: rgb(var(--text-mid-rgb) / var(--tw-text-opacity, 1));
}
.text-white {
  --tw-text-opacity: 1;
  color: rgb(var(--shade-white) / var(--tw-text-opacity, 1));
}
.text-white\/70 {
  color: rgb(var(--shade-white) / 0.7);
}
.underline {
  text-decoration-line: underline;
}
.overline {
  text-decoration-line: overline;
}
.line-through {
  text-decoration-line: line-through;
}
.underline-offset-2 {
  text-underline-offset: 2px;
}
.accent-amber-500 {
  accent-color: rgb(var(--shade-amber-500) / 1);
}
.opacity-0 {
  opacity: 0;
}
.opacity-100 {
  opacity: 1;
}
.opacity-25 {
  opacity: 0.25;
}
.opacity-50 {
  opacity: 0.5;
}
.opacity-60 {
  opacity: 0.6;
}
.opacity-70 {
  opacity: 0.7;
}
.opacity-75 {
  opacity: 0.75;
}
.opacity-80 {
  opacity: 0.8;
}
.opacity-90 {
  opacity: 0.9;
}
.shadow {
  --tw-shadow: var(--mc-shadow-sm);
  --tw-shadow-colored: var(--mc-shadow-sm);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-2xl {
  --tw-shadow: var(--mc-shadow-xl);
  --tw-shadow-colored: var(--mc-shadow-xl);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-lg {
  --tw-shadow: var(--mc-shadow-md);
  --tw-shadow-colored: var(--mc-shadow-md);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-xl {
  --tw-shadow: var(--mc-shadow-lg);
  --tw-shadow-colored: var(--mc-shadow-lg);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.outline-none {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.outline {
  outline-style: solid;
}
.ring {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-1 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-2 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-accent\/30 {
  --tw-ring-color: rgb(var(--accent) / 0.3);
}
.ring-accent\/40 {
  --tw-ring-color: rgb(var(--accent) / 0.4);
}
.ring-focus {
  --tw-ring-color: var(--focus-ring);
}
.ring-status-info\/70 {
  --tw-ring-color: rgb(var(--status-info) / 0.7);
}
.ring-status-warning\/70 {
  --tw-ring-color: rgb(var(--status-warning) / 0.7);
}
.ring-theme-panel {
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(var(--surface-panel-bg-rgb) / var(--tw-ring-opacity, 1));
}
.blur {
  --tw-blur: blur(8px);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.filter {
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.backdrop-blur {
  --tw-backdrop-blur: blur(8px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.backdrop-blur-sm {
  --tw-backdrop-blur: blur(4px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.transition {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
  transition-timing-function: var(--mc-motion-ease-standard);
  transition-duration: var(--mc-motion-duration-fast);
}
.transition-all {
  transition-property: all;
  transition-timing-function: var(--mc-motion-ease-standard);
  transition-duration: var(--mc-motion-duration-fast);
}
.transition-colors {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--mc-motion-ease-standard);
  transition-duration: var(--mc-motion-duration-fast);
}
.transition-none {
  transition-property: none;
}
.transition-opacity {
  transition-property: opacity;
  transition-timing-function: var(--mc-motion-ease-standard);
  transition-duration: var(--mc-motion-duration-fast);
}
.transition-transform {
  transition-property: transform;
  transition-timing-function: var(--mc-motion-ease-standard);
  transition-duration: var(--mc-motion-duration-fast);
}
.duration-\[1000ms\] {
  transition-duration: 1000ms;
}
.duration-fast {
  transition-duration: var(--mc-motion-duration-fast);
}
.duration-medium {
  transition-duration: var(--mc-motion-duration-medium);
}
.duration-slow {
  transition-duration: var(--mc-motion-duration-slow);
}
.ease-decelerate {
  transition-timing-function: var(--mc-motion-ease-decelerate);
}
.ease-linear {
  transition-timing-function: linear;
}
.will-change-transform {
  will-change: transform;
}
.\[color\:var\(--ib-tint-idle\)\] {
  color: var(--ib-tint-idle);
}
.\[grid-template-columns\:repeat\(auto-fill\2c minmax\(220px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(220px,1fr));
}
.\[grid-template-columns\:repeat\(auto-fill\2c minmax\(250px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(250px,1fr));
}
.\[grid-template-columns\:repeat\(auto-fill\2c minmax\(260px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(260px,1fr));
}
.\[grid-template-columns\:repeat\(auto-fill\2c minmax\(320px\2c 1fr\)\)\] {
  grid-template-columns: repeat(auto-fill,minmax(320px,1fr));
}

/* ===== Design tokens (MC-234 — matches Multicode-dashboard.html verbatim) =====
   These are the variables the design reference uses directly. The app is
   dark-only, so the tokens live on `:root` and every element resolves them
   with no theme class required. */

:root {
  /* The --bg* family aliases the surface role bundle's grounds. It used to
     alias a parallel set of role names (--surface-page, --surface-panel, …)
     that no theme declared, so a theme rebinding a role away from its
     neutral-ramp rung left these reading the rung while the applicator
     painted the binding. One name per ground ends that; which token a
     component happens to read can no longer change what colour it gets. */
  --bg: var(--surface-page-bg);
  --bg-card: var(--surface-panel-bg);
  --bg-modal: var(--surface-modal-bg);
  --bg-elev: var(--surface-panel-bg-1);
  --bg-elev2: var(--surface-panel-bg-2);
  --bg-hover: var(--surface-hover-bg);
  --bg-well: var(--surface-field-bg);
  /* Hairlines ride the theme's ink rung (0) at the named alpha knobs, so a
     theme's hairline tint follows its ramp with zero per-theme lines; a theme
     retunes only the knobs (high-contrast). The colour half never needs
     re-declaring — rung 0 is the theme's own. */
  --hairline-alpha-soft: 0.04;
  --hairline-alpha: 0.08;
  --hairline-alpha-strong: 0.14;
  --border-soft: rgb(var(--shade-neutral-0) / var(--hairline-alpha-soft));
  --border: rgb(var(--shade-neutral-0) / var(--hairline-alpha));
  --border-strong: rgb(var(--shade-neutral-0) / var(--hairline-alpha-strong));
  /* opaque slate panel-edge (D2) — a distinct role from the alpha-white
     hairlines above, wrapping the --line-* roles */
  --border-panel: rgb(var(--line-panel));
  --border-panel-alt: rgb(var(--line-panel-alt));
  /* The ambient ink ramp — the ground a region has not re-pointed, which is
     the page. Each rung binds BOTH forms: the triplet carries the value and
     the wrapped handle derives from it, so the two can never disagree.
     Tailwind's text-theme-* utilities are generated as
     `rgb(var(--rung) / <alpha-value>)` and read the TRIPLET; CSS consumers
     read the wrapped handle. Both are re-pointed together by every role block
     in styles/surfaces.css, which is what lets a utility call site leave the
     page ramp when it renders inside a differently-inked region. */
  --text-strong-rgb: var(--shade-neutral-0);
  --text-strong: rgb(var(--text-strong-rgb));
  --text-rgb: var(--shade-neutral-100);
  --text: rgb(var(--text-rgb));
  --text-mid-rgb: var(--shade-neutral-400);
  --text-mid: rgb(var(--text-mid-rgb));
  --text-dim-rgb: var(--shade-neutral-500);
  --text-dim: rgb(var(--text-dim-rgb));
  --text-faint-rgb: var(--shade-neutral-650);
  --text-faint: rgb(var(--text-faint-rgb));
  --text-faintest-rgb: var(--shade-neutral-700);
  --text-faintest: rgb(var(--text-faintest-rgb));
  /* Top-of-stack elevation — aliases the --mc-shadow-* ramp's ceiling step
     (design-tokens.css) instead of carrying its own geometry. */
  --shadow-modal: var(--mc-shadow-xl);
  /* The accent as INK. --accent is a FILL: consumers pair it with --on-accent,
     so its luminance is chosen to CARRY that ink, which on a light theme puts
     it above the ~L 0.53 ceiling where ink still clears AA on a pale ground.
     Collapsing these two back into one token costs one side or the other.
     Derives to --accent, so a theme only re-points it when its accent is a
     fill bright enough to fail as text. */
  --accent-ink: var(--accent);
  --accent-ink-hover: var(--accent-hover);
  /* The accent as ink for DISPLAY text on the page ground — today the public
     homepage's hero line, which is the product's brand statement and the one
     place the accent is set at 64px/700.

     It is its own rung because the OBLIGATION is different, not the taste.
     WCAG grades text that large at 3:1 rather than 4.5, and that gap is the
     whole decision: on sandstorm's cream the accent-as-ink lands at 6.72 and
     the pole-shifted `-on-ground` twin at 14.04, both far past what a headline
     owes, and both bought by spending the brand hue down to espresso. Given
     the real bar, sandstorm keeps clay at 3.59 and meadow keeps pink at 3.36.

     PAGE-GROUND ONLY, and the enumerator says so by expanding it against the
     page alone: a value chosen against a 3:1 bar has no business on a surface
     where the same token would be read at body size. Derives to --accent-ink,
     so a theme re-points it only when its page ground makes the darker ink a
     needless sacrifice — the five uniform-dark themes never do, and their
     mint arrives here unshifted. */
  --accent-ink-display: var(--accent-ink);
  /* The accent as ink ON A GROUND — the same split the member palette already
     carries (`--member-N-ink-on-ground` below). The triplet above is the theme's
     declared accent-as-ink and stays a triplet, because Tailwind's alpha closure
     and half a dozen `rgb(var(--accent-ink))` call sites read it that way; this
     is the wrapped form every paint site actually uses, shifted toward the
     surface's own pole and recomputed per role by the applicator's closure.
     A single triplet cannot do this job: meadow's page is vivid mint and its
     panels evergreen, so accent-coloured text needs opposite corrections on the
     two, and measuring only the triplet reported 20 unreadable pairs as none. */
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --mint: rgb(var(--mint-rgb));
  --mint-dim: rgb(var(--mint-dim-rgb));
  --mint-tint: rgb(var(--accent-tint));  /* opaque dark-emerald subtle fill (wraps the --accent-tint role) */
  --pink: rgb(var(--pink-rgb));
  --violet: rgb(var(--violet-rgb));
  /* MC-422: lighter violet for the sidebar admin chrome (admin glyph, "staff"
     badge, view-as-non-admin toggle). Distinct from --violet (#8b5cf6);
     theme-constant, so the light block below repeats the same value. */
  --violet-light: rgb(var(--violet-light-rgb));
  --cyan: rgb(var(--cyan-rgb));
  --amber: rgb(var(--amber-rgb));
  --rose: rgb(var(--rose-rgb));

  /* ── identity slots — the functional (hash-keyed) identity palette ────────
     Six bundles, one per slot, consumed through utils/functional-palette.ts.
     The MAPPING (identity → slot) is that module's; the PAINT is the token
     graph's, which is the whole point of the split: the palette used to return
     a hex from a hardcoded array behind a raw-literal escape, so a theme could
     not restyle an identity even though it can restyle everything else.

     The fills are the six hues the array held, read from the shared supply
     instead of retyped — byte-identical output, so no disc changes colour on
     account of the fill.

     What DOES change is the ink. Eight consumers each picked their own: three
     followed the PAGE ground (--bg / --avatar-initial-text), which reads on a
     dark theme and washes out on a light one, and one took white on a
     mid-chroma pink at roughly 3.6:1. One bundle per slot ends that by giving
     the ink a single home beside its fill.

     `-ink` reads --member-ink-on-fill, ONE per-theme knob rather than six
     copies of a fixed value. It defaulted to --on-accent directly, which was
     correct only while every fill stayed bright — the same assumption that
     broke the solid status buttons, where a theme-constant near-black sat on a
     role a light theme resolves dark. A theme that darkens its fills must
     lighten this ink, and pinning it made that impossible to express. One knob
     states the polarity once; sandstorm is the first theme to flip it.

     `-ink-on-ground` is for the site that paints an identity colour as TEXT on
     an ordinary card ground, where the fill itself is too bright. It derives
     through the SAME polarity knob the runtime Pill tone uses
     (--tone-ink-toward / --tone-ink-shift), so it is correct in both polarities
     by construction rather than by a second per-hue ramp.

     SELF is a reserved bundle, not a seventh slot: the viewer's own identity
     always paints --member-self-*, and no hash can land on it. It holds the
     emerald that slot 1 used to, which is why slot 1 is now blue — a reserved
     colour only means "you" if nobody else can draw it.

     A theme may re-point any of these, and sandstorm does: on an ivory panel
     the bright fills measure 1.6–3.2:1, so it takes the 700 rungs and flips
     the ink knob. :root carries a total default so nothing resolves to
     nothing. */
  --member-self-ink: var(--member-ink-on-fill);
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-1-ink: var(--member-ink-on-fill);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink: var(--member-ink-on-fill);
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink: var(--member-ink-on-fill);
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink: var(--member-ink-on-fill);
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink: var(--member-ink-on-fill);
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink: var(--member-ink-on-fill);
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));

  /* MC-422: theme-constant dark foreground for text/glyphs placed on a bright
     accent or brand fill (avatar letters, brand-mark "M"). Stays #000000 in
     both themes so the letter never washes out — the fill is theme-constant,
     so its foreground must be too.
     The triplet carries the value; the colour wraps it. Tailwind's text-on-accent
     needs the unwrapped form to take an opacity modifier, and deriving both from
     one rung keeps the two consumers from drifting apart. */
  --on-accent-rgb: var(--shade-black);
  --on-accent: rgb(var(--on-accent-rgb));
  /* The semantic status FILLS — the ground a tinted control, a solid button or
     an invalid border paints with. DERIVATION ONLY: the value is a per-theme
     rung declared as `--<name>-rgb` in every theme file, and the wrapped form
     here is what call sites read. A fill lands on a theme's own grounds, so a
     theme-constant value made the ramp decide the paint for grounds it has
     never seen; the triplet moved out and this line stayed, which is what keeps
     the two forms from disagreeing.
     `--black` is not one of these — it backs black-alpha tints over imagery, so
     it is theme-constant by nature and keeps its value here. */
  --danger: rgb(var(--danger-rgb));
  --success: rgb(var(--success-rgb));
  --warning: rgb(var(--warning-rgb));
  --info: rgb(var(--info-rgb));
  /* The three activity registers. They used to borrow a DECORATIVE hue —
     --violet for in-flight, --orange for stopped — which is how the activity
     feed ended up spelling five in-flight states in three colours: the tone
     set had no word for "in flight", so each site picked a hue. Named here as
     first-class semantic fills, they take the same shape as their four
     siblings above and the same values they already shipped, so nothing moves
     and the vocabulary gains three words. */
  --progress: rgb(var(--progress-rgb));
  --attention: rgb(var(--attention-rgb));
  --stopped: rgb(var(--stopped-rgb));
  /* The status fill as a MARK — a rail node, a deploy dot, a presence dot, a
     spinner ring, a progress bar. A mark's whole obligation is to be
     distinguishable from the ground behind it, and a theme-level fill cannot
     hold that against grounds of opposite polarity: meadow's page is vivid mint
     and its panels evergreen, so one opaque value clearing 3:1 on the page must
     be darker than 0.132 luminance while clearing 3:1 on the panel demands
     lighter than 0.159. That window is empty, which is why every mark on that
     theme measured 1.66–2.96 and no re-pointed rung could have fixed it.

     Same derivation as --tone-<t>-text, --accent-ink-on-ground and
     --member-N-ink-on-ground: shift the fill toward the surface's own pole,
     recomputed per role by the applicator's closure.

     The name drops the `-ink-` segment its siblings carry, deliberately — a
     mark is a painted solid, not ink, and the register that grades it is
     `boundary` (3:1, WCAG 1.4.11) rather than text.

     All seven rungs, including the three activity registers that have no mark
     call site today. They are members of the same family; declaring a subset is
     how the defect above stayed invisible on three of them. */
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --black: rgb(var(--shade-black));
  /* Raw-literal audit: palette names + light variants that rendered raw in
     status maps, alert banners, and agent chrome. Exact-value; light variants
     follow the --violet-light precedent (the N00-shade sibling of a base
     palette token). */
  --orange: rgb(var(--orange-rgb));
  --yellow: rgb(var(--yellow-rgb));
  --indigo: rgb(var(--indigo-rgb));
  --amber-light: rgb(var(--amber-light-rgb));
  /* `--info-light`, `--error-light` and `--error-soft` stood here and are gone.
     They were the same defect as a hue read wearing a SEMANTIC name: `:root`
     aliases over fixed ramp rungs (`--shade-blue-400`, `--shade-red-300`,
     `--shade-red-350`) that no theme re-points and no surface corrects, so a
     gate keyed on hue names could never have seen them. Their readers now take
     `--tone-<t>-text`, which derives per surface, and deleting the aliases is
     what makes the convergence unreversible — there is nothing left to read. */
  /* MC-423: theme-constant overlay/alpha tokens. The home + projects surfaces
     used these raw (`rgba(0,0,0,0.6)` scrims, `#fff` on-colour text, and
     accent-alpha fills); naming them gives the two-tier convention a Tier-1
     token to alias. Theme-constant — they sit on images / coloured surfaces, so
     the light block below repeats the same values to stay pixel-identical. */
  --scrim: rgb(var(--shade-black) / 0.6);
  --text-oncolor: rgb(var(--shade-white));
  --mint-alpha-10: rgb(var(--mint-rgb) / 0.1);
  --mint-alpha-30: rgb(var(--mint-rgb) / 0.3);
  --amber-alpha-10: rgb(var(--amber-rgb) / 0.1);
  /* Alpha variants of the SEMANTIC family, for the washes a status surface
     paints — a warning banner's ground and edge. They read the semantic
     triplet rather than a hue triplet for the same reason their opaque
     siblings do: the wash under a warning has to move when a theme re-points
     what warning looks like. Same naming as the hue-family variants above; the
     segment before `-alpha` is the family.

     There is no `--danger-alpha-10` twin. An alpha baked over `transparent`
     composites against whatever the region happens to sit on, which is a
     ground no instrument can name and the pair contract therefore cannot
     grade. `--tone-danger-bg` is the same wash stated against `--surface-bg`,
     recomputed by every role block, and graded against `--tone-danger-text` on
     each one — so an error wash reaches for the tinted register instead. The
     two survivors below are the same defect and are the population of a later
     workstream, not an endorsement. */
  --warning-alpha-08: rgb(var(--warning-rgb) / 0.08);
  --warning-alpha-15: rgb(var(--warning-rgb) / 0.15);
  /* Raw-literal audit: scrim/backdrop + mobile-shell values previously raw in
     layouts/mobile.css. Theme-constant overlay family, like --scrim above.
     One-off accent tints stay inline at the call site as
     color-mix(in srgb, var(--token) N%, transparent) — only values with no
     token-expressible form are named here. */
  --scrim-soft: rgb(var(--shade-black) / 0.4);      /* slide-up sheet overlay backdrop */
  --scrim-strong: rgb(var(--shade-black) / 0.65);   /* deploy / presence pill background */
  --media-backdrop: var(--black);     /* letterbox behind media previews */
  --dot-muted: rgb(var(--shade-neutral-550));                  /* draft / inactive status dot */
  /* App scrollbar chrome (was the retired --color-scrollbar-* channel family).
     Track rides the themeable panel surface; thumb rides the opaque panel-edge
     (warm re-points that role onto its ramp); hover is the one slate pick a
     theme overrides directly (warm.css). */
  --scrollbar-track: var(--bg-card);
  --scrollbar-thumb: var(--border-panel-alt);
  /* --scrollbar-hover is a per-theme manifest entry (each theme picks its
     grab-tone rung; midnight-mono holds the canonical slate-600). */
  /* Raw-literal audit: explore/trending `.x-*` card vocabulary (index.css
     component rules). Exact-value mints — no existing token matched the
     literal these rules used. Theme-constant (sit on card images / coloured
     pill fills), same single-definition pattern as the overlay family above. */
  --violet-light-alpha-30: rgb(var(--violet-light-rgb) / 0.3);  /* .xcard hover border */
  --white-alpha-16: rgb(var(--shade-white) / 0.16);     /* .x-hero-card hover border */
  --scrim-rank: rgb(var(--shade-black) / 0.62);                  /* .x-rank badge background */
  --scrim-card: rgb(var(--shade-ink-scrim) / 0.55);              /* explore/trending card scrim */
  --scrim-tagpin: rgb(var(--shade-black) / 0.55);                /* .x-tagpin background */
  --rose-alpha-92: rgb(var(--rose-rgb) / 0.92);            /* .x-pin.hot near-opaque fill */
  --mint-alpha-92: rgb(var(--mint-rgb) / 0.92);             /* .x-pin.new near-opaque fill */
  --text-on-rose-pin: rgb(var(--shade-rose-995));
  --text-on-mint-pin: rgb(var(--shade-emerald-995));
  /* MC-425: workspace-view feed icon + glow colours. Theme-constant (same value
     in the light block below), so the light/dark split is a no-op for these —
     kept in both blocks per the two-tier add-token rule. */
  --indigo-alpha-25: rgb(var(--indigo-rgb) / 0.25);   /* resurfaced feed-card glow inner ring */
  --indigo-alpha-09: rgb(var(--indigo-rgb) / 0.09);   /* resurfaced feed-card glow outer halo */
  --sync-blue: rgb(var(--shade-blue-300));            /* sync-in-progress feed icon */
  --commit-amber: rgb(var(--shade-amber-400));         /* pull/commit feed icon */
  --font-mono: var(--mc-font-mono);  /* alias — canonical token is --mc-font-mono */
}

/* MC-424: derived Tier-1 surface + shadow tokens. These are NOT raw literals —
   each composes an existing theme-constant Tier-1 colour, so a group-edit of
   the base colour re-tunes them. `--success-subtle` / `--danger-surface` are the
   8% / 15% translucent forms of `--success` / `--danger` (the New-Project
   template-card selected tint + the provisioning error-icon background);
   `--shadow-focus-ring` is the inset 1px selected-card ring. Declared at :root
   (theme-constant) — the `var(--…)` inputs re-resolve per active theme lazily on
   the consuming element. color-mix is already used across web/src (ActivityCard,
   PromptBar, FeedDivider). */
:root {
  --success-subtle: color-mix(in srgb, var(--success) 8%, transparent);
  --danger-surface: color-mix(in srgb, var(--danger) 15%, transparent);
  --shadow-focus-ring: 0 0 0 1px var(--success) inset;
  /* The KEYBOARD FOCUS INDICATOR — the ring every primitive draws on
     `:focus`, and a different thing from `--shadow-focus-ring` above, which
     despite its name is the selected-CARD ring and is pinned to `--success`
     for every surface in every theme.
     Declared as a token rather than left as the `ring-accent/40` utility the
     primitives layer used to inline, for one reason: a colour that exists only
     inside a Tailwind class is a colour no contrast instrument can enumerate,
     and a focus indicator is exactly the information WCAG 2.4.11 asks to be
     distinguishable. Now it expands against every surface ground like any
     other declared ink, and the schema grades it in the boundary register.

     The VALUE follows the closed-tone ink law, for the reason that law exists:
     a fixed ring colour cannot clear 3:1 on both polarities of a mixed theme.
     Meadow's page is vivid mint and its panels are evergreen, and the
     arithmetic is not close — the luminance band satisfying both is empty. So
     the ring is the accent shifted toward the SURFACE'S own pole, which the
     applicator's dependency closure recomputes per role. As
     `rgb(var(--accent) / 0.4)` it failed 3:1 on 112 of 112 surface grounds;
     derived this way it clears all 112.

     `--focus-ring-color` is the authored override — declared by a theme that
     wants a ring the derivation does not produce, and by nobody else. Same
     optional-override seam `--tone-<t>-ink` gives the tone inks. */
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  /* MC-425: composite two-layer feed-card glow (resurfaced activity card). Holds
     the full multi-value box-shadow — a 2px violet inner ring + 20px outer halo —
     composed from the `--indigo-alpha-*` Tier-1 colours, exactly like
     `--shadow-focus-ring`/`--shadow-modal` are composite shadow tokens. The
     `--feed-card-glow` component var aliases this single token. */
  --shadow-feed-glow: 0 0 0 2px var(--indigo-alpha-25), 0 0 20px var(--indigo-alpha-09);
  /* Accent-tinted hover glow (project-detail hero CTA). A GLOW, not elevation:
     colour-carrying shadows live here as composite semantics — the --mc-shadow-*
     ramp is ink-only and Tailwind's colored-shadow utilities can't recolor a
     var() shadow. Geometry mirrors the ramp's md step. */
  --shadow-accent-glow: 0 10px 15px -3px rgb(var(--shade-emerald-500) / 0.25);
  /* Tinted-control STRENGTH — the color-mix percentages the tone recipe below
     mixes over `transparent`. A tinted chip reads the ground THROUGH itself, so
     the recipe is polarity-sensitive: 10%/30% over a dark ground is a legible
     deep chip; the same over a light ground (meadow's vivid mint page) washes
     out to a pale smudge. Unlike INK — where dark-on-dark is INVISIBLE and the
     fix must be per-surface (see the ink ramp) — a mid-percentage tint reads
     acceptably on both polarities, so the strength is theme-bound: one knob a
     light-polarity theme lifts (meadow → 18%/45%). Every consumer (the --tone-*
     tokens below + the Pill in globals.css) reads these two, so one override
     retones all tinted controls at once. Dark themes leave the default and are
     byte-unchanged. */
  /* --tone-bg-mix / --tone-border-mix are PER-THEME manifest knobs (each
     theme declares its tinted-control strength; midnight-mono holds the
     canonical 10% / 30%). */
  /* The ink half of the tint recipe — the DIRECTION and AMOUNT every tone's ink
     is shifted by. See "The ink law" further down for which tones read it: the
     answer is all of them.

     This block once described a split. A closed tone named its ink outright and
     only the runtime-toned Pill derived one, because an open tone had no token
     to pre-pick. Pill's colour prop is deleted and the naming half was measured
     wrong, so there is no split left to describe — but the reasoning below is
     the reasoning FOR the derivation, and it applies to every tone now rather
     than to the one that had no alternative.

     Without the derivation a tone paints its own tint AND the text on top of
     it, and the bare tone never clears AA against a tint of itself in EITHER
     polarity. Shifting the tone away from its own tint keeps the tint vivid;
     pre-shifting the fill instead would fix the text and mud the tint, since
     one value feeds both.

     The knob is a DIRECTION plus an AMOUNT, not a single "darken" magnitude,
     because the correct direction is a property of the theme's polarity: a
     light theme's tint is pale so its ink must go darker, and a dark theme's
     tint is deep so its ink must go LIGHTER. A darken-only knob is unusable on
     half the themes — measured, a dark theme's bare-tone ink sits at 3.7-4.0:1
     on its own tint, and raising a darken value there moves it the wrong way.

     The direction follows the TINT'S GROUND, not the page's polarity, and it
     cannot be derived from color-scheme — that was tried and measured false.
     sandstorm is light and needs `black` (cream tints). meadow is ALSO light and
     needs `white`: its tinted controls sit on dark tints (#174432, #2d3347)
     despite a light page, and forcing it toward black took its failing Pill
     cells from 6 to 7. So :root carries `white` and a theme re-points only when
     its own tints say so.

     Measured across all seven themes on /showcase, failing Pill tone cells,
     before → after: sandstorm 0→0, midnight-mono 2→0, meadow 6→1, ocean 3→1,
     slate 3→1, warm 3→1, high-contrast 2→0. The one that survives everywhere is
     the NEUTRAL tone, whose ink is a ramp step rather than a derived tone — a
     calibration matter, not this derivation's.

     Mixed in oklab — an srgb mix desaturates, and a muddy chip is the thing
     being avoided.

     Declared PER SURFACE, and the PAGE entry is the one that carries the
     fallback — the direction follows the TINT'S ground, and a theme's surfaces
     need not agree about their ground's polarity (meadow is light and its
     evergreen panels want `white` while its mint page wants `black`). The
     other four roles default to the page's answer, and so does the AMBIENT
     pair below, which is what a region with no role declaration resolves.

     The defaulting runs page → everything else, not theme-wide → each role,
     and that direction is load-bearing rather than stylistic. The applicator
     binds the ambient knob only INSIDE a `[data-surface]` block, so an
     un-roled region reads `:root`. Pointing `:root` at a theme-wide knob the
     theme no longer declares would silently return every un-roled region to
     the shared default — measured on sandstorm, a homepage tone pill went from
     6.64:1 to 1.29:1 against its own fill, because a theme that needs the dark
     direction had stopped being able to say so anywhere the applicator does
     not reach. Pointing it at the page entry means an un-roled region inherits
     the polarity of the ground it is actually sitting on. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: var(--surface-page-tone-ink-toward);
  --surface-panel-tone-ink-shift: var(--surface-page-tone-ink-shift);
  --surface-modal-tone-ink-toward: var(--surface-page-tone-ink-toward);
  --surface-modal-tone-ink-shift: var(--surface-page-tone-ink-shift);
  --surface-field-tone-ink-toward: var(--surface-page-tone-ink-toward);
  --surface-field-tone-ink-shift: var(--surface-page-tone-ink-shift);
  --surface-frame-tone-ink-toward: var(--surface-page-tone-ink-toward);
  --surface-frame-tone-ink-shift: var(--surface-page-tone-ink-shift);
  --tone-ink-toward: var(--surface-page-tone-ink-toward);
  --tone-ink-shift: var(--surface-page-tone-ink-shift);
}

/* ── Tier 2: component variables ──────────────────────────────────────────
   MC-417 — the second layer of the two-tier design-variable convention
   (see docs/claude/design-tokens.md → "Two-tier model").

   Each component variable ALIASES a Tier-1 semantic token by default —
   `--<component>-<property>: var(--<tier-1-token>)`. A component reads its own
   variable (`color: var(--text-strong)`), never a raw literal. The aliasing
   gives blast-radius control:
     • override the Tier-1 token (at :root, a theme class, or a
       `data-design-scope` block) → every alias moves together (group edit);
     • override the component variable itself → only that component changes
       (individual edit).
   This works because CSS custom-property substitution is lazy: the alias is
   re-resolved at computed-value time on the consuming element, so a scoped
   Tier-1 override flows through live.

   HARD RULE: the right-hand side of every declaration here is ALWAYS a
   `var(--<tier-1-token>)` reference — never a raw hex/dimension literal. A
   literal RHS silently breaks the group-edit blast radius. Every name carries
   a `<component>` segment so it can never collide with a flat Tier-1 token
   name (`--border`, `--bg`, …). Consumers: the primitives layer
   (`components/primitives/`) reads its vars from this block, and MC-423
   migrated the home surfaces onto theirs — edits here repaint those
   components. Migrating the remaining feature components is a separate
   sub-track. */
:root {
  /* Button — emphasis × tone. The primitive composes an emphasis (visual
     weight) with a tone (semantic colour). Its paint no longer supplies from
     here: a socket whose value holds a `var()` computes where it is DECLARED,
     so every one of these froze at the page's ground and the generated
     applicator had to re-declare each of them inside each surface role to
     defeat that. The sockets moved onto `.mc-btn` in styles/globals.css, keyed
     on the element's own data-emphasis / data-tone, where each `var()` on the
     right-hand side resolves in the region the button is actually in — and the
     whole re-declaration population goes with them.

     Two inputs remain, and neither is a socket. `--btn-radius` is a dimension,
     which no ground re-points. `--btn-outline-neutral-{fill,ink,edge}` are
     OPTIONAL theme inputs the secondary button reads with a default fallback
     (sandstorm and meadow give it an accent tint) — declared by the two themes
     that want them and by nobody here, the same shape `--tone-<t>-text` uses
     for `--tone-<t>-ink`. */
  /* Modal / dialog */
  --modal-bg: var(--bg-modal);
  --modal-shadow: var(--shadow-modal);
  /* Form input */
  --input-bg: var(--bg-well);
  --input-border: var(--border);
  --input-text: var(--text);
  --input-invalid-border: var(--danger);
  /* Form label */
  /* Form select */
  --select-bg: var(--bg-elev);
  --select-border: var(--border);
  --select-text: var(--text);
  --select-invalid-border: var(--danger);
  /* Checkbox / radio tint — the checked fill, so it tracks the theme's accent
     rather than a hue alias. These feed `accent-color`, which paints its own
     checkmark, so they take --accent (the fill) and not --accent-ink. */
  --checkbox-accent: rgb(var(--accent));
  --radio-accent: rgb(var(--accent));
  /* Icon button — its glyph ink and its overlay-solid disc are sockets on
     `.mc-iconbtn` (styles/globals.css), keyed on the element's own data-tone,
     and the caller-tint variant's three fallbacks live there too. The `tint`
     variant itself was already correct: a caller hands the primitive `var()`
     references and they land as inline custom properties ON the element, which
     is a component-scoped declaration reached from the other direction. */
  /* Disclosure row */
  --disclosure-header-bg: var(--bg-card);
  /* Stepper — the step rail's three states. A step's ink and its marker border
     move together, so a done step reads as settled rather than merely dimmer
     than the current one. */
  /* Tone vocabulary — the shared semantic-colour set every interactive
     primitive (Button/Badge/IconButton) aliases. Each tone is a triple: an INK,
     a bg fill at --tone-bg-mix, and a border at --tone-border-mix. The ink is
     always a rung apart from the fill it sits on, never the same value — a tint
     IS that fill, so one value serving both is readable only while the two land
     on opposite sides of the ground, which no longer holds once a theme goes
     light. Brand-green (--mint, the identity hue) stays distinct from
     success-green (--success), and neither is a tone's ink.
     neutral is the deliberate exception on the FILL side: its bg mixes
     --text-dim rather than a status colour, and its border is solid --border
     rather than a mix. Its ink still steps off that fill, to the mid rung.

     Every -bg below mixes over --surface-bg — the AMBIENT GROUND
     of the region the control sits in — rather than over `transparent`. The
     two are the same arithmetic where the region is the one the browser would
     have composited against (mixing C at 10% over G and compositing C at 10%
     alpha over G both give 0.1·C + 0.9·G), so no value moves; what changes is
     that the result is a DECLARED colour instead of one that exists only at
     paint time. Six tones over five surfaces over seven themes is 210 grounds
     that appeared in no manifest and that the pair checker could not evaluate
     — which is why "every token is compliant within its theme" was not a
     checkable claim. The applicator re-points --surface-bg per role and the
     generated closure re-declares each tone against it, so the 210 arrive as
     output rather than as hand-maintenance.

     The -border half deliberately stays translucent, because ONE token serves
     two consumers with different grounds: a tinted Badge paints its edge over
     the chip's own fill (a background paints to the border edge), while an
     outline Button has no fill and paints the same edge over the surface.
     Pinning it opaque forces a choice and makes it wrong for the other — the
     measured cost was 112 Badge and tinted-Button edges rendering a step
     duller across the seven themes. Translucent is correct for both, and the
     pair enumerator composites it over whichever ground it is measuring, so
     nothing goes unevaluated for the sake of it. */
  /* ── The ink law ──────────────────────────────────────────────────────────
     A tone's INK is DERIVED from that tone's own fill, by the same shift the
     runtime-toned Pill uses: away from the fill, toward --tone-ink-toward by
     --tone-ink-shift, mixed in oklab. One law for every tone, open or closed.

     It used to be two. A closed tone NAMED its ink per theme
     (`rgb(var(--status-<t>))`) and only the open one derived, on the reasoning
     that a closed set CAN name its ink and an open set cannot — so naming was
     taken wherever it was possible. Measured, that is backwards. A named rung
     is picked in advance of the ground it will land on, and it can be wrong
     about it: meadow's --status-info reads 2.32 on its own info tint over the
     panel ground, 2.37 over the page and 2.86 over the frame — a text register
     sitting at half the floor, on every surface, in a shipped theme. The derivation cannot be wrong that way
     — it is computed FROM the fill it has to clear, and the applicator binds
     its direction per surface, so the same declaration adapts to a region
     whose ground disagrees with the page. Across the seven themes the derived
     ink clears the text floor on every tone; the same cells named from a bare
     hue clear it on none.

     Mixed in oklab, not srgb: an srgb shift desaturates, and a muddy chip is
     what the derivation exists to avoid. The pair enumerator evaluates both
     spaces (web/src/utils/theme-pairs.ts) — a derived ink is still a declared
     colour, which is the whole claim.

     A theme OVERRIDES by declaring --tone-<t>-ink, which each -text entry reads
     as an optional input with the derivation as its fallback. The override
     earns its place on tones whose ink is not a shift of their own fill —
     sandstorm's brand ink is clay while its accent fill is coral, a hue change
     no lighten/darken can express.

     The override is a separate INPUT token rather than a re-declaration of
     -text itself, and that is load-bearing rather than tidy. The surface
     closure cuts at theme-authored names, and that set is global by necessity:
     a role block (`[data-surface="panel"]`) is not theme-scoped, so a value it
     re-declares would out-rank the `:root` declaration of EVERY theme, not just
     the authoring one. Overriding -text directly therefore froze the token for
     all seven themes — measured, sandstorm authoring its brand ink took
     meadow's brand ink on panel from 3.57 to 1.09, because meadow stopped
     recomputing against its evergreen ground. Reading an input the themes
     mostly do not declare keeps -text derivable everywhere: the authoring theme
     gets its constant, and every other theme keeps a value that follows the
     ground it lands on. */

  /* neutral is the standing example of that override, at the supply tier: its
     fill is an ink rung (--text-dim), so deriving would shift an ink off an
     ink — the same category error the TopBar credits chip renders. Its ink is
     the ramp step above its fill, named outright. */
  /* The neutral tone's ink is the one that named a ramp rung outright rather
     than deriving off its own fill, and it is the last place the old shape
     survived: `--text-mid` is authored against the SURFACE ground, while this
     ink lands on the neutral TINT, which is that ground mixed with dim. On
     meadow's mint page the two differ by enough to read 2.68.

     Shifted toward the surface's pole, like the event inks, rather than derived
     off its own fill like the SATURATED tones. Deriving was tried and measured
     worse — 30 new failures down to 2.29 — because the shift is calibrated for
     a status hue and a neutral tint is only a few points off its own ground, so
     shifting it away from itself lands nowhere. Anchoring to a legible ramp rung
     and then moving it off the tint is the correction that works. */
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  /* The neutral tone's border, derived like every sibling tone's rather than
     borrowing the ambient hairline. `var(--border)` is an alpha line sized for
     a surface ground; over the neutral TINT — which is that same ground mixed
     with dim — it composites to within 1.02 of what it sits on, a line that
     draws nothing. */
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  /* The hue tones. The -bg/-border mixes take the hue alias, since a tint is a
     fill; the -text derives from that same alias, so fill and ink can never
     disagree about which colour the tone IS. */
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-border: color-mix(in srgb, var(--success) var(--tone-border-mix), transparent);
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-border: color-mix(in srgb, var(--info) var(--tone-border-mix), transparent);
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-border: color-mix(in srgb, var(--warning) var(--tone-border-mix), transparent);
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-border: color-mix(in srgb, var(--danger) var(--tone-border-mix), transparent);
  /* progress — machinery moving on its own (syncing, merging, a staging build
     under way). halted — stopped without failing (cancelled). Both were live
     paint before they were vocabulary: the activity feed passed --violet and
     --orange straight into an open tone prop, so their (ink, ground) pairs
     were constructed at render and appeared in no manifest. They enter as
     REGISTERS, named for the state rather than the hue, which is what keeps
     the set a vocabulary instead of a palette. */
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-border: color-mix(in srgb, var(--progress) var(--tone-border-mix), transparent);
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-border: color-mix(in srgb, var(--stopped) var(--tone-border-mix), transparent);
  /* attention — the app is waiting on the USER (a prompt awaiting input, an
     approval). Distinct from warning, which says something is off: nothing is
     wrong here, someone is simply up. It had no register at all, and the one
     site that needed it read `--accent-strong`, a name declared in no
     stylesheet, so those pills rendered with no fill. */
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-border: color-mix(in srgb, var(--attention) var(--tone-border-mix), transparent);
  /* brand is a ROLE, so it tracks the theme's accent — naming a hue alias here
     pins every theme's brand controls to green regardless of its accent. The
     ink derives from the accent FILL rather than from --accent-ink, whose
     :root value is the bare accent and therefore the failing case; a theme
     that wants an authored brand ink says so by declaring --tone-brand-text,
     which is what sandstorm does to keep its clay. */
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-border: color-mix(in srgb, rgb(var(--accent)) var(--tone-border-mix), transparent);
  /* Badge — tone pills. Its {bg, ink, border} sockets are declared on
     `.mc-badge` in styles/globals.css, keyed on the element's own data-tone,
     not here: a socket declared at `:root` computes there, so a badge on a
     re-pointed surface kept the page's ink — which is exactly the incident
     surfaces.css records, a CreditBadge on the black frame holding a dark
     green nobody could read. `--badge-scrim-bg` below is not one of those: it
     is a fixed scrim, and no ground re-points it. */
  /* `--status-error` lived here, an alias of the raw danger fill. Its last
     consumer was a failure glyph in the check rows, which is a mark and now
     reads the twin. Deleted with its siblings below rather than left for the
     next mark to find: a name that claims a status and resolves a supply is
     invisible to every gate that reads either. */
  /* Sidebar / app-shell chrome (MC-422). Presence and admin vars alias
     theme-constant Tier-1 tokens (so they stay identical across themes); nav
     text and the presence-dot border alias theme-tracking tokens (so they
     adapt with the theme, fixing the previous dark-first hardcoding).

     The BRAND MARK stays theme-constant — its gradient runs between two fixed
     hues, so pointing either end at a theme's accent would recolour the logo.
     The nav accent is a separate role and does track the theme; the two were
     one token, which is why the mark could not hold still while the rail
     followed a non-green accent. */
  --sidebar-brand-gradient-start: var(--mint);
  --sidebar-brand-gradient-end: var(--cyan);
  --sidebar-accent: rgb(var(--accent));
  --sidebar-admin-accent: var(--violet-light);
  --sidebar-presence-online: var(--success);
  /* Offline stays on the HUE supply, like --star-active-color below. Its
     sibling above is a live/available claim and moves onto the semantic family
     with every other one; an absence is not a caution, and painting it
     --warning would assert a problem the product does not report. */
  --sidebar-presence-offline: var(--amber);
  --sidebar-nav-active-text: var(--text-strong);
  --sidebar-nav-inactive: var(--text-dim);
  --sidebar-nav-glyph-inactive: var(--text-faint);
  --sidebar-avatar-text: var(--on-accent);
  --sidebar-dot-border: var(--bg);
  /* Alpha variants of --violet-light via color-mix — no raw rgba() literal on
     the RHS, so overriding --violet-light still moves these in lock-step
     (blast-radius preserved). */
  --sidebar-admin-badge-bg: color-mix(in srgb, var(--violet-light) 12%, transparent);
  --sidebar-admin-view-bg: color-mix(in srgb, var(--violet-light) 18%, transparent);
  --sidebar-admin-view-border: color-mix(in srgb, var(--violet-light) 45%, transparent);
  /* Sidebar nav-item active state. The shell surface, border, and text ramp
     migrated onto the `frame` surface role (data-surface="frame"); this active
     highlight stays a nav-item interaction token. */
  --sidebar-active-bg: var(--border-soft);
  /* MC-423 — home + projects surfaces (HomeGrid.tsx). Each aliases a Tier-1
     token; the component reads its own var, never a raw literal. */
  /* Deploy-status dot (DeployBadge) */
  --deploy-dot-live: var(--success);
  /* Activity row icon */
  /* Avatars */
  --avatar-on-color-text: var(--text-oncolor);
  /* The shared Avatar pattern's initial ink — the on-tint (on-accent) role;
     distinct from --avatar-on-color-text, which ProjectCard's owner strip
     pairs with the same palette as a deliberate white-ink variant. */
  /* The hero disc's frame ring — the hairline border colour as a 2px halo. */
  /* Card preview area */
  /* Online-collaborator + owner-strip badges */
  --badge-scrim-bg: var(--scrim);
  --online-dot-color: var(--success);
  /* Interactive star button */
  --star-active-color: var(--amber);
  --star-active-bg: var(--amber-alpha-10);
  /* Fork error toast */
  --toast-error-bg: var(--danger);
  --toast-error-text: var(--text-oncolor);
  /* Filter pills — the active-chip vocabulary rides the APPSHELL-ACCENT SEAM at
     the tone knobs (10%/30% =/= the retired mint-alpha aliases on every dark
     theme), not --mint directly: a theme that re-points the accent (meadow ->
     pink) must reach these chips, or they dissolve into an accent-coloured
     page. Declared on `.mc-chip-tokens` in
     styles/globals.css rather than here — the tint composes over --surface-bg,
     which every surface role re-points, so a chip resolving it at `:root` would
     tint the page's ground while sitting on a panel. */
  /* `--status-error-icon` and `--status-error-surface` lived here — a glyph
     colour and its tint for the provisioning step list. Both were aliases of a
     raw fill, which is what let a mark reach one: an alias makes a status
     claim its VALUE does not keep, and it is one name further from every
     pattern that would have caught it. Their two call sites now read the
     vocabulary directly — the tone pair for a glyph on a tint, the mark twin
     for one on a surface ground — and both of those are graded. */
  /* MC-424: New Project modal template-selection cards. Selected state aliases
     the success accent — the original literal #10b981 equals --success (mint is
     #34d399 and is undefined in html.light), so this stays pixel-identical in
     both themes. */
  --template-card-border-selected: var(--success);
  --template-card-bg-selected: var(--success-subtle);
  --template-card-shadow-selected: var(--shadow-focus-ring);
  --template-card-icon-selected: var(--success);
  /* MC-460: admin-configurable card image rendered in the icon slot when one
     is configured (else the glyph). Sized to sit on the icon+label header row
     without shifting the verbatim card layout. */
  --template-card-image-size: var(--mc-space-7);
  --template-card-image-radius: var(--mc-radius-xs);
  /* MC-424: provisioning timeout message text. */
  /* MC-426 — AdminConsole (/admin/console) sits in the `console` SCOPE: the
     root declares data-scope="terminal" data-surface="page" and the component
     reads the ordinary role/global vocabulary, rebound for the subtree by
     styles/surfaces.css [data-scope="terminal"]. The former --admin-console-*
     and --surface-console-* families are retired. */

  /* ── Overlay family (shared across modal / drawer / tooltip surfaces) ──
     Theme-constant ink for scrims + drop-shadows. ≥3 overlay callers, so
     shared rather than per-component; each call site keeps its own color-mix
     percentage — only the colour is tokenised. */
  --overlay-scrim: var(--scrim);
  --overlay-shadow-ink: var(--black);
  /* WelcomeModal hero chrome (+ inline-colour collapse off --color-*) */
  --welcome-hero-border: var(--text-oncolor);
  --welcome-hero-glow: var(--success-subtle);
  /* SpotlightTooltip — inline-colour collapse off --color-* */
  --spotlight-border-alt: var(--border-panel-alt);
  /* ProjectDetailModal — inline-colour collapse off --color-*: each var
     aliases the flat token its old channel read mapped to (D1/D2) */
  --projectmodal-tab-active: rgb(var(--accent));
  --projectmodal-border: var(--border-panel);
  --projectmodal-shadow: var(--shadow-modal);
  /* SnapshotFallback dim letter — panel role has no dim-ink member. */
  /* Feed cards — the tint backgrounds behind the sync/publish notices. The
     five glyph/border twins beside these are gone: the phase buttons that read
     them are Buttons on the closed tone set now, and the one avatar that read
     --synccard-border was painting a BORDER token as a disc fill. A component
     var with no consumer is not inert — the surface closure keeps re-emitting
     it into every role block, which is how a dead value stays alive enough to
     be copied. */
  --publishcard-warn-bg: var(--warning-alpha-08);
  --synccard-success-bg: var(--success-subtle);
  /* The attention chrome a status card draws around itself — a tone edge and a
     faint glow of the same tone. Both used to be hand-written color-mix()
     percentages at the call site, which is the shape that stops retoning: a
     theme that lifts --tone-border-mix for a light polarity moved every other
     tinted edge in the app and left these two cards behind. The glow is a
     quarter of the border strength, because a shadow spreads over ~12px and reads
     ~12px and reads far stronger than the 1px line would at the same
     percentage. A QUARTER is the ratio the hand-written pair already used
     (6% against 25%), kept rather than re-picked. */
  --statuscard-edge-mix: var(--tone-border-mix);
  --statuscard-glow-mix: calc(var(--tone-border-mix) / 4);
  /* The inline error strip inside those cards — the same tinted-fill
     vocabulary every other tinted surface reads. */
  --statuscard-error-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), transparent);
  /* Feed-card family — shared chrome for the feed/activity card cluster
     (BuildCard, CardConversation, AttachmentTree, AgentStartingHero,
     FeatureTestCard, ActivityCard); shared because the roles recur across
     ≥3 callers, same rule as --overlay-*. */
  --feedcard-border: var(--border-panel);
  --feedcard-border-strong: var(--border-panel-alt);
  --feedcard-accent: rgb(var(--accent));
  /* Per-sheet families for the co-located stylesheets (two-tier css
     coverage): each mirrors the tokens its sheet reads. */
  --xcard-text-oncolor: var(--text-oncolor);
  --xcard-oncolor: var(--black);
  --xcard-accent: rgb(var(--accent));
  --xcard-accent-alt: var(--violet-light);
  --directchat-accent: rgb(var(--accent));
  --directchat-accent-hover: rgb(var(--accent-hover));
  --directchat-hover: var(--bg-hover);
  --directchat-shadow: var(--shadow-modal);
  /* the unread-count badge. Its own handle rather than a bare --pink read: the
     hue is now aliased by the conversation event tiles, and a sheet reading the
     raw hue would drift the moment either consumer re-points it. */
  --directchat-unread-bg: var(--pink);
  --directchat-unread-ink: var(--text-oncolor);
  /* The own-message bubble's ink. Its own handle rather than a bare --on-accent
     read, the same reason the unread badge above has one. --on-accent and not
     --tone-brand-oncolor: both are graded against --accent by theme-pairs.ts
     and both are black today, but the bubble is a coloured FILL — the domain
     the theme files give --on-accent, "imagery or coloured fills, not
     surfaces" — while a tone's oncolor is the ink for a CONTROL painted at
     full severity. The send control needs no handle here: it is a Button
     primitive and takes its ink from that primitive's own tone binding. */
  --directchat-own-ink: var(--on-accent);
  --appshell-surface: var(--bg-card);
  /* Tracks the theme's accent, not a hue alias. FORM: consumers feed this into
     color-mix, so it must be a complete colour — a bare triplet there is
     invalid CSS and the tint silently drops. Note .mc-pill--tone paints both
     its fill AND its own text from this one value, so a theme whose accent is
     too light to read as text re-points this at the ink. */
  --appshell-accent: rgb(var(--accent));
  --appshell-oncolor: var(--black);
  --adminpanel-oncolor: var(--black);
  --mobileshell-accent: rgb(var(--accent));
  --mobileshell-accent-alt: var(--cyan);
  --mobileshell-oncolor: var(--on-accent);
  /* Shared chrome + primitives */
  --nonadminbanner-accent: var(--violet-light);
  --filterpill-glyph: var(--text-oncolor);
  --filterpill-oncolor: var(--on-accent);
  /* ProjectDetailHeader */
  --projectheader-admin-accent: var(--violet-light);
  /* ExploreCard — per-category accent, one entry per category. E-commerce was
     the one row that never got a var and read `--amber` at the call site; the
     comment here claimed it "uses --amber status", which named a semantic the
     category does not carry — a storefront is not a warning. It is a
     CATEGORICAL palette, the way the chart series are, so the four sit
     together and a theme re-points them together. */
  --explorecard-games: var(--cyan);
  --explorecard-ecommerce: var(--amber);
  --explorecard-personal: var(--violet-light);
  --explorecard-other: var(--mint);
  /* PromptBar — inline-colour collapse off --color-* (D1/D2 mapping) */
  --promptbar-send-hover-bg: rgb(var(--accent));
  --promptbar-accent: rgb(var(--accent));
  --promptbar-border: var(--border-panel);
  --promptbar-border-alt: var(--border-panel-alt);
  /* AgentSelector — inline-colour collapse off --color-* (D1/D2 mapping) */
  --agentselector-accent: rgb(var(--accent));
  --agentselector-accent-tint: var(--mint-tint);
  --agentselector-hover-bg: var(--bg-hover);
  --agentselector-border: var(--border-panel);
  --agentselector-border-alt: var(--border-panel-alt);
  /* SpaceDetailPage live/idle dot + MobileLayout bottom-nav label */
  --spacedetail-live: var(--success);

  /* ── MC-425: workspace views ──────────────────────────────────────────
     Component vars for the workspace page + its slide-over panels. Each RHS is
     a clean `var(--<tier-1-token>)` alias (the HARD RULE above). The workspace
     surfaces previously read the RGB-channel `--color-*` set directly; they now
     alias the global design-token palette using the same `--color-*` → flat
     mapping the `.admin-root` scope established (page→--bg, panel→--bg-card,
     text-primary→--text, text-muted→--text-dim, border→--border,
     border-alt→--border-strong, accent→--mint). A component reads its own var
     (`border: 1px solid var(--workspace-border)`), never a raw literal. */
  /* Workspace shell surface */
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
  --workspace-accent: rgb(var(--accent));
  /* Public-project banner */
  --public-banner-bg: var(--warning-alpha-08);
  --public-banner-text: var(--warning);
  --public-banner-border: var(--warning-alpha-15);
  /* Social feed card */
  --feed-card-glow: var(--shadow-feed-glow);
  --feed-sync-icon: var(--sync-blue);
  --feed-push-icon: var(--success);
  --feed-pull-icon: var(--commit-amber);
  /* Services panel — workspace status badge */
  /* A badge label is text on a FILL, not text on the page, so it cannot read a
     rung tuned against the page. --text-faint clears AA on sandstorm's ivory
     page and measures 4.02 on --border, the fill this badge actually uses;
     --text-mid measures 5.83 there. Every dark theme improves too, since mid
     sits lighter than faint on a dark border. */

  /* ── Friends surface (FriendsPage) ────────────────────────────────────
     Component vars for the friends list, request rows, and invite banner.
     Each RHS aliases a Tier-1 token (or a color-mix over one); the
     component reads its own var, never a raw literal. */
  --friends-online-accent: var(--success);
  --friends-online-row-bg: color-mix(in srgb, var(--success) 3.5%, transparent);
  /* Idle is the presence register's absence step, held on the hue supply for
     the reason --sidebar-presence-offline is. */
  --friends-idle-accent: var(--amber);
  --friends-common-icon: var(--violet-light);
  --friends-dot-ring: var(--bg-card);
  /* One control renders all three, so they move together: the fill and edge
     tint the accent, the label takes its ink. Splitting the bundle across two
     hues paints a green pill with a coral label. */
  --friends-add-bg: color-mix(in srgb, rgb(var(--accent)) 10%, transparent);
  --friends-add-border: color-mix(in srgb, rgb(var(--accent)) 40%, transparent);
  --friends-add-text: var(--accent-ink-on-ground);
  --friends-invite-banner-tint: color-mix(in srgb, rgb(var(--accent)) 5%, transparent);

  /* ── Trending card (community/TrendingCard) ───────────────────────────
     Preview media backdrop reuses the shared --media-backdrop; star reuses
     the shared --star-active-color. Everything else aliases a Tier-1 token
     (or a color-mix over one). */
  /* Showcase harness labels (pages/showcase.css) — the demo page's own captions
     and axis labels. They previously dimmed body text with `opacity: 0.6`, which
     multiplies whatever ramp step it lands on and so renders a colour that is
     not a step at all: no theme can re-point it and the contrast gate measures a
     value present in no stylesheet. Measured, those three rules produced 64 of
     the 79 nodes failing the colour-contrast gate.
     Safe as :root aliases despite the declaring-element staleness that forces
     styles/surfaces.css to re-declare its --badge-* twins: every one of these
     labels renders on the page or panel ground. The harness's frame regions
     (.sc-rail, .sc-bar) carry their own --sc-* vars, declared inline on the
     element so they resolve inside the role. */
  /* Dev overlay chrome (components/shared/DesignOverlay.tsx) — dark by
     default in every theme; reachable like any component var. */
  --devoverlay-label-ink: rgb(var(--shade-neutral-575));
  --devoverlay-secondary-ink: rgb(var(--shade-neutral-525));
  --devoverlay-pill-bg: rgb(var(--shade-neutral-940));
  --devoverlay-pill-ink: rgb(var(--shade-neutral-500));

  /* One-off inks */
  --trendingcard-rank-ink: rgb(var(--shade-amber-990));
  --projectmodal-code-ink: rgb(var(--shade-neutral-300));

  /* Conversation event types (components/feed/CardConversation.tsx) — the
     glyph tile behind each turn's event marker. A CATEGORICAL set like the
     chart series, not a status vocabulary: `commit` is amber because amber
     reads as a commit, not because a commit is a warning, so forcing these
     onto the semantic registers would name them wrong.

     Declared as PAIRS because that is what they are — a tint and the ink that
     lands on it. They used to be built inside a TypeScript Record, where the
     ink sat one line below its own ground and no CSS-parsing instrument could
     reach either. The value space was already closed; only the file format put
     it out of reach. Each tint derives from the hue the theme declares, so a
     theme re-pointing a hue moves the pair together.

     The INK follows the closed-tone ink law rather than naming the hue
     outright, and for the same reason: a named hue is picked before the ground
     it lands on is known. These inks have TWO grounds — the tile, where the ink
     strokes a glyph, and the surface, where the same token paints the event
     LABEL as text — and the label obligation is the strict one. Fixed hues
     failed 218 pairs, worst `#8b5cf6` violet at 3.48 on a hover row. Shifted
     toward the surface's own pole they clear all but five near-misses.
     `--event-continuation-ink` shifts too, but off `--text-mid` rather than off
     a hue: it is the one categorical entry with no hue of its own, and a ramp
     rung authored against the surface ground still needs moving off the TILE
     it also paints. */
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));

  /* Capability families — a second CATEGORICAL palette, over the capability and
     infra pills a creation proposal lists (components/creation/). Four hues for
     fifteen capabilities, grouped by FAMILY rather than per capability, so a
     row reads as "two AI things and a database" instead of a rainbow.

     INK ONLY, and that is the whole difference from the event family above: a
     capability pill is a NEUTRAL chip whose glyph carries the family hue, so
     there is no tint to pair the ink with. The pill's LABEL is painted by the
     badge ink, never by these — which is why the schema grades them in the
     boundary register (a stroked glyph) rather than as text.

     Green and red are deliberately absent. Green is the chosen-answer state on
     the concierge's option pills, so a green capability would read as "you
     picked this" about something the user did not pick; red reads as an error.
     The ink derivation is the closed-tone ink law, for the same reason the
     event inks use it: a hue named outright is picked before the ground it
     lands on is known, and these pills sit on four different surface roles. */
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));

  /* Admin cost chart (components/admin/WorkspacesTabView.tsx) — the nine
     categorical series are declared per theme; only the slice separator stays
     here, because it is a hairline drawn ON the slice fills rather than on any
     theme ground, which is the same reason --scrim and --text-oncolor stay. */
  --chart-slice-stroke:    rgb(var(--shade-black) / 0.3);

  /* Skeleton primitive (components/shared/Skeleton.tsx) */
  --skeleton-shimmer: var(--bg-elev2);
  --skeleton-card-bg: var(--bg-card);
  --trending-card-bg: var(--bg-card);
  --trending-share-bg: var(--text-oncolor);
  --trending-share-text: var(--bg);
  --trending-preview-bg: color-mix(in srgb, var(--violet-light) 15%, transparent);
  --trending-preview-text: var(--violet-light);
  --trending-preview-border: color-mix(in srgb, var(--violet-light) 40%, transparent);
  --trending-badge-bg: color-mix(in srgb, var(--amber) 92%, transparent);
  --trending-overlay-bg: color-mix(in srgb, var(--black) 55%, transparent);

  /* ── Trending page (TrendingPage) ─────────────────────────────────────
     Skeleton surface reuses --trending-card-bg/-border; an error banner's
     ground is --tone-danger-bg, the graded tinted register. Page-specific
     roles below. */
  --trending-error-text: var(--danger);

  /* ── Fork error toast (community/ForkToast) ───────────────────────────
     Violet-tinted confirmation toast. Border/shadow are color-mixes over
     --violet-light; text roles alias the flat text tokens. */
  --fork-toast-bg: var(--bg-elev2);
  --fork-toast-border: color-mix(in srgb, var(--violet-light) 40%, transparent);
  --fork-toast-accent: var(--violet-light);
  --fork-toast-shadow-tint: color-mix(in srgb, var(--violet-light) 18%, transparent);
}


/* Design tokens drive bg/color/font. Root size is 100% — the reader's own
   setting — and the --mc-text-* ramp is expressed in rem against it.
   line-height is browser default (`normal`): Tailwind preflight sets
   html { line-height: 1.5 } which would cascade to every element and break
   the gate's per-element line-height comparison, so it is reset here. Text
   that wants a ratio gets one from the closed leading set, which the type
   scale binds per step. */
html, body {
  /* UA reset on the document root: html/body have no sibling to push against. */
  /* margin-ok: document-root reset, not a distance asserted at a sibling. */
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mc-font-mono);
  /* 100%, not a px value, and the difference is the whole accessibility case
     for the rem type ramp. A px root pins 1rem to a number the app chose, so
     the browser's text-size preference — the setting assistive-technology
     guidance points low-vision users to — has nothing to act on. It is not a
     WCAG 1.4.4 failure, because zoom still works; it is worse in practice,
     because zoom scales layout too and puts horizontal scroll on a fixed-width
     page, so the accessible path costs the reader more than it should.
     100% inherits whatever the reader set, and the whole --mc-text-* ramp
     tracks it. */
  font-size: 100%;
  line-height: normal;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* Prevent iOS Safari bounce/zoom */
  -webkit-text-size-adjust: 100%;
  -moz-text-size-adjust: 100%;
       text-size-adjust: 100%;
}
/* The reading baseline, separate from the rem basis above. `html` at 100%
   makes 1rem whatever the reader's browser text-size preference says; this
   makes the app's own default text the `body` role rather than that raw basis.
   Without it every element declaring no size of its own would render at the
   browser default — a step and a half above the baseline the scale names, and
   above every role that is supposed to read smaller than it. */
body { min-height: 100vh; font-size: var(--mc-text-body); }
#root { height: 100vh; }

/* MC-234: Tailwind preflight applies `*, ::before, ::after { border-color:
   theme('borderColor.DEFAULT'); }` which paints every unstyled element's
   border-color as `#e5e7eb` (slate-200). The design's reference HTML omits
   Tailwind so border-color falls back to currentColor everywhere. Mirror
   that fallback so the structural-diff gate doesn't fire on each unstyled
   element's borderColor (the diff cascades to ~1000 mismatches without
   this). Components that explicitly set a border-color still override. */
*, *::before, *::after {
  border-color: currentColor;
}

/* MC-234: Tailwind preflight applies
   `input::placeholder, textarea::placeholder { color: theme(...) }`
   at higher specificity than a bare `::placeholder` selector. Match
   that specificity so the override wins and the gate's pseudo-element
   comparison sees the chromium-default `rgb(117, 117, 117)` the
   reference HTML inherits. */
input::-moz-placeholder, textarea::-moz-placeholder {
  color: rgb(var(--shade-neutral-460)); /* chromium-default placeholder grey (parity with the reference HTML) */
  opacity: 1;
}
input::placeholder,
textarea::placeholder {
  color: rgb(var(--shade-neutral-460)); /* chromium-default placeholder grey (parity with the reference HTML) */
  opacity: 1;
}

/* Mobile: prevent content from exceeding viewport */
#root {
  max-width: 100vw;
  overflow-x: hidden;
}
button { font-family: inherit; cursor: pointer; }

/* Custom scrollbar */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: var(--scrollbar-track);
}

::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-hover);
}

/* ===== Raw-literal audit: closed Tailwind palette registry =====
   One "R G B" triplet per family-shade that web/src actually uses. The
   Tailwind config's theme.colors closure maps every palette class
   (bg-red-400, text-emerald-500/20, ...) through these vars, so the class
   values flow from THIS file and the palette is closed — an undeclared
   family-shade generates no CSS. Values are frozen at Tailwind's defaults
   (zero visual change); entries whose value already has a semantic token
   carry the cross-note. Prefer the semantic token for new work; these
   entries retire one by one as surfaces migrate to the two-tier
   convention. Theme-constant, declared on :root. */
:root {
  --shade-amber-100: 254 243 199;
  --shade-amber-200: 253 230 138;
  --shade-amber-300: 252 211 77;  /* = --amber-light */
  --shade-amber-400: 251 191 36;  /* = --commit-amber */
  --shade-amber-500: 245 158 11;  /* = --amber */
  --shade-amber-600: 217 119 6;
  --shade-amber-700: 180 83 9;
  --shade-amber-800: 146 64 14;
  --shade-amber-900: 120 53 15;
  --shade-blue-300: 147 197 253;  /* = --sync-blue */
  --shade-blue-400: 96 165 250;  /* = --info-light */
  --shade-blue-500: 59 130 246;  /* = --info */
  --shade-blue-600: 37 99 235;
  --shade-blue-700: 29 78 216;
  --shade-blue-800: 30 64 175;
  --shade-blue-900: 30 58 138;
  --shade-cyan-400: 34 211 238;  /* = --cyan */
  --shade-cyan-500: 6 182 212;
  --shade-cyan-600: 8 145 178;
  --shade-cyan-700: 14 116 144;
  --shade-cyan-800: 21 94 117;
  --shade-emerald-200: 167 243 208;
  --shade-emerald-300: 110 231 183;
  --shade-emerald-400: 52 211 153;  /* = --mint */
  --shade-emerald-450: 43 181 131;  /* = --mint-dim (app step, no Tailwind class) */
  --shade-emerald-500: 16 185 129;  /* = --success */
  --shade-emerald-600: 5 150 105;
  --shade-emerald-700: 4 120 87;
  --shade-emerald-800: 6 95 70;
  --shade-emerald-900: 6 78 59;
  --shade-emerald-950: 10 20 18;  /* app dark accent tint (= --accent-tint role), darker than Tailwind's emerald-950 */
  --shade-gray-100: 243 244 246;
  --shade-gray-300: 209 213 219;
  --shade-gray-400: 156 163 175;
  --shade-gray-500: 107 114 128;  /* = --neutral */
  --shade-gray-600: 75 85 99;
  --shade-gray-700: 55 65 81;  /* console-scope disabled submit */
  --shade-green-300: 134 239 172;
  --shade-green-400: 74 222 128;
  --shade-green-500: 34 197 94;
  --shade-green-600: 22 163 74;
  --shade-green-700: 21 128 61;
  --shade-green-900: 20 83 45;
  --shade-indigo-400: 129 140 248;
  --shade-indigo-500: 99 102 241;  /* = --indigo */
  --shade-orange-400: 251 146 60;
  --shade-orange-500: 249 115 22;  /* = --orange */
  --shade-orange-600: 234 88 12;
  --shade-orange-800: 154 52 18;
  --shade-pink-100: 250 232 242;  /* pale pink — meadow light-theme --accent-tint */
  --shade-pink-400: 244 114 182;
  --shade-pink-500: 236 72 153;  /* = --pink */
  --shade-pink-700: 190 24 93;
  --shade-pink-750: 180 19 108;  /* oklch(0.51 0.20 355) — meadow's display accent; pink-700 sits at 3.14 on the mint page, inside the noise of a 3.0 bar */
  --shade-purple-400: 192 132 252;
  --shade-purple-500: 168 85 247;
  --shade-purple-900: 88 28 135;
  --shade-red-100: 254 226 226;
  --shade-red-200: 254 202 202;
  --shade-red-300: 252 165 165;  /* midnight-mono --status-danger */
  --shade-red-350: 252 129 129;  /* app step, no Tailwind class */
  --shade-red-400: 248 113 113;
  --shade-red-500: 239 68 68;  /* = --danger */
  --shade-red-600: 220 38 38;
  --shade-red-700: 185 28 28;
  --shade-red-800: 153 27 27;
  --shade-red-900: 127 29 29;
  --shade-red-950: 69 10 10;
  --shade-rose-400: 251 113 133;  /* = --rose */
  --shade-rose-500: 244 63 94;
  --shade-rose-700: 190 18 60;
  --shade-sky-400: 56 189 248;
  --shade-sky-500: 14 165 233;
  --shade-slate-200: 226 232 240;  /* console-scope strong ink */
  --shade-slate-300: 203 213 225;
  --shade-slate-400: 148 163 184;
  --shade-slate-500: 100 116 139;  /* console-scope dim ink */
  --shade-slate-600: 71 85 105;
  --shade-slate-700: 51 65 85;  /* console-scope border-alt */
  --shade-slate-800: 30 41 59;  /* = --line-panel / console-scope border */
  --shade-slate-50: 241 245 249;   /* Tailwind slate-50 */
  --shade-slate-900: 15 23 42;
  /* app-specific bespoke shades (documented one-off identities) */
  --shade-neutral-300: 212 212 212; /* #d4d4d4 code-block ink (themeable step) */
  --shade-neutral-460: 117 117 117; /* chromium-default placeholder grey (parity, see body rule) */
  --shade-amber-990: 26 18 5;      /* #1a1205 on-amber rank-badge ink */
  --shade-rose-995: 26 6 8;        /* #1a0608 on-rose pin ink */
  --shade-emerald-995: 4 20 13;    /* #04140d on-mint pin ink */
  --shade-ink-scrim: 8 8 10;       /* #08080a blue-hinted card-scrim ink */
  --shade-night-800: 26 26 42;     /* #1a1a2a console field */
  --shade-night-860: 21 21 42;     /* #15152a console hover */
  --shade-night-900: 17 17 25;     /* #111119 console surface */
  --shade-night-935: 14 14 22;     /* #0e0e16 console panel */
  --shade-night-940: 13 13 20;     /* #0d0d14 console recess */
  /* overlay-chrome greys */
  --shade-neutral-525: 119 119 119; /* #777777 dev-overlay secondary ink */
  --shade-neutral-575: 102 102 102; /* #666666 dev-overlay label ink */
  --shade-neutral-940: 17 17 17;    /* #111111 dev-overlay pill ground */
  --shade-slate-950: 2 6 23;
  --shade-violet-300: 196 181 253;  /* terminal scope's accent hover — the ramp
     had no step above 400, which the scope's accent already takes, and a hover
     that darkens on a constant-dark ground reads as a press */
  --shade-violet-400: 167 139 250;  /* = --violet-light */
  --shade-violet-500: 139 92 246;  /* = --violet */
  --shade-violet-600: 124 58 237;
  --shade-violet-700: 109 40 217;
  --shade-violet-900: 76 29 149;
  --shade-yellow-300: 253 224 71;
  --shade-yellow-400: 250 204 21;
  --shade-yellow-500: 234 179 8;  /* = --yellow */
  --shade-yellow-600: 202 138 4;
  --shade-yellow-800: 133 77 14;
  --shade-yellow-900: 113 63 18;

  /* Theme-constant statics: pure white/black that NEVER shift with a theme.
     Back the on-colour text (--text-oncolor / --on-accent) and the pure-black
     scrims — these must stay #fff/#000 even under a warm (or any) theme, so
     they are deliberately OUTSIDE the themeable neutral ramp below. */
  --shade-white: 255 255 255;
  --shade-black:   0   0   0;

  /* The app's neutral ramp is PER-THEME (no :root fallback): every theme file
     declares a total 16-rung --shade-neutral-* palette — midnight-mono holds
     the canonical near-black/near-white valuation. Totality is enforced by
     tests/theme-manifest-totality.test.ts, so a missing rung fails a test
     instead of silently resolving here. The dev-overlay one-off steps
     (300/460/525/575/940) stay in the shared supply above. */
}

/* ===== Tier-1 ROLE tokens (four-tier model: palette → ROLE → semantic → component) =====
   The alpha-capable layer: a role is a bare triplet, so `rgb(var(--role) / a)`
   composes an alpha at the call site, which a pre-wrapped colour cannot do.
   Tailwind's theme-* / text-theme-* utilities and the inline alpha sites read
   a triplet; the Tier-2 semantic tokens (--bg* / --text*) wrap one with rgb().

   The SURFACE roles and the CONTENT ramp used to live here as a second set of
   names beside the role bundle further down this file, and nothing kept the
   two in agreement — a theme binds the bundle, so the moment it moved a role
   off its neutral-ramp rung the two names held different colours. They are
   collapsed: a ground is `--surface-<role>-bg-rgb` on the bundle and an ink
   rung is `--text-*-rgb` on the ambient ramp, each with a wrapped twin that
   derives from it. What remains here is the per-theme manifest surface.

   Lines / accent / status are PER-THEME manifest entries with no :root
   fallback — each theme file declares --line-panel/-alt, the --accent triple,
   and the four --status-* roles. midnight-mono holds the canonical values
   (slate lines, the blessed mint accent pairing, the 400 text-legibility
   status shades — deliberately distinct from the 500-shade icon/fill
   semantics --danger/--success/--warning/--info), so this tier declares
   nothing at :root. */

/* ===== Surface ROLE BUNDLES — the closed 5-role region vocabulary =====
   A region declares its role with `data-surface="<role>"`; the applicator
   (styles/surfaces.css) paints {bg + ink + border} from the role's bundle.

   THE THEME OWNS THE ROLE TABLE. Every theme file declares the full binding
   set (all five roles' bg + ink ladder + edges, plus hover) — enforced by
   tests/theme-manifest-totality.test.ts — and a theme block always out-ranks
   this rule. The bundles below are DERIVATION GLUE, not a default a theme
   deviates from: they keep the page painted before theme.ts stamps
   data-theme at boot (and in any DOM with no theme attribute), riding the
   Tier-2 chain so they resolve against whatever palette is live.
   Closed set, decision ladder + enforcement: docs/claude/surfaces.md. */
:root {
  /* The AMBIENT GROUND — the ground of whatever region is being painted, the
     way --text-* is the ink of whatever region is being painted. The
     applicator re-points the ink ramp per role and, with this, the ground
     too; before it existed, nothing named "the ground here" and a value that
     needed one had to reach for --bg (which means the PAGE ground to its
     consumers) or stay translucent and let the browser composite at paint
     time. A tinted control is the second kind: its ground existed only as a
     rendered pixel and appeared in no manifest.

     Defaults to the page ground, which is what an un-declared region sits on.
     A theme never declares this — it declares the role grounds, and this
     follows whichever one the region binds. */
  --surface-bg: var(--surface-page-bg);

  /* page — the deepest ground (sidebar bg-by-coincidence, deep card wells) */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-border: var(--border-panel);

  /* panel — the lifted step; carries a depth level via data-elevation="0|1|2"
     (0 = panel, 1 = elev, 2 = elev2), resolved by the applicator. The hover
     ground is shared with modal (a panel/modal :hover state overlay). */
  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));   /* data-elevation="1" */
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));  /* data-elevation="2" */
  /* Ink ramp + edge family default to the theme globals (identity → the
     applicator re-point is a no-op on a same-polarity theme); a mixed-polarity
     theme (meadow) overrides these so content inside a dark panel reads light,
     with zero component changes. The .admin-root pattern, per role. */
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       var(--border-panel);
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  /* modal — the overlay step */
  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       var(--border-panel);
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  /* field — the recessed input/select ground (the elev step, matching Input) */
  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       var(--border);
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  /* frame — structural chrome (sidebar/appshell/mobileshell). Default binding
     equals page so dark themes are byte-unchanged; a light-polarity theme
     overrides bg+ink to keep a dark rail carrying light ink (see meadow). The
     ink is a stepped ramp (chrome carries strong…faintest text weights); the
     steps default to the --text-* ramp and a light theme overrides them so the
     dark rail keeps light text even when the page ramp inverts. Border is the
     alpha hairline --border (what all three chrome silos used), not the opaque
     panel edge. */
  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);

  /* console — retired as a ROLE: it is a SCOPE (the role vocabulary rebound
     onto the night/slate palettes for a subtree). The rebinding ruleset lives
     with the applicator: styles/surfaces.css [data-scope="terminal"]. */
}
.last\:border-0:last-child {
  border-width: 0px;
}
.last\:border-b-0:last-child {
  border-bottom-width: 0px;
}
.empty\:hidden:empty {
  display: none;
}
.hover\:scale-\[1\.02\]:hover {
  --tw-scale-x: 1.02;
  --tw-scale-y: 1.02;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.hover\:border-accent:hover {
  --tw-border-opacity: 1;
  border-color: rgb(var(--accent) / var(--tw-border-opacity, 1));
}
.hover\:border-accent\/40:hover {
  border-color: rgb(var(--accent) / 0.4);
}
.hover\:border-theme-border:hover {
  --tw-border-opacity: 1;
  border-color: rgb(var(--line-panel) / var(--tw-border-opacity, 1));
}
.hover\:bg-\[var\(--surface-hover-bg\)\]:hover {
  background-color: var(--surface-hover-bg);
}
.hover\:bg-accent-hover:hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--accent-hover) / var(--tw-bg-opacity, 1));
}
.hover\:bg-accent\/20:hover {
  background-color: rgb(var(--accent) / 0.2);
}
.hover\:bg-accent\/5:hover {
  background-color: rgb(var(--accent) / 0.05);
}
.hover\:bg-accent\/50:hover {
  background-color: rgb(var(--accent) / 0.5);
}
.hover\:bg-status-danger\/10:hover {
  background-color: rgb(var(--status-danger) / 0.1);
}
.hover\:bg-theme-border-alt:hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--line-panel-alt) / var(--tw-bg-opacity, 1));
}
.hover\:bg-theme-hover:hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-hover-bg-rgb) / var(--tw-bg-opacity, 1));
}
.hover\:bg-theme-hover\/20:hover {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.2);
}
.hover\:bg-theme-hover\/30:hover {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.3);
}
.hover\:bg-theme-hover\/50:hover {
  background-color: rgb(var(--surface-hover-bg-rgb) / 0.5);
}
.hover\:bg-theme-panel:hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-panel-bg-rgb) / var(--tw-bg-opacity, 1));
}
.hover\:bg-theme-panel\/70:hover {
  background-color: rgb(var(--surface-panel-bg-rgb) / 0.7);
}
.hover\:text-accent:hover {
  color: var(--accent-ink-on-ground);
}
.hover\:text-accent-hover:hover {
  color: var(--accent-ink-hover-on-ground);
}
.hover\:text-status-danger:hover {
  color: var(--tone-danger-text);
}
.hover\:text-status-success:hover {
  color: var(--tone-success-text);
}
.hover\:text-theme-primary:hover {
  --tw-text-opacity: 1;
  color: rgb(var(--text-strong-rgb) / var(--tw-text-opacity, 1));
}
.hover\:text-theme-secondary:hover {
  --tw-text-opacity: 1;
  color: rgb(var(--text-mid-rgb) / var(--tw-text-opacity, 1));
}
.hover\:underline:hover {
  text-decoration-line: underline;
}
.hover\:no-underline:hover {
  text-decoration-line: none;
}
.hover\:opacity-100:hover {
  opacity: 1;
}
.hover\:opacity-80:hover {
  opacity: 0.8;
}
.hover\:shadow-\[var\(--shadow-accent-glow\)\]:hover {
  --tw-shadow-color: var(--shadow-accent-glow);
  --tw-shadow: var(--tw-shadow-colored);
}
.focus\:border-accent:focus {
  --tw-border-opacity: 1;
  border-color: rgb(var(--accent) / var(--tw-border-opacity, 1));
}
.focus\:outline-none:focus {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.focus\:ring-2:focus {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-accent\/50:focus {
  --tw-ring-color: rgb(var(--accent) / 0.5);
}
.focus\:ring-focus:focus {
  --tw-ring-color: var(--focus-ring);
}
.focus-visible\:outline-none:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.focus-visible\:ring-2:focus-visible {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus-visible\:ring-accent\/50:focus-visible {
  --tw-ring-color: rgb(var(--accent) / 0.5);
}
.active\:bg-theme-hover:active {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-hover-bg-rgb) / var(--tw-bg-opacity, 1));
}
.hover\:enabled\:bg-theme-hover:enabled:hover {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--surface-hover-bg-rgb) / var(--tw-bg-opacity, 1));
}
.hover\:enabled\:opacity-100:enabled:hover {
  opacity: 1;
}
.hover\:enabled\:opacity-90:enabled:hover {
  opacity: 0.9;
}
.hover\:enabled\:\[background\:var\(--ib-tint-hover-bg\)\]:enabled:hover {
  background: var(--ib-tint-hover-bg);
}
.hover\:enabled\:\[color\:var\(--ib-tint-hover\)\]:enabled:hover {
  color: var(--ib-tint-hover);
}
.disabled\:cursor-not-allowed:disabled {
  cursor: not-allowed;
}
.disabled\:cursor-wait:disabled {
  cursor: wait;
}
.disabled\:opacity-30:disabled {
  opacity: 0.3;
}
.disabled\:opacity-40:disabled {
  opacity: 0.4;
}
.disabled\:opacity-50:disabled {
  opacity: 0.5;
}
.disabled\:opacity-60:disabled {
  opacity: 0.6;
}
.disabled\:hover\:scale-100:hover:disabled {
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.disabled\:hover\:shadow-none:hover:disabled {
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.group:hover .group-hover\:translate-x-0\.5 {
  --tw-translate-x: var(--mc-space-0-5);
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.group:hover .group-hover\:bg-black\/40 {
  background-color: rgb(var(--shade-black) / 0.4);
}
.group:hover .group-hover\:text-theme-primary {
  --tw-text-opacity: 1;
  color: rgb(var(--text-strong-rgb) / var(--tw-text-opacity, 1));
}
.group:hover .group-hover\:text-theme-secondary {
  --tw-text-opacity: 1;
  color: rgb(var(--text-mid-rgb) / var(--tw-text-opacity, 1));
}
.group:hover .group-hover\:opacity-100 {
  opacity: 1;
}
.group:active .group-active\:bg-black\/40 {
  background-color: rgb(var(--shade-black) / 0.4);
}
.group:active .group-active\:opacity-100 {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {

  .motion-reduce\:transition-none {
    transition-property: none;
  }
}
@media (min-width: 640px) {

  .sm\:bottom-auto {
    bottom: auto;
  }

  .sm\:left-auto {
    left: auto;
  }

  .sm\:right-4 {
    right: var(--mc-space-4);
  }

  .sm\:top-4 {
    top: var(--mc-space-4);
  }

  .sm\:block {
    display: block;
  }

  .sm\:hidden {
    display: none;
  }

  .sm\:w-80 {
    width: 320px;
  }

  .sm\:max-w-\[var\(--mc-panel-w-lg\)\] {
    max-width: var(--mc-panel-w-lg);
  }

  .sm\:max-w-lg {
    max-width: 512px;
  }

  .sm\:grid-cols-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sm\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .sm\:items-center {
    align-items: center;
  }

  .sm\:gap-2 {
    gap: var(--mc-space-2);
  }

  .sm\:rounded-2xl {
    border-radius: 16px;
  }

  .sm\:rounded-xl {
    border-radius: 12px;
  }

  .sm\:p-4 {
    padding: var(--mc-space-4);
  }

  .sm\:px-4 {
    padding-left: var(--mc-space-4);
    padding-right: var(--mc-space-4);
  }
}
@media (min-width: 768px) {

  .md\:flex {
    display: flex;
  }

  .md\:hidden {
    display: none;
  }

  .md\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .md\:grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .md\:flex-row {
    flex-direction: row;
  }
}
@media (min-width: 820px) {

  .min-\[820px\]\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .min-\[820px\]\:grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (min-width: 1536px) {

  .\32xl\:grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Explore tab — categorized trending. Complements the design tokens above. */

.x-content { flex: 1; padding: 22px 28px 56px; overflow-y: auto; }

/* ── category pills in the filter bar ── */
.x-catpill { padding: 5px 12px 5px 8px; background: transparent;
  border: 1px solid var(--border); color: var(--text-dim);
  font-size: var(--mc-text-caption); border-radius: 20px; transition: all var(--mc-motion-duration-fast); white-space: nowrap; }
.x-catpill .g { width: 16px; height: 16px; border-radius: 5px; flex-shrink: 0;
  font-size: 9px; /* layout-literal-ok: category emoji in a 16px chip — glyph sizing below the 12px text floor; caption would overflow the chip */
  background: var(--surface-panel-bg-2); color: var(--text-dim);
  /* raw-layout-ok: single-glyph centring box — one child centred on both axes, not sibling rhythm (rungs 1–4 ruled out) */
  display: flex; align-items: center; justify-content: center; }
.x-catpill:hover { border-color: var(--border-strong); color: var(--text-mid); }
.x-catpill.on { color: var(--text-strong); }
.x-catpill .ct { font-size: var(--mc-text-caption); color: var(--text-faint); }
.x-catpill.on .ct { color: inherit; opacity: .7; }

/* ── trending hero ── */
/* Both distances are this block's own inset, not a push at a neighbour: the
   hero paints nothing, so padding lands the same pixels the margins did, and
   the strip's trailing space is subsumed by .x-section's lead-in (which the
   two margins collapsed to anyway). 13px and 30px sit off the --mc-space-*
   scale, so no Stack gap can carry them. */
.x-hero-head { padding-bottom: 13px; }
.x-hero-title { font-size: var(--mc-text-lead); font-weight: 600; color: var(--text-strong); }
/* hue-alias-ok: tints an EMOJI (🔥). Every platform that ships colour emoji
   ignores it outright, and where it does land it decorates a flame rather than
   reporting a state — there is no severity here to derive from. */
.x-flame { color: var(--rose); }
.x-hero-sub { font-size: var(--mc-text-caption); color: var(--text-dim); }
.x-hero-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 1180px) { .x-hero-grid { grid-template-columns: 1fr 1fr; } .x-hero-grid > :nth-child(3) { display: none; } }

.x-hero-card { background: var(--surface-panel-bg); border: 1px solid var(--border);
  border-radius: 14px; overflow: hidden; text-decoration: none; color: inherit;
  /* raw-layout-ok: shell column — card preview + meta meet with no inter-child rhythm gap; SpaceStep has no 0 (rungs 1–2 ruled out) */
  display: flex; flex-direction: column; transition: all var(--mc-motion-duration-fast); position: relative; }
.x-hero-card:hover { border-color: var(--white-alpha-16); transform: translateY(-2px); }  /* layout-literal-ok: motion offset — a distance travelled, not a layout dimension; the --mc-* scale describes layout */
.x-hero-card .x-prev { position: relative; aspect-ratio: 16 / 8.6; overflow: hidden; }
.x-rank { position: absolute; top: 10px; left: 10px; z-index: 3;
  width: 26px; height: 26px; border-radius: 8px; background: var(--scrim-rank);
  backdrop-filter: blur(8px);
  font-size: var(--mc-text-body); font-weight: 700; color: var(--xcard-text-oncolor);
  /* raw-layout-ok: single-glyph centring box — one child centred on both axes, not sibling rhythm (rungs 1–4 ruled out) */
  display: flex; align-items: center; justify-content: center; }
.x-hero-card .x-meta { padding: 13px 15px 14px; }
.x-hero-card .x-title { font-size: var(--mc-text-lead); font-weight: 600; color: var(--text-strong); }
.x-by { font-size: var(--mc-text-caption); color: var(--text-mid); }
.x-stat { margin-left: auto; font-size: var(--mc-text-caption); color: var(--text-dim); }

/* ── grid section headers (Community / Public) ── */
.x-section { padding-top: 30px; }
.x-railhead { padding-bottom: 13px; }
.x-railtitle { font-size: var(--mc-text-body); font-weight: 600; color: var(--text-strong); }
.x-count { font-size: var(--mc-text-caption); color: var(--text-faint);
  padding: 2px 8px; background: var(--surface-panel-bg-2); border-radius: 10px; }

/* ── responsive project grid (one per section) ── */
.x-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(296px, 1fr)); gap: 14px; }

/* ── explore card ── */
.xcard { background: var(--surface-panel-bg); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden; text-decoration: none; color: inherit;
  /* raw-layout-ok: shell column — card preview + meta meet with no inter-child rhythm gap; SpaceStep has no 0 (rungs 1–2 ruled out) */
  display: flex; flex-direction: column; transition: all var(--mc-motion-duration-fast); cursor: pointer; }
.x-hero-card { cursor: pointer; }
/* hue-alias-ok: a hover hairline at 30% alpha — the card says "you are on me",
   not what it is. Separator register; carries no meaning to derive. */
.xcard:hover { border-color: var(--violet-light-alpha-30); transform: translateY(-1px); }  /* layout-literal-ok: motion offset — a distance travelled, not a layout dimension; the --mc-* scale describes layout */
.xcard .x-prev { position: relative; aspect-ratio: 16 / 9.4; overflow: hidden; }

/* preview hover overlay */
.x-overlay { position: absolute; inset: 0; z-index: 2;
  background: var(--scrim-card); backdrop-filter: blur(2px);
  opacity: 0; transition: opacity var(--mc-motion-duration-fast);
  /* raw-layout-ok: centred overlay affordance — a single hover pair centred on both axes over an inset-0 fill, not sibling rhythm (rungs 1–3 ruled out) */
  display: flex; gap: 8px; align-items: center; justify-content: center; }
.xcard:hover .x-overlay, .x-hero-card:hover .x-overlay { opacity: 1; }
.x-open { padding: 7px 16px; background: var(--xcard-text-oncolor); color: var(--xcard-oncolor); border: none;
  border-radius: 6px; font-size: var(--mc-text-caption); font-weight: 700; text-decoration: none; }
.x-fork { padding: 7px 14px; background: var(--xcard-accent-alt); color: var(--xcard-oncolor); border: none;
  border-radius: 6px; font-size: var(--mc-text-caption); font-weight: 700; text-decoration: none; }

/* corner badges on preview */
.x-badges { position: absolute; top: 8px; right: 8px; z-index: 3; }
.x-pin { padding: 2px 7px; border-radius: 9px; font-size: 9px; font-weight: 700; /* layout-literal-ok: corner-badge glyph (HOT/NEW) — glyph sizing below the 12px text floor; a mark over the preview, not copy */
  backdrop-filter: blur(8px); letter-spacing: var(--mc-tracking-wide); }
/* hue-alias-ok: two CATEGORICAL pins over a project preview — HOT and NEW are
   labels, not severities, and the pair is closed: each fill already carries the
   ink authored to sit on it (--text-on-rose-pin / --text-on-mint-pin), so the
   reading is graded by the pair rather than by the surface underneath. Sitting
   on an arbitrary screenshot is exactly why the ground cannot be derived. */
.x-pin.hot { background: var(--rose-alpha-92); color: var(--text-on-rose-pin); }  /* hue-alias-ok: categorical label pin, closed fill+ink pair */
.x-pin.new { background: var(--mint-alpha-92); color: var(--text-on-mint-pin); }  /* hue-alias-ok: categorical label pin, closed fill+ink pair */
.x-tagpin { position: absolute; bottom: 8px; left: 8px; z-index: 3;
  padding: 2px 8px; border-radius: 9px; font-size: 9px; color: var(--xcard-text-oncolor); /* layout-literal-ok: corner-badge glyph (tag pin) — glyph sizing below the 12px text floor, matching .x-pin */
  background: var(--scrim-tagpin); backdrop-filter: blur(8px); letter-spacing: var(--mc-tracking-wide); }

.xcard .x-meta { padding: 11px 13px 12px; }
.x-title-sm { flex: 1; font-size: var(--mc-text-body); font-weight: 500; color: var(--text-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.x-sub { font-size: var(--mc-text-caption); color: var(--text-dim);
  padding-top: 7px; border-top: 1px solid var(--border-soft); }
.x-by-sm { color: var(--text-mid); }
.x-sub .x-spread { margin-left: auto; }
.x-trend { color: var(--xcard-accent); font-weight: 600; }
.x-trend .ar { font-size: 8px; } /* layout-literal-ok: trend arrow — glyph sizing below the 12px text floor; an ornament beside the figure, read as an icon */

/* empty result */
.x-empty { grid-column: 1 / -1; padding: 40px; text-align: center;
  border: 1px dashed var(--border-strong); border-radius: 12px; color: var(--text-dim); }

/* Touch: hide the desktop page header on ExplorePage. The .header bar (title +
   search + sort) is pixel-pinned to the desktop reference (MC-361) and lays out
   ~478px wide — on a 390px phone the parent `.main { overflow: hidden }` clips
   it, cutting off the sort control, and its reference-pinned raw <input>/<select>
   sit at 32px (below the 44px touch floor and unable to inherit --mc-control-*).
   The mobile shell's own top bar already provides the "Explore" title + a search
   affordance, so the page header is redundant on touch. Scoped to
   `pointer: coarse` + the explore design-scope, so the desktop reference render
   is untouched. Mobile search/sort on Explore is a follow-up (wire the mobile
   top-bar search for /explore). */
@media (pointer: coarse) {
  [data-design-scope="explore"] .header { display: none; }
}

/* Coarse tap floor for the category filter pill (FilterPill's .x-catpill) —
   a primary filter control on the mobile Explore page. Its resting geometry
   (5px 12px padding, ~26px) is reference-pinned for desktop, so the floor is
   min-height-only and rides pointer:coarse: the token resolves to 44px there
   and the fine-pointer render stays byte-identical (MC-361 pin honored). */
@media (pointer: coarse) {
  .x-catpill { min-height: var(--mc-control-sm); }
}
/* App-global chrome + animation utilities (extracted from index.css so the
   global sheet holds only tokens + base styles).
   - .chat-scroll-container: mobile scroll stabilization
   - shared @keyframes + .animate-* utilities (spin, fadeInScale, slide, pulse, flash)
   - .scrollbar-hide utility
   - app-shell layout classes (.main/.header/.search/.filterbar/.avatar), used
     across HomeGrid, SocialFeed, ExplorePage, MobileLayout, AdminConsole
   Imported once at the app root (main.tsx). */

/* Mobile scroll optimization - prevents wobbling/jank */
.chat-scroll-container {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  overflow-x: hidden;
  transform: translateZ(0);
  will-change: scroll-position;
  backface-visibility: hidden;
}

/* Prevent layout shifts during scroll */
.chat-scroll-container > * {
  transform: translateZ(0);
  max-width: 100%;
}

/* Prevent horizontal overflow from breaking mobile scroll */
.chat-scroll-container pre,
.chat-scroll-container code {
  max-width: 100%;
  overflow-x: auto;
  word-break: break-word;
}

/* Sync spinner */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Modal animations */
@keyframes fadeInScale {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Build status toast animations */
@keyframes slideUpIn {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes slideDownOut {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(20px); opacity: 0; }  /* layout-literal-ok: motion offset — a distance travelled, not a layout dimension; the --mc-* scale describes layout */
}
.animate-slide-up-in { animation: slideUpIn var(--mc-motion-duration-medium) var(--mc-motion-ease-decelerate); }
.animate-slide-down-out { animation: slideDownOut var(--mc-motion-duration-medium) var(--mc-motion-ease-accelerate) forwards; }

/* Drill-in navigation (New Project category → sub-category). A quick horizontal
   slide + fade: forward pushes in from the right, back from the left. Reduced
   motion zeros the duration tokens, so this becomes an instant swap. */
@keyframes drillInForward {
  from { transform: translateX(8%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
@keyframes drillInBack {
  from { transform: translateX(-8%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
.animate-drill-in { animation: drillInForward var(--mc-motion-duration-slow) var(--mc-motion-ease-decelerate); }
.animate-drill-out { animation: drillInBack var(--mc-motion-duration-slow) var(--mc-motion-ease-decelerate); }

/* Social feed — status badge pulse (matches prototype dp keyframe) */
@keyframes statusPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.3; transform: scale(0.7); }
}

/* Hide scrollbar for clean horizontal scroll */
.scrollbar-hide {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
  display: none;
}

/* App-shell layout classes */
/* raw-layout-ok: shell content column — a grow/clip track (min-width:0; overflow:hidden), no inter-child rhythm gap; SpaceStep has no 0 (rungs 1–2 ruled out) */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.header { padding: 18px 28px;
  border-bottom: 1px solid var(--border); }
.h-title { font-size: var(--mc-text-title); font-weight: 600; color: var(--text-strong); }
/* No margin-top: the title/subtitle pair is arranged by PageHeader's own
   titleBlock Stack (gap 0.5 = the same 2px), in styled and unstyled mode alike. */
.h-sub { font-size: var(--mc-text-caption); color: var(--text-dim); }
.search { flex: 1; max-width: 280px; position: relative; }
.search input { width: 100%; padding: 8px 10px 8px 28px; background: var(--appshell-surface);
  border: 1px solid var(--border); border-radius: 6px;
  color: var(--text-strong); font-size: var(--mc-text-caption); outline: none; }
.search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--text-faint); font-size: var(--mc-text-caption); }
.sel { background: var(--appshell-surface); color: var(--text-mid);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 8px 10px; font-size: var(--mc-text-caption); outline: none; }
.icon-btn { padding: 8px 10px; background: var(--appshell-surface); color: var(--text-mid);
  border: 1px solid var(--border); border-radius: 6px; font-size: var(--mc-text-body);
  width: 36px;
  /* raw-layout-ok: single-glyph centring box — one icon centred on both axes, not sibling rhythm (rungs 1–4 ruled out) */
  display: flex; align-items: center; justify-content: center; }
.spacer { flex: 1; }
.filterbar { padding: 10px 28px;
  border-bottom: 1px solid var(--border-soft); }

.avatar { border-radius: 50%; color: var(--appshell-oncolor); font-weight: 700;
  /* raw-layout-ok: single-glyph centring box — the avatar initial, one child centred, not sibling rhythm (rungs 1–4 ruled out) */
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mc-font-mono); flex-shrink: 0; }

/* ── Button sockets (Button.tsx) ────────────────────────────────────────────
   A custom property whose value holds a `var()` computes at the element that
   DECLARES it, not at the element that reads it. Declared at `:root`, a
   control token therefore freezes at the PAGE's ground: a `data-surface` role
   or a `data-scope` subtree can re-point `--tone-danger-text` all it likes and
   the button keeps `:root`'s answer. The generated applicator
   (styles/surfaces.css) worked around that by re-declaring every dependent
   token inside every role block — correct, and a whole population of lines
   whose only job is to defeat the binding rule.

   Declaring the socket HERE removes the need for that population entirely. The
   rule matches on the button itself, so every `var()` on the right-hand side
   resolves in the region the button actually sits in. The socket name drops
   the matrix (`--btn-tinted-danger-text` → `--btn-text`) because the element
   already carries its own emphasis and tone as attributes — the selector
   holds what the name used to.

   The paint stays in Button.tsx as inline PROPERTY declarations reading these
   three sockets; a property binds at the matched element, so it was never the
   broken half. Ghost is the one emphasis with no `--btn-bg`: its background is
   a Tailwind class so the hover rule can override it, and an inline background
   always beats a class. */
.mc-btn {
  --btn-bg: transparent;
  --btn-text: var(--text);
  --btn-border: transparent;
}

/* solid — filled tone, on-colour ink. The ink is the tone vocabulary's
   `-oncolor` entry, which each theme states per tone: a status fill can sit at
   any rung, so the ink that clears it is a theme decision, not a derivation. */
.mc-btn[data-emphasis="solid"][data-tone="success"] { --btn-bg: var(--success);          --btn-text: var(--tone-success-oncolor); }
.mc-btn[data-emphasis="solid"][data-tone="warning"] { --btn-bg: var(--warning);          --btn-text: var(--tone-warning-oncolor); }
.mc-btn[data-emphasis="solid"][data-tone="danger"]  { --btn-bg: var(--danger);           --btn-text: var(--tone-danger-oncolor); }
.mc-btn[data-emphasis="solid"][data-tone="info"]    { --btn-bg: var(--info);             --btn-text: var(--tone-info-oncolor); }
.mc-btn[data-emphasis="solid"][data-tone="brand"]   { --btn-bg: rgb(var(--accent));      --btn-text: var(--tone-brand-oncolor); }
.mc-btn[data-emphasis="solid"][data-tone="stopped"] { --btn-bg: var(--stopped);          --btn-text: var(--tone-stopped-oncolor); }
/* NO TONE — the button makes no claim, which is what `secondary` and `ghost`
   always were. Selected by the ABSENCE of the attribute rather than by a
   `neutral` value, so the vocabulary has one way to say "no claim" instead of
   a name that looks like one.

   The solid case's label is the REGION's ground, not the page's, and this is
   the declaration site that makes that true rather than aspirational: the fill
   is `--text-dim`, a ramp rung, so ground and fill sit at opposite ends of that
   ramp on whichever surface the button lands. */
.mc-btn[data-emphasis="solid"]:not([data-tone]) {
  --btn-bg: var(--text-dim);
  --btn-text: var(--surface-bg);
}

/* tinted — 10% fill / solid ink / 30% border, off the shared tone set. Its
   hover DEEPENS the tint rather than dimming the whole control's opacity,
   which is the mechanism Pill already ships (--pill-tint-rest/-hover below).
   The app carried both treatments; this makes them agree.

   Opacity was the wrong instrument twice over. It fades the INK along with the
   fill, so the one part of the control that has to stay readable gets less
   readable the moment you point at it; and it is a fixed 10% dim whatever a
   theme did to --tone-bg-mix, so a theme that lifts the tint for a light
   polarity gets a hover that no longer reads as one.

   The rest strength IS `var(--tone-bg-mix)` over `--surface-bg`, which is
   exactly what `--tone-<t>-bg` composes, so nothing moves until the pointer
   arrives. */
.mc-btn[data-emphasis="tinted"] {
  --btn-tint-rest: var(--tone-bg-mix);
  --btn-tint-hover: calc(var(--tone-bg-mix) + 6%);
  --btn-fill: var(--btn-tint-rest);
  --btn-bg: color-mix(in srgb, var(--btn-tint-hue) var(--btn-fill), var(--surface-bg));
}
/* Each tone supplies its HUE; the fill strength above is shared, so lifting a
   theme knob moves every tinted button together. */
.mc-btn[data-emphasis="tinted"]:not([data-tone]) {
  --btn-tint-hue: var(--text-dim);
  --btn-text: var(--tone-neutral-text);
  --btn-border: var(--tone-neutral-border);
}
.mc-btn[data-emphasis="tinted"][data-tone="success"]   { --btn-tint-hue: var(--success);     --btn-text: var(--tone-success-text);   --btn-border: var(--tone-success-border); }
.mc-btn[data-emphasis="tinted"][data-tone="warning"]   { --btn-tint-hue: var(--warning);     --btn-text: var(--tone-warning-text);   --btn-border: var(--tone-warning-border); }
.mc-btn[data-emphasis="tinted"][data-tone="danger"]    { --btn-tint-hue: var(--danger);      --btn-text: var(--tone-danger-text);    --btn-border: var(--tone-danger-border); }
.mc-btn[data-emphasis="tinted"][data-tone="brand"]     { --btn-tint-hue: rgb(var(--accent)); --btn-text: var(--tone-brand-text);     --btn-border: var(--tone-brand-border); }
.mc-btn[data-emphasis="tinted"][data-tone="info"]      { --btn-tint-hue: var(--info);        --btn-text: var(--tone-info-text);      --btn-border: var(--tone-info-border); }
.mc-btn[data-emphasis="tinted"][data-tone="progress"] {
  --btn-tint-hue: var(--progress);
  --btn-text: var(--tone-progress-text);
  --btn-border: var(--tone-progress-border);
}
.mc-btn[data-emphasis="tinted"][data-tone="attention"] {
  --btn-tint-hue: var(--attention);
  --btn-text: var(--tone-attention-text);
  --btn-border: var(--tone-attention-border);
}
.mc-btn[data-emphasis="tinted"][data-tone="stopped"] {
  --btn-tint-hue: var(--stopped);
  --btn-text: var(--tone-stopped-text);
  --btn-border: var(--tone-stopped-border);
}
/* :not(:disabled) because CSS :hover matches a disabled control too — without
   the guard a disabled button paints the interactive affordance. */
button.mc-btn[data-emphasis="tinted"]:not(:disabled):hover { --btn-fill: var(--btn-tint-hover); }

/* outline — transparent fill, tone ink + edge. Neutral is the secondary
   button and keeps the elevated-surface look instead.

   Its three values are read through optional theme INPUTS
   (`--btn-outline-neutral-{fill,ink,edge}`) with the default as the fallback,
   the same shape `--tone-<t>-text` uses for `--tone-<t>-ink`. That indirection
   is load-bearing: sandstorm and meadow give the secondary button an accent
   tint, and a theme that re-declared the SOCKET would out-rank this rule for
   every theme rather than its own. Reading an input the other five do not
   declare keeps the default composing against whichever ground it lands on. */
.mc-btn[data-emphasis="outline"]:not([data-tone]) {
  --btn-bg: var(--btn-outline-neutral-fill, var(--bg-elev));
  /* Composed here, inside the graph, rather than at a theme block: a theme
     that froze a COMPOSITION would freeze the polarity of its own block while
     the ground recomputes per role. A theme picks the ink TRIPLET; the mix
     happens where the button is. */
  --btn-text: color-mix(in oklab, rgb(var(--btn-outline-neutral-ink, var(--text-rgb))), var(--tone-ink-toward) var(--tone-ink-shift));
  --btn-border: var(--btn-outline-neutral-edge, var(--border));
}
.mc-btn[data-emphasis="outline"][data-tone="success"] { --btn-text: var(--tone-success-text); --btn-border: var(--tone-success-border); }
.mc-btn[data-emphasis="outline"][data-tone="warning"] { --btn-text: var(--tone-warning-text); --btn-border: var(--tone-warning-border); }
.mc-btn[data-emphasis="outline"][data-tone="danger"]  { --btn-text: var(--tone-danger-text);  --btn-border: var(--tone-danger-border); }
.mc-btn[data-emphasis="outline"][data-tone="brand"]   { --btn-text: var(--tone-brand-text);   --btn-border: var(--tone-brand-border); }
.mc-btn[data-emphasis="outline"][data-tone="info"]    { --btn-text: var(--tone-info-text);    --btn-border: var(--tone-info-border); }
.mc-btn[data-emphasis="outline"][data-tone="stopped"] {
  --btn-text: var(--tone-stopped-text);
  --btn-border: var(--tone-stopped-border);
}

/* ghost — transparent, tone ink; neutral is the plain text button */
.mc-btn[data-emphasis="ghost"][data-tone="success"] { --btn-text: var(--tone-success-text); }
.mc-btn[data-emphasis="ghost"][data-tone="warning"] { --btn-text: var(--tone-warning-text); }
.mc-btn[data-emphasis="ghost"][data-tone="danger"]  { --btn-text: var(--tone-danger-text); }
.mc-btn[data-emphasis="ghost"][data-tone="brand"]   { --btn-text: var(--tone-brand-text); }
.mc-btn[data-emphasis="ghost"][data-tone="info"]    { --btn-text: var(--tone-info-text); }
.mc-btn[data-emphasis="ghost"][data-tone="stopped"] {
  --btn-text: var(--tone-stopped-text);
}

/* ── Badge sockets (Badge.tsx) ──────────────────────────────────────────────
   Same declaration-site rule as .mc-btn above, and the reason it matters here
   is the incident that named it: a CreditBadge sitting on the black app frame
   kept the page's dark green ink and rendered unreadable, because
   `--badge-brand-text` had already computed at `:root` before the frame ever
   re-pointed the tone under it. Keyed on data-tone alone — a badge paints the
   same three slots for every register, so there is no emphasis axis. */
/* The base rule IS the no-claim treatment: a chip with no data-tone is a
   label — a plugin id, a plan name, a count — and takes the neutral tint,
   whose fill is a ramp rung rather than a status colour. */
.mc-badge {
  --badge-bg: var(--tone-neutral-bg);
  --badge-text: var(--tone-neutral-text);
  --badge-border: var(--tone-neutral-border);
}
.mc-badge[data-tone="success"]  { --badge-bg: var(--tone-success-bg);  --badge-text: var(--tone-success-text);  --badge-border: var(--tone-success-border); }
.mc-badge[data-tone="warning"]  { --badge-bg: var(--tone-warning-bg);  --badge-text: var(--tone-warning-text);  --badge-border: var(--tone-warning-border); }
.mc-badge[data-tone="danger"]   { --badge-bg: var(--tone-danger-bg);   --badge-text: var(--tone-danger-text);   --badge-border: var(--tone-danger-border); }
.mc-badge[data-tone="info"]     { --badge-bg: var(--tone-info-bg);     --badge-text: var(--tone-info-text);     --badge-border: var(--tone-info-border); }
.mc-badge[data-tone="brand"]    { --badge-bg: var(--tone-brand-bg);    --badge-text: var(--tone-brand-text);    --badge-border: var(--tone-brand-border); }
.mc-badge[data-tone="progress"] { --badge-bg: var(--tone-progress-bg); --badge-text: var(--tone-progress-text); --badge-border: var(--tone-progress-border); }
.mc-badge[data-tone="attention"] { --badge-bg: var(--tone-attention-bg); --badge-text: var(--tone-attention-text); --badge-border: var(--tone-attention-border); }
.mc-badge[data-tone="stopped"]   { --badge-bg: var(--tone-stopped-bg);   --badge-text: var(--tone-stopped-text);   --badge-border: var(--tone-stopped-border); }

/* ── IconButton sockets (IconButton.tsx) ────────────────────────────────────
   Declaration site again, keyed on data-tone. `default` is the resting glyph
   rung, which is the one value the primitive already got right by painting it
   as a PROPERTY — a property binds at the matched element. The other three
   went through `:root` aliases and did not.

   The `tint` variant is deliberately untouched: its values are `var()`
   references the CALLER supplies from another domain's tokens, delivered as
   inline custom properties on the element itself. That is already a
   component-scoped declaration — the correct shape, arrived at from the other
   direction. */
.mc-iconbtn {
  --iconbtn-text: var(--text-dim);
  --iconbtn-bg: transparent;
  /* Caller-tint fallbacks. Every `tint` call overrides all three inline from
     its own scoped tokens, so these are what a mis-wired call falls back to —
     and a fallback is more useful resolving in the region than at the page.
     The hover surface is fully transparent but token-referencing, because the
     two-tier layer forbids a bare `transparent` literal on a Tier-2 var. */
  --ib-tint-idle: var(--text-dim);
  --ib-tint-hover: var(--text-dim);
  --ib-tint-hover-bg: color-mix(in srgb, var(--bg-hover) 0%, transparent);
}
.mc-iconbtn[data-tone="danger"] {
  --iconbtn-text: var(--tone-danger-text);
}
.mc-iconbtn[data-tone="overlay"] {
  --iconbtn-text: var(--text-oncolor);
}
/* overlay-solid: a filled scrim disc for a control floating over a dim overlay
   (coach exit, lightbox nav) — legible where the transparent `overlay` tone
   reads too faint on a busy backdrop. */
.mc-iconbtn[data-tone="overlay-solid"] {
  --iconbtn-text: var(--text-oncolor);
  --iconbtn-bg: var(--scrim);
}

/* ── Active filter-chip vocabulary ──────────────────────────────────────────
   The app-shell's accent chip: a tint of the SHELL accent, its own edge over
   that tint, and the ink that has to clear it. Two consumers carry it — the
   SegmentedControl pill treatment and the showcase accent-seam probe — so it
   is a shared class rather than a socket on either one. Declared here for the
   same reason as its siblings: `--surface-bg` and `--accent-ink-on-ground` are
   both re-pointed per role, and a chip that resolved them at `:root` would
   tint the page's ground while sitting on a panel.

   ONE class carries the whole vocabulary, including the inactive ink. Splitting
   it by state was tried and is wrong: an inactive chip still READS the active
   border (its own rule overrides only the colour, not the width), so a chip
   that declared just the muted half left the shorthand referencing an undefined
   var — which CSS answers by dropping the whole declaration, and the border
   disappeared rather than changing colour. */
.mc-chip-tokens {
  --pill-active-bg: color-mix(in srgb, var(--appshell-accent) var(--tone-bg-mix), var(--surface-bg));
  --pill-active-border: color-mix(in srgb, var(--appshell-accent) var(--tone-border-mix), var(--pill-active-bg));
  /* The ink, not the fill the two lines above tint with: this text sits ON that
     tint, so the accent's own brightness is what it has to clear. */
  --pill-active-text: var(--accent-ink-on-ground);
  --pill-inactive-text: var(--text-dim);
}

/* Pill primitive tone/tint (Pill.tsx). The runtime color-mix — tinting an
   arbitrary caller tone — and the :hover deepen can't live inline in the
   primitive (its .tsx token-discipline scan forbids functional colour forms and
   arbitrary-value Tailwind, and a primitive can't import a stylesheet). So
   Pill.tsx sets the runtime colour as --pill-tone and toggles these global
   classes. --pill-fill is the active tint strength (rest, or the deeper hover). */
.mc-pill--tone {
  /* Fill strengths derive from the theme-bound tone knobs (--tone-*-mix in
     index.css), so a pill retones with Button/Badge when a light-polarity theme
     lifts them — one knob, every tinted control. The calc() deltas reproduce the
     historical dark values (rest≈10%, hover 16%, border 40%) so dark themes are
     visually unchanged; meadow (18%/45%) lifts all three. */
  --pill-tint-rest: var(--tone-bg-mix);
  --pill-tint-hover: calc(var(--tone-bg-mix) + 6%);
  --pill-border-strength: calc(var(--tone-border-mix) + 10%);
  /* The pill's own tone. This used to be an inline override target — a caller
     handed Pill any CSS colour and it landed here — and this line was only the
     fallback. The prop is gone, so the fallback IS the value: a pill is the app
     accent, and a control that needs to say which STATE it is in reaches for
     Badge's closed register set instead. */
  --pill-tone: var(--appshell-accent);
  --pill-fill: var(--pill-tint-rest);
  /* Mixed over the region's ambient ground rather than over `transparent`, the
     same move the closed tones took: the arithmetic is identical (a colour at
     N% over G equals that colour at N% alpha composited over G), so no pill
     moves, but the fill becomes a value derived from two declared inputs
     instead of one that exists only where it happens to land. */
  background: color-mix(in srgb, var(--pill-tone) var(--pill-fill), var(--surface-bg));
  /* Ink derives from the tone rather than repeating it: the tone is a FILL, and
     the text sits on a tint OF that fill, so the bare tone never clears AA
     against its own tint. --tone-ink-toward / --tone-ink-shift (index.css) carry
     the theme's polarity — white on a dark theme, black on a light one — so one
     declaration serves both instead of a darken-only knob that is correct on
     half the themes. Mixed in oklab; an srgb mix desaturates.

     This is the SAME expression every closed tone's ink now uses — the ink law
     is one law, and the runtime tone is its open-tone instance.

     Declared as a component var and then read, rather than mixed inline in the
     `color` property, which is the two-tier form the rest of the vocabulary
     takes: Badge reads --badge-<t>-text, and this reads its twin. It stays in
     this rule rather than moving to index.css because the two ink knobs it
     reads are re-pointed per surface role: declared here it recomputes inside
     each region, and declared at :root it would freeze at the page's polarity
     for every pill on the page. */
  --pill-tone-text: color-mix(in oklab, var(--pill-tone), var(--tone-ink-toward) var(--tone-ink-shift));
  color: var(--pill-tone-text);
}
/* A bordered tone pill is a toggle; its on-state rests at the deeper hover
   strength so "selected" reads clearly, and its edge is the tinted tone. */
.mc-pill--tone.mc-pill--bordered {
  /* The edge composites over the pill's OWN fill, not over the surface: a
     background paints to the border edge, so that is the ground behind this
     pixel. Seeding it on the surface instead would shift every bordered pill's
     edge by the fill's own contribution. */
  border-color: color-mix(
    in srgb,
    var(--pill-tone) var(--pill-border-strength),
    color-mix(in srgb, var(--pill-tone) var(--pill-tint-hover), var(--surface-bg))
  );
  --pill-fill: var(--pill-tint-hover);
}
button.mc-pill--tone:not(:disabled):hover { --pill-fill: var(--pill-tint-hover); }
.mc-pill--tone .mc-pill__dot { background: var(--pill-tone); }
/* Radar-ping — the "still working" active-step treatment for the conversation
   feed. Replaces a subtle fade/shrink (statusPulse, or Tailwind's animate-pulse)
   — which read as idle — with a SOLID dot that never fades or shrinks, plus an
   expanding, fading ring so live agent activity is unmistakable ("Option A").
   Applied to two active-step dots today: the StatusRail live node and the
   ActivityCard in-progress status Pill. Each consumer supplies its own accent
   via --radar-ring-color (StatusRail: --feedcard-accent; Pill: --pill-tone), so
   the ring always matches the dot's own colour — no hardcoded hue. The
   statusPulse keyframe above is retained for the out-of-scope PromptBar /
   AgentStartingHero cold-start indicators. */
@keyframes radarPing {
  0% { transform: scale(1); opacity: 0.6; }
  80%, 100% { transform: scale(2.6); opacity: 0; }
}
.mc-radar-ping { position: relative; }
.mc-radar-ping::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background: var(--radar-ring-color);
  pointer-events: none;
  animation: radarPing 0.9s cubic-bezier(0, 0, 0.2, 1) infinite; /* layout-literal-ok: radar-ping cadence conveys live agent activity; survives reduced motion by staying off the duration tokens (static-ring fallback below) */
}
/* Reduced motion: drop the animated ring, but keep a static ring so "working"
   still reads as more than an idle dot. */
@media (prefers-reduced-motion: reduce) {
  .mc-radar-ping::after { animation: none; }
  .mc-radar-ping {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--radar-ring-color) 30%, transparent);
  }
}
/* The Pill status dot's radar tone — inherits the pill's own runtime tone. */
.mc-pill__dot--radar { --radar-ring-color: var(--pill-tone); }

/* Preview wake/rebuild overlay ("Pulse", spec 2026-07-31-resume-wake-overlay):
   a breathing accent dot reusing the radarPing ring, plus an indeterminate
   sweep bar for the rebuild case. Both live on the accent role. Reduced motion
   freezes the breathe and swaps the ring for the same static halo the radar
   fallback uses; the sweep parks as a static leading segment so "in flight"
   still reads. */
.mc-wake-dot {
  position: relative;
  width: var(--mc-icon-sm);
  height: var(--mc-icon-sm);
  border-radius: 9999px;
  background: rgb(var(--accent));
  --radar-ring-color: rgb(var(--accent));
  animation: wakeBreathe 2.2s ease-in-out infinite; /* layout-literal-ok: breathe cadence conveys an in-flight wake; stays off the motion duration tokens (reduced motion zeroes those into a 0s infinite loop) — the reduced-motion block below owns the fallback */
}
@keyframes wakeBreathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.35); }
}
.mc-wake-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background: var(--radar-ring-color);
  pointer-events: none;
  animation: radarPing 2.2s var(--mc-motion-ease-decelerate) infinite; /* layout-literal-ok: ring cadence matches the breathe above — off the duration tokens for the same reason */
}
.mc-sweep-bar {
  position: relative;
  overflow: hidden;
  width: 200px;
  height: 4px;
  border-radius: 9999px;
  background: color-mix(in srgb, rgb(var(--accent)) 18%, transparent);
}
.mc-sweep-bar::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: -40%;
  width: 40%;
  border-radius: 9999px;
  background: linear-gradient(90deg, transparent, rgb(var(--accent)), transparent);
  animation: sweepSlide 1.6s ease-in-out infinite; /* layout-literal-ok: sweep cadence conveys indeterminate progress — off the duration tokens for the same reason */
}
@keyframes sweepSlide {
  0% { left: -40%; }
  100% { left: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .mc-wake-dot { animation: none; }
  .mc-wake-dot::after {
    animation: none;
    background: transparent;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--radar-ring-color) 30%, transparent);
  }
  .mc-sweep-bar::after { animation: none; left: 0; }
}

/* Coarse floor for Pill's interactive roles (toggle filter pill / action
   chip — the button-rendered forms). Element-scoped to <button> so the
   display <span> role keeps its dense status-pill geometry: a read-only
   pill is not a tap target. min-height only; fine pointers never match. */
@media (pointer: coarse) {
  button.mc-pill {
    min-height: var(--mc-control-sm);
  }
}

/* Same floor for Badge's interactive form, and for the same reason: a display
   Badge is a dense metadata chip that reads without being touched, while a
   Badge with an onClick is an action ("Add credits", "Change plan"). Sizing
   from padding and a 10px font alone put those at roughly 23px on touch. */
@media (pointer: coarse) {
  button.mc-badge-action {
    min-height: var(--mc-control-sm);
  }
}

/* Touch tap floor for raw controls that don't read --mc-control-*. The rule,
   rather than a roster that would go stale on the next adopter: a control that
   carries the raw-control escape marker sizes from its own padding and font, so
   it never inherits the coarse token bump the primitives get for free — and if
   a thumb aims at it, it needs this class. On a coarse pointer it grows to the
   control-token floor; `pointer: fine` (desktop) is unaffected.

   The exception is what separates this class from data-tap-exempt: a control a
   thumb does NOT aim at — a dense filter chip, a category pill, a native
   checkbox glyph whose label extends the target — carries the exemption
   attribute and a reason instead. "Raw" is not the test; "aimed at" is.

   Reads the same token as the blocks below rather than repeating its value, so
   the floor has one declaration site — the coarse override in
   design-tokens.css. See docs/claude/responsive-spec.md. */
@media (pointer: coarse) {
  .touch-target { min-height: var(--mc-control-sm); }
}

/* Coarse floors for the closed-set toggle primitives (ToggleButton's
   `mc-toggle`, SegmentedControl's per-segment `mc-segment`): they size from
   caller padding + font, not --mc-control-*, so they need their own floor.
   min-height only — padding/width untouched so tight headers keep their
   layout; the token resolves to 44px inside this block (the coarse override
   above raises it), so no second literal. Fine pointers never match. */
@media (pointer: coarse) {
  .mc-toggle,
  .mc-segment {
    min-height: var(--mc-control-sm);
  }
}

/* Coarse floor for Switch, both treatments. The `switch` treatment's TRACK is
   deliberately not the thing that grows: its 20px height, 36px width and 20px
   knob travel are one arithmetic, so the button around it takes the floor and
   the track keeps every number it had. The `pill` treatment sizes from padding
   plus a caption font, the same shape as .mc-toggle above. min-height only, and
   the same token, so neither gains a second literal. */
@media (pointer: coarse) {
  .mc-switch-tap {
    min-height: var(--mc-control-sm);
  }
}

/* Coarse floor for InlineLink's STANDALONE seat — a link that is a flex or
   stack item (a service name, a build/branch chip, "see all", "Retry") rather
   than a word inside a sentence. The primitive is boxless by design, so it has
   no height of its own and lands around 17-22px; nothing constrains it the way
   a line box constrains a mid-prose link, which is exactly why WCAG's inline
   exemption does not reach it and the `inline` seat is left alone here.
   min-height only, and the primitive supplies the `inline-flex items-center`
   that makes it visible (an inline <a> would ignore min-height outright). Same
   token as the block above, so no second literal; fine pointers never match. */
@media (pointer: coarse) {
  .mc-inline-link-standalone {
    min-height: var(--mc-control-sm);
  }
}
/* GENERATED FILE — do not edit by hand.
   Written by scripts/gen-surfaces.ts from the theme contract schema
   (web/src/utils/theme-schema.ts). Regenerate with `npm run gen:surfaces`.
   tests/surfaces-generated.test.ts fails when this file and a fresh run
   disagree, so an edit made here is reverted by the next regeneration. */

/* ===========================================================================
   Surface-role applicator — paints {bg + ink + border} from the role bundle a
   region declares with `data-surface="<role>"`. This is the region-level analog
   of the `data-design-scope` attribute mechanism (styles/design-tokens.css),
   one tier down: it BINDS a bundle rather than re-pointing tokens ad hoc.

   The bundle tokens (`--surface-<role>-bg/-ink/-border`) live in web/src/index.css;
   the closed set, decision ladder, and enforcement live in docs/claude/surfaces.md.

   `border-color` is set but inert until the region opts into a visible border
   (border-width/style) — so declaring a role never paints an unwanted edge.
   =========================================================================== */

/* Role-ground utilities — the ambient ground follows the ground a region
   PAINTS, even where the region has not declared its role. A Tailwind
   utility can only set background-color, so without this a tinted control
   inside a `bg-theme-hover` card seeds on the ancestor role's ground and
   renders a step off its own backdrop. Declaring the role is still the
   remedy — it is what re-points the ambient INK, which this does not.

   Emitted BEFORE the role blocks. A utility class and a role attribute are
   both (0,1,0), and Tailwind's own `background-color` for these classes is
   generated into index.css, which main.tsx imports BEFORE this file — so on
   an element carrying both, the role block's `background` shorthand is what
   paints. The ambient ground has to name the same winner, which means the
   role block must come later here too. */
.bg-theme-page {
  --surface-bg: var(--surface-page-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.hover\:bg-theme-page:hover {
  --surface-bg: var(--surface-page-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.enabled\:bg-theme-page:enabled {
  --surface-bg: var(--surface-page-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.active\:bg-theme-page:active {
  --surface-bg: var(--surface-page-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.bg-theme-panel {
  --surface-bg: var(--surface-panel-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.hover\:bg-theme-panel:hover {
  --surface-bg: var(--surface-panel-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.enabled\:bg-theme-panel:enabled {
  --surface-bg: var(--surface-panel-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.active\:bg-theme-panel:active {
  --surface-bg: var(--surface-panel-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.bg-theme-hover {
  --surface-bg: var(--surface-hover-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.hover\:bg-theme-hover:hover {
  --surface-bg: var(--surface-hover-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.enabled\:bg-theme-hover:enabled {
  --surface-bg: var(--surface-hover-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.active\:bg-theme-hover:active {
  --surface-bg: var(--surface-hover-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.bg-theme-input {
  --surface-bg: var(--surface-field-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.hover\:bg-theme-input:hover {
  --surface-bg: var(--surface-field-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.enabled\:bg-theme-input:enabled {
  --surface-bg: var(--surface-field-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
.active\:bg-theme-input:active {
  --surface-bg: var(--surface-field-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}

[data-surface="page"] {
  background: var(--surface-page-bg);
  color: var(--surface-page-ink);
  border-color: var(--surface-page-border);
  --surface-bg: var(--surface-page-bg);
  --tone-ink-toward: var(--surface-page-tone-ink-toward);
  --tone-ink-shift: var(--surface-page-tone-ink-shift);
  --text-strong-rgb: var(--surface-page-ink-strong-rgb);
  --text-strong: var(--surface-page-ink-strong);
  --text-rgb: var(--surface-page-ink-rgb);
  --text: var(--surface-page-ink);
  --text-mid-rgb: var(--surface-page-ink-mid-rgb);
  --text-mid: var(--surface-page-ink-mid);
  --text-dim-rgb: var(--surface-page-ink-dim-rgb);
  --text-dim: var(--surface-page-ink-dim);
  --text-faint-rgb: var(--surface-page-ink-faint-rgb);
  --text-faint: var(--surface-page-ink-faint);
  --text-faintest-rgb: var(--surface-page-ink-faintest-rgb);
  --text-faintest: var(--surface-page-ink-faintest);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --friends-add-text: var(--accent-ink-on-ground);
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --input-text: var(--text);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --select-text: var(--text);
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
}
/* Each region establishes a self-contained ink/border CONTEXT: it re-points the
   polarity-dependent globals (--text-*, --border*) to its own role-local values
   for its whole subtree. Un-migrated components reading --text-strong / --border
   resolve to the surface-correct value automatically (CSS custom props cascade)
   — so a dark panel under a light theme shows LIGHT content with zero component
   changes. This is the .admin-root mechanism generalised to every role. The
   role-local tokens default to the theme globals (identity → no-op on a
   same-polarity theme); a mixed-polarity theme overrides them. (Tinted-control
   STRENGTH is theme-bound — the --tone-*-mix knobs live in index.css — but
   the tone-NEUTRAL family borrows surface ink, so the closure below picks
   up --tone-neutral-* from the supply and recomputes them against each
   region's local values: the seam between the surface vocabulary and the
   control vocabulary, derived rather than restated.) */
[data-surface="panel"] {
  background: var(--surface-panel-bg);
  color: var(--surface-panel-ink);
  border-color: var(--surface-panel-border);
  --surface-bg: var(--surface-panel-bg);
  --tone-ink-toward: var(--surface-panel-tone-ink-toward);
  --tone-ink-shift: var(--surface-panel-tone-ink-shift);
  --text-strong-rgb: var(--surface-panel-ink-strong-rgb);
  --text-strong: var(--surface-panel-ink-strong);
  --text-rgb: var(--surface-panel-ink-rgb);
  --text: var(--surface-panel-ink);
  --text-mid-rgb: var(--surface-panel-ink-mid-rgb);
  --text-mid: var(--surface-panel-ink-mid);
  --text-dim-rgb: var(--surface-panel-ink-dim-rgb);
  --text-dim: var(--surface-panel-ink-dim);
  --text-faint-rgb: var(--surface-panel-ink-faint-rgb);
  --text-faint: var(--surface-panel-ink-faint);
  --text-faintest-rgb: var(--surface-panel-ink-faintest-rgb);
  --text-faintest: var(--surface-panel-ink-faintest);
  --border-soft: var(--surface-panel-edge-soft);
  --border: var(--surface-panel-edge);
  --border-strong: var(--surface-panel-edge-strong);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --friends-add-text: var(--accent-ink-on-ground);
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --input-border: var(--border);
  --input-text: var(--text);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --select-border: var(--border);
  --select-text: var(--text);
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
}
[data-surface="modal"] {
  background: var(--surface-modal-bg);
  color: var(--surface-modal-ink);
  border-color: var(--surface-modal-border);
  --surface-bg: var(--surface-modal-bg);
  --tone-ink-toward: var(--surface-modal-tone-ink-toward);
  --tone-ink-shift: var(--surface-modal-tone-ink-shift);
  --text-strong-rgb: var(--surface-modal-ink-strong-rgb);
  --text-strong: var(--surface-modal-ink-strong);
  --text-rgb: var(--surface-modal-ink-rgb);
  --text: var(--surface-modal-ink);
  --text-mid-rgb: var(--surface-modal-ink-mid-rgb);
  --text-mid: var(--surface-modal-ink-mid);
  --text-dim-rgb: var(--surface-modal-ink-dim-rgb);
  --text-dim: var(--surface-modal-ink-dim);
  --text-faint-rgb: var(--surface-modal-ink-faint-rgb);
  --text-faint: var(--surface-modal-ink-faint);
  --text-faintest-rgb: var(--surface-modal-ink-faintest-rgb);
  --text-faintest: var(--surface-modal-ink-faintest);
  --border-soft: var(--surface-modal-edge-soft);
  --border: var(--surface-modal-edge);
  --border-strong: var(--surface-modal-edge-strong);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --friends-add-text: var(--accent-ink-on-ground);
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --input-border: var(--border);
  --input-text: var(--text);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --select-border: var(--border);
  --select-text: var(--text);
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
}
[data-surface="field"] {
  background: var(--surface-field-bg);
  color: var(--surface-field-ink);
  border-color: var(--surface-field-border);
  --surface-bg: var(--surface-field-bg);
  --tone-ink-toward: var(--surface-field-tone-ink-toward);
  --tone-ink-shift: var(--surface-field-tone-ink-shift);
  --text-strong-rgb: var(--surface-field-ink-strong-rgb);
  --text-strong: var(--surface-field-ink-strong);
  --text-rgb: var(--surface-field-ink-rgb);
  --text: var(--surface-field-ink);
  --text-mid-rgb: var(--surface-field-ink-mid-rgb);
  --text-mid: var(--surface-field-ink-mid);
  --text-dim-rgb: var(--surface-field-ink-dim-rgb);
  --text-dim: var(--surface-field-ink-dim);
  --text-faint-rgb: var(--surface-field-ink-faint-rgb);
  --text-faint: var(--surface-field-ink-faint);
  --text-faintest-rgb: var(--surface-field-ink-faintest-rgb);
  --text-faintest: var(--surface-field-ink-faintest);
  --border-soft: var(--surface-field-edge-soft);
  --border: var(--surface-field-edge);
  --border-strong: var(--surface-field-edge-strong);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --friends-add-text: var(--accent-ink-on-ground);
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --input-border: var(--border);
  --input-text: var(--text);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --select-border: var(--border);
  --select-text: var(--text);
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
}
[data-surface="frame"] {
  background: var(--surface-frame-bg);
  color: var(--surface-frame-ink);
  border-color: var(--surface-frame-border);
  --surface-bg: var(--surface-frame-bg);
  --tone-ink-toward: var(--surface-frame-tone-ink-toward);
  --tone-ink-shift: var(--surface-frame-tone-ink-shift);
  --text-strong-rgb: var(--surface-frame-ink-strong-rgb);
  --text-strong: var(--surface-frame-ink-strong);
  --text-rgb: var(--surface-frame-ink-rgb);
  --text: var(--surface-frame-ink);
  --text-mid-rgb: var(--surface-frame-ink-mid-rgb);
  --text-mid: var(--surface-frame-ink-mid);
  --text-dim-rgb: var(--surface-frame-ink-dim-rgb);
  --text-dim: var(--surface-frame-ink-dim);
  --text-faint-rgb: var(--surface-frame-ink-faint-rgb);
  --text-faint: var(--surface-frame-ink-faint);
  --text-faintest-rgb: var(--surface-frame-ink-faintest-rgb);
  --text-faintest: var(--surface-frame-ink-faintest);
  --border-soft: var(--surface-frame-edge-soft);
  --border: var(--surface-frame-edge);
  --border-strong: var(--surface-frame-edge-strong);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --accent-ink-on-ground: color-mix(in oklab, rgb(var(--accent-ink)), var(--tone-ink-toward) var(--tone-ink-shift));
  --attention-on-ground: color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-ai-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --danger-on-ground: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-response-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-status-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-thinking-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-tool-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-write-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --friends-add-text: var(--accent-ink-on-ground);
  --info-on-ground: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --input-border: var(--border);
  --input-text: var(--text);
  --member-1-ink-on-ground: color-mix(in oklab, var(--member-1-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-2-ink-on-ground: color-mix(in oklab, var(--member-2-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-3-ink-on-ground: color-mix(in oklab, var(--member-3-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-4-ink-on-ground: color-mix(in oklab, var(--member-4-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-5-ink-on-ground: color-mix(in oklab, var(--member-5-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-6-ink-on-ground: color-mix(in oklab, var(--member-6-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --member-self-ink-on-ground: color-mix(in oklab, var(--member-self-fill), var(--tone-ink-toward) var(--tone-ink-shift));
  --progress-on-ground: color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift));
  --select-border: var(--border);
  --select-text: var(--text);
  --stopped-on-ground: color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift));
  --success-on-ground: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-text: var(--tone-attention-ink, color-mix(in oklab, var(--attention), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-text: var(--tone-stopped-ink, color-mix(in oklab, var(--stopped), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --warning-on-ground: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
}
/* ── terminal scope ──────────────────────────────────────────────────────
   Not a role: a SCOPE — the role vocabulary re-instantiated on the
   terminal-dark night/slate palettes for a whole subtree (admin console,
   tutorial-complete). The subtree root declares data-scope="terminal" PLUS
   its own ordinary role (usually page). The block rebinds the same tokens
   a theme would — grounds, the global ink ramp, the role ink bundles and
   edges, opaque lines, accent — so interior regions resolve against the
   console palettes with zero component changes. Derived tokens are
   re-declared here rather than their Tier-0 inputs because custom
   properties compute at the element that declares them: re-pointing only
   --line-panel would leave --border-panel holding :root's already-computed
   value. Theme-constant by default; a theme MAY override via
   `:root[data-theme='x'] [data-scope="terminal"]`. Hairlines + edges are
   pinned white-alpha because the ground is constant-dark — a light theme's
   black-alpha hairlines would vanish on it. */
[data-scope="terminal"] {
  /* grounds — recessed aesthetic: panels sit DARKER than the surface */
  --surface-page-bg-rgb: var(--shade-night-900);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-panel-bg-rgb: var(--shade-night-935);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-night-935);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-night-935);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-modal-bg-rgb: var(--shade-night-935);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-field-bg-rgb: var(--shade-night-800);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-hover-bg-rgb: var(--shade-night-860);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  /* global ink ramp → slate (light ink on the night ground). Each rung binds
  both forms: the triplet carries the value, the wrapped handle derives from
  it. Tailwind's text-theme-* utilities read the TRIPLET, so re-pointing
  only the wrapped handle would leave every utility call site on the page
  ramp — measured before the triplet existed, a `text-theme-faint` label
  inside a terminal-scoped log body rendered sandstorm's page faint
  (#6b6860) on the night ground at 1.9:1. Alpha-capable, so
  `text-theme-muted/70` still composites. */
  /* dim and faint are slate-400, the same step as mid, because MEASURED against
  this scope's own panel ground (#0e0e16) the ramp has no room below it:
  slate-400 is 7.49, slate-500 is 4.04 and slate-600 is 2.54. Two rungs that
  read as text were sitting under the 4.5 floor, and a rung that cannot clear
  the floor is not a text rung — it is a decorative one wearing the name.
  faintest keeps slate-500 and IS that decorative register (4.04, above the
  3:1 non-text floor), which is the same shape the page ramp settled on. */
  --text-strong-rgb: var(--shade-slate-200);
  --text-strong: rgb(var(--text-strong-rgb));
  --text-rgb: var(--shade-slate-300);
  --text: rgb(var(--text-rgb));
  --text-mid-rgb: var(--shade-slate-400);
  --text-mid: rgb(var(--text-mid-rgb));
  --text-dim-rgb: var(--shade-slate-400);
  --text-dim: rgb(var(--text-dim-rgb));
  --text-faint-rgb: var(--shade-slate-400);
  --text-faint: rgb(var(--text-faint-rgb));
  --text-faintest-rgb: var(--shade-slate-500);
  --text-faintest: rgb(var(--text-faintest-rgb));
  --surface-page-ink-rgb: var(--shade-slate-300);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-slate-200);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-slate-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-slate-400);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-slate-400);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-slate-500);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));

  /* role ink bundles — an interior data-surface region re-points the
  globals to THESE, so they must carry the scope's ink too */
  --surface-panel-ink-rgb: var(--shade-slate-300);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-slate-200);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-slate-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-slate-400);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-slate-400);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-slate-500);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-modal-ink-rgb: var(--shade-slate-300);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-slate-200);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-slate-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-slate-400);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-slate-400);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-slate-500);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-field-ink-rgb: var(--shade-slate-300);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-slate-200);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-slate-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-slate-400);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-slate-400);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-slate-500);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));

  /* opaque lines + role borders pinned to the console's slate steps */
  --border-panel: rgb(var(--shade-slate-800));
  --border-panel-alt: rgb(var(--shade-slate-700));
  --surface-page-border: rgb(var(--shade-slate-800));
  --surface-panel-border: rgb(var(--shade-slate-800));
  --surface-modal-border: rgb(var(--shade-slate-800));
  --surface-field-border: rgb(var(--shade-slate-500));

  /* hairlines + role edges pinned light-alpha (constant-dark ground) */
  --border-soft: rgb(var(--shade-white) / 0.04);
  --border: rgb(var(--shade-white) / 0.08);
  --border-strong: rgb(var(--shade-white) / 0.14);
  --surface-panel-edge-soft: rgb(var(--shade-white) / 0.04);
  --surface-panel-edge: rgb(var(--shade-white) / 0.08);
  --surface-panel-edge-strong: rgb(var(--shade-white) / 0.14);
  --surface-modal-edge-soft: rgb(var(--shade-white) / 0.04);
  --surface-modal-edge: rgb(var(--shade-white) / 0.08);
  --surface-modal-edge-strong: rgb(var(--shade-white) / 0.14);
  --surface-field-edge-soft: rgb(var(--shade-white) / 0.04);
  --surface-field-edge: rgb(var(--shade-white) / 0.08);
  --surface-field-edge-strong: rgb(var(--shade-white) / 0.14);

  /* accent → violet (consumed as rgb(var(--accent))) */
  --accent: var(--shade-violet-400);
  --accent-hover: var(--shade-violet-300);
  --accent-ink-hover: var(--accent-hover);

  /* the tinted-control inputs. A scope IS a theme, so it owes these the way
  a theme does — and until the pair enumerator could read a scope, nobody
  could see that it did not have them. Inherited, a tinted control on the
  admin console mixed the ACTIVE theme's status fill and the active theme's
  strength into this scope's constant-dark ground: sandstorm's user got a
  different pill here than midnight-mono's, on a surface whose whole point
  is that it does not change with the theme.
  The rungs are the bright 500s and the strengths are 10%/30%, which is what
  every dark theme declares and what this ground wants. */
  --danger-rgb: var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb: var(--shade-blue-500);
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 36%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;
  --chart-user-prompt: rgb(var(--shade-blue-500));
  --chart-file-change: rgb(var(--shade-cyan-500));
  --chart-deploy: rgb(var(--shade-orange-500));
  --chart-rebase: rgb(var(--shade-yellow-500));
  --chart-agent-message: rgb(var(--shade-violet-500));
  --chart-conflict: rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default: rgb(var(--shade-gray-500));

  /* the AUTHORED tone-ink overrides, restated as this scope's own
  derivation. `--tone-<t>-text` reads `var(--tone-<t>-ink, <derivation>)`,
  so a theme that authors the override reaches straight through a scope
  that only re-points the fill underneath it: sandstorm authors
  --tone-brand-ink as its clay accent ink, and the console painted that
  clay on a violet-brand tint at 1.89-2.18:1 while believing it had
  declared its own accent.
  Restated for EVERY tone rather than for the one that bleeds today. The
  override is a per-theme escape by design, so any theme may take it on any
  tone tomorrow, and a scope that lists only today's authored one is a list
  that goes stale silently. */
  --tone-success-ink: color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-danger-ink: color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-warning-ink: color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-info-ink: color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-brand-ink: color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-progress-ink: color-mix(in oklab, var(--violet), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-halted-ink: color-mix(in oklab, var(--orange), var(--tone-ink-toward) var(--tone-ink-shift));
  --tone-neutral-ink: color-mix(in oklab, var(--text-dim), var(--tone-ink-toward) var(--tone-ink-shift));
  --mint-rgb: var(--shade-emerald-400);
  --mint-dim-rgb: var(--shade-emerald-450);
  --pink-rgb: var(--shade-pink-500);
  --violet-rgb: var(--shade-violet-500);
  --violet-light-rgb: var(--shade-violet-400);
  --cyan-rgb: var(--shade-cyan-400);
  --amber-rgb: var(--shade-amber-500);
  --amber-light-rgb: var(--shade-amber-300);
  --rose-rgb: var(--shade-rose-400);
  --orange-rgb: var(--shade-orange-500);
  --yellow-rgb: var(--shade-yellow-500);
  --indigo-rgb: var(--shade-indigo-500);

  /* the FRAME role. The scope bound four of the five roles, and the fifth
  was not a deliberate omission — nothing could see it. A frame region
  inside a terminal scope resolved its whole bundle from the ACTIVE theme,
  so an admin on sandstorm would have got an ivory rail inside a
  constant-dark console the moment one was added. The bundle mirrors the
  panel's: the night ground one step down, the slate ink ramp, white-alpha
  hairlines because the ground is constant-dark. */
  --surface-frame-bg-rgb: var(--shade-night-940);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-slate-300);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-slate-200);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-slate-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-slate-400);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-slate-400);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-slate-500);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border: rgb(var(--shade-slate-800));
  --surface-frame-edge-soft: rgb(var(--shade-white) / 0.04);
  --surface-frame-edge: rgb(var(--shade-white) / 0.08);
  --surface-frame-edge-strong: rgb(var(--shade-white) / 0.14);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --accent-ink-hover-on-ground: color-mix(in oklab, rgb(var(--accent-ink-hover)), var(--tone-ink-toward) var(--tone-ink-shift));
  --agentselector-accent: rgb(var(--accent));
  --agentselector-border: var(--border-panel);
  --agentselector-border-alt: var(--border-panel-alt);
  --agentselector-hover-bg: var(--bg-hover);
  --amber: rgb(var(--amber-rgb));
  --amber-alpha-10: rgb(var(--amber-rgb) / 0.1);
  --amber-light: rgb(var(--amber-light-rgb));
  --appshell-surface: var(--bg-card);
  --bg: var(--surface-page-bg);
  --bg-card: var(--surface-panel-bg);
  --bg-elev: var(--surface-panel-bg-1);
  --bg-elev2: var(--surface-panel-bg-2);
  --bg-hover: var(--surface-hover-bg);
  --bg-modal: var(--surface-modal-bg);
  --bg-well: var(--surface-field-bg);
  --capability-data-ink: color-mix(in oklab, var(--indigo), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-identity-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --capability-play-ink: color-mix(in oklab, var(--cyan), var(--tone-ink-toward) var(--tone-ink-shift));
  --checkbox-accent: rgb(var(--accent));
  --cyan: rgb(var(--cyan-rgb));
  --directchat-accent: rgb(var(--accent));
  --directchat-accent-hover: rgb(var(--accent-hover));
  --directchat-hover: var(--bg-hover);
  --directchat-unread-bg: var(--pink);
  --disclosure-header-bg: var(--bg-card);
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-commit-ink: color-mix(in oklab, var(--amber), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-continuation-ink: color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-deploy-ink: color-mix(in oklab, var(--pink), var(--tone-ink-toward) var(--tone-ink-shift));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --explorecard-ecommerce: var(--amber);
  --explorecard-games: var(--cyan);
  --explorecard-other: var(--mint);
  --explorecard-personal: var(--violet-light);
  --feed-card-glow: var(--shadow-feed-glow);
  --feedcard-accent: rgb(var(--accent));
  --feedcard-border: var(--border-panel);
  --feedcard-border-strong: var(--border-panel-alt);
  --focus-ring: var(--focus-ring-color, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --fork-toast-accent: var(--violet-light);
  --fork-toast-bg: var(--bg-elev2);
  --fork-toast-border: color-mix(in srgb, var(--violet-light) 40%, transparent);
  --fork-toast-shadow-tint: color-mix(in srgb, var(--violet-light) 18%, transparent);
  --friends-add-bg: color-mix(in srgb, rgb(var(--accent)) 10%, transparent);
  --friends-add-border: color-mix(in srgb, rgb(var(--accent)) 40%, transparent);
  --friends-common-icon: var(--violet-light);
  --friends-dot-ring: var(--bg-card);
  --friends-idle-accent: var(--amber);
  --friends-invite-banner-tint: color-mix(in srgb, rgb(var(--accent)) 5%, transparent);
  --indigo: rgb(var(--indigo-rgb));
  --indigo-alpha-09: rgb(var(--indigo-rgb) / 0.09);
  --indigo-alpha-25: rgb(var(--indigo-rgb) / 0.25);
  --input-bg: var(--bg-well);
  --input-border: var(--border);
  --input-text: var(--text);
  --mint: rgb(var(--mint-rgb));
  --mint-alpha-10: rgb(var(--mint-rgb) / 0.1);
  --mint-alpha-30: rgb(var(--mint-rgb) / 0.3);
  --mint-alpha-92: rgb(var(--mint-rgb) / 0.92);
  --mint-dim: rgb(var(--mint-dim-rgb));
  --mobileshell-accent: rgb(var(--accent));
  --mobileshell-accent-alt: var(--cyan);
  --modal-bg: var(--bg-modal);
  --nonadminbanner-accent: var(--violet-light);
  --pink: rgb(var(--pink-rgb));
  --projectheader-admin-accent: var(--violet-light);
  --projectmodal-border: var(--border-panel);
  --projectmodal-tab-active: rgb(var(--accent));
  --promptbar-accent: rgb(var(--accent));
  --promptbar-border: var(--border-panel);
  --promptbar-border-alt: var(--border-panel-alt);
  --promptbar-send-hover-bg: rgb(var(--accent));
  --public-banner-bg: var(--warning-alpha-08);
  --public-banner-border: var(--warning-alpha-15);
  --publishcard-warn-bg: var(--warning-alpha-08);
  --radio-accent: rgb(var(--accent));
  --rose: rgb(var(--rose-rgb));
  --rose-alpha-92: rgb(var(--rose-rgb) / 0.92);
  --scrollbar-thumb: var(--border-panel-alt);
  --scrollbar-track: var(--bg-card);
  --select-bg: var(--bg-elev);
  --select-border: var(--border);
  --select-text: var(--text);
  --shadow-feed-glow: 0 0 0 2px var(--indigo-alpha-25), 0 0 20px var(--indigo-alpha-09);
  --sidebar-accent: rgb(var(--accent));
  --sidebar-admin-accent: var(--violet-light);
  --sidebar-admin-badge-bg: color-mix(in srgb, var(--violet-light) 12%, transparent);
  --sidebar-admin-view-bg: color-mix(in srgb, var(--violet-light) 18%, transparent);
  --sidebar-admin-view-border: color-mix(in srgb, var(--violet-light) 45%, transparent);
  --sidebar-brand-gradient-end: var(--cyan);
  --sidebar-brand-gradient-start: var(--mint);
  --sidebar-presence-offline: var(--amber);
  --skeleton-card-bg: var(--bg-card);
  --skeleton-shimmer: var(--bg-elev2);
  --spotlight-border-alt: var(--border-panel-alt);
  --star-active-bg: var(--amber-alpha-10);
  --star-active-color: var(--amber);
  --statuscard-edge-mix: var(--tone-border-mix);
  --statuscard-error-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), transparent);
  --statuscard-glow-mix: calc(var(--tone-border-mix) / 4);
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-attention-border: color-mix(in srgb, var(--attention) var(--tone-border-mix), transparent);
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-border: color-mix(in srgb, rgb(var(--accent)) var(--tone-border-mix), transparent);
  --tone-brand-text: var(--tone-brand-ink, color-mix(in oklab, rgb(var(--accent)), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-border: color-mix(in srgb, var(--danger) var(--tone-border-mix), transparent);
  --tone-danger-text: var(--tone-danger-ink, color-mix(in oklab, var(--danger), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-border: color-mix(in srgb, var(--info) var(--tone-border-mix), transparent);
  --tone-info-text: var(--tone-info-ink, color-mix(in oklab, var(--info), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-neutral-text: var(--tone-neutral-ink, color-mix(in oklab, var(--text-mid), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-progress-border: color-mix(in srgb, var(--progress) var(--tone-border-mix), transparent);
  --tone-progress-text: var(--tone-progress-ink, color-mix(in oklab, var(--progress), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-border: color-mix(in srgb, var(--stopped) var(--tone-border-mix), transparent);
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-border: color-mix(in srgb, var(--success) var(--tone-border-mix), transparent);
  --tone-success-text: var(--tone-success-ink, color-mix(in oklab, var(--success), var(--tone-ink-toward) var(--tone-ink-shift)));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-border: color-mix(in srgb, var(--warning) var(--tone-border-mix), transparent);
  --tone-warning-text: var(--tone-warning-ink, color-mix(in oklab, var(--warning), var(--tone-ink-toward) var(--tone-ink-shift)));
  --trending-badge-bg: color-mix(in srgb, var(--amber) 92%, transparent);
  --trending-card-bg: var(--bg-card);
  --trending-preview-bg: color-mix(in srgb, var(--violet-light) 15%, transparent);
  --trending-preview-border: color-mix(in srgb, var(--violet-light) 40%, transparent);
  --trending-preview-text: var(--violet-light);
  --trending-share-text: var(--bg);
  --violet-light: rgb(var(--violet-light-rgb));
  --violet-light-alpha-30: rgb(var(--violet-light-rgb) / 0.3);
  --warning-alpha-08: rgb(var(--warning-rgb) / 0.08);
  --warning-alpha-15: rgb(var(--warning-rgb) / 0.15);
  --workspace-accent: rgb(var(--accent));
  --workspace-border: var(--border);
  --workspace-border-alt: var(--border-strong);
  --workspace-text: var(--text);
  --workspace-text-muted: var(--text-dim);
  --xcard-accent: rgb(var(--accent));
  --xcard-accent-alt: var(--violet-light);
  --yellow: rgb(var(--yellow-rgb));
}

/* Panel depth — one role, a level. data-elevation selects the lifted ground;
   0 (or absent) is the panel step, 1 = elev, 2 = elev2. */
[data-surface="panel"][data-elevation="1"] {
  background: var(--surface-panel-bg-1);
  --surface-bg: var(--surface-panel-bg-1);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
[data-surface="panel"][data-elevation="2"] {
  background: var(--surface-panel-bg-2);
  --surface-bg: var(--surface-panel-bg-2);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}

/* Hover state — a modifier, not a role; only ever overlays panel/modal. Opt-in
   via data-state="hover" (set by the consumer on interactive regions), so a
   static panel never picks up a hover ground. */
[data-surface="panel"][data-state="hover"],
[data-surface="modal"][data-state="hover"] {
  background: var(--surface-hover-bg);
  --surface-bg: var(--surface-hover-bg);

  /* Dependency closure — every supply token that transitively reads one of
     the re-points above, re-declared with its own definition so it recomputes
     here instead of inheriting the value it already computed at :root. A
     custom property with a var() value computes at its DECLARING element, so
     a token left out does not fall back — it silently keeps the ground it was
     defined against. Generated: a new token joins by joining the graph. */
  --event-commit-bg: color-mix(in srgb, var(--amber) 9.4%, var(--surface-bg));
  --event-continuation-bg: color-mix(in srgb, var(--text-mid) 9.4%, var(--surface-bg));
  --event-deploy-bg: color-mix(in srgb, var(--pink) 9.4%, var(--surface-bg));
  --event-response-bg: color-mix(in srgb, var(--success) 9.4%, var(--surface-bg));
  --event-status-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-thinking-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --event-tool-bg: color-mix(in srgb, var(--info) 9.4%, var(--surface-bg));
  --event-write-bg: color-mix(in srgb, var(--violet) 9.4%, var(--surface-bg));
  --tone-attention-bg: color-mix(in srgb, var(--attention) var(--tone-bg-mix), var(--surface-bg));
  --tone-brand-bg: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), var(--surface-bg));
  --tone-danger-bg: color-mix(in srgb, var(--danger) var(--tone-bg-mix), var(--surface-bg));
  --tone-info-bg: color-mix(in srgb, var(--info) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-bg: color-mix(in srgb, var(--text-dim) var(--tone-bg-mix), var(--surface-bg));
  --tone-neutral-border: color-mix(in srgb, var(--text-dim) var(--tone-border-mix), var(--surface-bg));
  --tone-progress-bg: color-mix(in srgb, var(--progress) var(--tone-bg-mix), var(--surface-bg));
  --tone-stopped-bg: color-mix(in srgb, var(--stopped) var(--tone-bg-mix), var(--surface-bg));
  --tone-success-bg: color-mix(in srgb, var(--success) var(--tone-bg-mix), var(--surface-bg));
  --tone-warning-bg: color-mix(in srgb, var(--warning) var(--tone-bg-mix), var(--surface-bg));
}
/* High Contrast — accessibility-lean dark variant: pure-black ground, wider
   surface separation, brighter text steps, strengthened hairlines. Same
   override surface as warm.css: the themeable neutral ramp + line-role
   re-points + hairline tints. Accents/status inherit from :root. */
:root[data-theme='high-contrast'] {
  --theme-label: 'High Contrast';
  --theme-visibility: preview;

  /* ── Tier-0 themeable neutral ramp ── */
  --shade-neutral-950: 0 0 0;        /* page ground: pure black */
  --shade-neutral-925: 5 5 5;
  --shade-neutral-900: 12 12 12;
  --shade-neutral-875: 20 20 20;
  --shade-neutral-850: 28 28 28;
  --shade-neutral-800: 40 40 40;
  --shade-neutral-890: 20 20 20;     /* input well = the elev step (no split here) */

  --shade-neutral-0:   255 255 255;
  --shade-neutral-100: 245 245 245;  /* brighter body text */
  --shade-neutral-400: 205 205 205;
  --shade-neutral-500: 175 175 175;
  --shade-neutral-550: 155 155 155;  /* dot-muted — interpolated */
  --shade-neutral-650: 144 143 143;
  --shade-neutral-700: 115 115 115;
  --shade-neutral-720: 85 85 85;     /* stronger opaque border-alt */
  --shade-neutral-775: 64 64 64;     /* stronger opaque border */

  /* opaque line roles ride the strengthened ramp steps (warm precedent) */
  --line-panel:     var(--shade-neutral-775);
  --line-panel-alt: var(--shade-neutral-720);

  /* hairlines visibly stronger — knob overrides; colour rides rung 0 */
  --hairline-alpha-soft: 0.10;
  --hairline-alpha: 0.16;
  --hairline-alpha-strong: 0.28;

  /* accent — inherits the canon mint pairing (was :root's) */
  --accent:       var(--shade-emerald-400);
  --accent-hover: var(--shade-emerald-450);
  --accent-tint:  var(--shade-emerald-950);

  /* status text roles — 400 shades on dark ground (canon values) */
  --status-success: var(--shade-emerald-400);
  --status-danger:  var(--shade-red-400);
  --status-warning: var(--shade-amber-400);
  --status-info:    var(--shade-blue-400);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-400);
  --status-attention: var(--shade-cyan-400);
  --status-stopped:   var(--shade-orange-400);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* per-surface tone-ink derivation. MEASURED, not defaulted: each surface's
     eight tinted-control inks were computed under white and black at both
     shifts, and white clears the text floor on 12/12 while black clears 1/12 —
     this theme's grounds are dark on every role, so the ink shifts away from
     the tint toward white everywhere. 45% measured equal or better than 30%
     here, but no ink is under floor at 30%, so the shift stays where it
     renders today; moving it is a retune with no defect behind it. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* tinted-control strength (canon values) */
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;

  /* scrollbar hover grab-tone (canon slate pick) */
  --scrollbar-hover: rgb(var(--shade-slate-600));

  /* ── role table (full, totality-enforced): the theme IS the binding set —
     no :root fallback valuates a role. Parts bind this theme's own rungs;
     panel-grade borders ride this theme's --line-panel; edges ride the
     structural hairlines (rung 0 through the alpha knobs). ── */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--line-panel));
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--line-panel));
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       rgb(var(--shade-neutral-700));
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);
}
/* Meadow — the first LIGHT-polarity theme, in its FRAMED form: a vivid mint
   page inside deep-evergreen chrome. The model's mixed-polarity case: two
   total neutral palettes, and per-role bindings choose between them.

     --shade-neutral-*    the light ramp — luminance CLIMBS 0 (darkest text)
                          → 950 (lightest page). page + field ride it.
     --shade-evergreen-*  the dark-island ramp (on-hue near-black at H=162,
                          never neutral #000, so chrome stays in the mint
                          family). frame/panel/modal + the hover ground
                          rebind onto it; content inside reads LIGHT through
                          the role applicator's subtree re-point.

   All rungs are R G B triplets authored in OKLCH at H=162 and stored as
   sRGB (the store-triplet convention); every non-palette line is a rung
   reference or a manifest knob, so the two ramps are the only value-bearing
   surface in this file.

   The theme's judgment calls, each a deliberate departure:
     1. --surface-page decouples from the ramp → vivid mint
        (--shade-emerald-400): pale cards must FLOAT on a more-saturated
        page, or elevation reads inverted on a light ramp.
     2. Frame's base ink binds the MID rung — the rail runs a weight quieter
        than panel text (panels bind base at 100).
     3. Accent → pink (+ --appshell-accent): mint-tinted controls dissolve
        into the mint page; hue-separation is the fix. The sidebar keeps its
        own mint accent — mint pops on the dark rail.
     4. The input well (rung 890) is a soft mint, not stark white — a tinted
        light is easier on the eye; field otherwise rides the light ramp's
        standard identity chain (dark ink, no rebinding).

   The theme-constant statics (--shade-white/-black and everything on them —
   scrims, --text-oncolor, --on-accent) are NOT overridden: they sit on
   imagery or coloured fills, not on surfaces. No shared hue ramp is
   overridden — that would shift on-colour pin inks globally. */
:root[data-theme='meadow'] {
  --theme-label: 'Meadow';
  --theme-visibility: preview;

  /* Native form controls / scrollbars follow the page polarity under meadow
     only. Scoped to this block by design — :root stays undeclared so dark
     themes are unaffected. */
  color-scheme: light;

  /* ── light neutral ramp (total) — luminance climbs 0 → 950 ── */
  --shade-neutral-0:   15 20 16;     /* --text-strong  #0f1410 */
  --shade-neutral-100: 32 40 34;     /* --text  #202822 */
  --shade-neutral-400: 90 100 92;    /* --text-mid  #5a645c */
  --shade-neutral-500: 95 105 97;  /* --text-dim  #5f6961 */
  --shade-neutral-550: 131 141 133;  /* --dot-muted  #838d85 */
  --shade-neutral-650: 101 110 103;  /* --text-faint  #656e67 */
  --shade-neutral-700: 129 139 132;  /* --text-faintest  #818b84 */
  --shade-neutral-720: 190 201 192;  /* opaque border-alt  #bec9c0 */
  --shade-neutral-775: 205 215 207;  /* opaque border  #cdd7cf */
  --shade-neutral-800: 213 227 216;  /* --bg-hover  #d5e3d8 */
  --shade-neutral-850: 222 233 224;  /* --bg-elev2  #dee9e0 */
  --shade-neutral-875: 228 237 230;  /* --bg-elev  #e4ede6 */
  --shade-neutral-890: 217 246 228;  /* input well  #d9f6e4 — mintier than the
                                        elev step it splits from (judgment 4) */
  --shade-neutral-900: 234 242 236;  /* --bg-card  #eaf2ec */
  --shade-neutral-925: 239 245 240;  /* --bg-modal  #eff5f0 */
  --shade-neutral-950: 244 249 245;  /* pale near-white — feeds card/modal/elev */

  /* ── evergreen ramp (total) — the dark-island palette, H=162 ── */
  --shade-evergreen-0:   235 249 241;  /* #ebf9f1  oklch(0.970 0.018 162) */
  --shade-evergreen-100: 211 226 218;  /* #d3e2da  oklch(0.900 0.020 162) */
  --shade-evergreen-400: 201 217 208;  /* #c9d9d0  oklch(0.870 0.020 162) */
  --shade-evergreen-500: 170 184 176;  /* #aab8b0  oklch(0.770 0.020 162) */
  --shade-evergreen-550: 154 169 161;  /* #9aa9a1  oklch(0.720 0.020 162) */
  --shade-evergreen-650: 155 170 161;  /* #9baaa1 */
  --shade-evergreen-700: 123 138 130;  /* #7b8a82 */
  --shade-evergreen-720: 67 88 77;     /* #43584d  oklch(0.440 0.032 162) */
  --shade-evergreen-775: 50 69 59;     /* #32453b */
  --shade-evergreen-800: 44 64 54;     /* #2c4036  oklch(0.350 0.030 162) */
  --shade-evergreen-850: 39 60 50;     /* #273c32  oklch(0.335 0.032 162) */
  --shade-evergreen-875: 32 51 41;     /* #203329 */
  --shade-evergreen-890: 29 47 38;     /* #1d2f26  oklch(0.285 0.029 162) */
  --shade-evergreen-900: 24 42 33;     /* #182a21  oklch(0.265 0.028 162) */
  --shade-evergreen-925: 17 33 25;     /* #112119  oklch(0.230 0.026 162) */
  --shade-evergreen-950: 9 23 16;      /* #091710  oklch(0.190 0.025 162) */

  /* opaque line roles ride the light ramp's border steps */
  --line-panel:     var(--shade-neutral-775);
  --line-panel-alt: var(--shade-neutral-720);

  /* tinted-control strength — dark-tuned tint percentages wash out over the
     vivid mint ground, so lift both knobs (theme-bound, not surface-bound:
     a mid-% tint reads on either polarity) */
  --tone-bg-mix: 18%;
  --tone-border-mix: 45%;

  /* ...and the ink half, PER SURFACE — meadow is the theme that proves the
     knob had to be split. It is the only one whose grounds disagree about
     polarity: the page is the vivid mint (#34d399) and the field is a pale
     wash, both LIGHT, while panel, modal and frame are evergreen deeps. One
     theme-wide direction cannot serve both, and meadow declaring none meant
     every surface fell back to `:root`'s `white` — correct on the evergreens
     and backwards on the mint, where a tone's ink was being shifted toward the
     ground it had to be read against.

     It went unmeasured because the closed tones used to NAME their ink per
     theme, so the only thing this knob steered was the runtime-toned Pill —
     and meadow renders few of those on its light surfaces. The ink law routes
     every tone through it, which is what made the gap render and the pair
     enumerator report it.

     45% on the light pair, matching the other light theme: the shift has to
     out-run the tone's own tint, not merely differ from it. The evergreens keep
     the shared 30% — a deep ground gives the lighter direction more room. */
  --surface-page-tone-ink-toward: black;
  --surface-page-tone-ink-shift: 55%;
  --surface-field-tone-ink-toward: black;
  --surface-field-tone-ink-shift: 52%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 38%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* ── page bundle (judgment 1 — the vivid mint page, decoupled from the
     ramp): the mint ground carries the light ramp's dark ink ── */
  --surface-page-bg-rgb: var(--shade-emerald-400);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-evergreen-875);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-evergreen-800);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-evergreen-775);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-evergreen-720);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  /* ── frame → evergreen (base ink at the MID rung — judgment 2) ── */
  --surface-frame-bg-rgb: var(--shade-evergreen-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-border:       rgb(var(--shade-evergreen-850));
  --surface-frame-ink-rgb: var(--shade-evergreen-400);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-evergreen-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-evergreen-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-evergreen-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-evergreen-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-evergreen-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-edge-soft:    rgb(var(--shade-evergreen-875));
  --surface-frame-edge:         rgb(var(--shade-evergreen-775));
  --surface-frame-edge-strong:  rgb(var(--shade-evergreen-720));

  /* ── panel → evergreen ── */
  --surface-panel-bg-rgb: var(--shade-evergreen-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-evergreen-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-evergreen-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-evergreen-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-evergreen-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-evergreen-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-evergreen-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-evergreen-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-evergreen-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--shade-evergreen-775));
  /* The soft hairline and the plain one are ONE step on this theme, and that
     is the ramp's own rule rather than an oversight: the panel's hover ground
     (#2c4036) sits above every edge rung below 775, so a genuinely softer line
     drawn under it disappears on hover rows — measured at 1.00 against its own
     ground. The band between the hover ground and the plain edge is not wide
     enough for two visible steps, so the decorative one yields. */
  --surface-panel-edge-soft:    rgb(var(--shade-evergreen-775));
  --surface-panel-edge:         rgb(var(--shade-evergreen-775));
  --surface-panel-edge-strong:  rgb(var(--shade-evergreen-720));

  /* ── modal → evergreen ── */
  --surface-modal-bg-rgb: var(--shade-evergreen-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-evergreen-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-evergreen-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-evergreen-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-evergreen-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-evergreen-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-evergreen-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--shade-evergreen-775));
  --surface-modal-edge-soft:    rgb(var(--shade-evergreen-850));
  --surface-modal-edge:         rgb(var(--shade-evergreen-775));
  --surface-modal-edge-strong:  rgb(var(--shade-evergreen-720));

  /* hover ground follows the island polarity — a hovered panel/modal stays
     dark (this rung is what the old hand-authored islands were missing) */
  --surface-hover-bg-rgb: var(--shade-evergreen-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  /* ── field: light ramp — the well-rung ground, the light ramp's dark ink,
     and opaque light-mint edge steps instead of the alpha hairlines
     (judgment 4). ── */
  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:      rgb(var(--shade-neutral-500));
  --surface-field-edge-soft:   rgb(var(--shade-neutral-800));
  --surface-field-edge:        rgb(var(--shade-neutral-775));
  --surface-field-edge-strong: rgb(var(--shade-neutral-720));

  /* sidebar accents riding the dark rail (nav state, presence) */
  --sidebar-active-bg:          rgb(var(--shade-emerald-200));
  --sidebar-nav-active-text:    rgb(var(--shade-evergreen-900));
  --sidebar-nav-inactive:       rgb(var(--shade-evergreen-500));
  --sidebar-nav-glyph-inactive: rgb(var(--shade-evergreen-700));
  --sidebar-dot-border:         rgb(var(--shade-evergreen-950));

  /* ── accent: pink primary (judgment 3). No Tier-0 pink-600, so hover
     lightens to pink-400 rather than darkening. --accent-tint is consumed
     as rgb(var(--accent-tint)) → bare triplet. ── */
  --accent:       var(--shade-pink-500);
  /* Display accent — the homepage hero. This theme authors no accent-as-ink
     rung, so --accent-ink derives to the pink FILL, which measures 1.83 as
     text on the vivid mint page: the hero's brand line was unreadable and
     nothing rendered it. pink-750 is the same hue at 3.36 against a 3.0 bar
     — pink-700 clears at 3.14, which is margin an antialiased glyph edge
     spends on its own. */
  --accent-ink-display: var(--shade-pink-750);
  --accent-hover: var(--shade-pink-400);
  --accent-tint:  var(--shade-pink-100);

  /* app-shell accent → pink so on-page mint-tinted controls (pills) don't
     dissolve into the mint ground; the sidebar keeps :root's mint accent.
     FORM: consumers feed this into color-mix, so it must be a complete
     COLOUR — a bare triplet there is invalid CSS and the tint silently
     drops (the washed-out filter chips). */
  --appshell-accent: rgb(var(--accent));

  /* inactive filter-chip ink: --text-dim (rung 500) is tuned for the
     near-white grounds; directly on the vivid mint page it washes out —
     ride the mid rung instead */

  /* secondary button → pink tint that reads on the dark panels; strength
     tracks the tinted-control knobs so it stays consistent with Badge/Pill */
  --btn-outline-neutral-fill:     color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), transparent);
  /* The accent TRIPLET, not a composed colour. A token a theme authors is a CUT
     POINT — the applicator deliberately never re-emits it in a role block,
     since that would overwrite the theme's own value — so anything COMPOSED
     here is frozen at this block and cannot follow a surface. Both compositions
     were tried and measured: the accent fill outright put a raw pink on this
     theme's brand tint at 3.57, and the accent's derived ink was worse at 1.14
     because the ink froze here while the tint recomputed on the panel. The
     theme picks the rung; :root composes it. */
  --btn-outline-neutral-ink:    var(--accent);
  --btn-outline-neutral-edge: color-mix(in srgb, rgb(var(--accent)) var(--tone-border-mix), transparent);

  /* status text: :root's 400 shades are tuned for dark ground and wash out
     on light — re-point at the Tier-0 600-shades */
  --status-success: var(--shade-emerald-600);
  --status-danger:  var(--shade-red-600);
  --status-warning: var(--shade-amber-600);
  --status-info:    var(--shade-blue-600);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-600);
  --status-attention: var(--shade-cyan-600);
  --status-stopped:   var(--shade-orange-600);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* scrollbar hover grab-tone — its :root value is a slate pick, off the
     ramp; ride the light ramp instead */
  --scrollbar-hover: rgb(var(--shade-neutral-650));
}
/* Midnight Mono — the neutral-canon look: true-neutral near-black surfaces,
   near-white/grey text, the blessed mint accent. This file holds the CANONICAL
   valuation (lifted from :root): :root is derivation-only, so every theme —
   this one included — is a total manifest. There is no fallback valuation:
   a theme missing an entry fails tests/theme-manifest-totality.test.ts
   rather than silently inheriting these values.

   NOTE (task: designer-pull retarget): the MC-415 tracker pull still emits
   plain `:root {}` blocks, which any value-bearing theme block out-ranks
   (0-2-0 over 0-1-0) — colour-token pulls are shadowed under EVERY theme
   until the pull emits `:root[data-theme='<active>']` blocks. */
:root[data-theme='midnight-mono'] {
  --theme-label: 'Midnight Mono';
  --theme-visibility: all;

  /* ── neutral ramp (total) — true neutral; higher rung = darker ── */
  --shade-neutral-0:   255 255 255;  /* --text-strong  #ffffff */
  --shade-neutral-100: 236 236 236;  /* --text  #ececec */
  --shade-neutral-400: 170 170 170;  /* --text-mid  #aaaaaa */
  --shade-neutral-500: 136 136 136;  /* --text-dim  #888888 */
  --shade-neutral-550: 130 130 130;  /* --dot-muted  #828282 */
  --shade-neutral-650: 134 134 133;  /* --text-faint  #868685 */
  --shade-neutral-700: 106 106 106;  /* --text-faintest  #6a6a6a — decorative register, 3.66 on the page */
  --shade-neutral-720: 58 58 58;     /* opaque border-alt  #3a3a3a */
  --shade-neutral-775: 38 38 38;     /* opaque border  #262626 */
  --shade-neutral-800: 30 30 30;     /* --bg-hover  #1e1e1e */
  --shade-neutral-850: 26 26 26;     /* --bg-elev2  #1a1a1a */
  --shade-neutral-875: 22 22 22;     /* --bg-elev  #161616 */
  --shade-neutral-890: 22 22 22;     /* input well = the elev step (no split here) */
  --shade-neutral-900: 19 19 19;     /* --bg-card  #131313 */
  --shade-neutral-925: 14 14 14;     /* --bg-modal  #0e0e0e */
  --shade-neutral-950: 10 10 10;     /* --bg  #0a0a0a */

  /* opaque line roles — the slate panel-edge picks */
  --line-panel:     var(--shade-slate-800);
  --line-panel-alt: var(--shade-slate-700);

  /* accent — the blessed mint pairing; --accent-tint is the opaque
     dark-emerald subtle fill (consumed as rgb(var(--accent-tint))) */
  --accent:       var(--shade-emerald-400);
  --accent-hover: var(--shade-emerald-450);
  --accent-tint:  var(--shade-emerald-950);

  /* status text roles — 400 shades, tuned for dark ground */
  --status-success: var(--shade-emerald-400);
  /* red-400 -> red-300. The ink sits on a /20 wash of ITSELF, not on the page,
     and at 400 that pair measured 4.39 — the same failure mode sandstorm's
     rungs had in the opposite polarity. 300 puts it at 6.40. */
  --status-danger:  var(--shade-red-300);
  --status-warning: var(--shade-amber-400);
  --status-info:    var(--shade-blue-400);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-400);
  --status-attention: var(--shade-cyan-400);
  --status-stopped:   var(--shade-orange-400);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* per-surface tone-ink derivation. MEASURED, not defaulted: each surface's
     eight tinted-control inks were computed under white and black at both
     shifts, and white clears the text floor on 12/12 while black clears 1/12 —
     this theme's grounds are dark on every role, so the ink shifts away from
     the tint toward white everywhere. 45% measured equal or better than 30%
     here, but no ink is under floor at 30%, so the shift stays where it
     renders today; moving it is a retune with no defect behind it. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* tinted-control strength */
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;

  /* scrollbar hover grab-tone */
  --scrollbar-hover: rgb(var(--shade-slate-600));

  /* ── role table (full, totality-enforced): the theme IS the binding set —
     no :root fallback valuates a role. Parts bind this theme's own rungs;
     panel-grade borders ride this theme's --line-panel; edges ride the
     structural hairlines (rung 0 through the alpha knobs). ── */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--line-panel));
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--line-panel));
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       rgb(var(--shade-neutral-700));
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);
}
/* Ocean — blue-leaning dark variant: deep blue-cast grounds, cool text.
   Same override surface as warm.css: the themeable neutral ramp + line-role
   re-points + hairline tints. Accents/status inherit from :root. */
:root[data-theme='ocean'] {
  --theme-label: 'Ocean';
  --theme-visibility: preview;

  /* ── Tier-0 themeable neutral ramp (cool blue cast) ── */
  --shade-neutral-950: 8 10 16;      /* #080a10 */
  --shade-neutral-925: 11 14 21;
  --shade-neutral-900: 15 18 28;
  --shade-neutral-875: 18 22 33;
  --shade-neutral-850: 22 27 40;
  --shade-neutral-800: 30 36 52;
  --shade-neutral-890: 18 22 33;     /* input well = the elev step (no split here) */

  --shade-neutral-0:   240 245 255;  /* cool near-white */
  --shade-neutral-100: 224 231 242;
  --shade-neutral-400: 148 160 180;
  --shade-neutral-500: 139 150 168;
  --shade-neutral-550: 103 114 133;  /* dot-muted — interpolated on the cool cast */
  --shade-neutral-650: 131 140 156;
  --shade-neutral-700: 102 112 128;
  --shade-neutral-720: 52 62 80;
  --shade-neutral-775: 36 44 60;

  /* opaque line roles ride the cool ramp steps (warm precedent) */
  --line-panel:     var(--shade-neutral-775);
  --line-panel-alt: var(--shade-neutral-720);

  /* hairline strong-step deliberately heavier than stock (colour rides rung 0) */
  --hairline-alpha-strong: 0.16;

  /* accent — inherits the canon mint pairing (was :root's) */
  --accent:       var(--shade-emerald-400);
  --accent-hover: var(--shade-emerald-450);
  --accent-tint:  var(--shade-emerald-950);

  /* status text roles — 400 shades on dark ground (canon values) */
  --status-success: var(--shade-emerald-400);
  --status-danger:  var(--shade-red-400);
  --status-warning: var(--shade-amber-400);
  --status-info:    var(--shade-blue-400);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-400);
  --status-attention: var(--shade-cyan-400);
  --status-stopped:   var(--shade-orange-400);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* per-surface tone-ink derivation. MEASURED, not defaulted: each surface's
     eight tinted-control inks were computed under white and black at both
     shifts, and white clears the text floor on 12/12 while black clears 1/12 —
     this theme's grounds are dark on every role, so the ink shifts away from
     the tint toward white everywhere. 45% measured equal or better than 30%
     here, but no ink is under floor at 30%, so the shift stays where it
     renders today; moving it is a retune with no defect behind it. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* tinted-control strength (canon values) */
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;

  /* scrollbar hover grab-tone (canon slate pick) */
  --scrollbar-hover: rgb(var(--shade-slate-600));

  /* ── role table (full, totality-enforced): the theme IS the binding set —
     no :root fallback valuates a role. Parts bind this theme's own rungs;
     panel-grade borders ride this theme's --line-panel; edges ride the
     structural hairlines (rung 0 through the alpha knobs). ── */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--line-panel));
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--line-panel));
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       rgb(var(--shade-neutral-550));
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);
}
/* Sandstorm — a warm-sand LIGHT theme in its FRAMED form: Claude's ivory page
   and coral mark, anchored by a dune-shadow rail. Three total palettes; every
   per-role binding chooses between them.

     --shade-neutral-*   the sand ramp — luminance CLIMBS 0 (darkest ink)
                         → 950 (lightest panel). page/panel/modal/field ride it.
     --shade-clay-*      the coral ramp, same climbing convention. Supplies the
                         accent and the deep-terracotta text pick.
     --shade-espresso-*  the dark-island ramp (dark convention: 0 = lightest ink
                         → 950 = darkest ground). frame + the rail's hover
                         ground rebind onto it; content inside reads DARK
                         through the role applicator's subtree re-point.

   The hues are measured off Anthropic's own artwork rather than invented:
   the ivory #f0eee6 is oklch(0.948 0.011 95) and the coral #d97757 is
   oklch(0.672 0.131 39). Sand is authored at H=92 and clay at H=39, so rung
   neutral-875 reproduces the ivory and clay-650 the coral to within a bit.
   Espresso sits at H=75 — browner than sand, so the rail reads as wet earth
   rather than dead black. All rungs are stored as sRGB triplets; every
   non-palette line is a rung reference or a manifest knob.

   The theme's judgment calls, each a deliberate departure:
     1. Elevation INVERTS on a light ramp — lighter reads higher. The page
        takes the ivory (875) and cards float ABOVE it, climbing 900 → 925 →
        950 as they lift. This is Claude's own model, not a borrowed dark-theme
        habit: a card darker than its page would read as a hole. The page
        cannot sit at the ramp's pale end, or elevation has nowhere to climb.
     2. Coral is a FILL, never text. clay-650 scores 2.7–3.1 against the four
        light grounds — under AA. But :root pins --on-accent to black, which
        lands 5.68 ON the coral: exactly the black-on-coral of the brand's own
        artwork. So the accent stays true coral for fills, and --accent-ink
        carries the text job from the deep end of the ramp.
     3. Frame → espresso. Claude's product is uniformly light; the rail is the
        departure. It earns the slot by quoting the brand's black-on-coral and
        by giving a low-contrast cream page one hard edge to sit against.
     4. The input well (rung 890) breaks the ramp's luminance order — it is
        near-white paper (#fefdfb), BRIGHTER than the panel containing it.
        A well on cream should read as fresh paper; the same slot meadow used
        for its mint well, in the opposite direction.
     5. Both tinted-control knobs lift. Coral at :root's 10% over a cream page
        is invisible — the ground is already 94% light, so a low-% tint has no
        room to separate. Badges and pills need the mix strength to read at all.
     6. The hairline alphas lift too. :root's 0.04/0.08/0.14 assume a dark
        ground where hairlines LIGHTEN; here they are near-black at low alpha
        over cream, and need more presence to survive.
     7. The ink rungs are compressed against a hard ceiling. A page this light
        leaves only L 0.21–0.53 for ink that clears AA, so strong/body/mid/dim
        are packed into that band and 650/700 are the decorative register only
        (Anthropic's own caption grey sits near 2.3 on this ivory). Lightening
        any of 0–500 to open the ramp up trades away AA on the page.

   The theme-constant statics (--shade-white/-black and everything on them —
   scrims, --text-oncolor, --on-accent) are NOT overridden: they sit on imagery
   or coloured fills, not on surfaces. Judgment 2 depends on --on-accent
   remaining black. No shared hue ramp is overridden — that would shift
   on-colour pin inks globally. */
:root[data-theme='sandstorm'] {
  --theme-label: 'Sandstorm';
  --theme-visibility: all;

  /* Native form controls / scrollbars follow the PAGE polarity, which is the
     dominant surface — the espresso rail is the island, not the rule. Scoped
     to this block by design; :root stays undeclared so dark themes are
     unaffected. */
  color-scheme: light;

  /* ── sand ramp (total) — luminance climbs 0 → 950, H=92 ── */
  --shade-neutral-0: 25 24 21;      /* #191815  oklch(0.210 0.006 92)  text-strong — warm near-black */
  --shade-neutral-100: 44 42 37;    /* #2c2a25  oklch(0.285 0.009 92)  text (body) */
  --shade-neutral-400: 82 80 72;    /* #525048  oklch(0.430 0.013 92)  text-mid */
  --shade-neutral-500: 99 96 88;    /* #636058  oklch(0.490 0.013 92)  text-dim — the AA floor (judgment 7) */
  --shade-neutral-550: 103 100 92;  /* #67645c  oklch(0.503 0.013 90)  dot-muted — a dot, not text */
  --shade-neutral-650: 104 101 94;  /* #68655e  text-faint — 4.79 on the ivory page */
  --shade-neutral-700: 131 129 121; /* #838179  text-faintest — decorative register, 3.13 on the ivory page */
  --shade-neutral-720: 193 190 181; /* #c1beb5  oklch(0.800 0.013 92)  opaque border-alt */
  --shade-neutral-775: 212 209 200; /* #d4d1c8  oklch(0.860 0.013 92)  opaque border */
  --shade-neutral-800: 231 228 218; /* #e7e4da  oklch(0.918 0.013 92)  bg-hover */
  --shade-neutral-850: 237 234 225; /* #edeae1  oklch(0.936 0.012 92)  bg-elev2 */
  --shade-neutral-875: 240 238 230; /* #f0eee6  oklch(0.948 0.011 92)  PAGE — the ivory */
  --shade-neutral-890: 254 253 251; /* #fefdfb  oklch(0.995 0.003 92)  input well — paper (judgment 4) */
  --shade-neutral-900: 245 243 236; /* #f5f3ec  oklch(0.963 0.009 92)  PANEL — the base card */
  --shade-neutral-925: 248 246 241; /* #f8f6f1  oklch(0.973 0.007 92)  MODAL / elev 1 */
  --shade-neutral-950: 251 249 246; /* #fbf9f6  oklch(0.983 0.005 92)  elev 2 — the top step */

  /* ── clay ramp (total) — the coral supply, same climbing convention, H=39 ── */
  --shade-clay-0: 53 21 10;         /* #35150a  oklch(0.240 0.055 39) */
  --shade-clay-100: 105 47 27;      /* #692f1b  oklch(0.380 0.070 39)  accent-ink-hover — set
                                       one fill-step (0.07 L) under clay-400, so a link hovers
                                       by the same amount a button does */
  --shade-clay-400: 133 61 37;      /* #853d25  oklch(0.450 0.105 39) */
  --shade-clay-500: 170 81 51;      /* #aa5133  oklch(0.540 0.125 39)  the clay-as-TEXT pick (judgment 2) */
  --shade-clay-550: 194 96 63;      /* #c2603f  oklch(0.600 0.135 39)  accent-hover — darkens, per light */
  --shade-clay-650: 217 119 86;     /* #d97756  oklch(0.672 0.131 39)  ACCENT — the coral */
  --shade-clay-700: 228 137 107;    /* #e4896b  oklch(0.720 0.120 39) */
  --shade-clay-720: 237 163 138;    /* #eda38a  oklch(0.780 0.095 39) */
  --shade-clay-775: 244 188 169;    /* #f4bca9  oklch(0.840 0.070 39) */
  --shade-clay-800: 249 204 189;    /* #f9ccbd  oklch(0.880 0.055 39) */
  --shade-clay-850: 251 217 205;    /* #fbd9cd  oklch(0.910 0.042 39) */
  --shade-clay-875: 254 227 218;    /* #fee3da  oklch(0.935 0.032 39) */
  --shade-clay-890: 255 233 226;    /* #ffe9e2  oklch(0.950 0.026 39) */
  --shade-clay-900: 255 237 232;    /* #ffede8  oklch(0.960 0.021 39)  accent-tint — pale blush */
  --shade-clay-925: 255 243 238;    /* #fff3ee  oklch(0.972 0.015 39) */
  --shade-clay-950: 255 248 245;    /* #fff8f5  oklch(0.983 0.009 39) */

  /* ── espresso ramp (total) — the dark island, H=75, dark convention ── */
  --shade-espresso-0: 248 244 239;  /* #f8f4ef  oklch(0.968 0.008 75)  rail ink-strong */
  --shade-espresso-100: 222 216 209;/* #ded8d1  oklch(0.885 0.012 75)  rail ink */
  --shade-espresso-400: 182 176 168;/* #b6b0a8  oklch(0.760 0.014 75)  rail ink-mid */
  --shade-espresso-500: 151 145 137;/* #979189  oklch(0.660 0.014 75)  rail ink-dim */
  --shade-espresso-550: 142 136 128;/* #8e8880  oklch(0.630 0.014 75)  rail dot-muted */
  --shade-espresso-650: 138 132 124;/* #8a847c  oklch(0.616 0.014 75)  rail ink-faint — 4.92 on the rail */
  --shade-espresso-700: 111 106 98; /* #6f6a62  oklch(0.520 0.013 75)  rail ink-faintest — decorative register, 3.40 on the rail */
  --shade-espresso-720: 77 71 63;   /* #4d473f  oklch(0.400 0.015 75)  rail edge-strong */
  --shade-espresso-775: 62 56 49;   /* #3e3831  oklch(0.345 0.015 75)  rail edge */
  --shade-espresso-800: 55 50 42;   /* #37322a  oklch(0.320 0.015 75)  rail hover ground */
  --shade-espresso-850: 49 44 37;   /* #312c25  oklch(0.296 0.014 75)  rail border */
  --shade-espresso-875: 43 38 32;   /* #2b2620  oklch(0.272 0.013 75)  rail edge-soft */
  --shade-espresso-890: 39 35 29;   /* #27231d  oklch(0.258 0.012 75) */
  --shade-espresso-900: 35 31 26;   /* #231f1a  oklch(0.243 0.012 75) */
  --shade-espresso-925: 30 26 22;   /* #1e1a16  oklch(0.222 0.010 75) */
  --shade-espresso-950: 23 21 17;   /* #171511  oklch(0.196 0.008 75)  FRAME — the dune-shadow rail */

  /* opaque line roles ride the sand ramp's border steps */
  --line-panel: var(--shade-neutral-775);
  --line-panel-alt: var(--shade-neutral-720);

  /* judgment 6 — hairlines are near-black at low alpha over cream; :root's
     dark-tuned alphas vanish here */
  --hairline-alpha-soft: 0.05;
  --hairline-alpha: 0.10;
  --hairline-alpha-strong: 0.18;

  /* judgment 5 — tinted-control strength (theme-bound, not surface-bound) */
  --tone-bg-mix: 16%;
  --tone-border-mix: 42%;
  /* ...and the ink half, for the runtime-toned pills — declared PER SURFACE.
     The direction follows the tint's ground rather than the theme's polarity,
     so it is a role entry the way the ink ramp is: the applicator binds the
     ambient `--tone-ink-*` to the role's entry, and `:root` defaults an
     unstated role back to the theme-wide `white` / `30%`. Sandstorm states all
     five because four of its grounds are pale — this is the theme that needs
     the DARK direction, its tints being washes rather than deeps.

     45%, not 35%: a tone pill paints its ink by mixing the tone toward this
     polarity, and the text then sits on a tint OF that same tone, so the shift
     has to out-run the tint rather than merely differ from it. At 35% the amber
     usage-pill measured 4.09 on its own wash; 45% puts it at 5.72, which leaves
     headroom for the tones /fixtures does not instantiate.

     The FRAME is the exception, and it is the reason this knob is per-surface
     rather than per-theme. The frame is sandstorm's one constant-DARK ground
     (espresso-950, the dune-shadow rail), so a tone sitting on it needs the
     ink to go LIGHTER while every other surface in this theme needs it darker.
     This entry said `black` until the ink law landed and it was measured — it
     never rendered, because a hand-maintained patch list in the surface
     generator was overriding the frame's tone inks outright with bright
     shades. Deleting that list is what made the direction load-bearing, and
     what surfaced that the direction was wrong. */
  --surface-page-tone-ink-toward: black;
  --surface-page-tone-ink-shift: 45%;
  --surface-panel-tone-ink-toward: black;
  --surface-panel-tone-ink-shift: 45%;
  --surface-modal-tone-ink-toward: black;
  --surface-modal-tone-ink-shift: 45%;
  --surface-field-tone-ink-toward: black;
  --surface-field-tone-ink-shift: 45%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 45%;

  /* ── page bundle: the ivory ground, sand's dark ink ── */
  --surface-page-bg-rgb: var(--shade-neutral-875);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  /* ── panel → above the ivory, with the lifted steps CLIMBING to the ramp's
     pale end (judgment 1). Pinning the base card at 950 would leave elevation
     nowhere to go but down, which renders a "higher" step darker. ── */
  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-925);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-950);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border: rgb(var(--line-panel));
  --surface-panel-edge-soft: var(--border-soft);
  --surface-panel-edge: var(--border);
  --surface-panel-edge-strong: var(--border-strong);

  /* ── modal → rides between the base card and its top step, so it reads apart
     from a panel without leaving the lifted band ── */
  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border: rgb(var(--line-panel));
  --surface-modal-edge-soft: var(--border-soft);
  --surface-modal-edge: var(--border);
  --surface-modal-edge-strong: var(--border-strong);

  /* ── field → the paper well (judgment 4), with opaque sand edges instead of
     the alpha hairlines: a well needs a drawn lip, not a wash ── */
  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border: rgb(var(--shade-neutral-700));
  --surface-field-edge-soft: rgb(var(--shade-neutral-800));
  --surface-field-edge: rgb(var(--shade-neutral-775));
  --surface-field-edge-strong: rgb(var(--shade-neutral-720));

  /* ── frame → espresso (judgment 3) ── */
  --surface-frame-bg-rgb: var(--shade-espresso-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-espresso-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-espresso-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-espresso-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-espresso-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-espresso-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-espresso-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border: rgb(var(--shade-espresso-850));
  --surface-frame-edge-soft: rgb(var(--shade-espresso-875));
  --surface-frame-edge: rgb(var(--shade-espresso-775));
  --surface-frame-edge-strong: rgb(var(--shade-espresso-720));

  /* hover ground: the sand wash under a hovered row. Panels sit at the ramp's
     pale end, so hover DARKENS toward the ivory — the inverse of a dark
     theme's lift, and the reason this can't ride :root's value. */
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  /* ── accent: the coral. Consumed as a fill everywhere --on-accent (black)
     rides on top; --accent-tint is consumed as rgb(var(--accent-tint)) → it
     must be a bare triplet. ── */
  --accent: var(--shade-clay-650);
  --accent-hover: var(--shade-clay-550);
  --accent-tint: var(--shade-clay-900);

  /* judgment 2 — the coral is a fill, so the ink drops to a rung that clears AA
     on the hardest ground it lands on. That ground is not the page but the 16%
     coral TINT under a badge/chip, which is darker than the panel and pulls the
     pick a rung past what the page alone would ask for. */
  /* Display accent — the homepage hero. Judgment 2 above sends the accent's
     TEXT job to the deep end of the ramp because clay-650 scores 2.7–3.1 on
     the light grounds; at 64px/700 the bar is 3.0, so the ramp does not have
     to be walked that far. clay-550 measures 3.59 on the cream page and is
     the lightest committed step that clears — the most clay the ground will
     carry. clay-400 (6.72) and the pole-shifted twin (14.04) both clear by
     spending hue nobody asked them to spend. */
  --accent-ink-display: var(--shade-clay-550);
  --accent-ink: var(--shade-clay-400);
  --accent-ink-hover: var(--shade-clay-100);

  /* The true coral: the pill vocabulary tints FROM this value and derives its
     ink by shifting it away from the tint (--tone-ink-toward / --tone-ink-shift),
     so handing it a pre-shifted colour here would buy readable text with a
     muddy chip. */
  --appshell-accent: rgb(var(--accent));

  /* The ink law's override, and the one theme that needs it. Every tone derives
     its ink from its own fill by shifting toward a pole, which can lighten or
     darken but cannot change HUE. This theme's brand ink is a deliberate hue
     move: --accent-ink is clay-400, picked per judgment 2 above against the 16%
     coral tint rather than against the page, and a shift of the coral fill
     lands somewhere else. Declaring the tone ink directly is how a theme says
     so, through the -ink INPUT rather than by re-declaring -text: a role block
     is not theme-scoped, so overriding the output would freeze it for all seven
     themes at once.

     The authored ink is now GONE, and the trade it recorded is the reason.
     An authored ink is theme-CONSTANT, so it cannot follow a surface whose
     ground disagrees with the rest of the theme — this theme's frame is that
     surface, and the clay measured 1.87 on its own brand tint there. The note
     that used to sit here called that "the trade a hue choice buys" and said
     outright that deriving would clear the floor on every surface. With the
     pair checker enforcing, a permanent exception is not on offer, so the
     brand tone takes the derivation: a coral shifted toward each surface's own
     pole rather than a constant clay. */

  /* secondary button → a clay tint, so it reads as the accent's quieter twin
     rather than a grey. Strength tracks the tinted-control knobs, keeping it
     consistent with Badge/Pill. */
  --btn-outline-neutral-fill: color-mix(in srgb, rgb(var(--accent)) var(--tone-bg-mix), transparent);
  /* The accent-as-ink TRIPLET. A theme-authored token is a cut point the
     applicator never re-emits, so a per-surface derivation composed here would
     freeze at this block while the tint it sits on recomputes per role. */
  --btn-outline-neutral-ink: var(--accent-ink);
  --btn-outline-neutral-edge: color-mix(in srgb, rgb(var(--accent)) var(--tone-border-mix), transparent);

  /* sidebar accents riding the espresso rail (nav state, presence) */
  --sidebar-active-bg: rgb(var(--shade-clay-650));
  --sidebar-nav-active-text: rgb(var(--shade-espresso-950));
  --sidebar-nav-inactive: rgb(var(--shade-espresso-500));
  --sidebar-nav-glyph-inactive: rgb(var(--shade-espresso-650));
  --sidebar-dot-border: rgb(var(--shade-espresso-950));

  /* Status INK. The hard ground is not the page but each tone's OWN tinted
     badge — a 16% wash of the tone over cream, which lands far lighter than
     any dark theme's ground. That pulls the picks down to the deep end of each
     ramp; the rungs differ per family only because the shared ramps space
     their steps differently (blue has no 700).

     Measured on /fixtures once the admin regions became mountable: the badge
     wash is lighter than the note above assumed, and three of the four rungs
     landed just under AA on it — danger 3.70, warning 4.09, success 4.49. Each
     drops one further step, which clears the worst measured wash for its family
     (4.76 / 6.62 / 5.56). Info is untouched: no measured pair reached it. */
  --status-success: var(--shade-emerald-900);
  --status-danger: var(--shade-red-800);
  --status-warning: var(--shade-amber-900);
  --status-info: var(--shade-blue-800);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-900);
  --status-attention: var(--shade-cyan-800);
  --status-stopped:   var(--shade-orange-800);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* Identity palette — the one theme that has to re-point it.
     :root's fills are tuned for a near-black ground and score 9.7–5.3:1 there.
     On this ivory panel (#f5f3ec) they measure 1.6–3.2:1: five of six sit
     under the 3:1 floor for a graphical object, and the disc reads as a pale
     smudge rather than an identity. The 700 rungs clear 4.5–6.4:1 here.

     The ink knob flips with them. A darkened fill under :root's near-black
     --on-accent would be dark-on-dark — the exact failure the solid status
     buttons shipped — so the letter takes the light end of this theme's
     inverted neutral ramp, clearing 5.0–7.1:1 on every slot.

     -ink-on-ground needs no entry: it derives from the fill through
     --tone-ink-toward/--tone-ink-shift, which this theme already flips. */
  --member-ink-on-fill: rgb(var(--shade-neutral-950));
  --member-self-fill: rgb(var(--shade-emerald-700));
  --member-1-fill: rgb(var(--shade-blue-700));
  --member-2-fill: rgb(var(--shade-pink-700));
  --member-3-fill: rgb(var(--shade-violet-700));
  --member-4-fill: rgb(var(--shade-cyan-700));
  --member-5-fill: rgb(var(--shade-amber-700));
  --member-6-fill: rgb(var(--shade-rose-700));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* scrollbar hover grab-tone — :root's is a slate pick, off the ramp */
  --scrollbar-hover: rgb(var(--shade-neutral-650));
}
/* Slate — the pre-migration look: blue-tinted surfaces, slate text, the
   emerald-500 accent. Values sourced from the retired --color-* channel
   family (git ref 9324ecbc, web/src/index.css "Colour channels" block),
   expressed the only way the tier grammar allows: literals live in the
   themeable --shade-neutral-* ramp override (warm.css precedent) and the
   accent re-points at existing Tier-0 emerald entries.

   Fidelity note: pre-migration, the blue --color-* family (Tailwind theme-*
   utilities) and the grey --bg* hex family coexisted per-consumer; one ramp
   now feeds both, so Slate's ramp is uniformly blue-cast — the elev steps
   (875/850), which had no retired blue value, are interpolated on the same
   cast. Opaque line steps land on slate-800/700, matching :root's slate line
   roles, so borders read as they always did. --content-strong (ramp step 0)
   stays :root white. */
:root[data-theme='slate'] {
  --theme-label: 'Slate';
  --theme-visibility: all;

  /* ── Tier-0 themeable neutral ramp (blue-cast surfaces + slate text) ── */
  --shade-neutral-950: 10 10 15;    /* page  #0a0a0f (retired --color-page) */
  --shade-neutral-925: 12 12 20;    /* modal/input  #0c0c14 (--color-input) */
  --shade-neutral-900: 15 15 24;    /* panel  #0f0f18 (--color-panel) */
  --shade-neutral-875: 20 24 36;    /* elev — interpolated on the blue cast */
  --shade-neutral-850: 24 30 46;    /* elev2 — interpolated on the blue cast */
  --shade-neutral-800: 30 41 59;    /* hover  #1e293b slate-800 (--color-hover) */
  --shade-neutral-890: 20 24 36;    /* input well = the elev step (no split here) */

  --shade-neutral-100: 226 232 240; /* text  #e2e8f0 slate-200 (--color-text-primary) */
  --shade-neutral-0:   255 255 255; /* text-strong — :root white, now explicit (totality) */
  --shade-neutral-400: 148 163 184; /* text-mid  #94a3b8 slate-400 */
  --shade-neutral-500: 140 154 172; /* text-dim  #8c9aac — lifted off slate-500, which read 3.07 on the panel hover ground */
  --shade-neutral-550: 90 106 128;  /* dot-muted — interpolated on the cast */
  --shade-neutral-650: 133 145 160;   /* text-faint  #8591a0 — lifted off slate-600 (1.93 on hover) */
  --shade-neutral-700: 106 115 131;    /* #6a7383 text-faintest — interpolated on the cast */
  --shade-neutral-720: 51 65 85;    /* opaque border-alt  #334155 slate-700 */
  --shade-neutral-775: 36 47 64;    /* opaque border  #242f40 — lifted off slate-800, which WAS the hover ground */

  /* ── accent: the retired emerald-500 primary + emerald-400 hover ── */
  --accent:       var(--shade-emerald-500);  /* #10b981 */
  --accent-hover: var(--shade-emerald-400);  /* #34d399 */
  --accent-tint:  var(--shade-emerald-950);  /* #0a1412 — the exact retired
     --color-accent-subtle value; declared (no :root fallback) */

  /* opaque line roles — the slate panel-edge picks (canon values, now
     declared: no :root fallback) */
  --line-panel:     var(--shade-neutral-775);
  --line-panel-alt: var(--shade-slate-700);

  /* status text roles — 400 shades on dark ground (canon values) */
  --status-success: var(--shade-emerald-400);
  --status-danger:  var(--shade-red-400);
  --status-warning: var(--shade-amber-400);
  --status-info:    var(--shade-blue-400);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-400);
  --status-attention: var(--shade-cyan-400);
  --status-stopped:   var(--shade-orange-400);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* per-surface tone-ink derivation. MEASURED, not defaulted: each surface's
     eight tinted-control inks were computed under white and black at both
     shifts, and white clears the text floor on 12/12 while black clears 1/12 —
     this theme's grounds are dark on every role, so the ink shifts away from
     the tint toward white everywhere. 45% measured equal or better than 30%
     here, but no ink is under floor at 30%, so the shift stays where it
     renders today; moving it is a retune with no defect behind it. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* tinted-control strength (canon values) */
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;

  /* scrollbar hover grab-tone (canon slate pick) */
  --scrollbar-hover: rgb(var(--shade-slate-600));

  /* ── role table (full, totality-enforced): the theme IS the binding set —
     no :root fallback valuates a role. Parts bind this theme's own rungs;
     panel-grade borders ride this theme's --line-panel; edges ride the
     structural hairlines (rung 0 through the alpha knobs). ── */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--line-panel));
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--line-panel));
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       rgb(var(--shade-neutral-550));
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);
}
/* Warm — the first theme preset. A delta over the :root default (Midnight
   Mono): warm ground, cool pop. Overrides ONLY the neutral ramp (plus the
   line-role re-point + hairline tints below); accents (--mint / --accent* /
   status colours) inherit from :root so the warm ground keeps its cool
   highlights.

   Four-tier model: a theme reskins by overriding the Tier-0 PALETTE only. Here
   that is the themeable --shade-neutral-* ramp — every surface and text role and
   semantic (surface/content roles, bg/text tokens) derives from it, so warming
   the ramp warms the whole shell in one place. The theme-constant statics
   (--shade-white/--shade-black) are deliberately NOT overridden, so on-colour
   text and pure-black scrims stay #fff/#000. The alpha-white --border* hairlines
   are theme-variable in their own right (warm-white tint) and stay literal (D2). */
:root[data-theme='warm'] {
  --theme-label: 'Warm';
  --theme-visibility: all;

  /* ── Tier-0 themeable neutral ramp (warm tones) — every surface/content role
     and bg/text semantic derives from these ── */
  --shade-neutral-950: 11 10 8;    /* --bg      #0b0a08 */
  --shade-neutral-925: 16 14 11;   /* --bg-modal  #100e0b */
  --shade-neutral-900: 22 19 15;   /* --bg-card  #16130f */
  --shade-neutral-875: 26 22 18;   /* --bg-elev  #1a1612 */
  --shade-neutral-850: 31 26 21;   /* --bg-elev2  #1f1a15 */
  --shade-neutral-800: 36 30 24;   /* --bg-hover  #241e18 */
  --shade-neutral-890: 26 22 18;   /* input well = the elev step (no split here) */

  --shade-neutral-0:   250 248 244; /* --text-strong  #faf8f4 (warm near-white) */
  --shade-neutral-100: 232 228 221; /* --text  #e8e4dd */
  --shade-neutral-400: 166 159 150; /* --text-mid  #a69f96 */
  --shade-neutral-500: 152 146 138; /* --text-dim  #98928a */
  --shade-neutral-550: 119 111 103; /* --dot-muted — interpolated on the warm cast */
  --shade-neutral-650:  139 134 126;   /* --text-faint  #8b867e */
  --shade-neutral-700:  110 106 98;   /* --text-faintest  #6e6a62 */
  --shade-neutral-720:  56 48 40;   /* opaque border-alt  #383028 */
  --shade-neutral-775:  43 37 30;   /* opaque border  #2b251e */

  /* Warm keeps opaque borders in its own brown-greys, not :root's slate —
     re-point the line roles onto the warm ramp steps above. */
  --line-panel:     var(--shade-neutral-775);
  --line-panel-alt: var(--shade-neutral-720);

  /* scrollbar hover grab-tone — the one scrollbar piece that doesn't ride the
     ramp/roles above (its :root value is a slate pick) */
  --scrollbar-hover: rgb(var(--shade-neutral-650));

  /* accent — inherits the canon mint pairing (was :root's) */
  --accent:       var(--shade-emerald-400);
  --accent-hover: var(--shade-emerald-450);
  --accent-tint:  var(--shade-emerald-950);

  /* status text roles — 400 shades on dark ground (canon values) */
  --status-success: var(--shade-emerald-400);
  --status-danger:  var(--shade-red-400);
  --status-warning: var(--shade-amber-400);
  --status-info:    var(--shade-blue-400);

  /* The three registers the activity vocabulary needed and did not have:
     in-flight work, work waiting on the USER, and work stopped without
     failing. Each takes this theme's own status rung, like its four
     siblings above. */
  --status-progress:  var(--shade-violet-400);
  --status-attention: var(--shade-cyan-400);
  --status-stopped:   var(--shade-orange-400);
  /* semantic status FILLS — the ground a tinted control, solid button or
     invalid border paints with, distinct from the --status-* text roles above.
     Declared per theme because a fill lands on this theme's grounds; the
     wrapped form derives in index.css so the two can never disagree. */
  --danger-rgb:   var(--shade-red-500);
  --success-rgb: var(--shade-emerald-500);
  --warning-rgb: var(--shade-amber-500);
  --info-rgb:    var(--shade-blue-500);

  --progress-rgb:  var(--shade-violet-500);
  --attention-rgb: var(--shade-cyan-500);
  --stopped-rgb:   var(--shade-orange-500);
  /* member identity palette — the fill each hashed slot paints, and the ink
     that sits ON that fill. Declared per theme because a slot's fill lands on
     this theme's grounds: sandstorm takes the 700 rungs and flips the ink,
     because the bright rungs measure 1.6-3.2:1 on its ivory panel. The
     -ink-on-ground derivation stays in index.css and recomputes per surface
     through the applicator's closure. */
  --member-ink-on-fill: rgb(var(--shade-black));
  --member-self-fill: rgb(var(--shade-emerald-400));
  --member-1-fill: rgb(var(--shade-blue-400));
  --member-2-fill: rgb(var(--shade-pink-500));
  --member-3-fill: rgb(var(--shade-violet-400));
  --member-4-fill: rgb(var(--shade-cyan-400));
  --member-5-fill: rgb(var(--shade-amber-500));
  --member-6-fill: rgb(var(--shade-rose-400));

  /* chart series — the nine categorical fills the usage pie paints. Declared
     per theme, NOT per surface: the one call site is the admin usage pie, the
     slices are read against EACH OTHER with --chart-slice-stroke between them
     rather than against a ground, and five per-surface copies would be 35
     entries a theme declares and no surface ever renders. */
  --chart-user-prompt:     rgb(var(--shade-blue-500));
  --chart-file-change:     rgb(var(--shade-cyan-500));
  --chart-deploy:          rgb(var(--shade-orange-500));
  --chart-rebase:          rgb(var(--shade-yellow-500));
  --chart-agent-message:   rgb(var(--shade-violet-500));
  --chart-conflict:        rgb(var(--shade-purple-500));
  --chart-inference-image: rgb(var(--shade-pink-500));
  --chart-inference-video: rgb(var(--shade-rose-500));
  --chart-default:         rgb(var(--shade-gray-500));

  /* solid status bundle — a deep ground, a mid border and a light ink, for a
     surface that paints a whole strip in a severity rather than tinting one.
     The platform alert tab is the consumer. Distinct from the tinted --tone-*
     registers (10% over the surface ground) and from the solid BUTTON fills
     (the bright 500), because none of those read as an alert bar. */
  --status-solid-danger-bg:     var(--shade-red-900);
  --status-solid-danger-border: var(--shade-red-700);
  --status-solid-danger-ink:    var(--shade-red-200);
  --status-solid-warning-bg:     var(--shade-amber-900);
  --status-solid-warning-border: var(--shade-amber-700);
  --status-solid-warning-ink:    var(--shade-amber-200);

  /* the ink a solid BUTTON fill carries. Per theme because it must follow the
     fill this theme declared: the shared value assumed every status fill is a
     mid-luminance 500, which is one theme's arithmetic generalised to seven. */
  --tone-success-oncolor: rgb(var(--shade-black));
  --tone-warning-oncolor: rgb(var(--shade-black));
  --tone-danger-oncolor:  rgb(var(--shade-black));
  --tone-info-oncolor:    rgb(var(--shade-black));
  --tone-brand-oncolor:   rgb(var(--shade-black));

  --tone-stopped-oncolor: rgb(var(--shade-black));
  /* decorative hue reads — the named hues components reach for when no
     semantic role fits (a progress violet, a "new" mint pin, a halted orange).
     Declared per theme because they land on this theme's grounds; index.css
     keeps only the wrapping and the alpha derivations, so a theme that
     re-points a hue moves every tint of it at once. */
  --mint-rgb:          var(--shade-emerald-400);
  --mint-dim-rgb:      var(--shade-emerald-450);
  --pink-rgb:          var(--shade-pink-500);
  --violet-rgb:        var(--shade-violet-500);
  --violet-light-rgb:  var(--shade-violet-400);
  --cyan-rgb:          var(--shade-cyan-400);
  --amber-rgb:         var(--shade-amber-500);
  --amber-light-rgb:   var(--shade-amber-300);
  --rose-rgb:          var(--shade-rose-400);
  --orange-rgb:        var(--shade-orange-500);
  --yellow-rgb:        var(--shade-yellow-500);
  --indigo-rgb:        var(--shade-indigo-500);

  /* per-surface tone-ink derivation. MEASURED, not defaulted: each surface's
     eight tinted-control inks were computed under white and black at both
     shifts, and white clears the text floor on 12/12 while black clears 1/12 —
     this theme's grounds are dark on every role, so the ink shifts away from
     the tint toward white everywhere. 45% measured equal or better than 30%
     here, but no ink is under floor at 30%, so the shift stays where it
     renders today; moving it is a retune with no defect behind it. */
  --surface-page-tone-ink-toward: white;
  --surface-page-tone-ink-shift: 30%;
  --surface-panel-tone-ink-toward: white;
  --surface-panel-tone-ink-shift: 30%;
  --surface-modal-tone-ink-toward: white;
  --surface-modal-tone-ink-shift: 30%;
  --surface-field-tone-ink-toward: white;
  --surface-field-tone-ink-shift: 30%;
  --surface-frame-tone-ink-toward: white;
  --surface-frame-tone-ink-shift: 30%;

  /* tinted-control strength (canon values) */
  --tone-bg-mix: 10%;
  --tone-border-mix: 30%;

  /* ── role table (full, totality-enforced): the theme IS the binding set —
     no :root fallback valuates a role. Parts bind this theme's own rungs;
     panel-grade borders ride this theme's --line-panel; edges ride the
     structural hairlines (rung 0 through the alpha knobs). ── */
  --surface-page-bg-rgb: var(--shade-neutral-950);
  --surface-page-bg: rgb(var(--surface-page-bg-rgb));
  --surface-page-ink-rgb: var(--shade-neutral-100);
  --surface-page-ink: rgb(var(--surface-page-ink-rgb));
  --surface-page-ink-strong-rgb: var(--shade-neutral-0);
  --surface-page-ink-strong: rgb(var(--surface-page-ink-strong-rgb));
  --surface-page-ink-mid-rgb: var(--shade-neutral-400);
  --surface-page-ink-mid: rgb(var(--surface-page-ink-mid-rgb));
  --surface-page-ink-dim-rgb: var(--shade-neutral-500);
  --surface-page-ink-dim: rgb(var(--surface-page-ink-dim-rgb));
  --surface-page-ink-faint-rgb: var(--shade-neutral-650);
  --surface-page-ink-faint: rgb(var(--surface-page-ink-faint-rgb));
  --surface-page-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-page-ink-faintest: rgb(var(--surface-page-ink-faintest-rgb));
  --surface-page-border: rgb(var(--line-panel));

  --surface-panel-bg-rgb: var(--shade-neutral-900);
  --surface-panel-bg: rgb(var(--surface-panel-bg-rgb));
  --surface-panel-bg-1-rgb: var(--shade-neutral-875);
  --surface-panel-bg-1: rgb(var(--surface-panel-bg-1-rgb));
  --surface-panel-bg-2-rgb: var(--shade-neutral-850);
  --surface-panel-bg-2: rgb(var(--surface-panel-bg-2-rgb));
  --surface-panel-ink-rgb: var(--shade-neutral-100);
  --surface-panel-ink: rgb(var(--surface-panel-ink-rgb));
  --surface-panel-ink-strong-rgb: var(--shade-neutral-0);
  --surface-panel-ink-strong: rgb(var(--surface-panel-ink-strong-rgb));
  --surface-panel-ink-mid-rgb: var(--shade-neutral-400);
  --surface-panel-ink-mid: rgb(var(--surface-panel-ink-mid-rgb));
  --surface-panel-ink-dim-rgb: var(--shade-neutral-500);
  --surface-panel-ink-dim: rgb(var(--surface-panel-ink-dim-rgb));
  --surface-panel-ink-faint-rgb: var(--shade-neutral-650);
  --surface-panel-ink-faint: rgb(var(--surface-panel-ink-faint-rgb));
  --surface-panel-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-panel-ink-faintest: rgb(var(--surface-panel-ink-faintest-rgb));
  --surface-panel-border:       rgb(var(--line-panel));
  --surface-panel-edge-soft:    var(--border-soft);
  --surface-panel-edge:         var(--border);
  --surface-panel-edge-strong:  var(--border-strong);
  --surface-hover-bg-rgb: var(--shade-neutral-800);
  --surface-hover-bg: rgb(var(--surface-hover-bg-rgb));

  --surface-modal-bg-rgb: var(--shade-neutral-925);
  --surface-modal-bg: rgb(var(--surface-modal-bg-rgb));
  --surface-modal-ink-rgb: var(--shade-neutral-100);
  --surface-modal-ink: rgb(var(--surface-modal-ink-rgb));
  --surface-modal-ink-strong-rgb: var(--shade-neutral-0);
  --surface-modal-ink-strong: rgb(var(--surface-modal-ink-strong-rgb));
  --surface-modal-ink-mid-rgb: var(--shade-neutral-400);
  --surface-modal-ink-mid: rgb(var(--surface-modal-ink-mid-rgb));
  --surface-modal-ink-dim-rgb: var(--shade-neutral-500);
  --surface-modal-ink-dim: rgb(var(--surface-modal-ink-dim-rgb));
  --surface-modal-ink-faint-rgb: var(--shade-neutral-650);
  --surface-modal-ink-faint: rgb(var(--surface-modal-ink-faint-rgb));
  --surface-modal-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-modal-ink-faintest: rgb(var(--surface-modal-ink-faintest-rgb));
  --surface-modal-border:       rgb(var(--line-panel));
  --surface-modal-edge-soft:    var(--border-soft);
  --surface-modal-edge:         var(--border);
  --surface-modal-edge-strong:  var(--border-strong);

  --surface-field-bg-rgb: var(--shade-neutral-890);
  --surface-field-bg: rgb(var(--surface-field-bg-rgb));
  --surface-field-ink-rgb: var(--shade-neutral-100);
  --surface-field-ink: rgb(var(--surface-field-ink-rgb));
  --surface-field-ink-strong-rgb: var(--shade-neutral-0);
  --surface-field-ink-strong: rgb(var(--surface-field-ink-strong-rgb));
  --surface-field-ink-mid-rgb: var(--shade-neutral-400);
  --surface-field-ink-mid: rgb(var(--surface-field-ink-mid-rgb));
  --surface-field-ink-dim-rgb: var(--shade-neutral-500);
  --surface-field-ink-dim: rgb(var(--surface-field-ink-dim-rgb));
  --surface-field-ink-faint-rgb: var(--shade-neutral-650);
  --surface-field-ink-faint: rgb(var(--surface-field-ink-faint-rgb));
  --surface-field-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-field-ink-faintest: rgb(var(--surface-field-ink-faintest-rgb));
  --surface-field-border:       rgb(var(--shade-neutral-550));
  --surface-field-edge-soft:    var(--border-soft);
  --surface-field-edge:         var(--border);
  --surface-field-edge-strong:  var(--border-strong);

  --surface-frame-bg-rgb: var(--shade-neutral-950);
  --surface-frame-bg: rgb(var(--surface-frame-bg-rgb));
  --surface-frame-ink-rgb: var(--shade-neutral-100);
  --surface-frame-ink: rgb(var(--surface-frame-ink-rgb));
  --surface-frame-ink-strong-rgb: var(--shade-neutral-0);
  --surface-frame-ink-strong: rgb(var(--surface-frame-ink-strong-rgb));
  --surface-frame-ink-mid-rgb: var(--shade-neutral-400);
  --surface-frame-ink-mid: rgb(var(--surface-frame-ink-mid-rgb));
  --surface-frame-ink-dim-rgb: var(--shade-neutral-500);
  --surface-frame-ink-dim: rgb(var(--surface-frame-ink-dim-rgb));
  --surface-frame-ink-faint-rgb: var(--shade-neutral-650);
  --surface-frame-ink-faint: rgb(var(--surface-frame-ink-faint-rgb));
  --surface-frame-ink-faintest-rgb: var(--shade-neutral-700);
  --surface-frame-ink-faintest: rgb(var(--surface-frame-ink-faintest-rgb));
  --surface-frame-border:       var(--border);
  --surface-frame-edge-soft:    var(--border-soft);
  --surface-frame-edge:         var(--border);
  --surface-frame-edge-strong:  var(--border-strong);
}
