/* The Slider: the system's first control, from its tokens only. The
   core sheet: every tier, and nothing that names an effect (those are
   in effects.css, loaded after this one).

   A row: the label, the bar, the value. The bar is its own handle (the
   Bar Field's idea): the track is the inactive colour, the chosen part
   the active fill. Its size and corner are the slider's own tokens,
   which point at the spacing and radius scales; the corner never passes
   half the height. Every colour is a role (light-dark), so the slider
   follows the color-scheme it sits in.

   The colours, by role: page (the words inside the bar where they cross
   its fill); inactive (the track, the value field's ground); active (the
   fill); stroke (the inactive parts' stroke); stroke-active (the fill's
   stroke); text (the digits, the words inside the bar over the track);
   text-dim (the label beside the bar, the unit, the origin's hair);
   focus (the ring). The grid's lines are the Slider's own faint ink,
   --ds-slider-divider (the text colour at 9% or 12%). A state is the
   part's own colour tinted toward the
   text colour (Material's state layers) by the system's two rungs: the
   track and the fill --ds-state-hover under the hand, the fill also on
   a keyboard focus, --ds-state-held held; the field --ds-state-hover
   under the hand, --ds-state-held while it scrubs. No part borrows
   another role's colour for a state (the one ladder, with the Button:
   components/button.css). Off (data-off): the words dim, the fill the
   inactive ground, no tint, nothing taken by the hand.

   Two strokes, the system's switches: --ds-stroke-inactive on every
   inactive part (the track and the value field, never one alone) and
   --ds-stroke-active on the active part (the fill). Off is transparent.
   Both are inset, so a stroke never moves a box. The track's stroke is
   under the fill: with both on, each part wears its own.

   The fill is square at its value: it takes no corner of its own and is
   rounded only where it meets the bar's edge (owner, 2026-10-03). It is
   drawn as the whole bar's shape cut at the value (a clip), so its colour
   and its stroke follow the bar's curve exactly at either end, and a
   hair (one device pixel) closes it at the value, under the bar's
   corner.

   The words sit beside the bar or inside it (data-label, data-value on
   the row): inside, two layers over the bar, the text colour over the
   track and the page colour cut at the value, so the words read on
   either ground in either mode; the value's field is there too, a
   ground only while it is edited, and it takes no press until then (the
   bar under it does).

   One clock and one curve (the motion tokens): the fill follows a key, a
   snap or a typed value in half the clock, on the curve; a drag follows
   at once. The script sets data-tier on the row, data-dragging and
   data-grid (Shift held on an engaged bar) on the bar, data-pressed on
   a bar a press gave the keys (no keyboard ring and no focus tint until
   a key that is not a modifier: Chromium calls any key, Shift too,
   :focus-visible), data-scrubbing on a held field, data-held on the row
   while either holds, data-off on an off row, and data-<slot> on the
   row for each effect in use. */
/* the lights a slider's parts change by (round 6, iteration 20; owner,
   2026-10-12: "when I release a overstretch input field and slider and
   handles animate with different timings and easing"): the track's and
   the fill's tint toward the text colour and a painted bar's mark's
   ring, registered so each moves on the slider's clock and curve, the
   clock and curve its stretch and its grip let go on, while a colour
   itself never transitions (a colour edited lands at once); the
   track's tint is a layer of its own (the bar's ::after, below) */
@property --fill-tint {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}
@property --mark-ring {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
/* the value field's ground and its unit's ink, on the same clock (the
   motion audit, 2026-10-12: a scrub let go dropped the field's held
   ground in one frame while the fill's tint eased) */
@property --field-tint {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}
@property --unit-ink {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}
.ds-slider {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: var(--ds-slider-gap);
  color: var(--ds-color-text);
  /* the system's type (round 5): its family and weight; 16 / 24, its
     values the mono 15; 14 / 20 and the mono 14 in a compact surface
     (components/surface.css) */
  font-family: var(--ds-type-family);
  font-size: var(--type, var(--ds-text-16));
  line-height: var(--line, calc(var(--ds-grid-cell) * 6));
  font-weight: var(--ds-type-weight);
  /* the value's share, and its edge on the device pixel: the fill, the
     light and the words inside the bar are cut there */
  --value: 0;
  --edge: round(nearest, calc(var(--value) * 100%), var(--ds-hair));
  /* the fill's run: from the start to the value; a bipolar slider runs
     it from its origin, a range between its two ends (the script writes
     --from and --to) */
  --from: 0;
  --to: var(--value);
  --from-edge: round(nearest, calc(var(--from) * 100%), var(--ds-hair));
  --to-edge: round(nearest, calc(var(--to) * 100%), var(--ds-hair));
  /* an arrival lands on the curve (an effect may land it on the bounce) */
  --arrive: var(--ds-motion-ease);
  /* the corner of the bar, its value field and its bubble: the
     controls' own, as every control's and every field's
     (components/button.css): a surface's hand-down, else the global
     menu's Control corner, else the token (a slider alone, outside the
     lab, keeps --ds-slider-radius) */
  --slider-corner: var(--control-corner, var(--ds-slider-radius));
}
.ds-slider[data-label="beside"] {
  grid-template-columns: var(--ds-slider-label) minmax(0, 1fr);
}
.ds-slider[data-value="beside"] {
  grid-template-columns: minmax(0, 1fr) var(--ds-slider-value);
}
.ds-slider[data-label="beside"][data-value="beside"] {
  grid-template-columns: var(--ds-slider-label) minmax(0, 1fr) var(
      --ds-slider-value
    );
}
.ds-slider__label {
  overflow: hidden;
  color: var(--ds-color-text-dim);
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* the bar sits in a wrap so an effect, and the words inside the bar,
   can share its coordinates and still leave its box; the wrap isolates
   the stack, the bar in front of what emerges behind it */
.ds-slider__wrap {
  position: relative;
  isolation: isolate;
  min-width: 0;
}
.ds-slider__bar {
  position: relative;
  z-index: 1;
  height: var(--ds-slider-height);
  border-radius: min(var(--slider-corner), var(--ds-slider-height) / 2);
  background: var(--ds-color-inactive);
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
  /* the ring is the system's (below), never the engine's: a bar a press
     focused may still be :focus-visible, and must show none */
  outline: none;
  /* no overflow clip: every layer inside keeps to the bar's shape by its
     own corner and clip, and the finger's hit band (below) must reach
     past the bar */
  cursor: ew-resize;
  /* the finger on a bar is the bar's: no page pan, pinch-zoom still
     allowed (owner's rule on the phone); no tap wash */
  touch-action: pinch-zoom;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}
/* the track's tint: the text colour over the inactive ground inside
   the stroke, under the fill (below it in the bar's own stack), at the
   state's rung, its opacity moving on the slider's clock and curve. A
   layer of its own and an opacity, not the bar's colour: WebKit drops
   a margin transition running on a box (the give letting go) when a
   registered property starts to transition there (measured 2026-10-12:
   the bar came home in one frame while its field eased) */
.ds-slider__bar::after {
  content: "";
  position: absolute;
  inset: var(--stroke-inactive-w);
  z-index: -1;
  border-radius: inherit;
  background: var(--ds-color-text);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--ds-motion-clock) var(--ds-motion-ease);
}
.ds-slider[data-track] .ds-slider__bar::after {
  display: none;
}
.ds-slider__fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  /* the closing line below keeps under the bar's corner */
  overflow: hidden;
  background: color-mix(
    in srgb,
    var(--ds-color-active),
    var(--ds-color-text) var(--fill-tint)
  );
  box-shadow: inset 0 0 0 var(--stroke-active-w) var(--ds-stroke-active);
  clip-path: inset(0 calc(100% - var(--to-edge)) 0 var(--from-edge));
  transition:
    clip-path var(--ds-motion-follow) var(--arrive),
    --fill-tint var(--ds-motion-clock) var(--ds-motion-ease);
}
/* the stroke's side at the value: the active stroke's own weight in the
   pixels just before the value's edge (where a divider at that value is
   drawn), inside the fill, cut by the bar; at a weight of 0 (the
   default: the active stroke is off) none at all (round 6, iteration
   16, 2026-10-11; owner: "There are weird black lines here and there
   (look at one in range slider) fix it holistically": the side was a
   hair whatever the weight, so with the stroke off every fill still
   ended on a line of the stroke role's ink, black in light). Chromium
   paints a box on whole CSS pixels, so a box a hair wide spread across
   two device pixels at 125% and 150%: it is painted past its box (a
   spread of 2) and cut back to its own edges by a clip, whose edges
   fall where the weight puts them, in whole device pixels at every
   zoom (measured in both engines, 2026-10-07) */
.ds-slider__fill::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--edge) - var(--stroke-active-w));
  width: var(--stroke-active-w);
  background: var(--ds-stroke-active);
  box-shadow: 0 0 0 2px var(--ds-stroke-active);
  clip-path: inset(0);
  transition: left var(--ds-motion-follow) var(--arrive);
}
/* the states: the track's and the fill's own colours, tinted toward the
   text colour by the system's two rungs (the Button's ladder,
   components/button.css); a keyboard focus tints the fill. The tints
   move on the slider's clock and curve (round 6, iteration 20), a press
   takes the held rung at once (below) and a release lets it go with
   the stretch and the grip, as one move */
/* the hand on the bar is the script's (data-hover, components/slider.js
   and range.js, never a finger's): WebKit keeps :hover on a bar a
   captured drag let go off it until the mouse next moves, so its tints
   stayed while the stretch settled (the motion audit, 2026-10-12) */
.ds-slider__bar[data-hover]::after {
  opacity: var(--ds-state-hover);
}
/* the bar's edge under the hand and held (iteration 21, the ladder's
   More): the rungs' tokens, the rest's by default */
.ds-slider__bar[data-hover],
.ds-slider[data-state="hover"] .ds-slider__bar {
  box-shadow: inset 0 0 0 var(--hover-edge-w) var(--ds-state-hover-edge);
}
.ds-slider[data-held] .ds-slider__bar,
.ds-slider[data-state="held"] .ds-slider__bar {
  box-shadow: inset 0 0 0 var(--held-edge-w) var(--ds-state-held-edge);
}
.ds-slider__bar[data-hover] .ds-slider__fill {
  --fill-tint: var(--ds-state-hover);
}
.ds-slider__bar:focus-visible:not([data-pressed]) .ds-slider__fill {
  --fill-tint: var(--ds-state-hover);
}
/* a state forced for a specimen (round 5, the States grid: data-state
   hover, held, focus on the slider), so a frozen cell paints what the
   hand does: the hover tint on track and fill, the held tint on the
   fill, the ring on the bar */
.ds-slider[data-state="hover"] .ds-slider__bar::after {
  opacity: var(--ds-state-hover);
}
.ds-slider[data-state="hover"] .ds-slider__fill {
  --fill-tint: var(--ds-state-hover);
}
.ds-slider[data-state="held"] .ds-slider__fill {
  --fill-tint: var(--ds-state-held);
}
.ds-slider[data-held] .ds-slider__fill {
  --fill-tint: var(--ds-state-held);
}
/* a ring only where the keys brought the focus (html[data-kbd],
   lib/core.js; owner, 2026-10-08) */
html[data-kbd] .ds-slider__bar:focus-visible:not([data-pressed]) {
  outline: var(--focus-ring-w) solid var(--ds-color-focus);
  outline-offset: var(--focus-ring-gap);
}
/* under the hand the value follows at once */
.ds-slider[data-held] .ds-slider__fill,
.ds-slider[data-held] .ds-slider__fill::after,
.ds-slider[data-held] .ds-slider__inside--fill {
  transition-duration: 0s;
}
/* a recolour (a Mode, a stroke switch, a colour edited: lib/core.js)
   rides the clock on every part; a state's tint answers at once,
   outside it */
html[data-recolour] .ds-slider__bar,
html[data-recolour] .ds-slider__fill,
html[data-recolour] .ds-slider__field,
html[data-recolour] .ds-slider__label,
html[data-recolour] .ds-slider__input,
html[data-recolour] .ds-slider__unit,
html[data-recolour] .ds-slider__inside {
  transition:
    background-color var(--ds-motion-clock) var(--ds-motion-ease),
    color var(--ds-motion-clock) var(--ds-motion-ease),
    box-shadow var(--ds-motion-clock) var(--ds-motion-ease);
}

/* ---- the Shift dividers -------------------------------------------------
   the Bar Field's dividers, "very faint vertical dividers that sliders
   snaps to" (owner, 2026-09-03): one faint ink, --ds-slider-divider (the
   text colour at 9% in light, 12% in dark), not the stroke role (the
   2026-10-04 "same colour as outline" was the value field's seam and
   the origin's line, never these), at the coarse steps, shown while
   Shift is held on an engaged bar, page-wide, fading in and out on the
   whole clock; the value snaps to them. Each line is a hair, one device
   pixel, in the pixel just before the fill's edge at its value, its
   edge rounded on its own as --edge is: the script writes them as
   explicit stops (--lines, components/slider.js dividerLines), only
   strictly between the ends (never a line at either end) and never at
   a bipolar slider's origin (its own hair is there). A stepped slider
   shows its steps at rest */
.ds-slider__grid {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  --line-ink: var(--ds-slider-divider);
  background-image: var(--lines, none);
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity var(--ds-motion-clock) var(--ds-motion-ease);
}
.ds-slider__bar[data-grid] .ds-slider__grid,
.ds-slider__bar[data-ticks] .ds-slider__grid {
  opacity: 1;
}
/* clear of the words inside the bar (components/slider.js writes their
   extents: --words-l from the left edge, --words-r from the right) */
.ds-slider[data-label="inside"] .ds-slider__grid,
.ds-slider[data-value="inside"] .ds-slider__grid {
  -webkit-mask-image: linear-gradient(
    to right,
    transparent var(--words-l, 0px),
    #000 var(--words-l, 0px),
    #000 calc(100% - var(--words-r, 0px)),
    transparent calc(100% - var(--words-r, 0px))
  );
  mask-image: linear-gradient(
    to right,
    transparent var(--words-l, 0px),
    #000 var(--words-l, 0px),
    #000 calc(100% - var(--words-r, 0px)),
    transparent calc(100% - var(--words-r, 0px))
  );
}

/* ---- a painted track (a colour channel): the bar shows the track's
   image (no tint under the hand), the fill draws nothing, and a mark
   stands at the value: a pill of 3, 16 high about the bar's centre (on
   the cell in either density), in the page's ground ringed by a hair of
   the text colour, so it reads on any colour in either mode. Under the
   hand, a keyboard focus or held its ring is 2, one size always: the
   Range's ends' rule since iteration 18, and since iteration 20 their
   body and their clock (owner, 2026-10-12: "Make sure all these little
   handles in sliders (range and color) animate in the same way and it's
   the same as other transitions as well"): its light moves on the
   slider's clock and curve, at once under a press, its place with the
   fill's edge. At either end it stays inside the bar by half its width
   and its widest ring, so it never hangs off a rounded end and never
   moves when the ring grows ----------------------------------------- */
.ds-slider[data-track] .ds-slider__bar {
  background: var(--track);
  /* a painted track is a colour, not an inactive part: no inactive
     stroke round it (round 6, iteration 16's follow-up; owner: "there
     are weird glitches like this allover the place", a light ring round
     a dark gradient's rounded end), only the hair of the text at 12 %
     every colour shown as a colour wears (the dropdown's theme strip,
     the ladder's swatches), dark on a light end and lost on a dark one */
  box-shadow: inset 0 0 0 var(--rule) var(--colour-hair);
}
.ds-slider[data-track] .ds-slider__fill {
  visibility: hidden;
}
.ds-slider__mark {
  /* the Range's ends' body (components/range.css): 3, on the device
     pixel, a pill */
  --mark-w: round(nearest, calc(var(--ds-grid-cell) * 0.75), var(--ds-hair));
  /* back by half its width, on the device pixel as --edge is (a 3 goes
     back 1, so 2 of it stand past its place) */
  --mark-back: round(nearest, calc(var(--mark-w) / -2), var(--ds-hair));
  --mark-ring: var(--rule);
  /* its ring under the hand, a keyboard focus or held: 2, one size
     always, said once */
  --mark-ring-on: 2px;
  position: absolute;
  top: calc(50% - var(--ds-space-8));
  bottom: calc(50% - var(--ds-space-8));
  /* inside the bar at either end, its widest ring too, each end
     reckoned from the mark's own side of its place (iteration 21: one
     inset of half the width put a 3's ring half a pixel past the bar's
     right end, and the mark between pixels at both) */
  left: clamp(
    calc(var(--mark-ring-on) - var(--mark-back)),
    var(--edge),
    calc(100% - var(--mark-w) - var(--mark-back) - var(--mark-ring-on))
  );
  width: var(--mark-w);
  margin-left: var(--mark-back);
  border-radius: var(--mark-w);
  background: var(--ds-color-page);
  box-shadow: 0 0 0 var(--mark-ring) var(--ds-color-text);
  pointer-events: none;
  transition:
    left var(--ds-motion-follow) var(--arrive),
    --mark-ring var(--ds-motion-clock) var(--ds-motion-ease);
}
.ds-slider[data-held] .ds-slider__mark {
  --mark-ring: var(--mark-ring-on);
  transition-duration: 0s;
}
.ds-slider[data-track] .ds-slider__bar[data-hover] {
  background: var(--track);
}
.ds-slider[data-track] .ds-slider__bar[data-hover] .ds-slider__mark {
  --mark-ring: var(--mark-ring-on);
}
.ds-slider[data-track]
  .ds-slider__bar:focus-visible:not([data-pressed])
  .ds-slider__mark {
  --mark-ring: var(--mark-ring-on);
}

/* ---- off: a slider that takes no hand and no key keeps its place and
   its value; its words dim, readable (the ladder's off), its ground and
   strokes as at rest, no tint ------------------------------------------ */
.ds-slider[data-off] {
  pointer-events: none;
}
.ds-slider[data-off] .ds-slider__label,
.ds-slider[data-off] .ds-slider__input,
.ds-slider[data-off] .ds-slider__unit {
  color: var(--ds-color-text-dim);
}
.ds-slider[data-off] .ds-slider__fill {
  /* the fill at a third of its ink (components/surface.css --off-ink):
     an off bar still says where its value stands ("An off state must
     still be readable"; round 6, iteration 17's review: the inactive
     ground read as 0 beside 25°) */
  background: color-mix(
    in srgb,
    var(--ds-color-active) var(--off-ink),
    var(--ds-color-inactive)
  );
}
.ds-slider[data-off] .ds-slider__mark {
  visibility: hidden;
}
/* a painted bar that is off is an off bar like any other (the visual
   audit, 2026-10-12: the inactive ground in the colour's faint hair,
   its fill hidden, read as a blank box): the inactive stroke, and its
   fill at a third of its ink saying where its value stands */
.ds-slider[data-track][data-off] .ds-slider__bar {
  background: var(--ds-color-inactive);
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
}
.ds-slider[data-track][data-off] .ds-slider__fill {
  visibility: visible;
}

/* ---- a bipolar slider's origin: a hair of the text-dim role across
   the bar, under the fill, in the pixel just before the origin's edge
   (where a divider at that value would be: the grid leaves the origin
   out, so the two never double). Drawn as the dividers are, a band of
   a gradient over the bar's width, so it lands on one device pixel as
   they do (a box a hair wide is smoothed across two at 125%) --------- */
.ds-slider__origin {
  --at: round(nearest, calc(var(--origin) * 100%), var(--ds-hair));
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: linear-gradient(
    to right,
    transparent calc(var(--at) - var(--ds-hair)),
    var(--ds-color-text-dim) calc(var(--at) - var(--ds-hair)),
    var(--ds-color-text-dim) var(--at),
    transparent var(--at)
  );
  pointer-events: none;
}

/* ---- the words inside the bar ------------------------------------------
   two layers over the bar: the words in the text colour, then the same
   words in the page colour cut at the value, so over the fill they wear
   the fill's ink. Neither takes the hand: the bar under them is the
   control. The label at the left, the value at the right, each 8 in */
.ds-slider__inside {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  padding-inline: var(--ds-space-8);
  color: var(--ds-color-text);
  pointer-events: none;
}
.ds-slider__inside > .ds-slider__label {
  flex: 0 1 auto;
  min-width: 0;
  color: inherit;
}
.ds-slider__invalue {
  flex: none;
  margin-left: auto;
  font-family: var(--ds-font-mono);
  font-size: var(--mono-type, var(--ds-text-15));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ds-slider__inside--fill {
  color: var(--ds-color-page);
  clip-path: inset(0 calc(100% - var(--to-edge)) 0 var(--from-edge));
  transition: clip-path var(--ds-motion-follow) var(--arrive);
}

/* the value: digits in mono on the inactive ground (a field at rest is
   an inactive part, so it wears the track's stroke), the unit dim (a
   sign joined to the number, a word 4 apart). A scrubbable field is a
   swipe until the caret is in it (owner, 2026-10-08: "make entire field
   be swipe cursor but when clicked it becomes text editing"; the same
   on 2026-09-07: "should display a slider cursor until user clicks to
   edit text", which supersedes the 2026-09-05 pair of a text cursor on
   the digits and a scrub cursor on the unit): the whole box, pads, free
   room, digits and unit, shows the scrub cursor at rest and while it
   scrubs, wherever the hand goes mid-scrub (the root lock, below); only
   an editing field (data-editing, written by components/slider.js on a
   click without a move or a keyboard focus) shows the text cursor, over
   the whole box as one line of text; the unit never has a cursor of
   its own; a finger's field only reads. Under the hand the field is
   tinted by the hover rung, held by the held one while it scrubs and
   while it is edited (2026-09-07: "for editing text we turn full white
   on the entire field"); a ring only where the keys brought the focus */
.ds-slider__field {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  box-sizing: border-box;
  height: var(--ds-slider-height);
  padding-inline: var(--ds-space-8);
  border-radius: min(var(--slider-corner), var(--ds-slider-height) / 2);
  background: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--field-tint)
  );
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
  transition: --field-tint var(--ds-motion-clock) var(--ds-motion-ease);
  font-family: var(--ds-font-mono);
  font-size: var(--mono-type, var(--ds-text-15));
  cursor: ew-resize;
  user-select: none;
  -webkit-user-select: none;
}
@media (hover: hover) {
  .ds-slider__field:not([data-inside]):not([data-scrubbing]):not(
      [data-editing]
    ):hover {
    --field-tint: var(--ds-state-hover);
    box-shadow: inset 0 0 0 var(--hover-edge-w) var(--ds-state-hover-edge);
  }
  /* its digits take the rung's words, as the Button's do (iteration
     21's More: hover-text, held-text; iteration 24's audit: the field
     the decision names read the edge but not the words) */
  .ds-slider__field:not([data-inside]):not([data-scrubbing]):not(
      [data-editing]
    ):hover
    .ds-slider__input {
    color: var(--ds-state-hover-text);
  }
}
.ds-slider__field[data-scrubbing],
.ds-slider__field[data-editing] {
  --field-tint: var(--ds-state-held);
}
.ds-slider__field:not([data-inside])[data-scrubbing],
.ds-slider__field:not([data-inside])[data-editing] {
  box-shadow: inset 0 0 0 var(--held-edge-w) var(--ds-state-held-edge);
}
.ds-slider__field:not([data-inside])[data-scrubbing] .ds-slider__input,
.ds-slider__field:not([data-inside])[data-editing] .ds-slider__input {
  color: var(--ds-state-held-text);
}
/* a press takes the held ground at once, the let-go eases it back */
.ds-slider[data-held] .ds-slider__field,
.ds-slider[data-held] .ds-slider__unit {
  transition-duration: 0s;
}
.ds-slider__input {
  box-sizing: content-box;
  width: calc(var(--digits) * 1ch);
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ds-color-text);
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: right;
  outline: none;
  caret-color: currentColor;
  /* the field's: a swipe, or text while it is edited */
  cursor: inherit;
  user-select: text;
  -webkit-user-select: text;
  --digits: 3;
}
/* the words are the floor, never a cut: the digits' width stays the
   field's (its flex basis, squeezed as before where its row is short),
   and the least it takes is its words as drawn, so a reader's own
   spacing (WCAG 1.4.12's letter-spacing of 0.12em) widens it (iteration
   21's accessibility audit: "12–48" read "12-4", "1.00" "1.0"); at the
   system's spacing nothing moves */
@supports (field-sizing: content) {
  .ds-slider__input {
    field-sizing: content;
    /* a definite width caps a flex item's least at itself: the digits'
       width is the basis instead, and the least the words */
    flex-basis: calc(var(--digits) * 1ch);
    width: auto;
    min-width: auto;
  }
  /* inside a bar the field fits its content (it stands absolute, so no
     row squeezes it): the digits' width is its floor */
  .ds-slider__field[data-inside] .ds-slider__input {
    flex-basis: auto;
    min-width: calc(var(--digits) * 1ch);
  }
}
.ds-slider__field[data-editing],
.ds-slider__field[data-editing] .ds-slider__input,
.ds-slider__field[data-editing] .ds-slider__unit {
  cursor: text;
}
/* the lock: a scrub shows the swipe wherever the hand goes (both
   engines choose the cursor from the node under the hand and ignore
   the capture: Blink's EventHandler::SelectCursor and WebKit's
   selectCursor hit-test, read 2026-10-08), as the sash's col-resize
   lock in ds.css; written by components/slider.js, components/range.js
   and the Global card's opacity (lib/panes.js, through scrubField) for
   the scrub's life, Escape and destroy included; only one scrubs at a
   time */
html[data-scrubbing],
html[data-scrubbing] * {
  cursor: ew-resize !important;
  user-select: none;
  -webkit-user-select: none;
}
.ds-slider__input::selection {
  background: var(--ds-color-stroke);
  color: var(--ds-color-text);
}
.ds-slider__unit {
  padding-left: var(--ds-space-4);
  color: color-mix(
    in srgb,
    var(--ds-color-text-dim),
    var(--ds-color-text) var(--unit-ink)
  );
  transition: --unit-ink var(--ds-motion-clock) var(--ds-motion-ease);
}
/* a sign that belongs to the number (%, °, ×) joins it (components/
   format.js) */
.ds-slider__unit[data-sign] {
  padding-left: 0;
}
@media (hover: hover) {
  .ds-slider__field:hover .ds-slider__unit {
    --unit-ink: 100%;
  }
}
html[data-kbd] .ds-slider__field[data-editing]:not([data-inside]) {
  outline: var(--focus-ring-w) solid var(--ds-color-focus);
  outline-offset: var(--focus-ring-gap);
}
/* the field inside the bar: over the value's slot at the bar's right,
   4 in from the bar's top and bottom (its corner the bar's less 4, so
   the two are concentric), unseen and taking no press until it is
   edited (a click on the bar there edits it): then it takes the held
   tint of the inactive ground (the edit look), its digits and a ring of
   the focus colour inside its edge, and the words under it step aside */
.ds-slider__field[data-inside] {
  position: absolute;
  /* 4 in from the bar's top and bottom, 2 where the bar is under 24 */
  --inset: clamp(
    2px,
    calc(var(--ds-slider-height) - var(--ds-space-4) * 5),
    var(--ds-space-4)
  );
  top: var(--inset);
  right: 0;
  bottom: var(--inset);
  z-index: 3;
  height: auto;
  border-radius: max(
    0px,
    min(var(--slider-corner), var(--ds-slider-height) / 2) - var(--inset)
  );
  background: transparent;
  box-shadow: none;
}
.ds-slider__field[data-inside]:not([data-editing]) {
  pointer-events: none;
}
.ds-slider__field[data-inside] .ds-slider__input,
.ds-slider__field[data-inside] .ds-slider__unit {
  color: transparent;
}
.ds-slider__field[data-inside][data-editing] {
  background: color-mix(
    in srgb,
    var(--ds-color-inactive),
    var(--ds-color-text) var(--ds-state-held)
  );
  outline: none;
}
html[data-kbd] .ds-slider__field[data-inside][data-editing] {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-focus);
}
.ds-slider__field[data-inside][data-editing] .ds-slider__input {
  color: var(--ds-color-text);
}
.ds-slider__field[data-inside][data-editing] .ds-slider__unit {
  color: var(--ds-color-text-dim);
}
.ds-slider__wrap:has(.ds-slider__field[data-inside][data-editing])
  .ds-slider__invalue {
  visibility: hidden;
}

/* a finger: the bar keeps its height at rest, with a hit band of 48; the
   value reads; the bar drives */
@media (pointer: coarse) {
  .ds-slider__bar::before {
    content: "";
    position: absolute;
    inset: calc((var(--ds-grid-cell) * 12 - 100%) / -2) 0;
  }
  .ds-slider__field {
    pointer-events: none;
  }
}

@media (forced-colors: active) {
  .ds-slider__bar {
    outline: 1px solid CanvasText;
  }
  .ds-slider__fill {
    forced-color-adjust: none;
    background: Highlight;
  }
  /* one layer of words: the system's own, its text on the backplate
     forced colours give it, readable over the Highlight fill and the
     ground alike; the second, cut at the value, drew over it out of
     register (the critique of iteration 24: "1 px" read "11 px", "32
     px" with a ghost "3", and a label over the fill black on its black
     backplate) */
  .ds-slider__inside--fill {
    display: none;
  }
  /* and the field inside the bar keeps its digits unseen until it is
     edited: forced colours paint a transparent colour, so its input and
     its unit stood 4 left of the words' own, a ghost "3" before "32 px"
     (the critique of iteration 24) */
  .ds-slider__field[data-inside]:not([data-editing]) .ds-slider__input,
  .ds-slider__field[data-inside]:not([data-editing]) .ds-slider__unit {
    forced-color-adjust: none;
    color: transparent;
  }
  html[data-kbd] .ds-slider__bar:focus-visible:not([data-pressed]),
  html[data-kbd] .ds-slider__field[data-editing] {
    outline: var(--focus-ring-forced-w) solid Highlight;
  }
  /* the field takes a scrub and a click: it shows its box, as the
     Dropdown's field does (iteration 24's audit: forced colours drop
     its inset edge, and its digits floated with no field) */
  .ds-slider__field:not([data-inside]) {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
}

/* ---- marks of the caller's (setMarks, round 6, iteration 24): a hair
   at each value's share across the bar, under the value's mark, drawn
   as the origin's is (a band of a gradient, on one device pixel), in
   the text-dim role unless the caller's sheet inks its kind
   (--hair-ink); none is built until one is asked for ------------------ */
.ds-slider__marks {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
.ds-slider__hair {
  --at: round(nearest, calc(var(--at-share) * 100%), var(--ds-hair));
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
    to right,
    transparent calc(var(--at) - var(--ds-hair)),
    var(--hair-ink, var(--ds-color-text-dim)) calc(var(--at) - var(--ds-hair)),
    var(--hair-ink, var(--ds-color-text-dim)) var(--at),
    transparent var(--at)
  );
}
