/* Spindle components. Load after tokens.css; behaviours live in bundle.js (window.Spindle).
   One prefix (sp-), BEM-style modifiers (sp-btn--primary), state classes (is-*) and data-state attributes. */

@property --sp-ring-a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }

:root {
  /* Motion tokens (mirrored in Spindle.tokens for JS) */
  --dur-tap: 120ms;      /* presses, small state changes */
  --dur-quick: 240ms;    /* hovers, toggles, reduced-motion fades */
  --dur-settle: 320ms;   /* things settling into place: shake, shove, magnetic return */
  --dur-spring: 420ms;   /* springy pops: chips, segments, thumbs */
  --dur-reveal: 600ms;   /* slides and reveals: a record leaving its sleeve */
  --dur-flip: 700ms;     /* RecordFlip */
  --dur-moment: 1000ms;  /* burst ring, a result moment */
  --dur-spin: 1800ms;    /* one turn at 33 1/3 rpm */
  --dur-coast: 3000ms;   /* a result record spins, then coasts to rest */
  --dur-toast: 3200ms;
  --ease-snap: cubic-bezier(.2, .7, .2, 1);
  --ease-burst: cubic-bezier(.16, .84, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-fall: cubic-bezier(.5, 0, .75, 0);
  /* Focus, layers, scrims and touch */
  --focus-width: 2px;
  --focus-offset: 2px;
  --scrim: rgb(20 20 24 / .38);
  --opacity-dimmed: .45;
  --z-toast: 1000;
  --tap-min: 44px;
  /* Active burst ring palette (Aurora by default) */
  --sp-ring-1: var(--ring-aurora-1);
  --sp-ring-2: var(--ring-aurora-2);
  --sp-ring-3: var(--ring-aurora-3);
}
.sp-ring--aurora { --sp-ring-1: var(--ring-aurora-1); --sp-ring-2: var(--ring-aurora-2); --sp-ring-3: var(--ring-aurora-3); }
.sp-ring--foil   { --sp-ring-1: var(--ring-foil-1);   --sp-ring-2: var(--ring-foil-2);   --sp-ring-3: var(--ring-foil-3); }
.sp-ring--sage   { --sp-ring-1: var(--ring-sage-1);   --sp-ring-2: var(--ring-sage-2);   --sp-ring-3: var(--ring-sage-3); }
.sp-ring--arcane { --sp-ring-1: var(--ring-arcane-1); --sp-ring-2: var(--ring-arcane-2); --sp-ring-3: var(--ring-arcane-3); }
.sp-ring--silver { --sp-ring-1: var(--ring-silver-1); --sp-ring-2: var(--ring-silver-2); --sp-ring-3: var(--ring-silver-3); }

/* ---------- Shared ---------- */
/* Visually hidden, still read by screen readers */
.sp-sr { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
/* Focus: a violet ring with a paper gap, so it reads on paper, petrol and the foil alike */
:where(.sp-btn, .sp-chip, .sp-tab, .sp-seg button, .sp-input, .sp-holo-motion, .sp3d, .sp-stage-focus):focus-visible {
  outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); box-shadow: 0 0 0 var(--focus-offset) var(--paper);
}

/* ---------- Button ---------- */
.sp-btn {
  box-sizing: border-box; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font: 600 15px/20px var(--font-text); padding: 12px 22px; min-height: var(--tap-min); border-radius: var(--radius-md);
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  transition: border-color var(--dur-quick) var(--ease-snap);
}
/* primary: champagne gold with a lit top edge; a band of light crosses it on hover. The ink label carries the contrast
   (9:1 on the gold); the darker edge outlines the fill on white. */
.sp-btn--primary {
  background: linear-gradient(180deg, color-mix(in oklab, var(--gold) 62%, #fff) 0%, var(--gold) 52%, color-mix(in oklab, var(--gold) 90%, #000) 100%);
  color: var(--on-gold); border-color: color-mix(in oklab, var(--gold) 62%, #000);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .6); isolation: isolate;
}
.sp-btn--primary::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgb(255 255 255 / .75) 50%, transparent 58%) no-repeat;
  background-size: 260% 100%; background-position: 140% 0;
}
@media (hover: hover) { .sp-btn--primary:hover::before { animation: sp-sweep 900ms var(--ease-snap); } }
@keyframes sp-sweep { from { background-position: 140% 0, 0 0; } to { background-position: -40% 0, 0 0; } }
@media (forced-colors: active) { .sp-btn--primary { background: ButtonFace; color: ButtonText; border-color: ButtonText; } }
.sp-btn--secondary { background: var(--paper); color: var(--ink); border-color: var(--line-strong); }
.sp-btn--secondary:hover { border-color: var(--ink); }
.sp-btn--danger { background: var(--danger); color: var(--on-danger); }
.sp-btn:disabled { background: var(--band); color: var(--ink-muted); border-color: transparent; cursor: not-allowed; }

/* ---------- PressSquash (uses the scale property, so it combines with MagneticHover's translate) ---------- */
.sp-squash:active:not(:disabled) { scale: 1.04 .9; }
.sp-squash.is-release { animation: sp-unsquash 380ms var(--ease-spring); }
@keyframes sp-unsquash { 0% { scale: 1.04 .9; } 50% { scale: .98 1.04; } 100% { scale: 1 1; } }

/* ---------- MagneticHover ---------- */
.sp-magnetic { transition: translate var(--dur-settle) var(--ease-spring); }
.sp-magnetic > span { display: inline-block; transition: translate var(--dur-settle) var(--ease-spring); }

/* ---------- BurstRing (pattern) ---------- */
.sp-burst { --sp-radius: var(--radius-md); }
.sp-burst--round { --sp-radius: 999px; }
.sp-burst::after {
  content: ""; position: absolute; inset: -3px; border-radius: calc(var(--sp-radius) + 3px);
  border: 3px solid transparent; pointer-events: none; opacity: 0;
  background: repeating-conic-gradient(from var(--sp-ring-a), var(--sp-ring-1) 0deg, var(--sp-ring-2) 60deg, var(--sp-ring-3) 120deg, var(--sp-ring-1) 180deg) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
}
.sp-burst.is-burst::after { animation: sp-burst var(--dur-moment) var(--ease-burst) forwards; }
@keyframes sp-burst {
  0%   { --sp-ring-a: 0deg;   opacity: 1; inset: -3px;  border-radius: calc(var(--sp-radius) + 3px); }
  100% { --sp-ring-a: 200deg; opacity: 0; inset: -20px; border-radius: calc(var(--sp-radius) + 20px); }
}

/* ---------- LevelUpShimmer ---------- */
.sp-levelup { position: relative; overflow: hidden; isolation: isolate; }
.sp-levelup::after {
  content: ""; position: absolute; inset: -20% -60%; z-index: -1; pointer-events: none; opacity: 0;
  background: linear-gradient(105deg, transparent 35%, #d4c8fe 42%, #b3d4ff 47%, #a2e1ec 51%, #a6e4c8 55%, transparent 62%);
  transform: translateX(-60%);
}
.sp-levelup.is-levelup { animation: sp-pop var(--dur-spring) var(--ease-spring); }
.sp-levelup.is-levelup::after { animation: sp-shimmer 900ms var(--ease-snap) forwards; }
@keyframes sp-shimmer { 0% { opacity: 1; transform: translateX(-60%); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateX(60%); } }
@keyframes sp-pop { 0% { transform: scale(1); } 40% { transform: scale(1.03); } 100% { transform: scale(1); } }

/* ---------- ScoreTick ---------- */
.sp-odo { display: inline-flex; font-variant-numeric: tabular-nums; line-height: 1; }
.sp-odo-chars { display: inline-flex; }
.sp-odo-digit { display: inline-block; height: 1em; overflow: hidden; transition: width 700ms var(--ease-burst); }
.sp-odo-col { display: block; transition: transform 700ms var(--ease-burst); }
/* digits centre in their column: a display face without tabular figures leaves a narrow 1 off to one side */
.sp-odo-col b { display: block; height: 1em; font-weight: inherit; text-align: center; }
.sp-odo-char { display: inline-block; }
.sp-delta { display: inline-block; font: 600 14px/1 var(--font-text); color: var(--violet); opacity: 0; }
.sp-delta.is-on { animation: sp-delta 900ms var(--ease-snap) forwards; }
@keyframes sp-delta { 0% { opacity: 0; transform: translateY(6px); } 20% { opacity: 1; transform: none; } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-10px); } }

/* ---------- SparkBurst ---------- */
:where(.sp-spark-host) { position: relative; }
.sp-spark { position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px; border-radius: 2px; pointer-events: none; }

/* ---------- ErrorShake (forms) ---------- */
.sp-field { display: grid; gap: var(--space-1); }
.sp-field-row { display: flex; gap: var(--space-2); }
.sp-input {
  font: 400 15px/20px var(--font-text); padding: 11px 14px; min-height: var(--tap-min); border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong); background: var(--paper-raised); color: var(--ink); min-width: 0;
}
.sp-field.is-invalid .sp-input { border-color: var(--danger); background: var(--danger-soft); }
.sp-field-msg { margin: 0; font: 400 13px/18px var(--font-text); color: var(--danger); min-height: 18px; }
.sp-shake { animation: sp-shake var(--dur-settle) var(--ease-snap); }
@keyframes sp-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-6px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(2px); } }

/* ---------- ProgressSegments ---------- */
.sp-progress { position: relative; border-radius: var(--radius-sm); --sp-radius: var(--radius-sm); }
.sp-progress-segs { display: grid; grid-template-columns: repeat(var(--sp-segs, 10), 1fr); gap: var(--space-1); }
.sp-progress-seg { height: 14px; border-radius: 4px; background: var(--paper-raised); border: 1px dashed var(--line-strong); position: relative; overflow: hidden; }
.sp-progress-seg.is-full { border: 1px solid transparent; background: linear-gradient(90deg, var(--petrol), var(--progress-1)); }
.sp-progress-seg.is-mid.is-full { background: linear-gradient(90deg, var(--progress-2), var(--progress-3)); }
.sp-progress-seg.is-high.is-full { background: linear-gradient(90deg, var(--progress-3), var(--violet)); }
.sp-progress-seg.is-pop { animation: sp-segpop var(--dur-spring) var(--ease-spring); }
.sp-progress-seg.is-pop::after { content: ""; position: absolute; inset: 0; background: #fff; animation: sp-segflash var(--dur-spring) ease-out forwards; }
@keyframes sp-segpop { 0% { transform: scaleY(1); } 40% { transform: scaleY(1.5); } 100% { transform: scaleY(1); } }
@keyframes sp-segflash { 0% { opacity: .95; } 100% { opacity: 0; } }
.sp-level { display: inline-block; transform-origin: left center; }
.sp-level.is-up { animation: sp-lvlpop 500ms var(--ease-spring); }
@keyframes sp-lvlpop { 0% { transform: scale(1); } 40% { transform: scale(1.25); color: var(--violet); } 100% { transform: scale(1); } }

/* ---------- 3D stages (vinyl, record flip, turntable, sleeve, crate) ---------- */
.sp3d { position: relative; }
.sp3d-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.sp3d:focus-visible { border-radius: var(--radius-md); }

/* ---------- The CSS record: loaders, rows, covers, toasts, and the 3D fallback ---------- */
@keyframes sp-spin { to { transform: rotate(360deg); } }
.sp-vinyl { position: relative; display: inline-block; width: var(--sp-size, 160px); aspect-ratio: 1; border-radius: 50%; flex: none; }
.sp-vinyl-disc, .sp-vinyl-sheen { position: absolute; inset: 0; border-radius: 50%; }
.sp-vinyl-disc {
  --base: #141517; --grooves: repeating-radial-gradient(circle, rgba(255,255,255,.035) 0 1px, rgba(0,0,0,0) 1px 3px); --art: var(--petrol);
  background: radial-gradient(circle, transparent 0 33%, rgba(255,255,255,.08) 33.5%, transparent 34.5%), var(--grooves), var(--base);
}
.sp-vinyl-disc::after { content: ""; position: absolute; inset: 33%; border-radius: 50%; background: var(--art) center / cover; }
.sp-vinyl-disc::before { content: ""; position: absolute; left: 50%; top: 50%; width: 4.8%; height: 4.8%; margin: -2.4%; border-radius: 50%; background: var(--paper); z-index: 1; box-shadow: inset 0 0 0 1px rgba(0,0,0,.25); }
.sp-vinyl-sheen {
  pointer-events: none; mix-blend-mode: screen;
  background: conic-gradient(from 35deg, transparent 0 6%, rgba(255,255,255,.22) 11%, transparent 18% 50%, rgba(255,255,255,.16) 58%, transparent 66%);
  -webkit-mask: radial-gradient(circle, transparent 0 33%, #000 34% 99%, transparent 100%); mask: radial-gradient(circle, transparent 0 33%, #000 34% 99%, transparent 100%);
}
.sp-vinyl--color .sp-vinyl-disc { --base: var(--vinyl-color); --grooves: repeating-radial-gradient(circle, rgba(255,255,255,.07) 0 1px, rgba(0,0,0,.06) 1px 3px); }
.sp-vinyl--splatter .sp-vinyl-disc { --base: #ebe6dc; --grooves: repeating-radial-gradient(circle, rgba(0,0,0,.05) 0 1px, rgba(0,0,0,0) 1px 3px), radial-gradient(circle at 30% 35%, var(--petrol) 0 7%, transparent 7.5%), radial-gradient(circle at 68% 62%, var(--gold) 0 5%, transparent 5.5%), radial-gradient(circle at 72% 28%, var(--petrol) 0 3%, transparent 3.5%), radial-gradient(circle at 28% 74%, var(--gold) 0 4%, transparent 4.5%), radial-gradient(circle at 55% 82%, var(--ink) 0 3%, transparent 3.5%), radial-gradient(circle at 80% 46%, var(--vinyl-color) 0 2.5%, transparent 3%); }
.sp-vinyl--marble .sp-vinyl-disc { --base: conic-gradient(from 20deg, #eef0f2, #dfe3e6 18%, var(--petrol) 21%, #eef0f2 26%, #dfe3e6 58%, var(--ink) 61%, #eef0f2 66%); --grooves: repeating-radial-gradient(circle, rgba(0,0,0,.045) 0 1px, rgba(0,0,0,0) 1px 3px); }
.sp-vinyl--clear .sp-vinyl-disc { --base: rgba(201,214,232,.55); }
.sp-vinyl--holo .sp-vinyl-disc { --base: conic-gradient(from 0deg, #cfc6f5, #b9d9f2, #c9efe0, #efe6c4, #f0cde6, #cfc6f5); --grooves: repeating-radial-gradient(circle, rgba(0,0,0,.06) 0 1px, rgba(255,255,255,.05) 1px 3px); }
.sp-vinyl--holo .sp-vinyl-sheen { background: conic-gradient(from 35deg, transparent 0 6%, rgba(255,255,255,.55) 11%, transparent 18% 50%, rgba(255,255,255,.45) 58%, transparent 66%); }
/* gold: a plated pressing in the champagne gold; the light stays put while it turns */
.sp-vinyl--gold .sp-vinyl-disc { --base: radial-gradient(circle, #e2c98a 0 40%, #c9a755 70%, #b28f3e 100%); --grooves: repeating-radial-gradient(circle, rgba(92,66,12,.16) 0 1px, rgba(255,246,214,.12) 1px 3px); }
.sp-vinyl--gold .sp-vinyl-sheen { mix-blend-mode: normal; background: conic-gradient(from 35deg, transparent 0 4%, rgba(255,251,234,.75) 11%, transparent 19% 48%, rgba(255,251,234,.6) 58%, transparent 67%), conic-gradient(from 125deg, transparent 0 8%, rgba(110,80,18,.28) 14%, transparent 20% 56%, rgba(110,80,18,.22) 64%, transparent 70%); }
/* smoke: smoked translucent vinyl, the page showing through a warm grey tint */
.sp-vinyl--smoke .sp-vinyl-disc { --base: radial-gradient(circle, rgba(46,40,38,.5) 0 60%, rgba(30,26,25,.7) 100%); --grooves: repeating-radial-gradient(circle, rgba(255,255,255,.07) 0 1px, rgba(0,0,0,.05) 1px 3px); }
.sp-vinyl--smoke .sp-vinyl-sheen { background: conic-gradient(from 35deg, transparent 0 6%, rgba(255,255,255,.34) 11%, transparent 18% 50%, rgba(255,255,255,.26) 58%, transparent 66%); }
/* a record that fills its box (VinylRecord without WebGL) */
.sp-vinyl--fill { display: block; width: 100%; }

/* ---------- CoverTile ---------- */
.sp-cover {
  --rx: 0deg; --ry: 0deg; --gx: 50%; --gy: 50%; --peek: 0%;
  position: relative; display: grid; gap: var(--space-2); width: var(--sp-cover-w, 100%); padding: 0; margin: 0;
  border: 0; background: none; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.sp-cover:focus-visible { outline: none; }
.sp-cover:focus-visible .sp-cover-stage { outline: var(--focus-width) solid var(--focus); outline-offset: 7px; }
.sp-cover-stage {
  --sp-radius: var(--radius-sm);
  position: relative; aspect-ratio: 1; border-radius: var(--radius-sm);
  transform: perspective(800px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform var(--dur-settle) var(--ease-spring), filter var(--dur-quick) var(--ease-snap), opacity var(--dur-quick) var(--ease-snap);
}
.sp-cover-vinyl, .sp-cover-ring { position: absolute; inset: 3%; transform: translateX(var(--peek)); transition: transform var(--dur-reveal) var(--ease-burst); }
.sp-cover-vinyl { --sp-size: 94%; }
.sp-cover-vinyl.sp-vinyl { width: auto; }
.sp-cover-ring { z-index: 2; border-radius: 50%; pointer-events: none; }
.sp-cover-art {
  position: absolute; inset: 0; z-index: 1; border-radius: var(--radius-sm); overflow: hidden; isolation: isolate;
  background: var(--band); box-shadow: inset 0 0 0 1px rgba(18, 22, 26, .08);
}
.sp-cover-art img, .sp-cover-art canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: -1; }
.sp-cover-art::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity var(--dur-quick) var(--ease-snap);
  background: radial-gradient(circle at var(--gx) var(--gy), rgba(255,255,255,.42), rgba(255,255,255,0) 55%); mix-blend-mode: soft-light;
}
.sp-cover-art::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit;
  background:
    linear-gradient(115deg, transparent 40%, rgb(255 255 255 / .42) 48%, rgb(255 255 255 / .1) 53%, transparent 60%) no-repeat,
    linear-gradient(180deg, rgb(255 255 255 / .16), transparent 34%);
  background-size: 260% 100%, 100% 100%; background-position: 140% 0, 0 0;
}
@media (hover: hover) and (pointer: fine) {
  .sp-cover:not([aria-disabled="true"]):hover .sp-cover-art::before { animation: sp-sweep 950ms var(--ease-snap); }
}
.sp-cover--rare .sp-cover-art::before { display: none; }
.sp-cover-sweep { position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit; }
.sp-cover-meta { display: grid; gap: 2px; min-width: 0; }
/* names wrap in full; set --sp-cover-lines (title) and --sp-cover-artist-lines to clamp them where space is tight */
.sp-cover-title, .sp-cover-artist { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: break-word; text-wrap: pretty; }
.sp-cover-title { font: 600 15px/20px var(--font-text); -webkit-line-clamp: var(--sp-cover-lines, none); line-clamp: var(--sp-cover-lines, none); }
.sp-cover-artist { font: 400 13px/18px var(--font-text); color: var(--ink-muted); -webkit-line-clamp: var(--sp-cover-artist-lines, none); line-clamp: var(--sp-cover-artist-lines, none); }
/* hover: the record peeks out and the cover catches the light */
@media (hover: hover) and (pointer: fine) {
  .sp-cover[data-state="idle"]:hover { --peek: 10%; }
  .sp-cover:not([aria-disabled="true"]):hover .sp-cover-art::after { opacity: 1; }
}
.sp-cover[data-state="idle"]:focus-visible { --peek: 10%; }
/* picked: waiting for the reveal; a petrol frame that leaves room for the focus ring */
.sp-cover[data-state="picked"] { --peek: 16%; }
.sp-cover[data-state="picked"] .sp-cover-stage::before { content: ""; position: absolute; inset: -4px; border: 2px solid var(--petrol); border-radius: calc(var(--radius-sm) + 4px); pointer-events: none; }
/* right: the record slides out and spins, a ring bursts from it, sparks fly off its rim */
.sp-cover[data-state="right"] { --peek: 24%; z-index: 2; }
/* wrong: the record backspins, is pushed home into its sleeve with a bump, then the cover greys */
.sp-cover[data-state="wrong"] { --peek: 0%; }
.sp-cover[data-state="wrong"] .sp-cover-vinyl, .sp-cover[data-state="wrong"] .sp-cover-ring { transition: transform 260ms var(--ease-snap) 380ms; }
.sp-cover[data-state="wrong"] .sp-cover-stage { filter: grayscale(.85); opacity: .6; transition: transform var(--dur-settle) var(--ease-spring), filter var(--dur-quick) var(--ease-snap) 640ms, opacity var(--dur-quick) var(--ease-snap) 640ms; animation: sp-shove var(--dur-settle) var(--ease-snap) 600ms; }
@keyframes sp-shove { 0% { translate: 0 0; } 30% { translate: 3px 0; } 100% { translate: 0 0; } }
/* revealed: the answer, after a miss */
.sp-cover[data-state="revealed"] { --peek: 20%; z-index: 1; }
/* dimmed: the other options step back */
.sp-cover[data-state="dimmed"] .sp-cover-stage { filter: grayscale(.5); opacity: var(--opacity-dimmed); }
.sp-cover[aria-disabled="true"] { cursor: default; }

/* ---------- RareHoloCover and HoloFoil ---------- */
/* .sp-holo: any card the HoloFoil engine runs on. Without WebGL (or in forced colours) it keeps this quiet silver. */
.sp-holo { touch-action: pan-y; background: linear-gradient(118deg, #dfe2e7 0%, #eceef1 38%, var(--foil-violet) 50%, var(--foil-ice) 58%, var(--foil-silver) 72%, #dcdfe4 100%); }
.sp-holo-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.sp-holo-motion {
  display: none; position: absolute; right: 12px; bottom: 12px; z-index: 2;
  font: 600 13px/16px var(--font-label); letter-spacing: .01em; padding: 10px 14px; min-height: var(--tap-min);
  border-radius: var(--radius-pill); border: 1px solid rgb(18 22 26 / .18); background: rgb(255 255 255 / .72); color: var(--ink); cursor: pointer;
}
@media (forced-colors: active) { .sp-holo-canvas { display: none; } .sp-holo { background: Canvas; border-color: CanvasText; } }
.sp-cover--rare .sp-cover-stage { background: none; transition: filter var(--dur-quick) var(--ease-snap), opacity var(--dur-quick) var(--ease-snap); }
.sp-cover-art .sp-holo-canvas { z-index: 0; }
.sp-holo-on .sp-cover-art > img, .sp-holo-on .sp-cover-art > canvas:not(.sp-holo-canvas) { opacity: 0; }
.sp-cover--rare .sp-cover-art::after { display: none; }
/* reverse holo: the foil frames the art like a reverse-holo trading card; the art and its title stay crisp */
.sp-cover--reverse .sp-cover-art > img, .sp-cover--reverse .sp-cover-art > canvas:not(.sp-holo-canvas) {
  opacity: 1; z-index: 1; inset: 7%; width: 86%; height: 86%; border-radius: 3px; box-shadow: 0 0 0 1px rgb(18 22 26 / .12);
}

/* ---------- CoverPlaceholder: loading and missing art ---------- */
.sp-cover-art[data-loading] { display: grid; place-items: center; }
.sp-cover-art[data-loading] img { opacity: 0; }
.sp-cover-loader { display: none; width: 100%; place-items: center; justify-items: center; }
.sp-cover-art[data-loading] .sp-cover-loader { display: grid; }
.sp-cover-loader .sp-vinyl { --sp-size: 30%; width: 30%; min-width: 36px; }
.sp-cover-art[data-loading] .sp-cover-loader .sp-vinyl-disc { animation: sp-spin var(--dur-spin) linear infinite; }
.sp-cover-art img { transition: opacity var(--dur-reveal) var(--ease-snap); }

/* ---------- CoverGrid ---------- */
/* the gap leaves room for a record sliding out; equal padding on both sides keeps the row centred */
.sp-cover-grid { --sp-cover-w: 180px; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-5); padding-inline: calc(var(--sp-cover-w) * .1); }
.sp-cover-grid > .sp-cover { width: var(--sp-cover-w); }
.sp-cover-grid--s { --sp-cover-w: 128px; }
.sp-cover-grid--l { --sp-cover-w: 240px; }
.sp-cover-grid--split { max-width: calc(var(--sp-cover-w) * 3.2 + var(--space-5) * 2); margin-inline: auto; }
@media (max-width: 520px) {
  .sp-cover-grid, .sp-cover-grid--s, .sp-cover-grid--l { --sp-cover-w: min(180px, calc(50vw - 52px)); gap: var(--space-4) 32px; }
}

/* ---------- SpinLoader ---------- */
.sp-loader { display: inline-flex; align-items: center; gap: var(--space-2); font: 600 13px/16px var(--font-label); color: var(--petrol); }
.sp-loader .sp-vinyl { --sp-size: 24px; }
.sp-loader--m .sp-vinyl { --sp-size: 40px; }
.sp-loader--l .sp-vinyl { --sp-size: 72px; }
.sp-loader--l { flex-direction: column; gap: var(--space-3); }
.sp-loader .sp-vinyl-disc { animation: sp-spin var(--dur-spin) linear infinite; }

/* ---------- RecordRow ---------- */
.sp-record-row { display: inline-flex; align-items: center; gap: var(--space-3); padding: 6px; }
.sp-slot { position: relative; --sp-size: 30px; --sp-radius: 999px; width: 30px; height: 30px; flex: none; display: grid; place-items: center; transition: transform var(--dur-settle) var(--ease-spring); }
.sp-slot::before { content: ""; position: absolute; inset: 1px; border-radius: 50%; border: 1.5px dashed var(--line-strong); transition: opacity var(--dur-quick) var(--ease-snap); }
.sp-slot .sp-vinyl { position: absolute; inset: 0; width: 30px; opacity: 0; transform: scale(.6) rotate(-40deg); transition: opacity var(--dur-quick) var(--ease-snap), transform var(--dur-spring) var(--ease-spring), filter var(--dur-quick) var(--ease-snap); }
.sp-slot[data-state="current"] { transform: scale(1.18); }
.sp-slot[data-state="current"]::before { border: 2px solid var(--petrol); inset: -4px; }
.sp-slot[data-state="current"] .sp-vinyl { opacity: 1; transform: none; }
.sp-slot[data-state="wrong"]::before { opacity: 0; }
/* a named song wears a gold rim */
.sp-slot[data-state="right"]::before { border: 2px solid var(--gold); inset: -3px; }
.sp-slot[data-state="right"] .sp-vinyl { opacity: 1; transform: none; }
.sp-slot[data-state="wrong"] .sp-vinyl { opacity: .45; transform: scale(.82); filter: grayscale(1); }
.sp-slot[data-state="wrong"] .sp-vinyl-disc::after { background: var(--band); }

/* ---------- Sticker: die-cut record-shop price stickers ---------- */
/* three layers: the outline (a hairline that follows any shape), the white die-cut paper, the printed face */
.sp-sticker {
  --sp-tilt: -3deg; --sp-face: var(--violet-soft); --sp-ink: var(--ink); --sp-clip: none; --sp-edge: 2.5px;
  display: inline-flex; vertical-align: middle; transform: rotate(var(--sp-tilt));
  filter: drop-shadow(0 0 .6px rgb(18 22 26 / .45));
}
.sp-sticker-paper { display: inline-flex; padding: var(--sp-edge); background: #fff; border-radius: var(--sp-r, 999px); clip-path: var(--sp-clip); }
.sp-sticker-face {
  position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap;
  font: 700 13px/14px var(--font-text); color: var(--sp-ink); background: var(--sp-face);
  padding: 6px 11px; border-radius: calc(var(--sp-r, 999px) - var(--sp-edge)); clip-path: var(--sp-clip);
}
/* paper grain */
.sp-sticker-face::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5; mix-blend-mode: multiply;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .16 0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* the corner curling up catches the light */
.sp-sticker-face::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at 100% 0, rgb(255 255 255 / .7), rgb(255 255 255 / 0) 34%); }
.sp-sticker-face > * { position: relative; z-index: 1; }
.sp-sticker svg { width: 14px; height: 14px; }
/* colours */
.sp-sticker--petrol { --sp-face: var(--petrol-soft); }
.sp-sticker--ink { --sp-face: var(--ink); --sp-ink: var(--paper); }
.sp-sticker--ink .sp-sticker-face::before { mix-blend-mode: screen; filter: invert(1); opacity: .35; }
.sp-sticker--ink .sp-sticker-face::after { background: radial-gradient(circle at 100% 0, rgb(255 255 255 / .28), rgb(255 255 255 / 0) 34%); }
.sp-sticker--foil { --sp-face: linear-gradient(110deg, #d4c8fe, #b3d4ff 30%, #a6e4c8 60%, #f5e3b0 85%); }
.sp-sticker--plain { --sp-face: var(--paper); }
/* medals: gold, silver and bronze foil for a score; light runs across the foil as it lands and on hover */
.sp-sticker--gold { --sp-face: linear-gradient(115deg, var(--medal-gold-2) 0%, var(--medal-gold-1) 18%, var(--medal-gold-2) 34%, var(--medal-gold-3) 50%, var(--medal-gold-2) 64%, var(--medal-gold-1) 82%, var(--medal-gold-2) 100%); }
.sp-sticker--silver { --sp-face: linear-gradient(115deg, var(--medal-silver-2) 0%, var(--medal-silver-1) 18%, var(--medal-silver-2) 34%, var(--medal-silver-3) 50%, var(--medal-silver-2) 64%, var(--medal-silver-1) 82%, var(--medal-silver-2) 100%); }
.sp-sticker--bronze { --sp-face: linear-gradient(115deg, var(--medal-bronze-2) 0%, var(--medal-bronze-1) 18%, var(--medal-bronze-2) 34%, var(--medal-bronze-3) 50%, var(--medal-bronze-2) 64%, var(--medal-bronze-1) 82%, var(--medal-bronze-2) 100%); }
:is(.sp-sticker--gold, .sp-sticker--silver, .sp-sticker--bronze, .sp-sticker--foil) .sp-sticker-face {
  color: var(--on-foil); font-weight: 800; background-size: 240% 100%; background-position: 0 0; transition: background-position 1100ms var(--ease-snap);
}
:is(.sp-sticker--gold, .sp-sticker--silver, .sp-sticker--bronze).sp-sticker--dot .sp-sticker-face { width: 54px; height: 54px; font-size: 14px; line-height: 15px; }
:is(.sp-sticker--gold, .sp-sticker--silver, .sp-sticker--bronze, .sp-sticker--foil):hover .sp-sticker-face,
:is(.sp-sticker--gold, .sp-sticker--silver, .sp-sticker--bronze, .sp-sticker--foil).is-new .sp-sticker-face { background-position: 100% 0; }
/* shapes */
.sp-sticker--dot .sp-sticker-face { width: 50px; height: 50px; padding: 0 6px; white-space: normal; text-align: center; font-size: 11px; line-height: 13px; }
.sp-sticker--oval { --sp-r: 50%; }
.sp-sticker--oval .sp-sticker-face { padding: 9px 18px; border-radius: 50%; }
.sp-sticker--burst { --sp-r: 0; --sp-edge: 3px; --sp-clip: polygon(50% 0%, 59% 13%, 75% 7%, 75% 23%, 93% 25%, 85% 39%, 100% 50%, 85% 61%, 93% 75%, 75% 77%, 75% 93%, 59% 87%, 50% 100%, 41% 87%, 25% 93%, 25% 77%, 7% 75%, 15% 61%, 0% 50%, 15% 39%, 7% 25%, 25% 23%, 25% 7%, 41% 13%); }
.sp-sticker--burst .sp-sticker-face { width: 64px; height: 64px; padding: 0 12px; white-space: normal; text-align: center; font-size: 11px; line-height: 12px; }
/* a price-gun strip: square-cut with zigzag ends */
.sp-sticker--strip { --sp-r: 0; --sp-edge: 2px; --sp-clip: polygon(0 0, 100% 0, 96% 20%, 100% 40%, 96% 60%, 100% 80%, 96% 100%, 0 100%, 4% 80%, 0 60%, 4% 40%, 0 20%); }
.sp-sticker--strip .sp-sticker-face { padding: 5px 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* slapped on: it lands too big, squashes for a frame, then settles */
.sp-sticker.is-new { animation: sp-stick 520ms var(--ease-snap); }
@keyframes sp-stick {
  0% { transform: rotate(calc(var(--sp-tilt) - 14deg)) scale(1.35); opacity: 0; }
  45% { transform: rotate(var(--sp-tilt)) scale(1); opacity: 1; }
  55% { transform: rotate(var(--sp-tilt)) scale(1.08, .9); }
  75% { transform: rotate(var(--sp-tilt)) scale(.98, 1.03); }
  100% { transform: rotate(var(--sp-tilt)) scale(1); }
}

/* ---------- Chip ---------- */
.sp-chip {
  display: inline-flex; align-items: center; gap: 6px; font: 600 14px/1 var(--font-text); color: var(--ink);
  padding: 10px 14px; border-radius: var(--radius-pill); border: 1px solid var(--line-strong); background: var(--paper-raised); cursor: pointer;
  transition: background var(--dur-quick) var(--ease-snap), color var(--dur-quick) var(--ease-snap), border-color var(--dur-quick) var(--ease-snap);
}
.sp-chip:hover { border-color: var(--ink); }
.sp-chip[aria-pressed="true"] { background: var(--petrol); border-color: var(--petrol); color: var(--on-petrol); }
.sp-chip[aria-pressed="true"].is-pop { animation: sp-chippop 360ms var(--ease-spring); }
@keyframes sp-chippop { 40% { transform: scale(1.08); } 100% { transform: scale(1); } }
.sp-chip .sp-vinyl { --sp-size: 16px; }

/* ---------- Tabs ---------- */
.sp-tabs { position: relative; display: flex; gap: var(--space-4); border-bottom: 1px solid var(--line); }
.sp-tab { font: 600 15px/20px var(--font-text); color: var(--ink-muted); background: none; border: 0; padding: 12px 2px; min-height: var(--tap-min); cursor: pointer; border-radius: 4px; }
.sp-tab[aria-selected="true"] { color: var(--ink); }
.sp-tabs-ink { position: absolute; bottom: -1px; left: 0; height: 3px; border-radius: 3px 3px 0 0; background: var(--petrol); transition: transform 380ms var(--ease-spring), width 380ms var(--ease-spring); }

/* ---------- SegmentedControl ---------- */
.sp-seg { position: relative; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; padding: 4px; border-radius: var(--radius-pill); background: var(--band); box-shadow: inset 0 0 0 1px var(--line); }
.sp-seg button { position: relative; z-index: 1; font: 600 14px/1 var(--font-text); color: var(--ink-muted); background: none; border: 0; padding: 10px 18px; border-radius: var(--radius-pill); cursor: pointer; transition: color var(--dur-quick) var(--ease-snap); }
.sp-seg button[aria-checked="true"] { color: var(--ink); }
/* the thumb carries a petrol hairline so the selection reads at 3:1 or better against the band */
.sp-seg-thumb { position: absolute; top: 4px; bottom: 4px; left: 0; border-radius: var(--radius-pill); background: var(--paper-raised); box-shadow: inset 0 0 0 1.5px var(--petrol); transition: transform var(--dur-spring) var(--ease-spring), width var(--dur-spring) var(--ease-spring); }
@media (pointer: coarse) { .sp-chip, .sp-seg button { min-height: var(--tap-min); } }

/* ---------- Dialog and sheet ---------- */
.sp-dialog { border: 0; padding: 0; background: transparent; max-width: min(480px, calc(100vw - 32px)); width: 100%; overflow: visible; }
.sp-dialog::backdrop { background: var(--scrim); }
.sp-dialog-panel { background: var(--paper-raised); border-radius: var(--radius-lg); border: 1px solid var(--line); padding: var(--space-5); display: grid; gap: var(--space-3); color: var(--ink); font-family: var(--font-text); }
.sp-dialog-panel h2 { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 30px; line-height: 1.1; letter-spacing: -.01em; color: var(--ink); text-wrap: balance; }
.sp-dialog-panel p { margin: 0; font-size: 17px; line-height: 26px; color: var(--ink); }
.sp-dialog-actions { display: flex; gap: var(--space-2); justify-content: flex-end; flex-wrap: wrap; margin-top: var(--space-2); }
.sp-dialog[open] .sp-dialog-panel { animation: sp-rise 480ms var(--ease-spring); }
.sp-dialog[open]::backdrop { animation: sp-fade var(--dur-quick) ease; }
.sp-dialog.is-closing .sp-dialog-panel { animation: sp-drop 200ms var(--ease-snap) forwards; }
@keyframes sp-rise { 0% { transform: translateY(24px) scale(.96); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes sp-drop { to { transform: translateY(12px) scale(.98); opacity: 0; } }
@keyframes sp-fade { from { opacity: 0; } }
@keyframes sp-fadeout { to { opacity: 0; } }
.sp-dialog--sheet { margin: auto auto 0; max-width: min(640px, 100vw); }
.sp-dialog--sheet .sp-dialog-panel { border-radius: var(--radius-lg) var(--radius-lg) 0 0; border-bottom: 0; padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); }
.sp-dialog--sheet[open] .sp-dialog-panel { animation: sp-slide 520ms var(--ease-spring); }
.sp-dialog--sheet.is-closing .sp-dialog-panel { animation: sp-slidedown var(--dur-quick) var(--ease-snap) forwards; }
@keyframes sp-slide { 0% { transform: translateY(100%); } 100% { transform: none; } }
@keyframes sp-slidedown { to { transform: translateY(100%); } }
.sp-dialog-grip { justify-self: center; width: 40px; height: 4px; border-radius: 4px; background: var(--line-strong); margin-top: -8px; }

/* ---------- Toast ---------- */
.sp-toasts { position: fixed; left: 0; right: 0; bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px)); display: grid; justify-items: center; gap: var(--space-2); pointer-events: none; z-index: var(--z-toast); padding: 0 16px; }
.sp-toast {
  pointer-events: auto; display: inline-flex; align-items: center; gap: var(--space-3); max-width: min(440px, 100%);
  background: var(--ink); color: var(--paper); border-radius: var(--radius-pill); padding: 10px 18px 10px 10px;
  font: 600 15px/20px var(--font-text); animation: sp-toastin 520ms var(--ease-spring);
}
.sp-toast .sp-vinyl { --sp-size: 28px; }
.sp-toast-icon { display: grid; place-items: center; width: 28px; height: 28px; }
.sp-toast.is-leaving { animation: sp-toastout var(--dur-quick) var(--ease-snap) forwards; }
@keyframes sp-toastin { 0% { transform: translateY(140%) rotate(-4deg); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes sp-toastout { to { transform: translateY(40%); opacity: 0; } }

/* ---------- StatTile ---------- */
.sp-stat { display: grid; gap: var(--space-2); align-content: start; padding: var(--space-4); border-radius: var(--radius-md); background: var(--paper-raised); border: 1px solid var(--line); min-width: 0; position: relative; }
.sp-stat-label { font: 600 13px/16px var(--font-label); letter-spacing: .01em; color: var(--petrol); }
.sp-stat-value { font: 400 44px/1 var(--font-display); letter-spacing: -.01em; color: var(--ink); font-variant-numeric: tabular-nums; }
.sp-stat-row { display: flex; align-items: baseline; gap: var(--space-2); }
.sp-stat-note { font: 400 13px/18px var(--font-text); color: var(--ink-muted); }
.sp-stat .sp-sticker { position: absolute; top: -12px; right: -10px; }

/* ---------- CSS turntable (Turntable without WebGL) ----------
   Geometry in fractions of the 5:4 plinth (x of its width, y of its width): the platter's centre at (.40, .40), radius .34;
   the record fills 90% of it; the arm pivots at (.88, .11) and is .50 long, so the stylus meets the outer groove at 27.7deg,
   the inner at 47.4deg and the locked groove at 48.9deg (Spindle's ARM angles in bundle.js). */
.sp-tt { position: relative; aspect-ratio: 5 / 4; container-type: inline-size; --sp-arm: 0deg; }
.sp-tt > span { position: absolute; display: block; }
.sp-tt-plinth { inset: 0; border-radius: var(--radius-md); background: var(--paper-raised); box-shadow: inset 0 0 0 1px var(--line); }
.sp-tt-platter { left: 6%; top: 7.5%; width: 68%; aspect-ratio: 1; border-radius: 50%; background: radial-gradient(circle, #aeb4bc 0 88%, #e6e9ed 92%, #c3c8cf 100%); }
.sp-tt-platter > span { position: absolute; border-radius: 50%; }
/* the strobe rows on the rim: 216 dots stand still at 33 1/3 rpm under 60 Hz light (a 60 Hz screen too), 180 under 50 Hz */
.sp-tt-strobe {
  inset: 0; background: #d9dde2 repeating-conic-gradient(#2a2f35 0 .62deg, transparent .62deg 1.6667deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 96.6%, #000 97% 99.4%, transparent 99.8%);
  mask: radial-gradient(circle closest-side, transparent 96.6%, #000 97% 99.4%, transparent 99.8%);
}
.sp-tt-strobe--50 {
  background: #d9dde2 repeating-conic-gradient(#2a2f35 0 .8deg, transparent .8deg 2deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 93.4%, #000 93.8% 96.2%, transparent 96.6%);
  mask: radial-gradient(circle closest-side, transparent 93.4%, #000 93.8% 96.2%, transparent 96.6%);
}
.sp-tt-mat { inset: 6.6%; background: #15171a; }
.sp-tt-platter > .sp-tt-record { inset: 5%; width: auto; }
.sp-tt-lamp { left: 58%; top: 85%; width: 4.4%; height: 3.4%; border-radius: 3px; background: #2a2f35; rotate: -32deg; }
.sp-tt-lamp::after { content: ""; position: absolute; inset: 28% 18%; border-radius: 2px; background: #59616b; transition: background var(--dur-quick) var(--ease-snap); }
.sp-tt[data-playing] .sp-tt-lamp::after { background: #ff8a4c; }
.sp-tt-rest { left: 88%; top: 76.25%; width: 3.4%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: #d9dde2; box-shadow: inset 0 0 0 1px var(--line-strong); }
.sp-tt-base { left: 88%; top: 13.75%; width: 10%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(circle, #eef0f2 0 34%, #c3c8cf 36% 62%, #e6e9ed 64%); box-shadow: inset 0 0 0 1px var(--line-strong); }
/* the arm: rotates about the pivot; a lifted arm shows a slightly bigger headshell */
.sp-tt-arm {
  left: 88%; top: 13.75%; width: 0; height: 62.5%; transform-origin: 0 0; rotate: var(--sp-arm);
  transition: rotate var(--dur-reveal) var(--ease-snap);
}
.sp-tt[data-arm="play"] .sp-tt-arm { transition: rotate 300ms linear; }
.sp-tt-arm > span { position: absolute; display: block; }
.sp-tt-tube { left: -.6cqw; top: -2cqw; width: 1.2cqw; bottom: 9%; border-radius: var(--radius-pill); background: linear-gradient(90deg, #aeb4bc, #eef0f2 45%, #aeb4bc); box-shadow: 0 0 0 .5px rgb(18 22 26 / .25); }
.sp-tt-weight { left: -2.6cqw; top: -9cqw; width: 5.2cqw; height: 5.2cqw; border-radius: 50%; background: #15171a; }
.sp-tt-head { left: -2cqw; bottom: 0; width: 4cqw; height: 11%; border-radius: 4px; background: var(--petrol); transition: scale var(--dur-quick) var(--ease-snap); transform-origin: 50% 0; }
.sp-tt[data-arm="cue"] .sp-tt-head, .sp-tt[data-arm="hold"] .sp-tt-head, .sp-tt[data-arm="return"] .sp-tt-head { scale: 1.14; }
/* backspin: the needle hops a groove */
.sp-tt.is-hop .sp-tt-head { animation: sp-tt-hop 300ms var(--ease-snap); }
@keyframes sp-tt-hop { 0%, 100% { scale: 1; } 40% { scale: 1.22; } }
@media (forced-colors: active) { .sp-tt-plinth { border: 1px solid CanvasText; } }

/* ---------- CSS sleeve (SleeveSlideOut without WebGL) ---------- */
.sp-sleeve { position: relative; aspect-ratio: 3 / 2; display: grid; place-items: center; }
.sp-sleeve-pair { position: relative; height: 100%; aspect-ratio: 1; transition: translate var(--dur-reveal) var(--ease-burst); }
.sp-sleeve-rec.sp-vinyl, .sp-sleeve-ring { position: absolute; inset: 2%; width: auto; transition: translate var(--dur-reveal) var(--ease-burst); }
.sp-sleeve-ring { border-radius: 50%; pointer-events: none; z-index: 2; }
.sp-sleeve-cover {
  position: absolute; inset: 0; z-index: 1; border-radius: var(--radius-sm); background: var(--band) center / cover no-repeat;
  box-shadow: inset 0 0 0 1px rgb(18 22 26 / .08);
}
.sp-sleeve[data-revealed] .sp-sleeve-pair { translate: -24% 0; }
.sp-sleeve[data-revealed] .sp-sleeve-rec, .sp-sleeve[data-revealed] .sp-sleeve-ring { translate: 50% 0; }
/* the 3D sleeve's ring rides over its canvas */
.sp-sleeve-ring--3d { position: absolute; inset: auto; }

/* ---------- Icons ---------- */
.sp-icon { width: 24px; height: 24px; flex: none; display: inline-block; vertical-align: middle; }

/* ---------- SpindleStack: the streak on a changer spindle ---------- */
.sp-stack {
  --w: 220px; --e: calc(var(--w) * .27); --rw: calc(var(--w) * .86); --re: calc(var(--rw) * .27);
  --th: 6px; --gap: 7px; --pth: 9px; --n: 0;
  display: inline-grid; justify-items: center; gap: var(--space-2);
}
.sp-stack-scene { position: relative; width: var(--w); height: calc(var(--pth) + var(--e) + var(--max, 12) * var(--gap) + var(--th) + 60px); }
.sp-stack-platter { position: absolute; z-index: 1; left: 0; right: 0; bottom: 0; height: calc(var(--e) + var(--pth)); }
.sp-stack-platter::before, .sp-stack-platter::after { content: ""; position: absolute; left: 0; right: 0; height: var(--e); border-radius: 50%; }
.sp-stack-platter::after { bottom: 0; background: #aeb4bc; }
.sp-stack-platter::before { top: 0; z-index: 1; background: radial-gradient(ellipse at 40% 35%, #f3f4f6, #d9dde2 55%, #c3c8cf); box-shadow: inset 0 0 0 1px rgba(18,22,26,.08); }
.sp-stack-recs { position: absolute; z-index: 2; inset: 0; transform-origin: 50% 100%; }
.sp-stack-recs.is-thud { animation: sp-stack-thud 260ms var(--ease-snap); }
@keyframes sp-stack-thud { 0% { transform: scaleY(1); } 35% { transform: scaleY(.97); } 100% { transform: scaleY(1); } }
.sp-stack-rec {
  position: absolute; left: calc((var(--w) - var(--rw)) / 2); width: var(--rw); height: calc(var(--re) + var(--th));
  bottom: calc(var(--pth) + (var(--e) - var(--re)) / 2 + var(--i) * var(--gap)); z-index: calc(var(--i) + 2);
}
.sp-stack-edge, .sp-stack-face { position: absolute; left: 0; right: 0; height: var(--re); border-radius: 50%; }
.sp-stack-edge { bottom: 0; background: linear-gradient(90deg, #050506, #1d1f22 50%, #050506); box-shadow: inset 0 -1px 0 rgba(255,255,255,.16); }
.sp-stack-face {
  top: 0; overflow: hidden;
  background:
    radial-gradient(ellipse closest-side, #0a0b0c 0 5%, var(--lab, var(--petrol)) 5.5% 36%, rgba(0,0,0,.25) 36.5%, transparent 38%),
    repeating-radial-gradient(ellipse closest-side, rgba(255,255,255,.06) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse at 35% 30%, #34383e, #131416 62%);
}
.sp-stack-rec.is-plated .sp-stack-edge { background: #9aa1aa; }
.sp-stack-rec.is-plated .sp-stack-face {
  background:
    radial-gradient(ellipse closest-side, #0a0b0c 0 5%, var(--lab, var(--petrol)) 5.5% 36%, rgba(0,0,0,.2) 36.5%, transparent 38%),
    repeating-radial-gradient(ellipse closest-side, rgba(0,0,0,.06) 0 1px, transparent 1px 3px),
    conic-gradient(from 20deg, #cfc6f5, #b9d9f2, #c9efe0, #efe6c4, #f0cde6, #cfc6f5);
}
.sp-stack-rec.is-plating .sp-stack-face::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-120%);
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.9) 48%, transparent 66%);
  animation: sp-stack-glint 900ms var(--ease-snap) forwards;
}
@keyframes sp-stack-glint { to { transform: translateX(120%); } }
.sp-stack-rec.is-dropping { animation: sp-stack-drop 520ms linear; }
@keyframes sp-stack-drop {
  0% { transform: translateY(-84px); opacity: 0; animation-timing-function: var(--ease-fall); }
  12% { opacity: 1; }
  62% { transform: translateY(0); animation-timing-function: var(--ease-snap); }
  76% { transform: translateY(-5px); animation-timing-function: var(--ease-fall); }
  90%, 100% { transform: translateY(0); }
}
/* the spindle rises out of the top record's centre hole */
.sp-stack-pin {
  position: absolute; left: calc(50% - 3px); width: 6px; height: 54px; z-index: 3; border-radius: 3px 3px 0 0;
  bottom: calc(var(--pth) + (var(--e) - var(--re)) / 2 + (var(--n) - 1) * var(--gap) + var(--re) / 2);
  background: linear-gradient(90deg, #9aa1aa, #eef0f2 45%, #aeb4bc);
}
.sp-stack-dust { position: absolute; left: 50%; width: 7px; height: 7px; border-radius: 50%; background: rgb(138 145 155 / .45); pointer-events: none; z-index: 4; }
.sp-stack-count { font: 600 13px/16px var(--font-label); letter-spacing: .01em; color: var(--petrol); }

/* ---------- CoverTile peek: the record rests half out of its sleeve, for a sleeve worth showing off ---------- */
.sp-cover--peek { --peek: 16%; }
@media (hover: hover) and (pointer: fine) { .sp-cover--peek[data-state="idle"]:hover { --peek: 22%; } }
.sp-cover--peek[data-state="idle"]:focus-visible { --peek: 22%; }

/* ---------- Invite: a control that hasn't been pressed yet breathes a gold halo now and then ----------
   For a round control (the halo follows its border-radius). Remove the class once it's been pressed. */
.sp-invite { position: relative; }
.sp-invite::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  animation: sp-invite 3.2s var(--ease-snap) 1.2s infinite;
}
@keyframes sp-invite {
  0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--gold) 90%, transparent), 0 0 0 0 color-mix(in oklab, var(--gold) 40%, transparent); }
  22% { box-shadow: 0 0 0 5px color-mix(in oklab, var(--gold) 55%, transparent), 0 0 14px 4px color-mix(in oklab, var(--gold) 30%, transparent); }
  60%, 100% { box-shadow: 0 0 0 14px color-mix(in oklab, var(--gold) 0%, transparent), 0 0 18px 10px color-mix(in oklab, var(--gold) 0%, transparent); }
}

/* ---------- MedalCard: a score card in its medal's material (bundle.js) ---------- */
.sp-medal-card { position: relative; isolation: isolate; overflow: hidden; }
.sp-medal-card--plain { background: var(--paper); }
.sp-medal-card--gold {
  --sp-metal: linear-gradient(118deg, var(--medal-gold-1) 0%, var(--foil-silver) 26%, var(--foil-violet) 42%, var(--foil-ice) 54%,
    var(--medal-gold-1) 70%, color-mix(in oklab, var(--medal-gold-2) 40%, var(--paper)) 86%, var(--medal-gold-1) 100%);
}
.sp-medal-card--silver {
  --sp-metal: linear-gradient(115deg, color-mix(in oklab, var(--medal-silver-2) 60%, var(--paper)) 0%, var(--medal-silver-1) 20%,
    color-mix(in oklab, var(--medal-silver-2) 75%, var(--paper)) 38%, color-mix(in oklab, var(--medal-silver-3) 45%, var(--paper)) 52%,
    color-mix(in oklab, var(--medal-silver-2) 70%, var(--paper)) 66%, var(--medal-silver-1) 84%, color-mix(in oklab, var(--medal-silver-2) 60%, var(--paper)) 100%);
}
.sp-medal-card--bronze {
  /* kept near neutral: the warmth is in the bands, not a peach wash over the card */
  --sp-metal: linear-gradient(115deg, color-mix(in oklab, var(--medal-bronze-2) 30%, var(--medal-silver-2)) 0%, var(--paper) 20%,
    color-mix(in oklab, var(--medal-bronze-2) 34%, var(--paper)) 38%, color-mix(in oklab, var(--medal-bronze-3) 50%, var(--medal-silver-2)) 52%,
    color-mix(in oklab, var(--medal-bronze-2) 30%, var(--paper)) 66%, var(--paper) 84%, color-mix(in oklab, var(--medal-bronze-2) 30%, var(--medal-silver-2)) 100%);
}
.sp-medal-card--silver, .sp-medal-card--bronze, .sp-medal-card--gold:not(.sp-holo-on) { background: var(--sp-metal); }
/* the pointer's light, and the sweep as the medal lands */
.sp-medal-card::before, .sp-medal-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; border-radius: inherit; }
.sp-medal-card::before {
  opacity: 0; transition: opacity var(--dur-quick) var(--ease-snap); mix-blend-mode: soft-light;
  background: radial-gradient(circle at var(--sp-mx, 50%) var(--sp-my, 50%), rgb(255 255 255 / .9), rgb(255 255 255 / 0) 55%);
}
.sp-medal-card.is-lit::before { opacity: 1; }
.sp-medal-card::after {
  background: linear-gradient(115deg, transparent 40%, rgb(255 255 255 / .6) 48%, rgb(255 255 255 / .14) 53%, transparent 60%) no-repeat;
  background-size: 260% 100%; background-position: 140% 0;
}
.sp-medal-card.is-landing::after { animation: sp-medal-sweep 1200ms var(--ease-snap); }
@keyframes sp-medal-sweep { from { background-position: 140% 0; } to { background-position: -40% 0; } }
.sp-medal-card--plain::before, .sp-medal-card--plain::after, .sp-medal-card.sp-holo-on::before, .sp-medal-card.sp-holo-on::after { display: none; }
/* a medal stuck on a card of its own metal: a deeper rim and shadow, so the sticker doesn't melt into the foil */
:is(.sp-medal-card--gold .sp-sticker--gold, .sp-medal-card--silver .sp-sticker--silver, .sp-medal-card--bronze .sp-sticker--bronze) {
  filter: drop-shadow(0 0 .8px rgb(18 22 26 / .7)) drop-shadow(0 3px 6px rgb(18 22 26 / .26));
}
:is(.sp-medal-card--gold .sp-sticker--gold, .sp-medal-card--silver .sp-sticker--silver, .sp-medal-card--bronze .sp-sticker--bronze) .sp-sticker-paper {
  background: color-mix(in oklab, var(--paper) 86%, var(--ink));
}
@media (forced-colors: active) { .sp-medal-card { background: Canvas; } .sp-medal-card::before, .sp-medal-card::after { display: none; } }

/* ---------- Reduced motion: fades and instant changes ---------- */
@media (prefers-reduced-motion: reduce) {
  .sp-btn, .sp-magnetic, .sp-magnetic > span, .sp-odo-col, .sp-odo-digit, .sp-cover-stage, .sp-cover-vinyl, .sp-cover-ring,
  .sp-slot, .sp-slot .sp-vinyl, .sp-tabs-ink, .sp-seg-thumb, .sp-tt-arm, .sp-tt-head, .sp-sleeve-pair, .sp-sleeve-rec, .sp-sleeve-ring { transition: none !important; }
  .sp-squash:active:not(:disabled) { scale: none; }
  .sp-squash.is-release, .sp-shake, .sp-levelup.is-levelup, .sp-levelup.is-levelup::after,
  .sp-progress-seg.is-pop, .sp-progress-seg.is-pop::after, .sp-level.is-up, .sp-delta.is-on,
  .sp-sticker.is-new, .sp-chip.is-pop, .sp-dialog[open] .sp-dialog-panel, .sp-dialog--sheet[open] .sp-dialog-panel, .sp-toast,
  .sp-cover[data-state="wrong"] .sp-cover-stage, .sp-stack-rec.is-dropping, .sp-stack-recs.is-thud, .sp-stack-rec.is-plating .sp-stack-face::after, .sp-tt.is-hop .sp-tt-head { animation: none; }
  /* the level-up tint fades in and out instead of sweeping */
  .sp-levelup.is-levelup { animation: sp-tint var(--dur-reveal) ease; }
  @keyframes sp-tint { 0%, 100% { background-color: transparent; } 40% { background-color: var(--violet-soft); } }
  .sp-burst.is-burst::after { animation: sp-fadeout var(--dur-reveal) ease forwards; opacity: 1; inset: -6px; }
  .sp-loader .sp-vinyl-disc, .sp-cover-art[data-loading] .sp-cover-loader .sp-vinyl-disc { animation: none; }
  .sp-btn--primary::before, .sp-cover-art::before { animation: none !important; }
  /* an invite holds still as a quiet gold halo; a medal card's foil lands without a sweep */
  .sp-invite::after { animation: none; box-shadow: 0 0 0 3px color-mix(in oklab, var(--gold) 55%, transparent); }
  .sp-medal-card.is-landing::after { animation: none; }
  .sp-medal-card::before { transition: none; }
  :is(.sp-sticker--gold, .sp-sticker--silver, .sp-sticker--bronze, .sp-sticker--foil) .sp-sticker-face { transition: none; }
  /* A playing record is the game's state, not decoration: it keeps turning at a steady 33 1/3 (bundle.js), with no
     spin-up, coast or backspin. Everything else above still fades or changes at once. */
  .sp-dialog.is-closing .sp-dialog-panel, .sp-dialog--sheet.is-closing .sp-dialog-panel { animation: sp-fadeout var(--dur-quick) ease forwards; }
}
