/*
 * The Slip Builder's controls (SlipControls.js): toggle, stepper, range
 * slider, odometer, count badge, collapse, accordion and sheet. The screen
 * that composes them is slip-builder.css.
 *
 * Colours are the app's semantic tokens (tokens.css), and the motion scale is
 * declared once here on the screen root so both sheets read the same values:
 *
 *   --sd-fade      fills, recolours, cross-fades
 *   --sd-chevron   the accordion and drawer chevrons
 *   --sd-check     the checkmark's stroke draw
 *   --sd-odo       one odometer roll
 *   --sd-roll      a stepper value sliding 8pt
 *   --sd-pop       badge and dot pops
 *   --sd-pulse     the counter badge's scale pulse
 *   --sd-spring    anything that travels — heights, cards, chips
 *
 * Reduced motion cuts every one of these to a short opacity change at the
 * bottom of this file: no odometer, no pulses, no travel.
 *
 * Declared on every host that draws these controls, not only on the slip:
 * the results screen Build Slip opens (its odometers, risk badge and toasts),
 * the five tool pages (the Lineup Builder, the Odds Converter, and the three
 * slip tools, whose sheets, toasts and shared code fields all read it), the
 * account page (its toasts) and the fixture page's Preview and Facts tabs
 * (the poll pills), so one value here moves all of them the same way.
 */

.slip,
.slip-results,
.lineup-builder,
.odds-converter,
.slip-merger,
.slip-splitter,
.code-converter,
.account,
.fixture-preview,
.fixture-facts,
.fixture-props,
.fixture-predictions,
.bet-builder {
  --sd-fade: 180ms;
  --sd-chevron: 200ms;
  --sd-check: 220ms;
  --sd-odo: 350ms;
  --sd-roll: 150ms;
  --sd-pop: 250ms;
  --sd-pulse: 250ms;
  --sd-spring: var(--spring-duration);
  --sd-thumb: 250ms;
  --se-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  /* The app's spring, and the press scale this screen's spec asks for. */
  --se-spring: var(--spring);
  --press-scale: 0.98;
}

/* --- Toggle ---------------------------------------------------------------- */

.slip-toggle {
  position: relative;
  flex: none;
  width: calc(46px * var(--slip-scale));
  height: calc(28px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--text-disabled);
  transition:
    background-color var(--sd-fade) var(--se-out),
    transform var(--spring-duration) var(--spring);
}

.slip-toggle[aria-checked="true"] {
  background: var(--accent);
}

/* Only the thumb travels, so only the thumb springs. */
.slip-toggle__thumb {
  position: absolute;
  top: calc(3px * var(--slip-scale));
  left: calc(3px * var(--slip-scale));
  width: calc(22px * var(--slip-scale));
  height: calc(22px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--surface);
  box-shadow: 0 1px calc(3px * var(--slip-scale)) rgb(var(--text-rgb) / 0.18);
  transition: transform var(--sd-fade) var(--se-spring);
}

.slip-toggle[aria-checked="true"] .slip-toggle__thumb {
  transform: translateX(calc(18px * var(--slip-scale)));
}

/* --- Stepper --------------------------------------------------------------- */

.slip-stepper {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--space-2) * var(--slip-scale));
}

/* 32pt visual (scaled), 44pt hit whatever the scale: the pseudo-element pads
   the target out to 44 without growing the circle the eye sees. */
.slip-stepper__btn {
  position: relative;
  display: grid;
  place-items: center;
  width: calc(32px * var(--slip-scale));
  height: calc(32px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  transition:
    background-color var(--sd-fade) var(--se-out),
    color var(--sd-fade) var(--se-out),
    transform var(--spring-duration) var(--spring);
}

.slip-stepper__btn::before {
  content: "";
  position: absolute;
  inset: calc((32px * var(--slip-scale) - 44px) / 2);
}

.slip-stepper__btn[data-pressed="true"] {
  box-shadow: inset 0 0 0 999px rgb(var(--text-rgb) / 0.06);
}

.slip-stepper__btn:disabled {
  color: var(--text-disabled);
  cursor: default;
}

.slip-stepper__value {
  position: relative;
  display: grid;
  width: calc(24px * var(--slip-scale));
  text-align: center;
  color: var(--text);
  font-size: calc(var(--text-base) * var(--slip-scale));
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Old and new share one cell; each slides 8pt the way the number moved. */
.slip-stepper__digit {
  grid-area: 1 / 1;
  transition:
    transform var(--sd-roll) var(--se-out),
    opacity var(--sd-roll) var(--se-out);
}

.slip-stepper__digit[data-enter="up"] {
  transform: translateY(calc(8px * var(--slip-scale)));
  opacity: 0;
}

.slip-stepper__digit[data-enter="down"] {
  transform: translateY(calc(-8px * var(--slip-scale)));
  opacity: 0;
}

.slip-stepper__digit[data-leave="up"] {
  transform: translateY(calc(-8px * var(--slip-scale)));
  opacity: 0;
}

.slip-stepper__digit[data-leave="down"] {
  transform: translateY(calc(8px * var(--slip-scale)));
  opacity: 0;
}

/* --- Range slider ---------------------------------------------------------- */

.slip-range {
  position: relative;
  /* Room for the 22pt thumbs either side of the 6pt rail. */
  padding: calc(12px * var(--slip-scale)) calc(11px * var(--slip-scale));
}

.slip-range__rail {
  position: relative;
  height: calc(6px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  /* Vertical pans stay the page's; horizontal ones are ours. */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/*
 * A full-width gradient, clipped to the span — so the colours are sampled
 * across the whole domain and a low span shows the low end of the gradient.
 * `--fill` is set by the caller per slider.
 */
.slip-range__fill {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
  background: var(--fill, var(--accent));
  transition: clip-path var(--sd-thumb) var(--se-out);
}

/* 44pt hit area at any scale; the 22pt (scaled) circle the eye sees is the
   pseudo-element, centred in it. */
.slip-range__thumb {
  position: absolute;
  top: 50%;
  width: 44px;
  height: 44px;
  margin: 0;
  border-radius: var(--radius-full);
  transform: translate(-50%, -50%);
  touch-action: none;
  cursor: grab;
  transition: left var(--sd-thumb) var(--se-out);
}

.slip-range__thumb::before {
  content: "";
  position: absolute;
  inset: calc((44px - 22px * var(--slip-scale)) / 2);
  border-radius: var(--radius-full);
  background: var(--surface);
  border: 2px solid var(--ring, var(--accent));
  box-shadow: 0 1px calc(4px * var(--slip-scale)) rgb(var(--text-rgb) / 0.14);
  transition:
    transform var(--sd-fade) var(--se-out),
    border-color var(--sd-fade) var(--se-out);
}

.slip-range__thumb:focus-visible {
  outline: none;
}

.slip-range__thumb:focus-visible::before {
  box-shadow: 0 1px calc(4px * var(--slip-scale)) rgb(var(--text-rgb) / 0.14),
    0 0 0 calc(3px * var(--slip-scale)) rgb(var(--accent-rgb) / 0.25);
}

/* Under a finger nothing eases — the thumb is being held, not animated. */
.slip-range[data-dragging] .slip-range__thumb,
.slip-range[data-dragging] .slip-range__fill {
  transition: none;
}

.slip-range[data-dragging="0"] .slip-range__thumb[data-index="0"],
.slip-range[data-dragging="1"] .slip-range__thumb[data-index="1"] {
  cursor: grabbing;
  z-index: 1;
}

.slip-range[data-dragging="0"] .slip-range__thumb[data-index="0"]::before,
.slip-range[data-dragging="1"] .slip-range__thumb[data-index="1"]::before {
  transform: scale(1.15);
}

/* The value, riding just above the active thumb's circle. */
.slip-range__tip {
  position: absolute;
  bottom: calc(50% + 11px * var(--slip-scale) + 6px);
  left: 50%;
  padding: calc(3px * var(--slip-scale)) calc(7px * var(--slip-scale));
  border-radius: calc(var(--radius-sm) * var(--slip-scale));
  background: rgb(var(--text-rgb) / 0.9);
  color: var(--text-inverse);
  font-size: calc(var(--text-xs) * var(--slip-scale));
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  white-space: nowrap;
  transform: translate(-50%, calc(4px * var(--slip-scale)));
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--sd-fade) var(--se-out),
    transform var(--sd-fade) var(--se-out);
}

.slip-range[data-dragging="0"] .slip-range__thumb[data-index="0"] .slip-range__tip,
.slip-range[data-dragging="1"] .slip-range__thumb[data-index="1"] .slip-range__tip {
  opacity: 1;
  transform: translate(-50%, 0);
}

.slip-range__ticks {
  position: relative;
  height: calc(14px * var(--slip-scale));
  margin-top: calc(6px * var(--slip-scale));
}

.slip-range__tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  color: var(--text-disabled);
  font-size: calc(var(--text-2xs) * var(--slip-scale));
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* --- Odometer -------------------------------------------------------------- */

.slip-odo {
  display: inline-flex;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Each column shows one em of a ten-digit strip; `--d` picks which. */
.slip-odo__digit {
  position: relative;
  height: 1em;
  overflow: hidden;
  transition: opacity var(--sd-fade) var(--se-out);
}

.slip-odo__digit[data-state="enter"] {
  opacity: 0;
}

.slip-odo__strip {
  display: flex;
  flex-direction: column;
  transform: translateY(calc(var(--d, 0) * -1em));
  transition: transform var(--sd-odo) var(--se-out);
}

.slip-odo__strip[data-snap] {
  transition: none;
}

.slip-odo__n {
  display: block;
  height: 1em;
  line-height: 1;
}

/* --- Count badge ----------------------------------------------------------- */

.slip-count {
  display: inline-flex;
  align-items: center;
  gap: calc(6px * var(--slip-scale));
  height: calc(26px * var(--slip-scale));
  padding: 0 calc(10px * var(--slip-scale)) 0 calc(5px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--accent);
  color: var(--text-inverse);
  font-size: calc(var(--text-xs) * var(--slip-scale));
  font-weight: var(--weight-bold);
}

.slip-count__num {
  display: grid;
  place-items: center;
  width: calc(16px * var(--slip-scale));
  height: calc(16px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--accent);
  font-size: calc(var(--text-2xs) * var(--slip-scale));
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.slip-count__num[data-anim="bounce"] {
  animation: slip-bounce 200ms var(--se-spring);
}

@keyframes slip-bounce {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

/* --- Collapse -------------------------------------------------------------- */

/* 0fr -> 1fr: an animated height without measuring one. */
.slip-collapse {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--sd-spring) var(--se-out);
}

.slip-collapse[data-shown="true"] {
  grid-template-rows: 1fr;
}

/* Contents fade in 120ms after a 60ms beat, so the box has started to open
   before anything appears inside it. */
.slip-collapse__inner {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 120ms var(--se-out);
}

/* Child combinators throughout: collapses nest (an accordion inside a sport's
   mount slot), and a descendant selector would light a closed panel's inner
   from the open slot around it. */
.slip-collapse[data-shown="true"] > .slip-collapse__inner {
  opacity: 1;
  transition-delay: 60ms;
}

/* --- Rail ------------------------------------------------------------------ */

/*
 * A row of pills that scrolls sideways, bleeding to the screen edge the way
 * the league bubbles do on the home tab: SureTOOLS' categories, the Lineup
 * Builder's formations. The pills are the "When" pills; five or seven of
 * them do not fit a 390pt frame on one line, and a wrapped second row reads
 * as two groups rather than one rail. Callers add `u-scroll-x` and
 * `data-lenis-prevent-wheel` (base.css, TabBar.js) so a trackpad can scroll
 * it and a finger can still scroll the page from it.
 */
.slip-rail {
  margin-inline: calc(var(--space-5) * var(--slip-scale) * -1);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.slip-rail::-webkit-scrollbar {
  display: none;
}

.slip-rail__track {
  display: flex;
  gap: calc(var(--space-3) * var(--slip-scale));
  width: max-content;
  padding-inline: calc(var(--space-5) * var(--slip-scale));
}

.slip-rail .slip-when {
  flex: none;
}

/* --- Accordion ------------------------------------------------------------- */

.slip-acc-list {
  display: flex;
  flex-direction: column;
}

/* A sport's accordion mounts and unmounts with its pill; the gap travels
   with it so the list closes up rather than leaving a hole. */
.slip-acc-slot[data-shown="true"] > .slip-collapse__inner {
  padding-bottom: calc(var(--space-3) * var(--slip-scale));
}

.slip-acc-slot > .slip-collapse__inner {
  transition:
    opacity 120ms var(--se-out),
    padding-bottom var(--sd-spring) var(--se-out);
}

.slip-acc__head {
  display: flex;
  align-items: center;
  gap: calc(var(--space-2) * var(--slip-scale));
  width: 100%;
  height: calc(48px * var(--slip-scale));
  padding: 0 calc(14px * var(--slip-scale)) 0 calc(16px * var(--slip-scale));
  border-radius: calc(14px * var(--slip-scale));
  background: var(--surface-sunken);
  color: var(--text);
  text-align: left;
  transition: transform var(--spring-duration) var(--spring);
}

.slip-acc__head[data-pressed="true"] {
  box-shadow: inset 0 0 0 999px rgb(var(--text-rgb) / 0.04);
}

.slip-acc__title {
  flex: 1;
  min-width: 0;
  font-size: calc(var(--text-md) * var(--slip-scale));
  font-weight: var(--weight-bold);
}

/* The collapsed header's mini-count — "Basketball · 2". */
.slip-acc__meta {
  color: var(--text-muted);
  font-size: calc(var(--text-sm) * var(--slip-scale));
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.slip-acc__chevron {
  display: grid;
  place-items: center;
  width: calc(20px * var(--slip-scale));
  height: calc(20px * var(--slip-scale));
  color: var(--text-muted);
  transition: transform var(--sd-chevron) var(--se-out);
}

/* Down when closed, up when open. */
.slip-acc[data-open="true"] .slip-acc__chevron {
  transform: rotate(180deg);
}

.slip-acc__panel[data-shown="true"] > .slip-collapse__inner {
  padding-top: calc(var(--space-3) * var(--slip-scale));
}

/* --- Sheet ----------------------------------------------------------------- */

.slip-sheet {
  position: fixed;
  inset: 0;
  /* Above the fixture/club/league/player stack (80–98); the same band the
     filter sheet occupies, which this can never be open alongside. */
  z-index: 96;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  max-width: var(--app-max-width);
  margin-inline: auto;
}

.slip-sheet[hidden] {
  display: none;
}

/* Scrim at 40% ink, fading on the shared beat. */
.slip-sheet__scrim {
  position: absolute;
  inset: 0;
  background: var(--text);
  opacity: 0;
  transition: opacity var(--sd-fade) var(--se-out);
  transition-delay: var(--stagger-step);
}

.slip-sheet[data-open="true"] .slip-sheet__scrim {
  opacity: 0.4;
  transition-delay: 0ms;
}

.slip-sheet__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  max-height: min(80dvh, calc(640px * var(--slip-scale)));
  padding-bottom: calc(calc(var(--space-4) * var(--slip-scale)) + var(--safe-bottom));
  background: var(--surface);
  border-radius: calc(24px * var(--slip-scale)) calc(24px * var(--slip-scale)) 0 0;
  box-shadow: var(--shadow-floating);
  transform: translateY(100%);
  transition: transform var(--sd-fade) var(--se-out);
}

/* An object arriving springs; on the way out it just leaves. */
.slip-sheet[data-open="true"] .slip-sheet__panel {
  transform: translateY(0);
  transition: transform var(--spring-duration) var(--spring) var(--stagger-step);
}

.slip-sheet__grabber {
  display: grid;
  place-items: center;
  padding: calc(var(--space-2) * var(--slip-scale)) 0 calc(var(--space-1) * var(--slip-scale));
}

.slip-sheet__bar {
  width: calc(36px * var(--slip-scale));
  height: calc(4px * var(--slip-scale));
  border-radius: var(--radius-full);
  background: var(--border);
}

.slip-sheet__title {
  padding: calc(var(--space-1) * var(--slip-scale)) calc(var(--space-5) * var(--slip-scale)) calc(var(--space-3) * var(--slip-scale));
  color: var(--text);
  font-size: calc(var(--text-lg) * var(--slip-scale));
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
}

.slip-sheet__body {
  flex: 1 1 auto;
  min-height: 0;
  padding: 0 calc(var(--space-5) * var(--slip-scale));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.slip-sheet__copy {
  padding-bottom: calc(var(--space-4) * var(--slip-scale));
  color: var(--text-secondary);
  font-size: calc(var(--text-md) * var(--slip-scale));
  font-weight: var(--weight-medium);
  line-height: 1.5;
}
