/* ============================================================================
   CHAD SANDERS OFFICIAL — THE JUKEBOX, 3D
   Wurlitzer-style cabinet built in CSS: walnut body, chrome trim, a colour-
   cycling lit arch over a glass dome that shows the record mechanism, paper
   title strips paged with chrome selector keys, the rack player (styled by
   cs-player.css) as the amplifier panel, and a lit speaker grille.

   Motion is driven by cs-jukebox3d.js through a few custom properties:
     --rx / --ry  cabinet tilt (pointer, desktop only)
     --beat       0..1 music level, set on .jb3-lit elements only
     --arm        tonearm angle
   ============================================================================ */

.jb3 {
  --nav-gap: 26px;
  --walnut-1: #4a2614;
  --walnut-2: #2e160a;
  --walnut-3: #1a0c05;
  --chrome-hi: #f4f8fc;
  --chrome:    #aab6c4;
  --chrome-lo: #4d5868;
  --amber:     #ffb347;
  --gold:      #e8a020;
  --paper:     #f2e8cc;
  --ink:       #1b1712;
  --strip-red: #b3261e;
  --strip-blue:#1f4e8c;
  --rainbow: linear-gradient(180deg, #ff3b2f, #ff9f1a, #ffe45c, #3ddc84, #22c3ff, #a855f7, #ff3b2f);
  --chrome-bar: linear-gradient(180deg, var(--chrome-hi) 0%, var(--chrome) 38%, var(--chrome-lo) 52%, var(--chrome) 70%, var(--chrome-hi) 100%);

  position: relative;
  padding: calc(var(--nav-h, 70px) + var(--nav-gap)) 1rem 4.5rem;
  /* No solid fill: the page's own drifting starfield (.atm-bg in the header)
     is fixed behind everything, so letting it through carries the same sky up
     from the song list below and past the cabinet. Only the cabinet's own
     spill of light is painted here. */
  background:
    radial-gradient(ellipse 60% 40% at 50% 8%, rgba(255,160,60,.10), transparent 70%),
    radial-gradient(ellipse 70% 50% at 50% 100%, rgba(0,200,255,.06), transparent 70%);
}

/* ── Page heading, lit inside the dome ─────────────────────────────────── */
.jb3-dome-head {
  position: absolute;
  left: 50%; top: 44px;             /* clear of the arch curve */
  width: 74%;
  transform: translateX(-50%);
  text-align: center;
  z-index: 3;
  pointer-events: none;
}
.jb3-eyebrow {
  font: 700 9px/1 'Orbitron', sans-serif;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--amber);
  text-shadow: 0 0 10px rgba(255,160,60,.55);
}
.jb3-h1 {
  margin: 7px 0 4px;
  font-family: 'Playfair Display', Georgia, serif;
  font-size: clamp(26px, 4.4vw, 40px);
  font-weight: 900;
  line-height: 1;
  color: #fff6ec;
  text-shadow: 0 0 14px rgba(0,0,0,.75), 0 2px 4px rgba(0,0,0,.6);
}
.jb3-h1 em {
  font-style: italic;
  color: #ffce7a;
  text-shadow: 0 0 12px rgba(255,170,60,.6), 0 0 30px rgba(255,140,40,.35);
}
.jb3-lede {
  margin: 0;
  font: 700 9.5px/1.5 'Orbitron', sans-serif;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #e0c49c;
  text-shadow: 0 1px 6px rgba(0,0,0,.8);
}

/* ── Stage + cabinet (3D) ───────────────────────────────────────────────── */
.jb3-stage {
  max-width: 900px;
  margin: 0 auto;
  perspective: 2400px;
  perspective-origin: 50% 20%;
  position: relative;
}
.jb3-stage::after {                       /* floor shadow */
  content: "";
  position: absolute;
  left: 8%; right: 8%; bottom: -34px;
  height: 46px;
  background: radial-gradient(ellipse at center, rgba(0,0,0,.85), transparent 70%);
  filter: blur(6px);
  z-index: -1;
}
.jb3-cabinet {
  --rx: 0deg; --ry: 0deg;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .6s cubic-bezier(.2,.7,.2,1);
}
.jb3-side {                               /* cabinet depth, seen when tilted */
  position: absolute;
  top: 190px; bottom: 0;
  width: 70px;
  background: linear-gradient(90deg, var(--walnut-2), var(--walnut-3));
  box-shadow: inset 0 0 30px rgba(0,0,0,.6);
}
.jb3-side--l { left: 0;  transform-origin: left center;  transform: rotateY(90deg); }
.jb3-side--r { right: 0; transform-origin: right center; transform: rotateY(-90deg); }

/* ── Lit arch + dome ───────────────────────────────────────────────────── */
.jb3-arch {
  position: relative;
  padding: 20px 20px 0;
  border-radius: 50% 50% 0 0 / 250px 250px 0 0;
  background:
    linear-gradient(90deg, rgba(0,0,0,.45), transparent 14%, transparent 86%, rgba(0,0,0,.45)),
    repeating-linear-gradient(92deg, var(--walnut-1) 0 3px, #3b1d0d 3px 8px, #5a3219 8px 10px, #3f1f0e 10px 15px);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.08);
}
.jb3-arch-light {                         /* colour-cycling tube following the arch */
  --beat: 0;
  position: absolute;
  inset: 6px 6px 0;
  border-radius: inherit;
  padding: 11px 11px 0;
  background: var(--rainbow);
  background-size: 100% 300%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  filter: brightness(calc(.72 + var(--beat) * .9)) drop-shadow(0 0 calc(4px + var(--beat) * 16px) rgba(255,170,70,.8));
  animation: jb3-cycle 9s linear infinite;
  pointer-events: none;
}
@keyframes jb3-cycle { to { background-position: 0 300%; } }

.jb3-dome {
  position: relative;
  height: 448px;
  border-radius: 50% 50% 6px 6px / 215px 215px 6px 6px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 45% at 50% 78%, rgba(255,170,80,.22), transparent 70%),
    radial-gradient(ellipse 80% 70% at 50% 65%, #3a2212 0%, #1b0f07 55%, #0a0503 100%);
  box-shadow:
    inset 0 0 0 3px var(--chrome-hi),
    inset 0 0 0 6px var(--chrome-lo),
    inset 0 24px 70px rgba(0,0,0,.75);
}
/* ── Dome interior ─────────────────────────────────────────────────────────
   The cabinet behind the mechanism: a ribbed back wall, a warm pool of light
   that breathes with the music, a floor the deck sits on, and a vignette that
   sinks the corners so the chrome reads against depth instead of flat brown. */
.jb3-backwall {
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 26%;
  background:
    linear-gradient(180deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.15) 45%, rgba(0,0,0,.55) 100%),
    repeating-linear-gradient(90deg,
      rgba(255,255,255,.055) 0 2px,
      rgba(0,0,0,.30) 2px 7px,
      rgba(255,255,255,.02) 7px 11px,
      rgba(0,0,0,.22) 11px 16px),
    linear-gradient(180deg, #4b2a16 0%, #2a1509 70%, #160a04 100%);
}
.jb3-spot {
  --beat: 0;
  position: absolute;
  left: 50%; top: 4%;
  width: 78%; height: 86%;
  transform: translateX(-50%);
  background:
    radial-gradient(ellipse 52% 44% at 50% 52%, rgba(255,196,120,calc(.20 + var(--beat) * .30)) 0%, rgba(255,150,60,.10) 42%, transparent 72%);
  mix-blend-mode: screen;
}
.jb3-floor {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 28%;
  background:
    linear-gradient(180deg, rgba(0,0,0,.65) 0%, rgba(0,0,0,.25) 22%, rgba(0,0,0,.8) 100%),
    linear-gradient(180deg, #2b1a10, #120a05);
  box-shadow: inset 0 14px 26px rgba(0,0,0,.7);
}
.jb3-vignette {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(ellipse 74% 66% at 50% 52%, transparent 52%, rgba(0,0,0,.55) 88%, rgba(0,0,0,.8) 100%);
}

.jb3-glass {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background:
    linear-gradient(115deg, rgba(255,255,255,.16) 0%, rgba(255,255,255,.03) 26%, transparent 48%, rgba(255,255,255,.06) 72%, transparent 86%);
}
.jb3-glass::after {                       /* slow reflection sweep */
  content: "";
  position: absolute; top: -20%; bottom: -20%;
  width: 22%;
  left: -40%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.13), transparent);
  transform: skewX(-18deg);
  animation: jb3-sweep 11s ease-in-out infinite;
}
@keyframes jb3-sweep { 0%, 62% { left: -40%; } 100% { left: 130%; } }

.jb3-marquee {
  position: absolute;
  /* Sits at the foot of the record player rather than over the title. It is
     absolutely positioned inside the dome, so this moves nothing else. */
  bottom: 0; left: 50%;
  transform: translateX(-50%);
  max-width: 62%;
  display: flex; align-items: center; gap: 8px;
  padding: 5px 14px;
  border-radius: 20px;
  background: rgba(0,0,0,.45);
  box-shadow: 0 0 0 1px rgba(255,200,120,.25);
  font: 700 10px/1 'Orbitron', sans-serif;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #ffd592;
  text-shadow: 0 0 8px rgba(255,170,60,.7);
  z-index: 6;              /* above the deck it now sits on */
  white-space: nowrap;
}
.jb3-marquee-text { overflow: hidden; text-overflow: ellipsis; }
.jb3-marquee-dot {
  flex: none;
  width: 7px; height: 7px; border-radius: 50%;
  background: #ff4b3a;
  box-shadow: 0 0 8px #ff4b3a;
  opacity: .35;
}
.jb3.is-playing .jb3-marquee-dot { opacity: 1; animation: jb3-blink 1.2s steps(2) infinite; }
@keyframes jb3-blink { 50% { opacity: .3; } }

/* ── Record mechanism ──────────────────────────────────────────────────── */
.jb3-mech { position: absolute; inset: 0; }

.jb3-rack-wrap {
  position: absolute;
  left: 9%; right: 9%; top: 150px;
  height: 128px;
  perspective: 700px;
  perspective-origin: 50% 40%;
  /* The rack is far wider than the cabinet, so it fades out at both ends
     instead of running off the side of the dome. */
  -webkit-mask: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
          mask: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
}
.jb3-rack {
  position: absolute;
  left: 0; bottom: 14px;
  display: flex;
  align-items: flex-end;
  transform-style: preserve-3d;
  transition: transform .75s cubic-bezier(.55,.05,.25,1);
}
.jb3-rec {
  position: relative;
  flex: none;
  width: 96px; height: 96px;
  margin-right: -74px;                    /* ~22px per record in the rack */
  border-radius: 50%;
  background:
    radial-gradient(circle, transparent 0 18%, rgba(255,255,255,.05) 18.5%, transparent 19%),
    repeating-radial-gradient(circle, #0f0f10 0 1px, #1d1d1f 1px 2.4px);
  box-shadow: 0 0 0 1.5px #050505, 6px 4px 10px rgba(0,0,0,.55);
  transform: rotateY(64deg);
  transition: transform .45s cubic-bezier(.3,.7,.2,1), opacity .35s, filter .3s;
  filter: brightness(.7);
}
.jb3-rec.is-sel  { transform: translateY(-16px) rotateY(64deg); filter: brightness(1.15); }
.jb3-rec.is-out  { transform: translateY(-70px) rotateY(64deg); opacity: 0; }
.jb3-rec-label, .jb3-disc-label {
  position: absolute;
  left: 50%; top: 50%;
  width: 38%; height: 38%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  box-shadow: 0 0 0 2px #0b0b0b;
}
/* A record has a HOLE, not a spindle: the post belongs to the platter, so the
   hole is all the record carries - in the rack, in flight, and on the deck. */
.jb3-rec-label::after,
.jb3-disc-label::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: 8%; height: 8%;
  min-width: 5px; min-height: 5px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #05060a, #0b0d12 60%, #16191f);
  box-shadow:
    inset 0 1px 2px rgba(0,0,0,.95),
    0 0 0 1px rgba(255,255,255,.14),
    0 1px 0 rgba(255,255,255,.10);
}

/* The spindle: fixed to the platter, standing proud of the record surface, so
   it shows through the hole when a record is down and stands alone when the
   deck is empty or a record is in transit. */
.jb3-spindle {
  position: absolute;
  left: 150px; top: 150px;
  width: 7px; height: 9px;
  margin: -9px 0 0 -3.5px;                /* hinge at the platter centre */
  transform-origin: 50% 100%;
  transform: rotateX(-90deg);             /* stands up out of the platter */
  transform-style: preserve-3d;
  border-radius: 3px 3px 1px 1px;
  background: linear-gradient(90deg,
    #4e5866 0%, #aeb9c6 18%, #f6fafd 40%, #ffffff 50%, #c3ccd8 66%, #6b7684 86%, #39424e 100%);
  box-shadow: 0 0 0 .5px rgba(0,0,0,.45);
  z-index: 6;
}
.jb3-spindle::after {                     /* turned tip */
  content: "";
  position: absolute;
  left: 0; right: 0; top: -2px;
  height: 5px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 28%, #ffffff, #cbd4df 55%, #77818e);
}
.jb3-spindle::before {                    /* shadow pooling on the record */
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 18px; height: 18px;
  margin: 0 0 -9px -9px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(0,0,0,.6), rgba(0,0,0,.25) 45%, transparent 72%);
  transform: rotateX(90deg);              /* lies flat again, on the disc */
}
.jb3-rail {
  position: absolute;
  left: 0; right: 0; bottom: 6px;
  height: 9px;
  border-radius: 5px;
  background: var(--chrome-bar);
  box-shadow: 0 4px 10px rgba(0,0,0,.6);
}

.jb3-turntable {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 212px;
  z-index: 4;                             /* the deck stands in the open bay */
  perspective: 900px;
  perspective-origin: 50% 0%;
}
.jb3-deck {                               /* flat plate the platter + arm sit on */
  position: absolute;
  left: 50%; bottom: -26px;
  width: 380px; height: 300px;
  margin-left: -190px;
  transform: rotateX(60deg);
  transform-origin: 50% 100%;
  transform-style: preserve-3d;
  border-radius: 18px;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.025) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, #262a31, #121418);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.08), inset 0 0 40px rgba(0,0,0,.6);
}
.jb3-platter {
  position: absolute;
  left: 22px; top: 22px;
  width: 256px; height: 256px;
  border-radius: 50%;
  background:
    radial-gradient(circle, #1a1a1a 0 84%, transparent 84.5%),
    conic-gradient(from 20deg, var(--chrome-hi), var(--chrome-lo), var(--chrome), var(--chrome-hi), var(--chrome-lo), var(--chrome-hi));
  box-shadow: 0 0 0 2px #0a0a0a, 0 14px 22px rgba(0,0,0,.6);
}
.jb3-disc {
  position: absolute;
  left: 34px; top: 34px;
  width: 232px; height: 232px;
  border-radius: 50%;
  transform-style: preserve-3d;
  transition: transform .5s cubic-bezier(.3,.7,.2,1), opacity .45s;
}
.jb3-disc.is-lifted { transform: translateZ(80px); opacity: 0; }
.jb3-disc::after {                        /* stationary light reflection over the spinning vinyl */
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 8%, rgba(255,255,255,.14) 12%, transparent 17% 55%, rgba(255,255,255,.10) 60%, transparent 65%);
  pointer-events: none;
}
.jb3-vinyl {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: repeating-radial-gradient(circle, #0c0c0d 0 1.2px, #1c1c1e 1.2px 2.8px);
  box-shadow: 0 0 0 2px #050505;
  will-change: transform;
}
.jb3-arm-base {
  position: absolute;
  left: 322px; top: 42px;
  width: 44px; height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, var(--chrome-hi), var(--chrome) 45%, var(--chrome-lo) 80%);
  box-shadow: 0 6px 10px rgba(0,0,0,.6);
}
.jb3-arm {
  --arm: 0deg;
  position: absolute;
  left: 322px; top: 42px;
  width: 0; height: 0;
  transform-style: preserve-3d;
  /* 7px of clearance over the disc. At 3px the headshell - 200px out from the
     bearing, and tipped when cueing - crossed the record surface and z-fought
     with it, which showed as a flicker at the needle end.  */
  transform: translateZ(7px) rotate(var(--arm));
  /* No CSS transition: cs-jukebox3d.js eases the angle itself, frame by frame.
     Both together fought each other and stuttered. */
  transition: none;
  will-change: transform;
}
/* Cueing up tips the arm about its bearing so the headshell rises and the
   pivot stays seated in its base - raising the whole arm made the base appear
   to come away from it. */
.jb3-arm.is-lifted { transform: translateZ(7px) rotate(var(--arm)) rotateX(2.5deg); }
.jb3-arm-wob {                            /* needle ride: tiny jitter, no transition */
  position: absolute;
  left: 0; top: 0;
  width: 0; height: 0;
  transform-origin: 0 0;
  transform-style: preserve-3d;
}
.jb3-arm-tube {
  position: absolute;
  left: -3.5px; top: -6px;
  width: 7px; height: 190px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--chrome-lo), var(--chrome-hi) 45%, var(--chrome) 70%, var(--chrome-lo));
  box-shadow: 4px 8px 8px rgba(0,0,0,.45);
}
.jb3-arm-weight {
  position: absolute;
  left: -13px; top: -52px;
  width: 26px; height: 34px;
  border-radius: 5px;
  background: linear-gradient(90deg, #3b414a, #cfd7e0 45%, #6c7784);
}
.jb3-arm-head {
  position: absolute;
  left: -10px; top: 178px;
  width: 20px; height: 34px;
  border-radius: 3px 3px 6px 6px;
  background: linear-gradient(90deg, #15171b, #3b4049 50%, #15171b);
  box-shadow: 0 0 0 1px var(--chrome);
  transform: rotate(-20deg);
  transform-origin: 50% 0;
  /* Flatten the headshell: it has no depth of its own, and leaving it in the
     3D context let it intersect the vinyl at shallow angles. */
  transform-style: flat;
  backface-visibility: hidden;
}

/* The record in flight lives INSIDE the deck plane and shares the disc's exact
   box, so when it lands its pose already equals the seated disc's - nothing
   pops from a flat overlay into the angled view. */
.jb3-flyer {
  position: absolute;
  left: 34px; top: 34px;
  width: 232px; height: 232px;
  border-radius: 50%;
  background: repeating-radial-gradient(circle, #0c0c0d 0 1.2px, #1c1c1e 1.2px 2.8px);
  box-shadow: 0 0 0 2px #050505, 0 18px 30px rgba(0,0,0,.6);
  transform-style: preserve-3d;
  z-index: 5;
  pointer-events: none;
}
.jb3-flyer[hidden] { display: none; }

/* ── Body below the arch ───────────────────────────────────────────────── */
.jb3-body {
  position: relative;
  padding: 0 34px 18px;
  border-radius: 0 0 18px 18px;
  background:
    linear-gradient(90deg, rgba(0,0,0,.5), transparent 10%, transparent 90%, rgba(0,0,0,.5)),
    repeating-linear-gradient(92deg, var(--walnut-1) 0 3px, #3b1d0d 3px 8px, #5a3219 8px 10px, #3f1f0e 10px 15px);
}
.jb3-pilaster {                           /* full-height lit columns on both edges */
  --beat: 0;
  position: absolute;
  top: 0; bottom: 60px;
  width: 12px;
  border-radius: 6px;
  background: var(--rainbow);
  background-size: 100% 300%;
  animation: jb3-cycle 9s linear infinite reverse;
  filter: brightness(calc(.7 + var(--beat) * .9)) drop-shadow(0 0 calc(3px + var(--beat) * 14px) rgba(255,170,70,.75));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.35);
}
.jb3-pilaster--l { left: 10px; }
.jb3-pilaster--r { right: 10px; }

.jb3-nameplate {
  --beat: 0;
  position: relative;
  margin: 18px -14px 0;                   /* now sits under the song selection */
  padding: 14px 20px 12px;
  text-align: center;
  border-radius: 6px;
  /* Dark plate, lit lettering: dark red script on bright chrome had almost no
     contrast, so the name now reads as lit glass against the cabinet. */
  background:
    radial-gradient(ellipse 60% 120% at 50% 50%, rgba(255,120,60,.12), transparent 70%),
    linear-gradient(180deg, #14171c 0%, #0a0c10 55%, #15191f 100%);
  box-shadow:
    0 6px 14px rgba(0,0,0,.55),
    inset 0 0 0 2px var(--chrome-lo),
    inset 0 0 0 4px rgba(0,0,0,.65),
    inset 0 2px 10px rgba(0,0,0,.8);
}
.jb3-script {
  display: block;
  font-family: 'Yellowtail', 'Brush Script MT', cursive;
  font-size: clamp(36px, 6.4vw, 54px);
  line-height: 1;
  color: #fff3ea;
  text-shadow:
    0 0 4px  rgba(255,110,70,.95),
    0 0 14px rgba(255,72,40,calc(.65 + var(--beat) * .35)),
    0 0 34px rgba(255,50,20,calc(.35 + var(--beat) * .35)),
    0 2px 2px rgba(0,0,0,.6);
}
.jb3-sub {
  display: block;
  margin-top: 5px;
  font: 700 9.5px/1.4 'Orbitron', sans-serif;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: #e8c79a;
  text-shadow: 0 0 8px rgba(255,150,60,.45);
}

/* ── Selector: bubble tubes + title strips ─────────────────────────────── */
.jb3-selector {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 34px;
  gap: 14px;
  margin-top: 14px;                       /* first panel under the dome now */
}
.jb3-tube {
  --beat: 0;
  position: relative;
  border-radius: 17px;
  overflow: hidden;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.35), inset 0 0 12px rgba(0,0,0,.6), 0 0 calc(6px + var(--beat) * 22px) rgba(255,160,60,.55);
}
.jb3-fluid {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, #ff6a3d, #ffb13d 40%, #ff3d6a);
  animation: jb3-hue 14s linear infinite;
  opacity: .85;
}
.jb3-tube--r .jb3-fluid { animation-delay: -7s; }
.jb3-tube::after {                        /* glass highlight */
  content: "";
  position: absolute;
  top: 6px; bottom: 6px; left: 6px;
  width: 6px;
  border-radius: 3px;
  background: linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,.1));
}
@keyframes jb3-hue { to { filter: hue-rotate(360deg); } }
.jb3-bubble {
  position: absolute;
  bottom: -12px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 32%, #fff, rgba(255,255,255,.7) 45%, rgba(255,255,255,.15) 75%);
  box-shadow: 0 0 5px rgba(255,255,255,.8), inset -1px -1px 2px rgba(0,0,0,.18);
  animation: jb3-rise linear infinite;
}
@keyframes jb3-rise {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  8%   { opacity: .9; }
  50%  { transform: translateY(-260px) translateX(3px); }
  100% { transform: translateY(-560px) translateX(-2px); opacity: .6; }
}

.jb3-strips {
  min-width: 0;
  padding: 12px;
  border-radius: 10px;
  background: linear-gradient(180deg, #161a20, #0b0d10);
  box-shadow: inset 0 0 0 2px var(--chrome-lo), inset 0 0 0 4px rgba(0,0,0,.6), 0 8px 18px rgba(0,0,0,.5);
}

/* Search (IDs/classes shared with the page's live-search script) */
.csd-jbx-search {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.csd-jbx-search-ico {
  position: absolute; left: 12px;
  width: 16px; height: 16px;
  color: var(--amber);
  pointer-events: none;
}
.csd-jbx-search-ico svg { width: 16px; height: 16px; }
.csd-jbx-search-input {
  flex: 1; min-width: 0;
  height: 38px;
  padding: 0 38px 0 36px;
  border-radius: 19px;
  border: 1px solid rgba(255,190,110,.35);
  background: #07090b;
  color: #f5e9d0;
  font: 500 14px 'Inter', sans-serif;
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.csd-jbx-search-input::placeholder { color: #8d7f69; }
.csd-jbx-search-input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px rgba(255,179,71,.18); }
.csd-jbx-search-input::-webkit-search-cancel-button { display: none; }
.csd-jbx-search-clear {
  position: absolute;
  right: calc(88px + 10px);
  width: 24px; height: 24px;
  display: none;
  align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: rgba(255,255,255,.1);
  color: #f5e9d0;
  cursor: pointer;
}
.csd-jbx-search-clear.is-shown { display: flex; }
.csd-jbx-search-clear svg { width: 11px; height: 11px; }
.csd-jbx-search-count {
  flex: none;
  width: 88px;
  text-align: right;
  font: 700 10px 'Orbitron', sans-serif;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--amber);
}
.csd-jbx-search-count.is-empty { color: #ff7a6b; }

/* Title-strip window */
.jb3-window {
  position: relative;
  padding: 10px;
  border-radius: 6px;
  background: #120c07;
  box-shadow: inset 0 0 0 2px #000, inset 0 6px 18px rgba(0,0,0,.8);
  perspective: 900px;
}
.jb3-window-glass {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(170deg, rgba(255,255,255,.10), transparent 30%, transparent 70%, rgba(255,255,255,.04));
}
.jb3-grid {
  --strip-h: 54px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* --rows is set per page by cs-jukebox3d.js: the last page holds fewer
     strips, and a fixed row count left a tall empty pane under them. */
  grid-template-rows: repeat(var(--rows, 6), var(--strip-h));
  grid-auto-flow: column;
  gap: 7px 10px;
  transform-origin: 50% 0;
}
.jb3-grid .csd-jbx-tab {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 0 10px 0 0;
  background:
    linear-gradient(180deg, var(--strip-red) 0 3px, transparent 3px 5px, var(--strip-red) 5px 6px, transparent 6px),
    linear-gradient(0deg,   var(--strip-blue) 0 3px, transparent 3px 5px, var(--strip-blue) 5px 6px, transparent 6px),
    var(--paper);
  box-shadow: 0 2px 0 rgba(0,0,0,.4), inset 0 0 18px rgba(120,90,40,.18);
  cursor: pointer;
  transition: transform .15s, box-shadow .2s, background-color .2s, filter .2s;
  outline: none;
}
.jb3-grid .csd-jbx-tab:hover { transform: translateY(-1px); filter: brightness(1.05); }
.jb3-grid .csd-jbx-tab:focus-visible { box-shadow: 0 0 0 3px var(--amber); }
.jb3-grid .csd-jbx-tab.jb3-off,
.jb3-grid .csd-jbx-tab.jbx-filtered { display: none; }
.jb3-grid .csd-jbx-tab--nofle { cursor: default; filter: grayscale(.8) brightness(.8); }

.jb3-code {
  flex: none;
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  width: 44px;
  margin: 6px 0;
  background: var(--strip-red);
  color: #fff4df;
  font: 600 16px/1 'Oswald', 'Arial Narrow', sans-serif;
  letter-spacing: .04em;
}
.jb3-thumb {
  flex: none;
  width: 34px; height: 34px;
  object-fit: cover;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.35);
}
.jb3-strip-text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.jb3-grid .csd-jbx-title {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 600 14.5px/1.1 'Oswald', 'Arial Narrow', sans-serif;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--ink);
}
.jb3-grid .csd-jbx-title mark { background: #ffd66b; color: inherit; padding: 0 1px; }
.jb3-artist {
  font: 700 8.5px/1 'Orbitron', sans-serif;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--strip-red);
  opacity: .85;
}
.jb3-live { display: none; align-items: flex-end; gap: 2px; height: 14px; flex: none; }
.jb3-live i { width: 3px; background: var(--strip-red); animation: jb3-eq .9s ease-in-out infinite; }
.jb3-live i:nth-child(2) { animation-delay: -.3s; }
.jb3-live i:nth-child(3) { animation-delay: -.6s; }
@keyframes jb3-eq { 0%,100% { height: 30%; } 50% { height: 100%; } }

.jb3-grid .csd-jbx-tab.csd-active {
  background-color: #fff5d6;
  box-shadow: 0 0 0 2px var(--amber), 0 0 18px rgba(255,179,71,.55), inset 0 0 18px rgba(255,200,80,.25);
}
.jb3-grid .csd-jbx-tab.csd-active .jb3-code { background: #d9480f; }
.jb3-grid .csd-jbx-tab.csd-active .jb3-live { display: flex; }
.jb3:not(.is-playing) .jb3-live i { animation-play-state: paused; }

.jb3-grid .csd-jbx-empty {
  display: none;
  grid-column: 1 / -1;
  grid-row: 1 / -1;
  align-self: center;
  text-align: center;
  font: 700 13px 'Orbitron', sans-serif;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--amber);
}
.jb3-grid .csd-jbx-empty.is-shown { display: block; }
.jb3-grid .csd-jbx-empty span {
  display: block; margin-top: 8px;
  font: 400 13px 'Inter', sans-serif; letter-spacing: 0; text-transform: none;
  color: #b8a88c;
}

/* Selector keys */
.jb3-keys {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center;
  gap: 8px;
  margin: 0 0 12px;                       /* sits above the search box */
}
.jb3-letters { display: flex; gap: 8px; }
.jb3-key {
  min-width: 42px; height: 38px;
  padding: 0 10px;
  border: 0;
  border-radius: 7px;
  background: linear-gradient(180deg, #ffffff 0%, #cfd8e2 40%, #8e9aa9 100%);
  box-shadow: 0 4px 0 #4a5361, 0 6px 10px rgba(0,0,0,.5), inset 0 1px 0 #fff;
  color: #1c2129;
  font: 600 17px/1 'Oswald', sans-serif;
  cursor: pointer;
  transition: transform .08s, box-shadow .08s, background .2s;
}
.jb3-key:hover { filter: brightness(1.06); }
.jb3-key:active { transform: translateY(3px); box-shadow: 0 1px 0 #4a5361, 0 2px 4px rgba(0,0,0,.5); }
.jb3-key:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }
.jb3-key.is-on {
  background: linear-gradient(180deg, #fff1c9 0%, #ffc35a 45%, #e08a12 100%);
  box-shadow: 0 2px 0 #7a4a06, 0 0 16px rgba(255,170,60,.6), inset 0 1px 0 #fff;
  transform: translateY(2px);
}
.jb3-key--arrow { font-size: 13px; }
.jb3-key--fx { font: 700 11px/1 'Orbitron', sans-serif; letter-spacing: .1em; }
.jb3-key--fx:not(.is-on) { color: #6a7382; }
.jb3-pageinfo {
  flex-basis: 100%;
  text-align: center;
  font: 700 9.5px 'Orbitron', sans-serif;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: #b89c6d;
}

/* ── Amplifier panel (hosts the untouched rack player) ─────────────────── */
.jb3-amp {
  position: relative;
  margin-top: 18px;
  padding: 12px 0 14px;
  border-radius: 12px;
  background: linear-gradient(180deg, #2a2f37, #121418);
  box-shadow: inset 0 0 0 2px var(--chrome-lo), inset 0 0 0 4px #000, 0 10px 22px rgba(0,0,0,.55);
}
.jb3-amp .csd-wrap { padding: 0 12px; }
.jb3-amp-top {
  display: flex; align-items: center; justify-content: center;
  gap: 14px;
  margin-bottom: 12px;
}
.jb3-amp-badge {
  margin: 0 10px;
  font: 700 9.5px 'Orbitron', sans-serif;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: #d9c197;
}
.jb3-vt {                                 /* glowing vacuum tubes */
  --beat: 0;
  position: relative;
  width: 20px; height: 34px;
  border-radius: 10px 10px 4px 4px;
  background:
    radial-gradient(ellipse 40% 30% at 50% 58%, rgba(255,150,50,calc(.35 + var(--beat) * .65)), transparent 70%),
    linear-gradient(90deg, rgba(255,255,255,.18), rgba(255,255,255,.04) 40%, rgba(255,255,255,.12));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.3), 0 0 calc(4px + var(--beat) * 16px) rgba(255,140,40,.6);
}
.jb3-vt::after {
  content: "";
  position: absolute; left: -2px; right: -2px; bottom: -6px;
  height: 7px; border-radius: 2px;
  background: linear-gradient(180deg, #555, #222);
}

/* ── Speaker grille + base ─────────────────────────────────────────────── */
.jb3-grille {
  position: relative;
  height: 180px;
  margin-top: 18px;
  border-radius: 12px 12px 6px 6px;
  overflow: hidden;
  background:
    repeating-linear-gradient(0deg,  rgba(0,0,0,.35) 0 2px, transparent 2px 4px),
    repeating-linear-gradient(90deg, rgba(0,0,0,.30) 0 2px, transparent 2px 4px),
    #3a2716;
  box-shadow: inset 0 0 0 3px var(--chrome), inset 0 0 0 6px #000, inset 0 12px 30px rgba(0,0,0,.65);
}
.jb3-grille-glow {
  --beat: 0;
  --punch: 0;
  position: absolute; inset: 0;
  /* The lamp behind the cloth: the lit area grows as well as brightens, so it
     reads as the speaker being driven rather than a lamp fading up. */
  background:
    radial-gradient(
      ellipse calc(26% + var(--punch) * 42%) calc(34% + var(--punch) * 48%) at 50% 60%,
      rgba(255,226,170, calc(.02 + var(--punch) * .70)) 0%,
      rgba(255,150,45,  calc(.01 + var(--punch) * .46)) 34%,
      rgba(255,110,20,  calc(0   + var(--punch) * .24)) 58%,
      transparent 76%);
  filter: brightness(calc(.85 + var(--punch) * .85));
  transition: filter .05s linear;
}
.jb3-grille-glow::after {                 /* bloom spilling past the cloth */
  content: "";
  position: absolute;
  left: 12%; right: 12%; top: 8%; bottom: 8%;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 55%, rgba(255,190,110, calc(var(--punch) * .34)), transparent 70%);
  filter: blur(14px);
}
.jb3-slats {
  position: absolute; inset: 0;
  display: flex; justify-content: space-evenly;
  padding: 0 12%;
}
.jb3-slats i { width: 7px; background: var(--chrome-bar); box-shadow: 3px 0 8px rgba(0,0,0,.5); }
.jb3-emblem {
  position: absolute;
  left: 50%; top: 50%;
  width: 70px; height: 70px;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, var(--chrome-hi), var(--chrome) 45%, var(--chrome-lo) 85%);
  box-shadow: 0 6px 14px rgba(0,0,0,.6), inset 0 0 0 3px rgba(255,255,255,.4);
  font: 400 30px 'Yellowtail', cursive;
  color: #8f1d15;
}
.jb3-base {
  height: 30px;
  margin: 16px -20px -18px;
  border-radius: 0 0 16px 16px;
  background: var(--chrome-bar);
  box-shadow: 0 10px 20px rgba(0,0,0,.6);
}

/* ══ LIGHT SHOW ═══════════════════════════════════════════════════════════
   Coloured beams sweeping behind the mechanism, lit only while a song plays
   and brightening with the music. Paused when silent so it costs nothing.   */
.jb3-lightshow {
  --beat: 0;
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 22%;
  overflow: hidden;
  opacity: 0;
  transition: opacity .9s ease;
  mix-blend-mode: screen;
  pointer-events: none;
}
.jb3.is-playing .jb3-lightshow { opacity: calc(.30 + var(--beat) * .70); }
.jb3-lightshow i {
  position: absolute;
  left: 50%; top: -14%;
  width: 30%; height: 150%;
  margin-left: -15%;
  transform-origin: 50% 0;
  clip-path: polygon(44% 0, 56% 0, 100% 100%, 0 100%);
  filter: blur(7px);
  animation: jb3-beam 6s ease-in-out infinite alternate;
  animation-play-state: paused;
}
.jb3.is-playing .jb3-lightshow i { animation-play-state: running; }
.jb3-lightshow i:nth-child(1) { background: linear-gradient(180deg, rgba(255,60,60,.60), transparent 72%);  animation-duration: 5.2s; animation-delay: -0.4s; }
.jb3-lightshow i:nth-child(2) { background: linear-gradient(180deg, rgba(255,170,40,.55), transparent 72%); animation-duration: 6.8s; animation-delay: -1.9s; animation-direction: alternate-reverse; }
.jb3-lightshow i:nth-child(3) { background: linear-gradient(180deg, rgba(90,255,140,.50), transparent 72%); animation-duration: 7.9s; animation-delay: -3.1s; }
.jb3-lightshow i:nth-child(4) { background: linear-gradient(180deg, rgba(60,190,255,.55), transparent 72%); animation-duration: 6.1s; animation-delay: -2.2s; animation-direction: alternate-reverse; }
.jb3-lightshow i:nth-child(5) { background: linear-gradient(180deg, rgba(190,90,255,.55), transparent 72%); animation-duration: 8.6s; animation-delay: -5.0s; }
.jb3-lightshow i:nth-child(6) { background: linear-gradient(180deg, rgba(255,80,190,.50), transparent 72%); animation-duration: 5.7s; animation-delay: -0.9s; animation-direction: alternate-reverse; }
@keyframes jb3-beam {
  from { transform: rotate(-42deg) scaleY(.86); }
  to   { transform: rotate( 42deg) scaleY(1.12); }
}

/* Slow drift of light specks, like a mirror ball across the back wall */
.jb3-sparkle {
  --beat: 0;
  position: absolute;
  left: -10%; right: -10%; top: 0; bottom: 24%;
  opacity: 0;
  transition: opacity 1s ease;
  mix-blend-mode: screen;
  pointer-events: none;
  background:
    radial-gradient(circle at 12% 22%, rgba(255,255,255,.55) 0 1.5px, transparent 2px),
    radial-gradient(circle at 34% 12%, rgba(255,220,180,.50) 0 1.6px, transparent 2px),
    radial-gradient(circle at 58% 28%, rgba(180,230,255,.50) 0 1.4px, transparent 2px),
    radial-gradient(circle at 78% 16%, rgba(255,255,255,.45) 0 1.6px, transparent 2px),
    radial-gradient(circle at 22% 52%, rgba(255,180,220,.45) 0 1.4px, transparent 2px),
    radial-gradient(circle at 68% 58%, rgba(255,255,255,.40) 0 1.5px, transparent 2px),
    radial-gradient(circle at 88% 44%, rgba(200,255,220,.45) 0 1.4px, transparent 2px);
  animation: jb3-drift 22s linear infinite;
  animation-play-state: paused;
}
.jb3.is-playing .jb3-sparkle { opacity: calc(.25 + var(--beat) * .5); animation-play-state: running; }
@keyframes jb3-drift { to { transform: translateX(10%) translateY(-4%); } }

/* ══ DETAIL PASS ══════════════════════════════════════════════════════════
   Edge beading, bevels, fasteners and engraving, so each panel reads as a
   moulded part with a lit edge rather than a flat rectangle.                */

/* Arch: chrome bullnose over the wood, with a shadow gap inside it */
.jb3-arch::before,
.jb3-arch::after {
  content: "";
  position: absolute;
  border-radius: inherit;
  pointer-events: none;
}
.jb3-arch::before {
  inset: 0;
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.22),
    inset 0 0 0 4px rgba(0,0,0,.55),
    inset 0 0 0 6px rgba(255,255,255,.10),
    inset 0 3px 8px rgba(255,255,255,.07);
}
.jb3-arch::after {
  inset: 14px 14px 0;
  box-shadow: inset 0 0 26px rgba(0,0,0,.75);
}

/* Cabinet body: grain sheen, edge beading, lit top seam */
.jb3-body::before,
.jb3-body::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
.jb3-body::before {
  background:
    linear-gradient(180deg, rgba(255,235,205,.13) 0, transparent 90px),
    radial-gradient(ellipse 120% 40% at 50% 0%, rgba(255,200,140,.10), transparent 70%);
}
.jb3-body::after {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 2px 0 0 rgba(0,0,0,.45),
    inset -2px 0 0 rgba(0,0,0,.45),
    inset 0 -2px 0 rgba(0,0,0,.5);
}

/* Fasteners */
.jb3-screw {
  position: absolute;
  width: 11px; height: 11px;
  border-radius: 50%;
  background:
    linear-gradient(115deg, rgba(0,0,0,.65) 0 46%, transparent 46% 54%, rgba(0,0,0,.65) 54%),
    radial-gradient(circle at 36% 32%, #fdfefe, #aab6c4 46%, #5a6472 78%, #2c333d);
  box-shadow: 0 1px 2px rgba(0,0,0,.7), inset 0 0 0 1px rgba(0,0,0,.35);
  z-index: 4;
}
.jb3-screw--tl { left: 9px;  top: 9px; }
.jb3-screw--tr { right: 9px; top: 9px; }
.jb3-screw--bl { left: 9px;  bottom: 9px; }
.jb3-screw--br { right: 9px; bottom: 9px; }

/* Bubble tubes: chrome end caps */
.jb3-cap {
  position: absolute;
  left: -2px; right: -2px;
  height: 14px;
  border-radius: 5px;
  background: var(--chrome-bar);
  box-shadow: 0 2px 5px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.8);
  z-index: 3;
}
.jb3-cap--t { top: -4px; }
.jb3-cap--b { bottom: -4px; }

/* Nameplate: moulded chrome bezel around the lit lettering */
.jb3-nameplate::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 9px;
  background: var(--chrome-bar);
  z-index: -1;
  box-shadow: 0 5px 12px rgba(0,0,0,.6);
}
.jb3-sub { text-shadow: 0 1px 0 rgba(0,0,0,.85), 0 0 8px rgba(255,150,60,.45); }

/* Amplifier: brushed face, moulded bezel, engraved badge */
.jb3-amp::before {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 8px;
  pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.035) 0 1px, transparent 1px 3px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.18),
    inset 0 -1px 0 rgba(0,0,0,.7),
    inset 0 0 22px rgba(0,0,0,.55);
}
.jb3-amp-badge {
  padding: 3px 12px;
  border-radius: 3px;
  background: linear-gradient(180deg, #0d1014, #191d23);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 0 rgba(255,255,255,.06);
  color: #e6cfa6;
  text-shadow: 0 1px 0 #000;
}

/* Title-strip window: mitred chrome frame, paper texture, embossed codes */
.jb3-window::before {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--chrome-hi), var(--chrome-lo) 28%, var(--chrome) 50%, var(--chrome-lo) 72%, var(--chrome-hi));
  z-index: -1;
  box-shadow: 0 4px 10px rgba(0,0,0,.6);
}
.jb3-grid .csd-jbx-tab {
  background-image:
    linear-gradient(180deg, var(--strip-red) 0 3px, transparent 3px 5px, var(--strip-red) 5px 6px, transparent 6px),
    linear-gradient(0deg,   var(--strip-blue) 0 3px, transparent 3px 5px, var(--strip-blue) 5px 6px, transparent 6px),
    repeating-linear-gradient(112deg, rgba(150,120,70,.05) 0 2px, transparent 2px 5px),
    linear-gradient(180deg, #fbf4e0, var(--paper) 55%, #e6d9b6);
  box-shadow:
    0 2px 0 rgba(0,0,0,.45),
    0 3px 6px rgba(0,0,0,.35),
    inset 0 1px 0 rgba(255,255,255,.75),
    inset 0 -1px 0 rgba(120,95,50,.35);
}
.jb3-code {
  background-image: linear-gradient(180deg, #c63a2f, var(--strip-red) 55%, #8d1a14);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 -1px 0 rgba(0,0,0,.4), 1px 0 2px rgba(0,0,0,.25);
  text-shadow: 0 1px 0 rgba(0,0,0,.55);
}
.jb3-thumb { box-shadow: 0 0 0 1px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.3); }

/* Selector keys: a key bed with wells, crisper key mouldings */
.jb3-keys {
  padding: 9px 12px;
  border-radius: 9px;
  background: linear-gradient(180deg, #1a1e24, #0c0f13);
  box-shadow: inset 0 2px 6px rgba(0,0,0,.8), inset 0 0 0 1px rgba(255,255,255,.06), 0 1px 0 rgba(255,255,255,.05);
}
.jb3-key {
  background-image: linear-gradient(180deg, #ffffff 0%, #e2e8ee 26%, #c2cdd9 52%, #93a0af 78%, #7b8796 100%);
  box-shadow:
    0 4px 0 #414a57,
    0 6px 10px rgba(0,0,0,.55),
    inset 0 1px 0 #fff,
    inset 1px 0 0 rgba(255,255,255,.7),
    inset -1px 0 0 rgba(0,0,0,.25),
    inset 0 -2px 3px rgba(0,0,0,.28);
  text-shadow: 0 1px 0 rgba(255,255,255,.65);
}

/* Grille: woven cloth, bevelled slats, embossed emblem */
.jb3-grille::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(45deg,  rgba(0,0,0,.18) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(-45deg, rgba(255,220,180,.05) 0 1px, transparent 1px 3px);
  box-shadow: inset 0 0 40px rgba(0,0,0,.75);
}
.jb3-slats i {
  background-image: linear-gradient(90deg, #6d7886 0%, #f2f6fa 22%, #b9c4d0 48%, #58626f 74%, #e9eff5 100%);
  box-shadow: 3px 0 8px rgba(0,0,0,.55), inset 0 0 0 1px rgba(0,0,0,.3);
}
.jb3-emblem {
  --punch: 0;
  text-shadow: 0 1px 0 rgba(255,255,255,.65), 0 -1px 0 rgba(0,0,0,.35),
               0 0 calc(var(--punch) * 22px) rgba(255,170,70, calc(var(--punch) * .9));
  box-shadow:
    0 6px 14px rgba(0,0,0,.65),
    inset 0 0 0 3px rgba(255,255,255,.45),
    inset 0 -4px 10px rgba(0,0,0,.35),
    inset 0 4px 10px rgba(255,255,255,.5);
}

/* Turntable: strobe dots round the platter rim */
.jb3-platter::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: repeating-conic-gradient(rgba(255,255,255,.5) 0 1.1deg, transparent 1.1deg 3.6deg);
  -webkit-mask: radial-gradient(circle, transparent 0 88%, #000 88.5%);
          mask: radial-gradient(circle, transparent 0 88%, #000 88.5%);
  opacity: .5;
}

/* Base: kick plate with a moulded lip */
.jb3-base {
  box-shadow: 0 10px 20px rgba(0,0,0,.6), inset 0 2px 0 rgba(255,255,255,.7), inset 0 -3px 6px rgba(0,0,0,.45);
}

/* ══ TURNTABLE DETAIL ═════════════════════════════════════════════════════
   The parts a real deck has, laid out in the same rotated plane as the platter
   so they share its perspective. All of it is static furniture except the arm
   itself: nothing here touches --arm, the wobble wrapper or the flying record,
   so the mechanism animations are untouched.                                 */

/* Plinth: moulded edge and a brushed top */
.jb3-deck::before {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 14px;
  pointer-events: none;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -2px 0 rgba(0,0,0,.65),
    inset 0 0 26px rgba(0,0,0,.5);
}

/* Felt mat under the record */
.jb3-platter::before {
  content: "";
  position: absolute;
  inset: 16px;
  border-radius: 50%;
  background:
    repeating-radial-gradient(circle, rgba(255,255,255,.035) 0 2px, transparent 2px 5px),
    radial-gradient(circle, #23262b 0 62%, #191c20 100%);
  box-shadow: inset 0 0 18px rgba(0,0,0,.75);
}

/* Pivot: gimbal housing above the bearing */
.jb3-gimbal {
  position: absolute;
  left: 322px; top: 42px;
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 5px;
  background: linear-gradient(145deg, #e7edf3, #97a3b1 45%, #4d5765);
  box-shadow: 0 3px 6px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.85);
  z-index: 3;
}

/* Arm rest: chrome cradle the arm parks in */
.jb3-armrest {
  position: absolute;
  left: 306px; top: 232px;
  width: 34px; height: 16px;
  border-radius: 4px 4px 7px 7px;
  background: linear-gradient(180deg, #d8e0e8, #7c8794 60%, #39414d);
  box-shadow: 0 3px 6px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.8);
}
.jb3-armrest::after {                     /* the clip */
  content: "";
  position: absolute;
  left: 50%; top: -5px;
  width: 16px; height: 7px;
  margin-left: -8px;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, #f2f6fa, #8d98a6);
}

/* Cue lever */
.jb3-cue {
  position: absolute;
  left: 296px; top: 92px;
  width: 9px; height: 30px;
  border-radius: 4px;
  background: linear-gradient(90deg, #4a5360, #dfe6ed 45%, #79838f);
  box-shadow: 0 2px 5px rgba(0,0,0,.6);
}
.jb3-cue::after {
  content: "";
  position: absolute;
  left: -4px; bottom: -6px;
  width: 17px; height: 10px;
  border-radius: 3px;
  background: linear-gradient(180deg, #2b3038, #15181d);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.2);
}

/* Anti-skate dial with its counterweight thread */
.jb3-antiskate {
  position: absolute;
  left: 350px; top: 96px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 32%, #f2f6fa, #9aa5b3 55%, #444d59);
  box-shadow: 0 2px 4px rgba(0,0,0,.6), inset 0 0 0 1px rgba(0,0,0,.3);
}
.jb3-antiskate::after {
  content: "";
  position: absolute;
  left: 50%; top: 14px;
  width: 1px; height: 16px;
  background: rgba(255,255,255,.45);
}

/* Speed and start controls */
.jb3-knob {
  position: absolute;
  width: 28px; height: 28px;
  border-radius: 50%;
  background:
    repeating-conic-gradient(rgba(0,0,0,.35) 0 3deg, transparent 3deg 9deg),
    radial-gradient(circle at 38% 34%, #6d7683, #333a44 60%, #1b1f25);
  box-shadow: 0 3px 7px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.28);
}
.jb3-knob i {
  position: absolute;
  left: 50%; top: 4px;
  width: 2px; height: 9px;
  margin-left: -1px;
  border-radius: 1px;
  background: #e9eef4;
}
.jb3-knob--speed { left: 344px; top: 190px; }
.jb3-knob--start { left: 344px; top: 236px; }

/* Strobe lamp beside the platter rim */
.jb3-strobe {
  --beat: 0;
  position: absolute;
  left: 292px; top: 168px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle, #ffdca6, #ff9d2e 55%, #7a3c00);
  box-shadow: 0 0 calc(4px + var(--beat) * 12px) rgba(255,160,50,.85);
}

/* ── Tonearm parts ────────────────────────────────────────────────────── */

/* Counterweight: machined ridges */
.jb3-arm-weight {
  background-image:
    repeating-linear-gradient(90deg, rgba(0,0,0,.28) 0 1px, transparent 1px 4px),
    linear-gradient(90deg, #2f353d, #dfe7ee 42%, #7d8895 72%, #353c45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 3px 6px rgba(0,0,0,.5);
}

/* VTA collar where the tube leaves the pivot */
.jb3-arm-collar {
  position: absolute;
  left: -6px; top: -8px;
  width: 12px; height: 15px;
  border-radius: 3px;
  background: linear-gradient(90deg, #414a56, #eef3f8 45%, #8a95a2);
  box-shadow: 0 2px 4px rgba(0,0,0,.5);
}

/* Tube: brushed metal with a lit edge */
.jb3-arm-tube {
  background-image: linear-gradient(90deg, #39404a 0%, #cfd8e1 28%, #ffffff 44%, #aab5c1 62%, #4d5663 88%, #2b323a 100%);
  box-shadow: 4px 8px 8px rgba(0,0,0,.45), inset 0 0 0 .5px rgba(0,0,0,.35);
}

/* Headshell: finger lift, cartridge body, stylus. The element's box is
   unchanged, so the arm-angle maths that finds the stylus still holds. */
.jb3-arm-head {
  background-image: linear-gradient(90deg, #0f1115 0%, #3d434c 38%, #545c67 52%, #1a1e24 100%);
  box-shadow: 0 0 0 1px var(--chrome), 0 3px 6px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.25);
}
.jb3-fingerlift {
  position: absolute;
  right: -7px; top: 2px;
  width: 9px; height: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, #eef3f8, #8c96a3);
}
.jb3-cart {
  position: absolute;
  left: 3px; right: 3px; top: 12px;
  height: 15px;
  border-radius: 2px;
  background: linear-gradient(180deg, #d24b2f, #8d2a18);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 1px 2px rgba(0,0,0,.5);
}
.jb3-stylus {
  position: absolute;
  left: 50%; bottom: -5px;
  width: 1.5px; height: 7px;
  margin-left: -.75px;
  background: linear-gradient(180deg, #f6fbff, #93a0ad);
  box-shadow: 0 0 3px rgba(255,255,255,.6);
}
/* ══ A SOLID DECK, NOT A FLAT PLATE ═══════════════════════════════════════
   The plinth was one rotated rectangle, so it read as a stretched shape. It is
   now a box: the top plate plus a front face and two sides standing up out of
   the plane, with the platter given a rim so it has depth too. The tilt is
   eased off and the perspective shortened, which reduces the horizontal
   stretch and makes the whole deck read as an object.
   Geometry inside the plane is unchanged, so the arm maths and the flying
   record still line up exactly.                                             */
.jb3-turntable { perspective: 760px; perspective-origin: 50% -10%; }
.jb3-deck { transform: rotateX(52deg); }

.jb3-deck-front,
.jb3-deck-side {
  position: absolute;
  background: linear-gradient(180deg, #2a2f37 0%, #171a20 45%, #0c0e12 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), inset 0 -2px 6px rgba(0,0,0,.7);
}
/* Front face: hinged down from the deck's front edge, so it stands up */
.jb3-deck-front {
  left: 0; right: 0; bottom: 0;
  height: 34px;
  border-radius: 0 0 14px 14px;
  transform-origin: 50% 100%;
  transform: rotateX(90deg);     /* hinges DOWN below the top surface */
}
.jb3-deck-front::after {                  /* chrome lip along the top edge */
  content: "";
  position: absolute;
  left: 8px; right: 8px; top: -2px;
  height: 4px;
  border-radius: 2px;
  background: var(--chrome-bar);
  opacity: .85;
}
/* Sides: hinged out from the left and right edges */
.jb3-deck-side {
  top: 12px; bottom: 0;
  width: 34px;
  background: linear-gradient(90deg, #232830, #101318);
}
.jb3-deck-side--l { left: 0;  transform-origin: 100% 50%; transform: rotateY(-90deg); }
.jb3-deck-side--r { right: 0; transform-origin: 0 50%;    transform: rotateY(90deg); }

/* Platter rim: a second disc sunk below the top surface reads as thickness */
.jb3-platter-rim {
  position: absolute;
  left: 22px; top: 22px;
  width: 256px; height: 256px;
  border-radius: 50%;
  background: linear-gradient(180deg, #4b535f, #12151a);
  transform: translateZ(-16px);
  box-shadow: 0 16px 26px rgba(0,0,0,.75);
}

/* ══ COVER ART ON DISPLAY ═════════════════════════════════════════════════
   The blank space to the left of the deck now holds the sleeve of whatever is
   on the platter, angled towards the viewer on a small stand.               */
/* The stage holds the position and supplies the perspective the sleeve moves
   in; the sleeve itself is free to be transformed when records change. */
.jb3-sleeve-stage {
  position: absolute;
  left: 5%;
  bottom: 34px;
  width: 168px; height: 168px;
  perspective: 1000px;
  perspective-origin: 50% 40%;
  z-index: 4;                             /* in front of the glass and its frame */
}
.jb3-sleeve {
  position: relative;
  width: 100%; height: 100%;
  perspective: 700px;
  will-change: transform;
}
.jb3-sleeve-art,
.jb3-sleeve-frame,
.jb3-sleeve-gloss {
  position: absolute;
  inset: 0;
  border-radius: 3px;
  transform: rotateY(24deg) rotateX(4deg);
  transform-origin: 100% 50%;
}
.jb3-sleeve-art {
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 2;                             /* above the frame, never behind it */
  box-shadow:
    0 22px 30px rgba(0,0,0,.7),
    0 0 0 1px rgba(0,0,0,.6),
    inset 0 0 40px rgba(0,0,0,.35);
}
.jb3-sleeve-frame {
  inset: -6px;
  z-index: 1;
  background: linear-gradient(140deg, #4a3320, #241608 55%, #3a2413);
  box-shadow: inset 0 1px 0 rgba(255,220,170,.35), inset 0 -2px 6px rgba(0,0,0,.8), 0 18px 26px rgba(0,0,0,.6);
}
.jb3-sleeve-gloss {
  background: linear-gradient(118deg, rgba(255,255,255,.26) 0%, rgba(255,255,255,.05) 26%, transparent 46%);
  pointer-events: none;
  z-index: 3;
}
.jb3-sleeve-shadow {
  position: absolute;
  left: -6%; right: 6%; bottom: -14px;
  height: 20px;
  background: radial-gradient(ellipse at center, rgba(0,0,0,.75), transparent 70%);
  filter: blur(4px);
}

@media (max-width: 900px) {
  .jb3-sleeve-stage { width: 120px; height: 120px; left: 3%; bottom: 26px; }
}
@media (max-width: 760px) {
  .jb3-sleeve-stage { display: none; }
}
/* ══ TWO COMPARTMENTS ═════════════════════════════════════════════════════
   The dome is now read as a real cabinet interior split at the chrome bar:

     above it  a glazed display case - ribbed back wall, the record magazine,
               the coloured lights - all seen THROUGH glass
     below it  an open mechanism bay where the deck and the cover art sit,
               in front of the glass

   --jb3-shelf is the height of the upper case, i.e. where the chrome bar sits.
   Everything keys off it, so the ribbing, the glass and the bay all stop on the
   same line instead of running past each other.                             */
.jb3-dome { --jb3-shelf: 272px; }

/* Upper case: ribbing stops exactly at the bar */
.jb3-backwall {
  top: 0; bottom: auto;
  height: var(--jb3-shelf);
  background:
    linear-gradient(180deg, rgba(0,0,0,.74) 0%, rgba(0,0,0,.12) 42%, rgba(0,0,0,.5) 100%),
    repeating-linear-gradient(90deg,
      rgba(255,255,255,.055) 0 2px,
      rgba(0,0,0,.30) 2px 7px,
      rgba(255,255,255,.02) 7px 11px,
      rgba(0,0,0,.22) 11px 16px),
    linear-gradient(180deg, #4b2a16 0%, #2a1509 70%, #160a04 100%);
  box-shadow: inset 0 -14px 22px rgba(0,0,0,.65);
}

/* Glass over the case: reflections, a cool tint, and the edge highlights of a
   real pane. Sits above the records but stops at the bar, so the deck and the
   sleeve below are unmistakably in front of it. */
.jb3-case {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--jb3-shelf);
  pointer-events: none;
  z-index: 2;
  background:
    linear-gradient(103deg,
      rgba(255,255,255,.14) 0%,
      rgba(255,255,255,.05) 12%,
      rgba(255,255,255,0) 26%,
      rgba(255,255,255,0) 58%,
      rgba(200,230,255,.07) 70%,
      rgba(255,255,255,.12) 82%,
      rgba(255,255,255,0) 92%),
    linear-gradient(180deg, rgba(140,190,235,.10), rgba(90,140,190,.03) 40%, rgba(0,0,0,.10));
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(255,255,255,.14),
    inset 0 -22px 30px rgba(0,0,0,.30);
}
.jb3-case::after {                        /* a soft bloom where the glass curves */
  content: "";
  position: absolute;
  left: 6%; right: 6%; top: 4%;
  height: 46%;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 0%, rgba(255,255,255,.10), transparent 70%);
}

/* The chrome bar: now the frame at the bottom of the glass, full width */
.jb3-divider {
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--jb3-shelf) - 7px);
  height: 16px;
  z-index: 3;
  background:
    linear-gradient(180deg,
      #f7fbff 0%, #cfd9e4 22%, #8d99a7 46%,
      #4c5663 54%, #9aa6b4 72%, #e8eef5 100%);
  box-shadow:
    0 6px 14px rgba(0,0,0,.65),
    0 -2px 8px rgba(0,0,0,.45),
    inset 0 1px 0 rgba(255,255,255,.95);
}
.jb3-divider::before,
.jb3-divider::after {                     /* mounting bolts at either end */
  content: "";
  position: absolute;
  top: 50%;
  width: 7px; height: 7px;
  margin-top: -3.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 32%, #fff, #97a3b1 55%, #3c4450);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
}
.jb3-divider::before { left: 3%; }
.jb3-divider::after  { right: 3%; }

/* Lower bay: no ribbing, a smoother machined recess the deck stands in */
.jb3-floor {
  top: var(--jb3-shelf);
  bottom: 0;
  height: auto;
  /* Lit bay. The deck and the album sleeve are both dark objects, and against
     the old near-black recess they had nothing to read against. This is the
     warm lamp wash a real cabinet has under its display shelf. */
  background:
    radial-gradient(ellipse 78% 68% at 50% 12%, rgba(255,203,132,.40), transparent 74%),
    radial-gradient(ellipse 50% 40% at 50% 96%, rgba(255,170,90,.16), transparent 70%),
    linear-gradient(180deg, rgba(0,0,0,.26) 0%, rgba(0,0,0,.02) 30%, rgba(0,0,0,.30) 80%, rgba(0,0,0,.55) 100%),
    repeating-linear-gradient(0deg, rgba(255,255,255,.035) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, #9a6a3d 0%, #6d4623 58%, #43270f 100%);
  box-shadow: inset 0 14px 22px rgba(0,0,0,.42), inset 0 -8px 18px rgba(0,0,0,.45);
}

/* The old shelf rail is replaced by the divider */
.jb3-rail { display: none; }

/* Lights fill the case: over the records (so the beams wash across them) but
   still under the glass pane and its chrome frame. */
.jb3-lightshow { bottom: auto; height: var(--jb3-shelf); z-index: 2; }
.jb3-sparkle   { bottom: auto; height: var(--jb3-shelf); z-index: 2; }

@media (max-width: 760px) {
  .jb3-dome { --jb3-shelf: 248px; }
}
/* ── Responsive ────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .jb3 { padding: 1.6rem .5rem 3.5rem; }
  .jb3-arch { padding: 14px 14px 0; border-radius: 50% 50% 0 0 / 150px 150px 0 0; }
  .jb3-dome { height: 372px; border-radius: 50% 50% 6px 6px / 130px 130px 6px 6px; }
  .jb3-marquee { bottom: 0; max-width: 72%; font-size: 9px; }
  .jb3-dome-head { top: 34px; width: 86%; }
  .jb3-h1 { font-size: 24px; }
  .jb3-lede { font-size: 8.5px; letter-spacing: .16em; }
  /* The magazine hangs from the bottom of this box, so its top position is
     what pulls the records up under the title. */
  .jb3-rack-wrap { top: 46px; transform: scale(.78); transform-origin: 50% 100%; }
  .jb3-turntable { transform: scale(.72); transform-origin: 50% 100%; }
  .jb3-body { padding: 0 20px 16px; }
  .jb3-pilaster { width: 8px; }
  .jb3-pilaster--l { left: 5px; } .jb3-pilaster--r { right: 5px; }
  .jb3-selector { grid-template-columns: minmax(0, 1fr); }
  .jb3-tube { display: none; }
  .jb3-strips { padding: 8px; }
  .jb3-grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: repeat(var(--rows, 12), var(--strip-h)); --strip-h: 46px; }
  .jb3-grille { height: 120px; }
  .jb3-side { display: none; }

  /* Selector keypad: one row that cannot wrap. A wrapping flexbox dropped the
     next-page arrow onto its own line at phone width. Grid pins FX, both
     arrows and the page label in place, and the letters take what is left and
     scroll sideways if a longer catalogue ever needs more than four pages. */
  .jb3-keys {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;   /* prev, letters, next */
    align-items: center;
    gap: 5px;
    padding: 8px;
  }
  .jb3-letters {
    gap: 5px;
    justify-content: center;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
  }
  .jb3-letters::-webkit-scrollbar { display: none; }
  .jb3-letters .jb3-key { scroll-snap-align: center; }
  .jb3-key { min-width: 36px; height: 40px; padding: 0 6px; font-size: 16px; }
  .jb3-key--fx { min-width: 34px; font-size: 10px; letter-spacing: .06em; }
  .jb3-key--arrow { min-width: 36px; font-size: 12px; }
  .jb3-pageinfo { grid-column: 1 / -1; margin-top: 2px; font-size: 9px; letter-spacing: .22em; }
}

@media (max-width: 380px) {
  .jb3-keys { gap: 4px; padding: 7px 6px; }
  .jb3-key { min-width: 33px; padding: 0 4px; font-size: 15px; }
  .jb3-key--fx { min-width: 31px; font-size: 9px; }
  .jb3-key--arrow { min-width: 32px; }
}

/* Reduced motion calms the cabinet: no tilt, sweep, bubbles or blinking.
   The record mechanism, spin and colour-cycling lights stay (see JS). */
@media (prefers-reduced-motion: reduce) {
  .jb3-cabinet { transition: none; }
  .jb3-glass::after { animation: none; display: none; }
  .jb3.is-playing .jb3-marquee-dot { animation: none; }
}

/* ══ MOBILE: VERTICAL SPACE ═══════════════════════════════════════════════
   A phone screen is all height, so the cabinet trims everything that is only
   there to breathe: shorter dome and grille, tighter chrome bands, smaller
   strips. Touch targets (strips, keys, transport) keep their size. Scoped to
   .jb3, so nothing here touches the live /music page.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {
  .jb3 { padding: 1rem .5rem 1.8rem; }

  /* Dome: the mechanism stays legible at a shorter height */
  .jb3-arch { padding: 10px 10px 0; }
  /* Upper case tightened: the title sat well clear of the record magazine and
     the empty band between them was the tallest thing on the screen. The head
     moves up and loses its internal padding, the magazine comes up to meet it,
     and the case (and so the whole cabinet) is shorter by the difference. */
  .jb3-dome { height: 266px; --jb3-shelf: 170px; }
  .jb3-marquee { bottom: 0; padding: 3px 11px; }
  .jb3-dome-head { top: 26px; }
  .jb3-h1 { margin: 3px 0 2px; }
  .jb3-lede { font-size: 8.5px; line-height: 1.35; }
  .jb3-eyebrow { font-size: 8px; letter-spacing: .28em; }
  .jb3-rack-wrap { top: 46px; }   /* wins over the earlier mobile rule; magazine hangs from this box's bottom */
  /* The deck slides right and shrinks so the album cover can take the empty
     space on the left, the way it sits on desktop. It was hidden on phones
     because a centred deck left nowhere to put it.

     Everything here is proportional, not fixed pixels: a fixed 40px shift and
     a 96px cover left only a 1px gap at 360px wide (a Galaxy at a larger
     display-size setting), so the deck appeared to sit on the artwork. The
     translate percentage is of the deck's own box, so the gap scales with the
     screen. */
  .jb3-turntable { transform: translateX(12%) scale(.42); }
  .jb3-sleeve-stage {
    display: block;
    left: 4%;
    bottom: 22px;
    width: clamp(72px, 24vw, 120px);
    height: clamp(72px, 24vw, 120px);
  }

  /* Big phones and small tablets have room for a larger deck */
  @media (min-width: 481px) {
    .jb3-turntable { transform: translateX(6%) scale(.62); }
    .jb3-sleeve-stage { width: clamp(120px, 20vw, 150px); height: clamp(120px, 20vw, 150px); }
  }

  /* Chrome nameplate */
  .jb3-nameplate { padding: 7px 14px 6px; }
  .jb3-script { font-size: clamp(26px, 8vw, 34px); }
  .jb3-sub { font-size: 8px; letter-spacing: .2em; }

  /* Title strips */
  .jb3-body { padding: 0 16px 12px; }
  .jb3-selector { margin-top: 12px; }
  .jb3-strips { padding: 7px; }
  .jb3-window { padding: 7px; }
  .jb3-grid { --strip-h: 44px; gap: 5px; }
  .csd-jbx-search { margin-bottom: 7px; }
  .csd-jbx-search-input { height: 34px; }
  .jb3-code { font-size: 15px; width: 40px; margin: 5px 0; }

  /* Amplifier: the panel tightens, the controls do not shrink */
  .jb3-amp { margin-top: 12px; padding: 8px 0 10px; }
  .jb3-amp-top { margin-bottom: 7px; gap: 10px; }
  .jb3-vt { width: 15px; height: 24px; }
  .jb3-amp-badge { font-size: 8px; letter-spacing: .2em; }
  .jb3 .csd-rack { padding: .45rem .4rem .5rem; gap: .3rem .4rem; }
  .jb3 .csd-center { gap: .45rem; padding: .2rem .5rem .45rem; margin-top: 0; }
  .jb3 .csd-lower { margin-top: .45rem; gap: .4rem; }
  .jb3 .csd-eq { height: 42px; }
  .jb3 .csd-ctrl { margin-top: .35rem; }

  /* Grille + base */
  .jb3-grille { height: 78px; margin-top: 12px; }
  .jb3-emblem { width: 48px; height: 48px; font-size: 21px; }
  .jb3-base { height: 20px; margin-top: 10px; }
}

/* The VU face carries "Chad Sanders Official" printed on the right dial. On a
   phone that dial is small enough that the lettering crowds the needle, so the
   name moves out to its own line under both meters - in the gap that was
   already there above the transport buttons, which do not move. */
@media (max-width: 580px) {
  .jb3 .csd-brand { display: none; }
  /* The brand line takes its height out of the panel's own padding, so the
     transport buttons stay exactly where they were. */
  .jb3 .csd-center { padding-top: 0; }
  .jb3 .csd-rack {
    grid-template-areas:
      "vuL vuR"
      "brand brand"
      "center center";
  }
  .jb3 .csd-rack::after {
    content: "Chad Sanders Official";
    display: block;
    grid-area: brand;
    /* cs-player.css uses ::after as an absolutely positioned screw head on the
       chassis. Put it back in the grid flow, or the brand row collapses to 0
       and the text floats over the transport row. */
    position: static;
    width: auto; height: auto;
    top: auto; right: auto;
    background: none;
    box-shadow: none;
    border-radius: 0;
    pointer-events: none;
    margin: 1px 0 -1px;
    text-align: center;
    font: 700 7.5px/1 'Orbitron', sans-serif;
    letter-spacing: .3em;
    text-transform: uppercase;
    color: #8f9bab;
    text-shadow: 0 1px 0 rgba(0,0,0,.8);
  }
}

/* ── "Next" under the song selection ──────────────────────────────────────
   A plain labelled way to reach the next page of titles, for anyone who does
   not read the little chrome arrows as controls. It names the page it will
   bring up and wraps round to A after the last one. */
.jb3-nextpage {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 9px auto 0;
  padding: 0 16px;
  height: 34px;
  border: 0;
  border-radius: 17px;
  background: linear-gradient(180deg, #2a3038, #171a20);
  box-shadow:
    inset 0 0 0 1px rgba(255,190,110,.35),
    inset 0 1px 0 rgba(255,255,255,.10),
    0 3px 8px rgba(0,0,0,.5);
  color: var(--amber);
  font: 700 10px 'Orbitron', sans-serif;
  letter-spacing: .26em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s, box-shadow .2s, transform .1s;
}
.jb3-nextpage[hidden] { display: none; }
.jb3-nextpage:hover {
  background: linear-gradient(180deg, #343b45, #1d2129);
  box-shadow: inset 0 0 0 1px var(--amber), inset 0 1px 0 rgba(255,255,255,.12), 0 4px 12px rgba(0,0,0,.55);
}
.jb3-nextpage:active { transform: translateY(1px); }
.jb3-nextpage:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.jb3-nextpage-let {
  display: inline-flex;
  align-items: center; justify-content: center;
  min-width: 20px; height: 20px;
  padding: 0 5px;
  border-radius: 5px;
  background: linear-gradient(180deg, #fff1c9, #ffc35a 55%, #e08a12);
  color: #3a2406;
  font: 600 14px/1 'Oswald', sans-serif;
  letter-spacing: 0;
}
.jb3-nextpage-arrow { font-size: 9px; opacity: .8; }

@media (max-width: 760px) {
  .jb3-nextpage { height: 38px; margin-top: 8px; letter-spacing: .2em; }
}

/* ── Music page only: drop the wordmark from the bar on phones ────────────
   The cabinet carries the name on its own nameplate, so repeating "Chad
   Sanders Official" in the bar above it is just height. This stylesheet only
   loads on the music page, and body.page-music keeps it to that page even so.
   768px matches where main.css swaps the links for the hamburger. The menu
   still has Home, so nothing becomes unreachable. */
@media (max-width: 768px) {
  body.page-music .site-header .nav-logo { display: none; }
}

/* ── Slideshow in the bay, right of the deck ──────────────────────────────
   A lit display panel that cross-fades through the gallery. Purely
   decorative: aria-hidden, no controls, nothing to click. Sits between the
   tonearm and the cabinet wall, angled to face the viewer the way the album
   sleeve on the other side does. Desktop only - on a phone the bay has no
   spare width (see the mobile block below). */
/* The gallery now lights the back wall of the display case instead of sitting
   in a frame: dim, slightly blurred and masked away at the edges, so it reads
   as a lit backdrop behind the records rather than a picture competing with
   them. Sits above the ribbed wall, below the records and the glass. */
.jb3-slides {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--jb3-shelf);
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: 1;
  filter: saturate(1.02) contrast(1.02);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 5%, #000 88%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 5%, #000 88%, transparent 100%);
}
.jb3-rack-wrap { z-index: 1; }      /* records stay in front of the backdrop */

/* The ribbed brown wall is what the photos were fighting. With the gallery
   carrying the back of the case, it comes off. */
.jb3-backwall { display: none; }
.jb3-slide {
  position: absolute;
  inset: 0;
  background-size: cover;
  /* Anchored to the top of the frame: centring cropped heads off the photos. */
  background-position: center top;
  opacity: 0;
  transition: opacity 1.6s ease-in-out;
}
.jb3-slide.is-on { opacity: 1; }
.jb3-slides-glass {                 /* only enough shade to hold the title */
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    /* pool of shade under the title, so it holds up over a bright photo */
    radial-gradient(ellipse 62% 42% at 50% 10%, rgba(6,4,2,.80), rgba(6,4,2,.30) 60%, transparent 78%),
    linear-gradient(180deg, rgba(8,5,3,.72) 0%, rgba(8,5,3,.46) 26%, rgba(8,5,3,.10) 46%,
                            rgba(8,5,3,.08) 74%, rgba(8,5,3,.44) 100%);
}

/* Over photographs the type needs its own edge, not just the scrim */
.jb3-dome-head .jb3-h1 { text-shadow: 0 0 18px rgba(0,0,0,.92), 0 2px 5px rgba(0,0,0,.85); }
.jb3-dome-head .jb3-lede,
.jb3-dome-head .jb3-eyebrow { text-shadow: 0 0 10px rgba(0,0,0,.95), 0 1px 3px rgba(0,0,0,.9); }

@media (prefers-reduced-motion: reduce) {
  .jb3-slide { transition-duration: 2.4s; }   /* gentler, still a slow fade */
}

/* The gallery stays on phones. It was hidden back when it was a framed panel
   in the bay with no width to spare; as the back wall of the display case it
   has the whole width and belongs there on every screen. */

/* ── Song details, rolling, in the bay beside the deck ────────────────────
   Whatever is playing, straight from the library. The text is rendered twice
   inside the roll and animated exactly one copy's worth, so the loop meets
   itself - it never blanks or jumps back to the top. Speed is set per song in
   cs-jukebox3d.js from the height of the text, so a long credit list scrolls
   at the same pace as a short one. */
.jb3-info {
  position: absolute;
  left: calc(50% + 205px);          /* clear of the tonearm at any dome width */
  right: 4%;
  /* Sits wholly in the open bay: at 26px its top edge crossed the chrome rail
     and overlapped the glazed case above, which is a different compartment. */
  bottom: 10px;
  aspect-ratio: 4 / 3;
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
  border-radius: 4px;
  background: linear-gradient(180deg, #17100a, #0d0805);
  transform: perspective(900px) rotateY(-16deg);
  transform-origin: 0% 50%;
  box-shadow:
    0 0 0 1px rgba(255,220,170,.22),
    0 0 0 4px rgba(20,12,6,.9),
    0 14px 26px rgba(0,0,0,.6),
    inset 0 0 26px rgba(0,0,0,.5);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
}
.jb3-info-roll {
  position: absolute;
  left: 0; right: 0; top: 0;
  padding: 0 14px;
  will-change: transform;
  animation: jb3-roll var(--roll, 34s) linear infinite;
}
@keyframes jb3-roll {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}
/* The lead-in is a full panel height, so each pass starts with the song name
   rising from the bottom edge rather than already halfway out of the top. It
   lives inside the repeated block, which keeps the loop seamless: the gap is
   part of the pattern, not a one-off offset. Set in px by cs-jukebox3d.js. */
.jb3-info-block { padding: var(--lead, 150px) 0 22px; }
.jb3-info-title {
  margin: 0 0 3px;
  font: 600 15px/1.2 'Oswald', sans-serif;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #ffe6bd;
}
.jb3-info-meta {
  margin: 0 0 9px;
  font: 700 8px/1.4 'Orbitron', sans-serif;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--amber);
}
.jb3-info-desc {
  margin: 0 0 10px;
  font: 400 11.5px/1.65 'Inter', sans-serif;
  color: #e4d4bd;
}
.jb3-info-credits {
  margin: 0;
  font: 400 10.5px/1.6 'Inter', sans-serif;
  color: #b9a88f;
  white-space: pre-line;            /* the admin field is typed line by line */
}
.jb3-info-copy {
  margin: 8px 0 0;
  font: 700 8px/1.4 'Orbitron', sans-serif;
  letter-spacing: .2em;
  color: #8d7c66;
}
.jb3-info-rule {
  height: 1px;
  margin: 12px 0 0;
  background: linear-gradient(90deg, transparent, rgba(255,200,130,.35), transparent);
}

@media (prefers-reduced-motion: reduce) {
  .jb3-info-roll { animation-duration: calc(var(--roll, 34s) * 1.6); }
}

@media (max-width: 760px) {
  .jb3-info { display: none; }      /* no spare width in the bay on a phone */
}

/* ── Song count, riding the chrome divider ───────────────────────────────
   Lifted out of the title block and parked just above the bar, drawn over it
   so the line reads as lettering on the chrome. Absolutely placed in the
   dome, so it changes no layout. --jb3-shelf is where the bar sits. */
.jb3-lede--bar {
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--jb3-shelf) - 21px);
  z-index: 5;
  margin: 0;
  text-align: center;
  color: #f6e6c9;
  text-shadow: 0 1px 3px rgba(0,0,0,.95), 0 0 10px rgba(0,0,0,.9);
  pointer-events: none;
}
@media (max-width: 760px) {
  .jb3-lede--bar { top: calc(var(--jb3-shelf) - 18px); font-size: 8px; letter-spacing: .14em; }
}

/* ── Brushed silver plinth ────────────────────────────────────────────────
   The deck body was near black, which read as a hole under the record. It is
   now a brushed aluminium casing: fine grain across the top, a lighter band
   where the light falls, and darker faces on the front and sides so the box
   still has weight. The platter, the felt and the vinyl are untouched. */
.jb3-deck {
  background:
    /* brush grain */
    repeating-linear-gradient(94deg,
      rgba(255,255,255,.16) 0 1px,
      rgba(255,255,255,.04) 1px 2px,
      rgba(0,0,0,.05) 2px 4px),
    /* sheen across the surface */
    linear-gradient(176deg,
      #f2f5f8 0%, #d7dde4 16%, #b7c0cb 38%, #cdd5de 52%,
      #9ea8b5 72%, #b9c2cd 88%, #8d97a4 100%);
  box-shadow:
    inset 0 0 0 2px rgba(255,255,255,.55),
    inset 0 0 30px rgba(60,70,85,.35);
}
.jb3-deck::before {                       /* inner bevel, now cut for metal */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.85),
    inset 0 -2px 0 rgba(90,100,115,.55),
    inset 0 0 22px rgba(70,80,95,.28);
}
/* The upright faces sit in shadow, so they stay a darker grade of the same
   metal rather than matching the lit top. */
.jb3-deck-front,
.jb3-deck-side {
  background: linear-gradient(180deg, #c9d1da 0%, #97a1ae 42%, #6e7884 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), inset 0 -2px 6px rgba(0,0,0,.45);
}
.jb3-deck-side {
  background: linear-gradient(90deg, #b6bfca, #7b8593);
}

/* ── Matching silver edging ───────────────────────────────────────────────
   The details panel and the album sleeve now wear the same polished frame as
   the deck: a bright top highlight, a brushed silver band, and a dark seam
   that sets it off the cabinet. One treatment, two places, so they read as a
   pair either side of the player. */
.jb3-info {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.35),
    0 0 0 1px rgba(255,255,255,.85),
    0 0 0 4px #a9b3bf,
    0 0 0 5px rgba(28,33,41,.95),
    0 14px 26px rgba(0,0,0,.6),
    inset 0 0 26px rgba(0,0,0,.5);
}
.jb3-sleeve-frame {
  background: linear-gradient(150deg, #eef2f6 0%, #bcc5d0 30%, #8f99a6 58%, #d3dae2 78%, #7f8996 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.9),
    inset 0 -2px 5px rgba(40,48,58,.55),
    0 0 0 1px rgba(28,33,41,.9),
    0 18px 26px rgba(0,0,0,.6);
}

/* ── Speaker grille as the bay's back wall ────────────────────────────────
   The grille moved up out of the lower cabinet and now fills the mechanism
   bay, behind the deck, the album sleeve and the details plaque, so the cloth
   and its beat-driven glow read through the whole player section. The slats
   and the CS emblem are gone: nothing sits in the middle of it any more. */
.jb3-grille--bay {
  position: absolute;
  left: 0; right: 0;
  top: var(--jb3-shelf);
  bottom: 0;
  height: auto;
  margin: 0;
  z-index: 0;                       /* behind every object in the bay */
  border-radius: 0;
  pointer-events: none;
  box-shadow: inset 0 14px 22px rgba(0,0,0,.55), inset 0 -8px 18px rgba(0,0,0,.45);
}
.jb3-grille--bay::before,
.jb3-grille--bay::after { content: none; }   /* frame trim from the old panel */
.jb3-grille--bay .jb3-grille-glow {
  /* the pulse now washes the whole bay rather than a small panel */
  background: radial-gradient(ellipse 62% 78% at 50% 42%, rgba(255,170,70,calc(.16 + var(--beat) * .60)), transparent 74%);
}
/* The plain lit floor is replaced by the cloth, so drop its own backdrop and
   let it carry only the shading that grounds the deck. */
.jb3-floor {
  background:
    linear-gradient(180deg, rgba(0,0,0,.34) 0%, rgba(0,0,0,.04) 30%, rgba(0,0,0,.26) 78%, rgba(0,0,0,.52) 100%);
  box-shadow: inset 0 12px 20px rgba(0,0,0,.38), inset 0 -8px 16px rgba(0,0,0,.42);
}

/* Smoked glass, not a solid plaque: with the speaker cloth behind it the
   opaque panel read as a hole cut in the bay. This keeps enough shade under
   the text to stay readable while the weave and the beat glow show through. */
.jb3-info {
  background: linear-gradient(180deg, rgba(18,11,6,.40) 0%, rgba(10,6,3,.52) 55%, rgba(14,9,5,.44) 100%);
  backdrop-filter: blur(1px) saturate(.9);
  -webkit-backdrop-filter: blur(1px) saturate(.9);
}

/* Thinner glass means the text carries more of its own contrast */
.jb3-info-title   { text-shadow: 0 1px 3px rgba(0,0,0,.95), 0 0 10px rgba(0,0,0,.85); }
.jb3-info-meta,
.jb3-info-copy    { text-shadow: 0 1px 3px rgba(0,0,0,.95); }
.jb3-info-desc,
.jb3-info-credits { text-shadow: 0 1px 3px rgba(0,0,0,.92), 0 0 8px rgba(0,0,0,.6); }

/* The selector's top margin was escaping .jb3-body (margin collapse), pushing
   the body's panel down and leaving a 14px seam of page background between the
   player and the keypad. flow-root keeps the margin inside, so the cabinet is
   one continuous piece from the arch to the base. */
.jb3-body { display: flow-root; }

/* Keypad butts straight up against the player: no strip of wood between the
   glass and the selector panel. */
.jb3-selector { margin-top: 0; }
@media (max-width: 760px) {
  .jb3-selector { margin-top: 0; }
}

/* ── Title off the middle of the photo ────────────────────────────────────
   Centred over the case, the heading landed straight on the subject of every
   gallery shot. It now sits to the left and lower, in the quieter corner, and
   the pool of shade behind it moves with it. */
.jb3-dome-head {
  /* Far enough in and down to clear the arch's curve, which cuts the corner
     hard: at 76px the case is only ~91px wide on that side and it clipped
     the T. */
  left: 9%;
  top: 106px;
  width: 54%;
  transform: none;
  text-align: left;
}
.jb3-slides-glass {
  background:
    radial-gradient(ellipse 56% 40% at 26% 26%, rgba(6,4,2,.82), rgba(6,4,2,.30) 62%, transparent 80%),
    linear-gradient(180deg, rgba(8,5,3,.52) 0%, rgba(8,5,3,.30) 26%, rgba(8,5,3,.08) 46%,
                            rgba(8,5,3,.08) 74%, rgba(8,5,3,.44) 100%);
}
@media (max-width: 760px) {
  .jb3-dome-head { left: 15%; top: 40px; width: 70%; }
}

/* ── Now-playing store links ──────────────────────────────────────────────
   Chrome-rimmed buttons in the same family as the page keys, each icon in its
   store's own colour so they read at a glance. Desktop: spread evenly in the
   empty space either side of the keys. Phones: a small grid in the bay beside
   the deck. Filled by cs-jukebox3d.js for whatever is playing. */
.jb3-keys { position: relative; }
.jb3-stores {
  position: absolute;
  top: 9px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
}
/* the key group is ~292px wide and centred; keep clear of it */
.jb3-stores--l { left: 12px;  right: calc(50% + 162px); }
.jb3-stores--r { right: 12px; left:  calc(50% + 162px); }

.jb3-store {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  flex: none;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, #2a3039, #11151a 70%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.75),
    0 0 0 3px #9aa5b2,
    0 0 0 4px rgba(20,24,30,.9),
    0 4px 10px rgba(0,0,0,.55);
  transition: transform .15s, box-shadow .2s, filter .2s;
}
.jb3-store svg { width: 17px; height: 17px; fill: currentColor; }
.jb3-store--spotify       { color: #1ed760; }
.jb3-store--apple_music   { color: #fa4d6a; }
.jb3-store--amazon_music  { color: #25d1da; }
.jb3-store--youtube       { color: #ff3b30; }
.jb3-store--youtube_music { color: #ff4e45; }
.jb3-store:hover,
.jb3-store:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.2);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.9),
    0 0 0 3px var(--amber),
    0 0 0 4px rgba(20,24,30,.9),
    0 0 14px rgba(255,179,71,.55);
  outline: none;
}

.jb3-stores-bay { display: none; }

@media (max-width: 760px) {
  .jb3-stores { display: none; }
  .jb3-stores-bay {
    display: grid;
    grid-template-columns: repeat(2, 19px);
    gap: 4px;
    position: absolute;
    right: 3%;
    /* starts just under the chrome rail so it never covers the lettering on it,
       and is short enough to end above the now-playing pill */
    top: calc(var(--jb3-shelf) + 11px);
    z-index: 6;
  }
  .jb3-stores-bay .jb3-store {
    width: 19px; height: 19px;
    box-shadow: 0 0 0 1px rgba(255,255,255,.7), 0 0 0 2px #8f9aa7, 0 2px 5px rgba(0,0,0,.55);
  }
  .jb3-stores-bay .jb3-store svg { width: 11px; height: 11px; }
}

/* ── Lit title strip ──────────────────────────────────────────────────────
   Like an old jukebox: the strips sit dark behind the glass and the selected
   one is lit from underneath, the lamp showing through the paper. The rest
   drop back in contrast and colour; the playing strip returns to full colour
   with a warm hotspot under the card and a glow spilling past its edges.
   :has() limits the dimming to when something is actually selected. */
.jb3-grid:has(.csd-active) .csd-jbx-tab:not(.csd-active) {
  filter: saturate(.62) contrast(.87) brightness(.83);
  transition: filter .35s ease;
}
.jb3-grid:has(.csd-active) .csd-jbx-tab:not(.csd-active):hover {
  filter: saturate(.8) contrast(.94) brightness(.92);   /* still reads as clickable */
}
.jb3-grid .csd-jbx-tab.csd-active {
  filter: none;
  background:
    /* the lamp under the paper */
    radial-gradient(ellipse 70% 120% at 55% 55%, rgba(255,236,170,.95) 0%, rgba(255,214,120,.45) 45%, transparent 75%),
    linear-gradient(180deg, var(--strip-red) 0 3px, transparent 3px 5px, var(--strip-red) 5px 6px, transparent 6px),
    linear-gradient(0deg,   var(--strip-blue) 0 3px, transparent 3px 5px, var(--strip-blue) 5px 6px, transparent 6px),
    #fff7df;
  box-shadow:
    0 0 0 1px rgba(255,200,110,.9),
    0 0 14px 2px rgba(255,190,90,.65),
    0 0 30px 6px rgba(255,170,60,.28),
    inset 0 0 16px rgba(255,220,140,.55);
  transition: filter .35s ease, box-shadow .35s ease;
}

/* "Music" had only a warm glow, which the italic's own rule kept separate from
   the dark shadow on the rest of the title. Give it the same drop shadow so it
   stands off the photographs, and keep a softer glow on top. */
.jb3-dome-head .jb3-h1 em {
  text-shadow:
    0 2px 5px rgba(0,0,0,.9),
    0 0 18px rgba(0,0,0,.8),
    0 0 12px rgba(255,170,60,.4);
}

/* ═══ EMPTY DECK ═══════════════════════════════════════════════════════
   Before a song is picked there is no record on the platter and no cover in
   the sleeve, so the first selection plays the full load animation instead of
   changing a record that was never chosen. */
.jb3.jb3-empty .jb3-disc,
.jb3.jb3-empty .jb3-sleeve-stage { opacity: 0; }
.jb3.jb3-empty .jb3-disc { transition: none; }

/* ═══ SHARE BUTTON ═════════════════════════════════════════════════════
   Sits with the store keys and copies a link straight to the song that is
   playing. It is a <button>, so it needs the keys' own reset, and it says
   "Link copied" on the chrome for a moment after a click. */
.jb3-share {
  color: #cfd8e3;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.jb3-share svg { fill: none; stroke: currentColor; }
.jb3-share.is-copied { color: #7ee2a8; }
.jb3-share[data-note]::after {
  content: attr(data-note);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(10,13,17,.92);
  box-shadow: 0 0 0 1px rgba(255,255,255,.5), 0 6px 14px rgba(0,0,0,.5);
  color: #e8eef6;
  font-family: var(--font-display, inherit);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}
.jb3-share { position: relative; }
@media (max-width: 860px) {
  .jb3-share[data-note]::after { bottom: auto; top: calc(100% + 6px); }
}

/* ═══ START BUTTON (link arrivals) ═══════════════════════════════════════════════════════
   A link to one song lands on an empty deck. Browsers keep a page silent
   until it is touched, so this sits on the platter and waits: pressing it is
   the touch that runs the mechanism with its sound and starts the record. */
.jb3-start {
  position: absolute;
  left: 50%; top: 46%;
  z-index: 9;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  width: 86px; height: 86px;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: #0d1014;
  background: radial-gradient(circle at 50% 32%, #ffd98a, #f0a93c 62%, #c9791c);
  box-shadow:
    0 0 0 2px rgba(255,255,255,.85),
    0 0 0 5px rgba(20,24,30,.75),
    0 12px 26px rgba(0,0,0,.6),
    0 0 34px rgba(255,186,84,.45);
  transition: transform .16s ease, box-shadow .2s ease, filter .2s ease;
}
.jb3-start svg { width: 30px; height: 30px; margin-left: 4px; }
.jb3-start-label {
  font-family: var(--font-display, inherit);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.jb3-start:hover, .jb3-start:focus-visible {
  transform: translate(-50%, -50%) scale(1.06);
  filter: brightness(1.06);
  outline: none;
}
.jb3-start:active { transform: translate(-50%, -50%) scale(.97); }
.jb3-start::before {                        /* a slow ring, so it reads as waiting */
  content: "";
  position: absolute; inset: -6px;
  border-radius: 50%;
  border: 2px solid rgba(255,198,112,.55);
  animation: jb3-start-ring 2.6s ease-out infinite;
}
@keyframes jb3-start-ring {
  0%   { transform: scale(1);    opacity: .8; }
  70%  { transform: scale(1.28); opacity: 0; }
  100% { transform: scale(1.28); opacity: 0; }
}
@media (max-width: 860px) {
  .jb3-start { width: 68px; height: 68px; top: 44%; }
  .jb3-start svg { width: 24px; height: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .jb3-start::before { animation: none; opacity: .55; }
  .jb3-start:hover { transform: translate(-50%, -50%); }
}
