/* =============================================================
   vinyl.css — the turntable
   -------------------------------------------------------------
   Built from real geometry rather than an animated GIF, so it
   scales to any projector resolution without going fuzzy and can
   be driven directly by playback state.

   Physical accuracy that actually matters visually:
     - 33 1/3 RPM = 1.8s per revolution. That is the real speed of
       an LP, and it reads correctly to anyone who has seen one.
     - The sheen does NOT rotate with the record. A fixed light
       source is what makes it look like a lit object rather than
       a spinning texture.
     - The tonearm tracks inward as the track progresses, which is
       a genuine progress indicator, not decoration.
   ============================================================= */

.deck {
  --deck-size: min(46vh, 30vw, 440px);
  position: relative;
  width:  calc(var(--deck-size) * 1.34);
  height: calc(var(--deck-size) * 1.18);
  flex: none;
  display: grid;
  place-items: center;
}

/* ---------- the plinth / base the platter sits in ---------- */
.platter {
  position: relative;
  width:  var(--deck-size);
  height: var(--deck-size);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%,
      var(--surface-2) 0%,
      var(--surface) 62%,
      color-mix(in srgb, var(--bg) 80%, black) 100%);
  box-shadow:
    0 0 0 1px var(--border),
    0 30px 70px -20px rgba(0, 0, 0, .85),
    0 0 calc(60px * var(--glow-strength))
      color-mix(in srgb, var(--accent) 22%, transparent);
  display: grid;
  place-items: center;
}

/* ---------- the record itself ---------- */
.record {
  position: relative;
  width:  92%;
  height: 92%;
  border-radius: 50%;
  background: var(--vinyl-base);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .06),
    0 8px 30px rgba(0, 0, 0, .6);
  animation: vinyl-spin 1.8s linear infinite;
  animation-play-state: paused;          /* JS flips this to running */
  will-change: transform;
}

.record.spinning { animation-play-state: running; }

/* Slow wind-up / wind-down so play and pause feel mechanical
   rather than like a light switch. */
.record { transition: filter 400ms var(--ease); }
.record:not(.spinning) { filter: saturate(.7) brightness(.85); }

/* ---------- grooves ----------
   Concentric rings at sub-pixel spacing. Because they are perfectly
   concentric they look static while spinning, which is exactly how
   a real record behaves -- the label and the seam below supply the
   motion cue. */
.record::before {
  content: '';
  position: absolute;
  inset: 3%;
  border-radius: 50%;
  background: repeating-radial-gradient(
    circle at 50% 50%,
    rgba(255, 255, 255, .050) 0px,
    rgba(255, 255, 255, .050) 1px,
    rgba(0, 0, 0, .55)        1px,
    rgba(0, 0, 0, .55)        3px
  );
  opacity: .55;
  pointer-events: none;
}

/* ---------- the lead-in seam ----------
   One faint radial line. This is the trick that makes the spin
   legible -- without it, concentric rings rotating look frozen. */
.record::after {
  content: '';
  position: absolute;
  inset: 3%;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    rgba(255, 255, 255, .13) 0deg,
    rgba(255, 255, 255, 0)   3deg,
    rgba(255, 255, 255, 0)   357deg,
    rgba(255, 255, 255, .13) 360deg
  );
  pointer-events: none;
}

/* ---------- fixed specular sheen ----------
   Sits OUTSIDE .record so it does not rotate. This is the single
   biggest contributor to the thing reading as a physical object. */
.sheen {
  position: absolute;
  inset: 4%;
  border-radius: 50%;
  pointer-events: none;
  background: conic-gradient(
    from 210deg at 50% 50%,
    transparent 0deg,
    var(--vinyl-sheen) 26deg,
    transparent 62deg,
    transparent 180deg,
    var(--vinyl-sheen) 208deg,
    transparent 244deg,
    transparent 360deg
  );
  opacity: calc(.30 * var(--glow-strength));
  mix-blend-mode: screen;
}

/* ---------- the label (album art) ---------- */
.label {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width:  34%;
  height: 34%;
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .5),
    0 0 0 4px color-mix(in srgb, var(--vinyl-base) 70%, black),
    0 4px 18px rgba(0, 0, 0, .55);
  display: grid;
  place-items: center;
}

.label img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

/* Placeholder shown before anything is playing. */
.label .label-empty {
  font-family: var(--font-display);
  font-size: calc(var(--deck-size) * .045);
  letter-spacing: .12em;
  color: rgba(0, 0, 0, .55);
  text-align: center;
  line-height: 1.3;
  padding: 8%;
  text-transform: uppercase;
}

/* ---------- spindle ---------- */
.spindle {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width:  7%;
  height: 7%;
  min-width: 8px; min-height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d8d8e0, #6b6b78 60%, #2a2a33);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, .6), inset 0 -1px 2px rgba(0,0,0,.5);
  z-index: 3;
}

/* =============================================================
   TONEARM
   -------------------------------------------------------------
   The angles below are not guesses -- they are derived from the
   layout proportions, so the stylus lands on the record at every
   screen size.

   With S = --deck-size, the pivot sits at (1.263S, 0.121S) and the
   record centre at (0.67S, 0.59S), which puts the record 0.757S
   from the pivot at a bearing of 141.7deg. The arm is 0.50S long,
   so by the law of cosines the stylus radius r satisfies

       r^2 = (0.822 - 0.756 * cos(theta)) * S^2

   where theta is the arm's offset from that 141.7deg bearing.
   Record edge is r = 0.46S, label edge is r = 0.156S.

   Solving gives the arm's absolute angle:
     176deg -> r = 0.44S  (just inside the outer edge: track start)
     153deg -> r = 0.28S  (comfortably outside the label: track end)
     180deg -> r = 0.48S  (just off the record: parked)

   So --arm-angle runs 0 -> 23 as the track plays, and -4 at rest.
   Note it SUBTRACTS: a larger angle means further in, because the
   arm swings toward that 141.7deg bearing as the song progresses.
   ============================================================= */

.tonearm {
  --arm-angle: -4deg;
  position: absolute;
  top:   6%;
  right: 2%;
  width:  calc(var(--deck-size) * .10);
  height: calc(var(--deck-size) * .10);
  z-index: 4;
  pointer-events: none;
}

/* pivot housing */
.tonearm::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #9aa0ad, #4a4f5c 55%, #23262e);
  box-shadow: 0 0 0 1px rgba(255,255,255,.10), 0 6px 16px rgba(0,0,0,.6);
}

/* counterweight behind the pivot */
.tonearm::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width:  calc(var(--deck-size) * .075);
  height: calc(var(--deck-size) * .075);
  border-radius: 50%;
  background: linear-gradient(160deg, #6f7583, #2b2f38);
  box-shadow: inset 0 -2px 4px rgba(0,0,0,.6);
  transform-origin: 0 0;
  /* Same absolute rotation as the arm, then pushed BACKWARD along it,
     so the counterweight stays behind the pivot as the arm swings
     instead of drifting off on its own. */
  transform: rotate(calc(176deg - var(--arm-angle)))
             translate(calc(var(--deck-size) * -.105), calc(var(--deck-size) * -.037));
  transition: transform 900ms var(--ease);
}

.arm {
  position: absolute;
  top: 50%; left: 50%;
  width:  calc(var(--deck-size) * .50);
  height: calc(var(--deck-size) * .022);
  border-radius: 999px;
  background: linear-gradient(180deg, #c3c8d2 0%, #878d9b 45%, #454a56 100%);
  box-shadow: 0 3px 10px rgba(0, 0, 0, .55);
  transform-origin: 0 50%;
  /* See the derivation above: 176deg puts the stylus at the outer
     edge, and subtracting the tracking angle walks it inward. */
  transform: rotate(calc(176deg - var(--arm-angle)));
  transition: transform 900ms var(--ease);
}

/* headshell + stylus at the far end of the arm */
.headshell {
  position: absolute;
  right: -2%;
  top: 50%;
  transform: translateY(-50%) rotate(-16deg);
  width:  calc(var(--deck-size) * .075);
  height: calc(var(--deck-size) * .045);
  border-radius: 3px 3px 5px 5px;
  background: linear-gradient(160deg, #d5d9e2, #5b616e);
  box-shadow: 0 2px 6px rgba(0,0,0,.6);
}

/* The stylus. Uses top, not bottom: the arm is rotated ~176deg, so
   local "up" is what points down onto the record on screen. */
.headshell::after {
  content: '';
  position: absolute;
  top: -22%;
  left: 22%;
  width: 2px;
  height: 24%;
  background: var(--accent);
  box-shadow: 0 0 calc(6px * var(--glow-strength)) var(--accent);
}

/* =============================================================
   ANIMATION
   ============================================================= */

@keyframes vinyl-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Respect the OS setting. A continuously spinning disc is exactly
   the kind of motion that triggers vestibular symptoms, and a
   classroom of 30 will include someone affected. */
@media (prefers-reduced-motion: reduce) {
  .record { animation: none !important; }
  .record.spinning::after {
    animation: vinyl-pulse 2.4s ease-in-out infinite;
  }
  .arm, .tonearm::after { transition: none; }
}

@keyframes vinyl-pulse {
  0%, 100% { opacity: .35; }
  50%      { opacity: .85; }
}
