/* range-slider.css: one stylesheet for reference/vanilla AND reference/react (same class names).
 *
 * Tokens: every colour/size is a custom property on .rs that falls back through the house
 * semantic tokens (UI_STANDARDS.md section 3: --bg-surface, --text-primary, --accent-primary,
 * --border-subtle, --focus-ring ...) and the motion tokens (_shared/ui-effects/motion-tokens.css:
 * --motion-fast, --ease-snappy). A project that defines those tokens re-skins the slider for free.
 * Light + dark designed together; prefers-reduced-motion zeroes every transition.
 * Spacing uses only the house scale (2, 4, 8, 12, 16, 24px).
 * Motion law (ui-transitions skill): only transform/opacity are transitioned. Handles and the window
 * move by `left`/`width` WITHOUT any transition, because they must follow the pointer instantly.
 */

.rs {
  --rs-surface: var(--bg-surface, hsl(0 0% 100%));
  --rs-subtle: var(--bg-subtle, hsl(220 14% 96%));
  --rs-elevated: var(--bg-elevated, hsl(0 0% 100%));
  --rs-text: var(--text-primary, hsl(222 39% 11%));
  --rs-muted: var(--text-muted, hsl(220 9% 32%));
  --rs-accent: var(--accent-primary, hsl(221 83% 43%));
  --rs-accent-soft: var(--accent-primary-soft, hsl(221 83% 43% / 0.14));
  --rs-on-accent: var(--text-inverted, hsl(0 0% 100%));
  --rs-border: var(--border-subtle, hsl(220 13% 84%));
  --rs-border-strong: var(--border-strong, hsl(220 9% 55%));
  --rs-focus: var(--focus-ring, hsl(221 83% 53%));
  --rs-warn: var(--warning, hsl(32 95% 30%));
  --rs-ok: var(--success, hsl(142 72% 26%));
  --rs-error: var(--error, hsl(0 72% 40%));
  --rs-shadow: 0 1px 3px hsl(222 39% 11% / 0.25);

  --rs-control: 32px;       /* buttons / inputs on fine pointers */
  --rs-track-h: 32px;       /* pointer area of the track */
  --rs-thumb-hit: 14px;     /* = 2 x HIT_PX (7px) from core.mjs */
  --rs-rail: 8px;
  --rs-radius: 8px;
  --rs-motion: var(--motion-fast, 180ms);
  --rs-motion-instant: var(--motion-instant, 120ms);
  --rs-ease: var(--ease-snappy, cubic-bezier(0.22, 1, 0.36, 1));

  display: grid;
  gap: 8px;
  min-width: 0;
  color: var(--rs-text);
  font-size: 0.875rem;
  line-height: 1.4;
}
.rs[hidden],
.rs [hidden] { display: none !important; } /* author display rules would otherwise beat the hidden attribute */

/* Touch screens: every target at least 44px (thumbs, arrows, chips, inputs). */
@media (pointer: coarse) {
  .rs {
    --rs-control: 44px;
    --rs-track-h: 44px;
    --rs-thumb-hit: 44px;
  }
}

@supports (color: oklch(0 0 0)) {
  .rs {
    --rs-accent: var(--accent-primary, oklch(0.49 0.2 262));
    --rs-accent-soft: var(--accent-primary-soft, oklch(0.49 0.2 262 / 0.14));
  }
}

/* Theme keys: the slider's own data-theme wins; otherwise it follows the PAGE (:root[data-theme]), the
 * convention keyword-search and multi-select-filter use, so one page toggle themes all three controls.
 * (2026-10-14, data-explorer: keyed on .rs alone, a light page on a dark OS kept a dark slider.) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rs:not([data-theme="light"]) {
    --rs-surface: var(--bg-surface, hsl(222 22% 11%));
    --rs-subtle: var(--bg-subtle, hsl(222 18% 16%));
    --rs-elevated: var(--bg-elevated, hsl(222 18% 20%));
    --rs-text: var(--text-primary, hsl(220 20% 93%));
    --rs-muted: var(--text-muted, hsl(218 13% 72%));
    --rs-accent: var(--accent-primary, hsl(213 94% 68%));
    --rs-accent-soft: var(--accent-primary-soft, hsl(213 94% 68% / 0.18));
    --rs-on-accent: var(--text-inverted, hsl(222 39% 11%));
    --rs-border: var(--border-subtle, hsl(222 14% 28%));
    --rs-border-strong: var(--border-strong, hsl(220 10% 50%));
    --rs-focus: var(--focus-ring, hsl(213 94% 68%));
    --rs-warn: var(--warning, hsl(38 92% 60%));
    --rs-ok: var(--success, hsl(142 69% 58%));
    --rs-error: var(--error, hsl(0 91% 71%));
    --rs-shadow: 0 1px 3px hsl(0 0% 0% / 0.6);
  }
}
.rs[data-theme="dark"],
:root[data-theme="dark"] .rs:not([data-theme="light"]) {
  --rs-surface: var(--bg-surface, hsl(222 22% 11%));
  --rs-subtle: var(--bg-subtle, hsl(222 18% 16%));
  --rs-elevated: var(--bg-elevated, hsl(222 18% 20%));
  --rs-text: var(--text-primary, hsl(220 20% 93%));
  --rs-muted: var(--text-muted, hsl(218 13% 72%));
  --rs-accent: var(--accent-primary, hsl(213 94% 68%));
  --rs-accent-soft: var(--accent-primary-soft, hsl(213 94% 68% / 0.18));
  --rs-on-accent: var(--text-inverted, hsl(222 39% 11%));
  --rs-border: var(--border-subtle, hsl(222 14% 28%));
  --rs-border-strong: var(--border-strong, hsl(220 10% 50%));
  --rs-focus: var(--focus-ring, hsl(213 94% 68%));
  --rs-warn: var(--warning, hsl(38 92% 60%));
  --rs-ok: var(--success, hsl(142 69% 58%));
  --rs-error: var(--error, hsl(0 91% 71%));
  --rs-shadow: 0 1px 3px hsl(0 0% 0% / 0.6);
}

/* Sticky: stays visible while the page scrolls (NK 2026-09-08 "timeline needs to stay visible when we scroll"). */
.rs[data-sticky] {
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 8px 0;
  background: var(--rs-surface);
}

/* ---------- header: label, i, readout (one line, never wraps: no layout shift while scrubbing) */
.rs-head {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.rs-label { font-weight: 600; white-space: nowrap; }
.rs-readout {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--rs-text);
}
/* The "i" (.rs-info) is an info-tip button: load info-tip.css (.claude/skills/info-tip). info-tip draws it 20px with
 * an exact 44x44 hit area (regression: 2026-10-14-hit-area-42px) and puts its popover in <body>, so the sticky
 * timeline, a clipping card or the next control can never cover it. The slider only lends it its colours, through
 * custom properties that inherit (stylesheet order never matters). */
.rs {
  --it-btn-text: var(--rs-muted);
  --it-btn-border: var(--rs-border-strong);
  --it-btn-bg: var(--rs-elevated);
}

/* ---------- buttons shared by chips, reset, arrows, play, live */
.rs button,
.rs select,
.rs input[type="text"] {
  font: inherit;
  color: inherit;
}
.rs-chip,
.rs-reset,
.rs-step,
.rs-play,
.rs-live,
.rs-speed {
  min-height: var(--rs-control);
  min-width: var(--rs-control);
  padding: 0 12px;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  background: var(--rs-elevated);
  color: var(--rs-text);
  font-size: 0.8125rem;
  cursor: pointer;
  transition: transform var(--rs-motion-instant) var(--rs-ease), opacity var(--rs-motion) var(--rs-ease);
  -webkit-tap-highlight-color: transparent;
}
.rs-chip:hover:not(:disabled),
.rs-reset:hover:not(:disabled),
.rs-step:hover:not(:disabled),
.rs-play:hover:not(:disabled),
.rs-live:hover:not(:disabled) {
  border-color: var(--rs-border-strong);
  background: var(--rs-subtle);
}
.rs-chip:active:not(:disabled),
.rs-reset:active:not(:disabled),
.rs-step:active:not(:disabled),
.rs-play:active:not(:disabled),
.rs-live:active:not(:disabled) {
  transform: scale(0.96);
}
.rs button:disabled,
.rs select:disabled,
.rs input:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.rs button:focus-visible,
.rs select:focus-visible,
.rs input:focus-visible {
  outline: 2px solid var(--rs-focus);
  outline-offset: 2px;
}
.rs-chip[aria-pressed="true"],
.rs-play[aria-pressed="true"] {
  border-color: var(--rs-accent);
  background: var(--rs-accent);
  color: var(--rs-on-accent);
}

.rs-presets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
.rs-reset { color: var(--rs-accent); }

/* ---------- track row: ‹ [track] › */
.rs-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}
.rs-step {
  flex: none;
  padding: 0;
  font-size: 1.125rem;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
}
.rs-trackwrap { flex: 1 1 auto; min-width: 0; }
.rs-track {
  position: relative;
  height: var(--rs-track-h);
  touch-action: none;           /* the page must not scroll or zoom while a finger drags the slider */
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
}
.rs-track[data-disabled] { cursor: default; opacity: 0.55; }
.rs-rail,
.rs-fill {
  position: absolute;
  top: 50%;
  height: var(--rs-rail);
  margin-top: calc(var(--rs-rail) / -2);
  border-radius: calc(var(--rs-rail) / 2);
  pointer-events: none;
}
.rs-rail { left: 0; right: 0; background: var(--rs-subtle); box-shadow: inset 0 0 0 1px var(--rs-border); }
.rs-fill { background: var(--rs-accent); }

/* The shaded middle: grab it to pan the window at constant width. */
.rs-window {
  position: absolute;
  top: 2px;
  bottom: 2px;
  border-radius: 4px;
  background: var(--rs-accent-soft);
  cursor: grab;
}
.rs-window:active { cursor: grabbing; }
.rs-window:focus-visible { outline: 2px solid var(--rs-focus); outline-offset: 1px; }

.rs-thumb {
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--rs-thumb-hit);
  margin-left: calc(var(--rs-thumb-hit) / -2);
  display: grid;
  place-items: center;
  cursor: ew-resize;
  outline: none;
  z-index: 2;
}
.rs-knob {
  width: 12px;
  height: 24px;
  border: 2px solid var(--rs-accent);
  border-radius: 4px;
  background: var(--rs-elevated);
  box-shadow: var(--rs-shadow);
  transition: transform var(--rs-motion) var(--rs-ease);
  pointer-events: none;
}
.rs[data-mode="asof"] .rs-knob { width: 18px; height: 18px; border-radius: 50%; }
.rs-thumb:hover .rs-knob { transform: scale(1.12); }
.rs-thumb:active .rs-knob { transform: scale(1.04); }
.rs-thumb:focus-visible .rs-knob { box-shadow: 0 0 0 3px var(--rs-surface), 0 0 0 5px var(--rs-focus); }
.rs-thumb[aria-disabled="true"] { cursor: default; }

/* ---------- ticks under the track (anchored to calendar dates / round numbers) */
.rs-ticks {
  position: relative;
  height: 16px;
  color: var(--rs-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.rs-tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
}
.rs-tick[data-edge="start"] { transform: none; }
.rs-tick[data-edge="end"] { transform: translateX(-100%); }

/* ---------- meta line: badge, span, step, play, speed, live (fixed widths: nothing jumps) */
.rs-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: var(--rs-control);
  color: var(--rs-muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}
.rs-span:empty,
.rs-steplabel:empty { display: none; }
.rs-badge {
  display: inline-block;
  min-width: 52px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center;
}
.rs-badge[data-live="true"] { color: var(--rs-ok); box-shadow: inset 0 0 0 1px var(--rs-ok); }
.rs-badge[data-live="false"] { color: var(--rs-warn); box-shadow: inset 0 0 0 1px var(--rs-warn); }
.rs-play { width: 84px; }
/* The first of Reset / Play / Live is pushed right; the rest follow it. */
.rs-reset,
.rs-play,
.rs-live { margin-left: auto; }
.rs-reset ~ .rs-play,
.rs-reset ~ .rs-live,
.rs-play ~ .rs-live { margin-left: 0; }
.rs-speed { padding: 0 8px; }

/* ---------- typed From / To boxes (commit on blur or Enter) */
.rs-inputs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}
.rs-field { display: grid; gap: 2px; flex: 1 1 120px; min-width: 0; }
.rs-field-label { color: var(--rs-muted); font-size: 0.75rem; }
.rs-dash { padding-bottom: 8px; color: var(--rs-muted); }
.rs-input {
  width: 100%;
  min-width: 0;
  min-height: var(--rs-control);
  padding: 0 8px;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  background: var(--rs-surface);
  color: var(--rs-text);
  font-variant-numeric: tabular-nums;
}
.rs-input::placeholder { color: var(--rs-muted); }
.rs-input[aria-invalid="true"] { border-color: var(--rs-error); }
/* The error line keeps its height when empty, so a message appearing or clearing never moves the page. */
.rs-error { flex-basis: 100%; min-height: 1.2em; line-height: 1.2; color: var(--rs-error); font-size: 0.75rem; }

/* ---------- unknown-value note */
.rs-note {
  margin: 0;
  color: var(--rs-muted);
  font-size: 0.75rem;
}
.rs-unknown { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.rs-unknown input { width: 16px; height: 16px; margin: 0; accent-color: var(--rs-accent); }
@media (pointer: coarse) {
  .rs-unknown { min-height: 44px; }
}

/* ---------- empty / single-value states */
.rs[data-state="empty"] .rs-readout,
.rs[data-state="single"] .rs-readout { color: var(--rs-muted); }

/* ---------- reduced motion: mandatory (UI_STANDARDS section 5; ui-transitions law 4) */
@media (prefers-reduced-motion: reduce) {
  .rs,
  .rs *,
  .rs *::before,
  .rs *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
  }
}
