/* ── Form primitives ─────────────────────────────────────────── */
input[type="text"], input[type="number"], input[type="password"],
input[type="search"], textarea, select {
  width: 100%;
  padding: 7px 10px;
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  transition: border-color var(--t1) var(--e), background var(--t1) var(--e),
    box-shadow var(--t1) var(--e);
}
input[type="search"] { appearance: none; }
input[type="search"]::-webkit-search-cancel-button { opacity: 0.45; cursor: pointer; }
input[type="number"] { font-family: var(--mono); font-size: var(--fz-sm); }
input:hover:not(:focus), textarea:hover:not(:focus), select:hover:not(:focus) { border-color: var(--line-2); }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--a-line);
  background: var(--well-focus);
  box-shadow: var(--ring);
}
::placeholder { color: var(--fg-4); }
textarea { resize: vertical; line-height: 1.6; }
/* No spinner arrows: they are a 9px target that crowds the figure, and every
   number field here is typed or nudged with the arrow keys anyway. */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

select {
  appearance: none;
  padding-right: 30px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.75 6 8.25l3.5-3.5' fill='none' stroke='%23a6a5b0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
select option { background: var(--raised); }

/* field */
.fld { display: grid; gap: 6px; }
.fld-group { display: grid; gap: var(--sp-3); }
.fld-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: 22px; }
.fld-actions { display: flex; align-items: center; gap: var(--sp-2); }
.fld label, .slider-top label {
  font-size: var(--fz-xs); font-weight: var(--fw-medium);
  color: var(--fg-3);
  letter-spacing: 0.01em;
}
.hint { font-size: var(--fz-xs); line-height: 1.45; color: var(--fg-3); transition: color var(--t1) var(--e); }
.hint.warn { color: var(--warn); }
.hint[hidden] { display: none; }
.fld-inline input:disabled { opacity: 0.52; cursor: not-allowed; }

.quota-warning {
  display: flex; align-items: flex-start; gap: 7px;
  padding: 7px 9px;
  color: var(--warn); background: rgba(224, 171, 104, 0.08);
  border: 1px solid rgba(224, 171, 104, 0.22); border-radius: var(--r2);
  font-size: var(--fz-2xs); line-height: 1.4;
}
.quota-warning[hidden] { display: none; }
.quota-warning .ico { flex: none; width: 14px; height: 14px; margin-top: 1px; }

.pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.pair.tight { gap: var(--sp-2); }
.pair[hidden] { display: none; }

/* The prompt is the primary input, so it claims all leftover height. */
.fld-hero {
  position: relative;
  flex: 1 1 auto !important; /* stylelint-disable-line declaration-no-important -- The prompt fills remaining composer height instead of the generic field flex. */
  min-height: 190px;
  display: grid;
  /* tab row + input row */
  grid-template-rows: auto minmax(0, 1fr);
}
/* The wrapper takes the flexible row; the textarea fills it. All text metrics
   come from the shared .hl-wrap block so the mirror cannot drift. */
/* The wrapper is a bounded scroller filling the flexible row. The textarea
   inside is unbounded (auto-grown), which is what makes the wrapper scroll. */
.fld-hero .hl-wrap { height: 100%; min-height: 0; }
/* Under the tab strip the well's top edge is the strip's own border, so the
   top corners square off and the top border is dropped to avoid a double line. */
.pane .hl-wrap {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-top-color: transparent;
}
.fld-hero[data-resized="1"] { flex: none !important; } /* stylelint-disable-line declaration-no-important -- Explicitly resized prompts must stop growing with the composer. */


/* ── Icons ───────────────────────────────────────────────────── */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico {
  width: var(--ico); height: var(--ico);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ico.solid { fill: currentColor; stroke: none; }
.ico-lg { width: 26px; height: 26px; }
.ico-xl { width: 34px; height: 34px; stroke-width: 1.3; }
.ico.err { stroke: var(--err); opacity: .8; }

/* Icon-only button. Tooltip comes from data-tip so no visible label is
   needed while the action stays discoverable. */
.ibtn {
  position: relative;
  display: inline-grid; place-items: center;
  width: 32px; height: 32px;
  flex: none;
  color: var(--fg-3);
  text-decoration: none;
  border-radius: var(--r2);
  transition: color var(--t1) var(--e), background var(--t1) var(--e);
}
.ibtn:hover { color: var(--fg); background: var(--raised); }
.ibtn:active { transform: scale(.94); }
.ibtn[hidden] { display: none; }
.ibtn-xs { width: 28px; height: 28px; --ico: 17px; }
/* The prompt block's two actions carry real weight now that the labels are
   gone: bigger glyph, brighter idle colour, and a visible resting surface so
   they read as buttons rather than as ornament. */
/* Recessed icon button for the prompt block: inset controls cut into the
   panel rather than bare glyphs floating on it. */
.fld-actions .ibtn {
  width: 30px; height: 30px;
  --ico: 19px;
  color: var(--fg-2);
  background: var(--well);
  box-shadow: inset 0 0 0 1px var(--line);
}
.fld-actions .ibtn:hover {
  color: var(--fg);
  background: var(--hover);
  box-shadow: inset 0 0 0 1px var(--line-2);
}
/* Header tools stay bare: the balances are the only thing on the bar with
   weight, and a row of boxed icons used to compete with them. */
.topbar-end .ibtn,
.topbar-lock {
  width: 34px; height: 34px;
  --ico: 19px;
}
.fld-actions .ibtn .ico,
.topbar-end .ibtn .ico,
.topbar-lock .ico { stroke-width: 1.9; }
.ibtn-accent { color: var(--a); }
.ibtn-accent:hover { color: var(--a); background: var(--a-dim); }
/* Settled state after a successful clean — reverts on the next edit. */
.ibtn[data-state="done"] { color: var(--ok); }
.ibtn[aria-pressed="false"] { color: var(--fg-4); }
.ibtn[aria-pressed="false"]:hover { color: var(--fg-2); }

[data-tip]::after {
  content: attr(data-tip);
  position: absolute; top: calc(100% + 6px); left: 50%;
  transform: translate(-50%, -3px);
  padding: 4px 7px;
  font-size: var(--fz-2xs); line-height: 1.3;
  white-space: nowrap;
  color: var(--fg-2);
  background: var(--hover);
  border: 1px solid var(--line-2);
  border-radius: var(--r1);
  box-shadow: var(--sh-1);
  opacity: 0; pointer-events: none;
  transition: opacity var(--t1) var(--e), transform var(--t1) var(--e);
  z-index: var(--z-tip);
}
[data-tip]:hover::after { opacity: 1; transform: translate(-50%, 0); transition-delay: 260ms; }
.result-actions [data-tip]::after,
.tray [data-tip]::after,
.fld-actions [data-tip]::after,
.seed [data-tip]::after,
.topbar-end [data-tip]::after,
.topbar-account [data-tip]::after { left: auto; right: 0; transform: translate(0, -3px); }
.fld-actions [data-tip]:hover::after,
.result-actions [data-tip]:hover::after,
.tray [data-tip]:hover::after,
.seed [data-tip]:hover::after,
.topbar-end [data-tip]:hover::after,
.topbar-account [data-tip]:hover::after { transform: translate(0, 0); }

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 7px 12px;
  font-size: var(--fz-sm); font-weight: var(--fw-medium);
  border-radius: var(--r2);
  white-space: nowrap;
  transition: background var(--t1) var(--e), color var(--t1) var(--e),
    border-color var(--t1) var(--e), transform var(--t1) var(--e), opacity var(--t1) var(--e);
}
.btn:active { transform: scale(0.978); }
.btn[hidden] { display: none; }
.btn-block { width: 100%; }
.btn-sm { padding: 6px 10px; font-size: var(--fz-xs); gap: 6px; --ico: 13px; }
.btn .ico { stroke-width: 1.7; }

.btn-primary { background: var(--a); color: var(--a-ink); font-weight: var(--fw-semibold); }
.btn-primary:hover { background: var(--a-hover); }
.btn-primary:disabled { background: var(--raised); color: var(--fg-4); cursor: not-allowed; transform: none; }

.btn-quiet { color: var(--fg-2); background: var(--raised); border: 1px solid var(--line); }
.btn-quiet:hover { color: var(--fg); background: var(--hover); border-color: var(--line-2); }

.btn-accent { color: var(--a); background: var(--a-dim); border: 1px solid var(--a-line); font-weight: var(--fw-semibold); }
.btn-accent:hover { background: rgba(179, 161, 255, 0.2); }

/* Confirms an irreversible loss; never the default focus. */
.btn-danger { color: var(--err); background: var(--err-dim); border: 1px solid rgba(232, 135, 135, 0.38); font-weight: var(--fw-semibold); }
.btn-danger:hover { color: #f0a5a5; background: rgba(232, 135, 135, 0.16); }

.btn-link {
  font-size: var(--fz-xs); color: var(--fg-3);
  transition: color var(--t1) var(--e);
}
.btn-link:hover { color: var(--a); }
.btn-link.centered { justify-self: center; }

/* ── Generate: the one purchase button on the page ──────────────
   This is the control that spends the user's quota, so it gets the full
   physical treatment: lit from above like every panel (a vertical accent
   gradient and a top lip), a dark hairline that keeps the edge crisp on the
   chrome, and an accent-tinted drop.

   While a job runs, the same button becomes its progress track instead of
   swapping for a different one. Gradients do not interpolate, so the fill
   lives on ::before and fades out; the travelling light lives on ::after and
   fades in. Every state keeps the same four shadows, so those blend as well:
   inset lip, inset ring, outer hairline, glow. */
.btn-go {
  position: relative; isolation: isolate; overflow: hidden;
  height: 46px;
  padding-inline: 44px;
  font-size: var(--fz-md); font-weight: var(--fw-semibold);
  color: var(--a-ink);
  background: var(--a);
  border-radius: var(--r3);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.36),
    inset 0 0 0 1px rgba(255, 255, 255, 0.1),
    0 0 0 1px rgba(10, 8, 20, 0.55),
    0 10px 24px -12px rgba(179, 161, 255, 0.6);
  transition: color var(--t2) var(--e), background-color var(--t2) var(--e),
    box-shadow var(--t2) var(--e), transform var(--t1) var(--e);
}
.btn-go::before, .btn-go::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; pointer-events: none;
  transition: opacity var(--t2) var(--e), filter var(--t1) var(--e);
}
.btn-go::before { background: linear-gradient(to bottom, #cabdff, var(--a) 55%, #a692fb); }
.btn-go::after {
  /* One soft band, slanted by skew so its edges stay transparent; it rests
     off the left edge, so dropping the animation can't strand it mid-button. */
  right: auto; width: 56%;
  opacity: 0;
  background: linear-gradient(90deg,
    rgba(214, 205, 255, 0) 0%, rgba(214, 205, 255, 0.03) 20%, rgba(214, 205, 255, 0.09) 38%,
    rgba(214, 205, 255, 0.15) 50%,
    rgba(214, 205, 255, 0.09) 62%, rgba(214, 205, 255, 0.03) 80%, rgba(214, 205, 255, 0) 100%);
  transform: translateX(-110%) skewX(-14deg);
}
.btn-go:hover::before { filter: brightness(1.06); }
.btn-go:hover {
  background: var(--a);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.42),
    inset 0 0 0 1px rgba(255, 255, 255, 0.12),
    0 0 0 1px rgba(10, 8, 20, 0.55),
    0 12px 28px -12px rgba(179, 161, 255, 0.78);
}
/* Press = travel down and the glow tucks in, not a generic shrink. */
.btn-go:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.24),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08),
    0 0 0 1px rgba(10, 8, 20, 0.55),
    0 6px 14px -10px rgba(179, 161, 255, 0.45);
}
.btn-go:disabled {
  color: var(--fg-4);
  background: var(--raised);
  transform: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.035),
    inset 0 0 0 1px var(--line-2),
    0 0 0 1px rgba(10, 8, 20, 0),
    0 10px 24px -12px rgba(179, 161, 255, 0);
}
.btn-go:disabled::before { opacity: 0; }
/* The shortcut travels with the label as two small keycaps, so icon, label,
   cost and keys read as one centred group. Glyphs are drawn, not typed: the
   text fonts render ↵ small and low, and ⌘ falls back to whatever the system
   has. Pressed into the fill (dark tint, darker bottom edge) rather than
   stacked on it, so they stay quieter than the label. */
.go-keys { display: inline-flex; gap: 3px; margin-left: 4px; }
.go-keys kbd {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 4px;
  font: var(--fw-semibold) 10px/1 var(--sans); letter-spacing: 0.02em;
  color: rgba(23, 19, 42, 0.5);
  background: rgba(23, 19, 42, 0.05);
  border: 0; border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgba(23, 19, 42, 0.1), inset 0 -1px 0 rgba(23, 19, 42, 0.14);
}
.go-keys .ico { width: 10px; height: 10px; stroke-width: 2.3; }
/* Not on a Mac: the same keys, labelled for a PC keyboard. */
[data-mod="ctrl"] .key-mod .ico { display: none; }
[data-mod="ctrl"] .key-mod::before { content: "Ctrl"; }
/* Can't fire it now (or no keyboard): say nothing rather than grey it out. */
.btn-go:disabled .go-keys { display: none; }
@media (hover: none) { .go-keys { display: none; } }
.btn-go .go-spin { display: none; }

/* Working ≠ unavailable. Grey answers "can I press this?"; the moment after
   pressing, the question is "is it doing anything?". So while the form is
   busy the button stays in the accent family as a dark track, with a spinner
   in place of the sparkle and a slow light band passing through. */
.generation-form[aria-busy="true"] .btn-go:disabled {
  color: var(--a);
  background: color-mix(in srgb, var(--a) 9%, var(--raised));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    inset 0 0 0 1px var(--a-line),
    0 0 0 1px rgba(10, 8, 20, 0),
    0 10px 24px -12px rgba(179, 161, 255, 0.22);
}
.generation-form[aria-busy="true"] .btn-go:disabled::after {
  opacity: 1;
  animation: goSweep 2.6s cubic-bezier(0.45, 0.05, 0.35, 1) var(--t2) infinite;
}
.generation-form[aria-busy="true"] .btn-go > .ico:first-child { display: none; }
.generation-form[aria-busy="true"] .btn-go .go-spin { display: block; }
.go-spin {
  flex: none; width: 15px; height: 15px;
  border: 2px solid var(--a-dim); border-top-color: currentColor;
  border-radius: 50%;
  animation: goSpin 0.85s linear infinite;
}
/* Elapsed time on the track's right edge, where the shortcut was. */
.go-time {
  position: absolute; right: 14px; top: 50%; translate: 0 -50%;
  font: var(--fw-medium) var(--fz-xs)/1 var(--mono); font-variant-numeric: tabular-nums;
  color: var(--fg-3);
}
.generation-form:not([aria-busy="true"]) .go-time { display: none; }
/* Same shape as sheenSweep: cross in the first half, then wait off-button.
   The loop restarts while the band is out of sight, so there is no seam; the
   old repeating-gradient version ended each cycle with the band mid-button
   and jumped. Offsets are of the band's own 56% width: -110% clears the left
   edge, 190% the right. */
@keyframes goSweep {
  0%   { transform: translateX(-110%) skewX(-14deg); }
  50%  { transform: translateX(190%) skewX(-14deg); }
  100% { transform: translateX(190%) skewX(-14deg); }
}
@keyframes goSpin { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) {
  .generation-form[aria-busy="true"] .btn-go:disabled::after { animation: none; opacity: 0; }
  .go-spin { animation-duration: 2.4s; }
}

/* Price rides inside the action that spends it: the same four-point glyph
   as the header gauge names the currency, mono tabular digits keep the
   figure planted while the count changes. On the accent it is a pale chip
   lifted out of the fill, not a grey hole punched into it. */
.cost-tag {
  display: inline-flex; align-items: center; gap: 3px;
  font: var(--fw-semibold) var(--fz-2xs)/1 var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  padding: 4px 8px 4px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.3);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
  color: rgba(23, 19, 42, 0.82);
}
.cost-tag .ico {
  width: 11px; height: 11px;
  fill: currentColor; stroke: none;
}
.cost-tag { transition: opacity var(--t2) var(--e); }
.cost-tag[hidden] { display: none; }
/* Re-quoting: the previous figure stays put, faded, until the new one lands. */
.cost-tag[data-stale="true"] { opacity: 0.5; }
.btn-go:disabled .cost-tag { background: var(--well); box-shadow: none; color: var(--fg-4); }

/* Generate and stop share one row, so starting a job never moves anything
   under the pointer: generate narrows and stop slides in at the far edge,
   well away from where the click landed. Hidden, stop keeps its box (at
   zero width) so it can animate out as well as in. */
.go-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 0px;
  column-gap: 0;
  transition: grid-template-columns var(--t2) var(--e-out), column-gap var(--t2) var(--e-out);
}
.go-row:has(> .btn-stop:not([hidden])) { grid-template-columns: minmax(0, 1fr) 92px; column-gap: 8px; }
.go-row > .btn-go { width: auto; min-width: 0; }
.btn-stop {
  min-width: 0; height: 46px; padding: 0; overflow: hidden;
  gap: 6px;
  color: var(--fg-2);
  background: var(--raised);
  border: 1px solid var(--line-2);
  border-radius: var(--r3);
  box-shadow: var(--sh-lip);
  transition: opacity var(--t2) var(--e), transform var(--t2) var(--e-out), visibility 0s,
    color var(--t1) var(--e), background var(--t1) var(--e), border-color var(--t1) var(--e);
}
.btn-stop .ico { width: 18px; height: 18px; fill: currentColor; stroke: none; }
@media (hover: hover) {
  .btn-stop:hover { color: var(--err); background: rgba(232, 135, 135, 0.1); border-color: rgba(232, 135, 135, 0.38); }
}
.go-row > .btn-stop[hidden] {
  display: inline-flex; visibility: hidden; pointer-events: none;
  opacity: 0; transform: translateX(12px);
  transition: opacity var(--t1) var(--e), transform var(--t1) var(--e), visibility 0s linear var(--t1);
}

/* ── Checkbox ────────────────────────────────────────────────── */
.check { display: flex; align-items: center; gap: var(--sp-2); cursor: pointer; color: var(--fg-2); font-size: var(--fz-sm); }
.check .sub { font-style: normal; font-size: var(--fz-2xs); color: var(--fg-3); margin-left: 4px; }
.check:hover { color: var(--fg); }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check > span:first-of-type {
  position: relative; flex: none;
  width: 16px; height: 16px;
  background: var(--well);
  border: 1px solid var(--line-2);
  border-radius: 5px;
  transition: background var(--t1) var(--e), border-color var(--t1) var(--e);
}
.check > span:first-of-type::after {
  content: ""; position: absolute; inset: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.8 8.4 6.4 11 12.2 5.2' fill='none' stroke='%2317132a' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/11px no-repeat;
  opacity: 0; transform: scale(0.6);
  transition: opacity var(--t1) var(--e), transform var(--t2) var(--e-out);
}
.check input:checked + span { background: var(--a); border-color: var(--a); }
.check input:checked + span::after { opacity: 1; transform: none; }
.check input:focus-visible + span { outline: 2px solid var(--a); outline-offset: 2px; }
.check:has(input:disabled) { opacity: 0.45; cursor: not-allowed; }
.check:has(input:disabled):hover { color: var(--fg-2); }
.switches { display: grid; gap: 9px; }

/* ── Segmented ───────────────────────────────────────────────── */
.seg { display: grid; grid-auto-flow: column; gap: 3px; padding: 3px; background: var(--well); border: 1px solid var(--line); border-radius: var(--r2); }
.seg label { position: relative; }
.seg input { position: absolute; opacity: 0; width: 0; height: 0; }
.seg span {
  display: block; padding: 7px 8px; text-align: center;
  font-size: var(--fz-xs); color: var(--fg-3);
  border-radius: var(--r1); cursor: pointer;
  transition: background var(--t1) var(--e), color var(--t1) var(--e);
}
.seg span:hover { color: var(--fg-2); }
.seg input:checked + span { background: var(--raised); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.3); }
.seg input:focus-visible + span { outline: 2px solid var(--a); outline-offset: 1px; }



/* ── Sliders ─────────────────────────────────────────────────── */
.slider { display: grid; gap: 5px; }
.slider-top { display: flex; align-items: center; justify-content: space-between; }
.pill {
  min-width: 32px; padding: 2px 6px;
  font: var(--fw-medium) var(--fz-2xs)/1.4 var(--mono); font-variant-numeric: tabular-nums;
  text-align: center; color: var(--fg);
  background: var(--well); border: 1px solid var(--line);
  border-radius: 20px;
  transition: color var(--t1) var(--e), border-color var(--t1) var(--e);
}
.slider:focus-within .pill { color: var(--a); border-color: var(--a-line); }

input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 18px;
  background: none; border: 0; padding: 0; cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track { height: 3px; border-radius: 2px; background: var(--line-2); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px; height: 13px; margin-top: -5px;
  border-radius: 50%; background: var(--fg-2);
  transition: background var(--t1) var(--e), transform var(--t1) var(--e-out),
    box-shadow var(--t1) var(--e);
}
input[type="range"]:hover::-webkit-slider-thumb { background: var(--fg); }
input[type="range"]:active::-webkit-slider-thumb,
input[type="range"]:focus-visible::-webkit-slider-thumb {
  background: var(--a); transform: scale(1.2); box-shadow: 0 0 0 5px var(--a-dim);
}
input[type="range"]::-moz-range-track { height: 3px; border-radius: 2px; background: var(--line-2); }
input[type="range"]::-moz-range-thumb { width: 13px; height: 13px; border: 0; border-radius: 50%; background: var(--fg-2); }

/* Scrub bar: for the one value a panel is about (the editor's strength). The
   fill is the value, and label and figure sit inside it, so it reads as one
   object instead of a hairline with a pill floating above. An invisible range
   input covers the bar, so pointer, touch and arrow keys behave natively. */
.scrub {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  height: 38px; padding: 0 var(--sp-3);
  background:
    linear-gradient(to right, transparent calc(25% - 1px), var(--line) 0 25%, transparent 0 calc(50% - 1px),
      var(--line) 0 50%, transparent 0 calc(75% - 1px), var(--line) 0 75%, transparent 0) center / 100% 8px no-repeat,
    var(--well);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  overflow: hidden;
  cursor: ew-resize;
  transition: border-color var(--t1) var(--e), box-shadow var(--t1) var(--e);
}
.scrub::before {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 0;
  width: var(--p, 50%);
  background: linear-gradient(to right, rgba(179, 161, 255, 0.06), rgba(179, 161, 255, 0.2));
  box-shadow: inset -2px 0 var(--a);
  pointer-events: none;
}
.scrub:hover { border-color: var(--line-2); }
.scrub:has(input:focus-visible), .scrub:active { border-color: var(--a-line); box-shadow: var(--ring); }
.scrub > span, .scrub > output { position: relative; pointer-events: none; }
.scrub > span { font-size: var(--fz-xs); font-weight: var(--fw-medium); color: var(--fg-2); }
.scrub > output { font: var(--fw-semibold) var(--fz-sm)/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.scrub input[type="range"] { position: absolute; inset: 0; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; }
/* A hairline thumb, so the value under the pointer is the value set. */
.scrub input[type="range"]::-webkit-slider-thumb { width: 2px; height: 38px; }
.scrub input[type="range"]::-moz-range-thumb { width: 2px; height: 38px; }
.scrub:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
/* A stack of them (the composer's steps / scale / CFG) runs a notch smaller. */
.scrubs { display: grid; gap: 6px; }
.scrub-sm { height: 34px; }
.scrub-sm input[type="range"]::-webkit-slider-thumb { height: 34px; }
.scrub-sm input[type="range"]::-moz-range-thumb { height: 34px; }


/* Shared Tag category indicators: dictionary, picker and autocomplete. */
.tag-category-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-4); }
.tag-category-dot.artist { background: #e88787; }
.tag-category-dot.copyright { background: #b3a1ff; }
.tag-category-dot.character { background: #74cf9b; }
.tag-category-dot.meta { background: #e0ab68; }
