/* ========================================================
   Dilla Time — Beatmaker's Workstation
   Top-down view of a beatmaker's desk
   ======================================================== */

* {
  box-sizing: border-box;
}

/* ============================================================
   Boot sequence — page loads in "powered off" state, JS adds
   .powered-on after the boot animation completes. Props fade in
   on staggered delays matching the LCD boot messages so the
   whole scene comes alive in unison with the sampler.
   ============================================================ */

/* Each prop is PLACED into the scene with directional motion — they slide,
   drop, or settle into their resting position rather than fading in. The
   end frame of every keyframe restores the prop's resting transform
   (rotation, etc.) so the existing static styling stays intact. Easing uses
   a slight back-overshoot so things "thump" into place like real objects. */

/* Notebook — placed down from upper-left */
@keyframes place-notebook {
  0% {
    opacity: 0;
    transform: translate(-50px, -30px) rotate(-12deg);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) rotate(-2deg);
  }
}

/* Polaroid — tossed onto the desk from the upper-right */
@keyframes place-polaroid {
  0% {
    opacity: 0;
    transform: translate(60px, -40px) rotate(15deg);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0);
  }
}

/* Vinyl — slid in from the bottom-left edge */
@keyframes place-vinyl {
  0% {
    opacity: 0;
    transform: translate(-60px, 30px);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0);
  }
}

/* LP fan — pushed up from below */
@keyframes place-lp-fan {
  0% {
    opacity: 0;
    transform: translate(-30px, 60px);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0);
  }
}

/* Soul Brother LP — dropped in from the upper-right corner */
@keyframes place-soul-brother {
  0% {
    opacity: 0;
    transform: translate(60px, -50px) rotate(20deg);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) rotate(6deg);
  }
}

/* Cassette — slid in from the right edge */
@keyframes place-cassette {
  0% {
    opacity: 0;
    transform: translate(70px, 10px);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0);
  }
}

/* Sticky note — drops onto the desk from above, twists as it settles */
@keyframes place-sticky {
  0% {
    opacity: 0;
    transform: translate(8px, -80px) rotate(-22deg) scale(0.92);
  }
  55% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) rotate(-4deg) scale(1);
  }
}

/* Funk LP — tossed in from the bottom-right corner */
@keyframes place-funk {
  0% {
    opacity: 0;
    transform: translate(70px, 40px) rotate(18deg);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) rotate(4deg);
  }
}

/* Props are hidden during the entire boot sequence — they only appear
   the instant the step cells light up (.powered-on fires at T≈4.02s).
   Once .powered-on is set, each prop runs its placement keyframe with
   a tiny millisecond stagger so they enter the scene one after another
   in quick succession rather than all snapping in at the exact same frame. */
body:not(.powered-on) .prop {
  opacity: 0;
  pointer-events: none;
}

/* Common animation settings — applied only under body.powered-on */
body.powered-on .prop {
  animation-duration: 0.7s;
  animation-timing-function: cubic-bezier(0.34, 1.4, 0.5, 1);
  animation-fill-mode: both;
}

/* Micro-staggers (50ms between props) so they cascade in over ~400ms
   total, starting the moment the step cells light up. */
body.powered-on .prop-notebook {
  animation-name: place-notebook;
  animation-delay: 0ms;
}
body.powered-on .prop-polaroid {
  animation-name: place-polaroid;
  animation-delay: 50ms;
}
body.powered-on .prop-vinyl {
  animation-name: place-vinyl;
  animation-delay: 100ms;
}
body.powered-on .prop-lp-fan {
  animation-name: place-lp-fan;
  animation-delay: 150ms;
}
body.powered-on .prop-soul-brother {
  animation-name: place-soul-brother;
  animation-delay: 200ms;
}
body.powered-on .prop-cassette {
  animation-name: place-cassette;
  animation-delay: 250ms;
}
body.powered-on .prop-sticky {
  animation-name: place-sticky;
  animation-delay: 300ms;
}
body.powered-on .prop-funk {
  animation-name: place-funk;
  animation-delay: 350ms;
}

/* Patch cables fade in over the desk early in the sequence — kept as
   opacity-only since cables don't get "placed", they're already wired up. */
@keyframes cables-arrive {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.cables {
  animation: cables-arrive 0.8s ease-out 0.2s both;
}

/* Boot LCD overlay — sits absolutely over the .lcd, hides cells while booting */
.lcd-boot {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "VT323", monospace;
  font-size: clamp(14px, 1.3vw, 22px);
  color: var(--lcd-text, #1f2913);
  letter-spacing: 2px;
  text-shadow: 0 0 4px rgba(60, 90, 40, 0.5);
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 2;
}

/* LCD dark only while NO power is detected — the moment power-on-detected
   fires (T≈0.22s) the LCD lights up green so the boot text is legible. */
body:not(.power-on-detected) .lcd {
  background: linear-gradient(180deg, #1a1f12 0%, #0e120a 100%);
  text-shadow: none;
}

body:not(.power-on-detected) .lcd::before {
  opacity: 0.25;
}

/* Light flicker when the LCD first wakes up (mimics real LCDs settling) */
body.power-on-detected .lcd {
  animation: lcd-wake 0.45s ease-out;
}

@keyframes lcd-wake {
  0% {
    filter: brightness(0.4);
    opacity: 0.7;
  }
  25% {
    filter: brightness(1.3);
    opacity: 1;
  }
  40% {
    filter: brightness(0.85);
  }
  100% {
    filter: brightness(1);
    opacity: 1;
  }
}

/* LCD cells stay hidden behind the boot overlay until the full sequence
   completes — power-on-detected lights the panel, .powered-on reveals
   the live BPM/STEP/MODE/SWING values. */
body:not(.powered-on) .lcd-cell {
  opacity: 0;
}

body:not(.powered-on) .lcd-boot {
  opacity: 1;
}

body.powered-on .lcd-boot {
  opacity: 0;
}

body.powered-on .lcd-cell {
  opacity: 1;
  transition: opacity 0.3s ease 0.2s;
}

/* Brand LED dot dark until power is detected (then pulses alongside the boot) */
body:not(.power-on-detected) .brand-mark .dot {
  animation: none;
  background: radial-gradient(circle at 35% 30%, #3a2a1a 0%, #1a0d05 100%);
  box-shadow:
    inset 0 1px 1px rgba(255, 220, 180, 0.08),
    inset 0 -1px 1px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.6);
}

/* Pads dim until powered — both inactive and "active" states muted */
body:not(.powered-on) .step {
  background: radial-gradient(circle at 30% 25%, #2a2520 0%, #1c1814 70%, #0e0c08 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    inset 0 -2px 4px rgba(0, 0, 0, 0.5),
    0 1px 0 rgba(0, 0, 0, 0.4);
  transition: none;
}

body:not(.powered-on) .step.active {
  background: radial-gradient(circle at 30% 25%, #2a2520 0%, #1c1814 70%, #0e0c08 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    inset 0 -2px 4px rgba(0, 0, 0, 0.5),
    0 1px 0 rgba(0, 0, 0, 0.4);
}

body:not(.powered-on) .step.beat::before {
  opacity: 0;
}

/* Smooth wake-up for pads when power kicks in */
body.powered-on .step {
  transition:
    background 0.6s ease,
    box-shadow 0.6s ease,
    transform 0.08s ease,
    filter 0.06s ease;
}

/* Pad self-test sweep — JS adds .self-test to each row in sequence */
.track-row.self-test .step {
  background: radial-gradient(circle at 30% 25%, #ffb46e 0%, #ff7a2b 60%, #c2410c 100%);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.45),
    inset 0 -3px 8px rgba(0, 0, 0, 0.5),
    0 0 14px rgba(255, 122, 43, 0.6);
  transition:
    background 0.15s ease,
    box-shadow 0.15s ease;
}

/* Reduced motion — collapse boot animations to near-instant */
@media (prefers-reduced-motion: reduce) {
  .prop,
  .cables {
    animation-duration: 0.01s;
    animation-delay: 0s;
  }
  .lcd-boot,
  .lcd-cell {
    transition: none;
  }
}

html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  background: #1a120a;
  font-family: "JetBrains Mono", monospace;
  color: #e9e1d3;
}

/* ------ The desk surface ------ */
.desk {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 50% at 50% 18%, rgba(255, 200, 130, 0.18), transparent 70%),
    radial-gradient(ellipse 90% 90% at 50% 55%, transparent 40%, rgba(0, 0, 0, 0.55) 100%),
    repeating-linear-gradient(
      92deg,
      rgba(0, 0, 0, 0.04) 0 2px,
      rgba(255, 220, 180, 0.02) 2px 5px,
      rgba(0, 0, 0, 0.05) 5px 9px,
      transparent 9px 14px
    ),
    repeating-linear-gradient(91deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 30px),
    linear-gradient(180deg, #5a3a22 0%, #4a2e1a 60%, #3a230f 100%);
  background-blend-mode: normal, multiply, normal, normal, normal;
  isolation: isolate;
}

.desk::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(ellipse 220px 60px at 12% 28%, rgba(20, 10, 5, 0.45), transparent 70%),
    radial-gradient(ellipse 180px 50px at 88% 72%, rgba(20, 10, 5, 0.4), transparent 70%),
    radial-gradient(ellipse 90px 25px at 70% 15%, rgba(20, 10, 5, 0.35), transparent 70%),
    radial-gradient(ellipse 140px 35px at 30% 85%, rgba(20, 10, 5, 0.4), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.desk::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 50;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.45 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/></svg>");
  mix-blend-mode: overlay;
  opacity: 0.45;
}

/* SVG cables container — sits in front of desk but behind stage props */
.cables {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  width: 100%;
  height: 100%;
}

.stage {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.stage > * {
  pointer-events: auto;
}

/* === Sampler stage === */
.sampler-stage {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -54%);
  width: clamp(820px, 72vw, 1400px);
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 10;
}

/* === Absolutely-positioned props === */
.prop {
  position: absolute;
}

.prop-notebook {
  top: 1.5vh;
  left: 1vw;
  width: 21vw;
  max-width: 340px;
  transform: rotate(-2deg);
  z-index: 3;
}

.prop-vinyl {
  bottom: 26vh;
  left: -9vw;
  width: 15vw;
  z-index: 3;
}

.prop-lp-fan {
  bottom: 10vh;
  left: -3vw;
  width: 19vw;
  max-width: 320px;
  z-index: 4;
}

.prop-soul-brother {
  top: -3vh;
  right: -3vw;
  width: 15vw;
  max-width: 240px;
  transform: rotate(6deg);
  z-index: 4;
}

.prop-polaroid {
  top: 16vh;
  right: 1vw;
  width: 12vw;
  max-width: 200px;
  z-index: 5;
}

.prop-cassette {
  top: 36vh;
  right: -4vw;
  width: 17vw;
  max-width: 280px;
  z-index: 4;
}

.prop-sticky {
  bottom: 12vh;
  left: 38vw;
  width: 9vw;
  max-width: 150px;
  z-index: 6;
  transform: rotate(-4deg);
}

.prop-funk {
  bottom: 11vh;
  right: -2vw;
  width: 14vw;
  max-width: 230px;
  transform: rotate(4deg);
  z-index: 4;
}

/* ============ Notebook (engine notes) ============ */
.notebook {
  position: relative;
  background:
    repeating-linear-gradient(180deg, transparent 0 1.4em, rgba(100, 140, 200, 0.18) 1.4em 1.45em),
    linear-gradient(180deg, #f4ecd6 0%, #ede2c4 100%);
  color: #2a1f10;
  padding: 3.5vh 1.4vw 2vh 2vw;
  font-family: "Special Elite", "JetBrains Mono", monospace;
  font-size: clamp(10px, 0.85vw, 14px);
  line-height: 1.5;
  border-radius: 2px;
  transform: rotate(-1.4deg);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 2vh 4vh -1vh rgba(0, 0, 0, 0.7),
    0 1vh 2vh -0.5vh rgba(0, 0, 0, 0.5);
  border-left: 2px solid rgba(220, 80, 80, 0.45);
  overflow: hidden;
  transition:
    transform 0.3s ease,
    box-shadow 0.3s;
}

.notebook::before {
  content: "";
  position: absolute;
  top: -18px;
  left: 50%;
  transform: translateX(-50%) rotate(-2deg);
  width: 120px;
  height: 32px;
  background: linear-gradient(180deg, rgba(255, 250, 220, 0.85), rgba(230, 220, 180, 0.7));
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
  opacity: 0.85;
  border: 1px solid rgba(0, 0, 0, 0.05);
}

.notebook::after {
  content: "";
  position: absolute;
  left: 30px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(220, 80, 80, 0.5);
}

.notebook:hover {
  transform: rotate(-1deg) translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 3vh 5vh -1vh rgba(0, 0, 0, 0.75),
    0 1.4vh 2.5vh -0.5vh rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(255, 200, 100, 0.08);
}

.notebook h2 {
  font-family: "Permanent Marker", cursive;
  font-size: 22px;
  color: #c2410c;
  margin: 0 0 14px 0;
  transform: rotate(-1deg);
  letter-spacing: 0.5px;
}

.notebook p {
  margin: 0 0 18px 0;
}

.notebook strong {
  background: rgba(255, 230, 120, 0.65);
  padding: 0 3px;
  font-weight: 700;
}

/* ============ Sampler chassis ============ */
.sampler-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 5;
  gap: 0.5vh;
  width: 100%;
}

.sampler-title {
  display: flex;
  align-items: center;
  gap: 1.2vw;
  font-family: "Permanent Marker", cursive;
  font-size: clamp(36px, 4.5vw, 64px);
  color: #f8e6c8;
  text-align: center;
  /* Push the title block up from the sampler chassis for breathing room */
  margin: 0 0 4vh 0;
  letter-spacing: 0.1vw;
  transform: rotate(-2deg);
  text-shadow:
    -1px -1px 0 #2a1810,
    1px 1px 0 #2a1810,
    2px 3px 0 rgba(0, 0, 0, 0.6),
    0 8px 20px rgba(0, 0, 0, 0.6);
}

.sampler-title em {
  font-style: normal;
  color: #ff7a2b;
  text-shadow:
    -1px -1px 0 #2a1810,
    1px 1px 0 #2a1810,
    2px 3px 0 rgba(0, 0, 0, 0.7),
    0 0 18px rgba(255, 122, 43, 0.45);
}

.dilla-logo-mark {
  width: clamp(48px, 5vw, 80px);
  height: clamp(48px, 5vw, 80px);
  object-fit: contain;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.5));
  transform: rotate(2deg); /* counter the title's -2deg so the logo sits straight */
}

.tagline-label {
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(8px, 0.6vw, 11px);
  color: rgba(248, 230, 200, 0.55);
  letter-spacing: 0.3vw;
  text-transform: uppercase;
  margin-bottom: 0.5vh;
}

.sampler {
  position: relative;
  width: 100%;
  max-width: 100%;
  padding: 2vh 1.4vw 2vh;
  border-radius: 0.8vw;
  background:
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.02) 0 1px, rgba(0, 0, 0, 0.02) 1px 2px),
    linear-gradient(180deg, #2a2520 0%, #1c1814 35%, #14110d 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    inset 1px 0 0 rgba(255, 255, 255, 0.04),
    inset -1px 0 0 rgba(0, 0, 0, 0.5),
    0 25px 60px -15px rgba(0, 0, 0, 0.85),
    0 8px 18px -4px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.7);
  transform: rotateX(2deg);
}

/* Corner screws */
.screw {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #d4cfc4 0%, #7a7368 45%, #2a2620 100%);
  box-shadow:
    inset 0 0 2px rgba(0, 0, 0, 0.7),
    0 1px 1px rgba(0, 0, 0, 0.6);
  transition: transform 0.3s ease;
  cursor: pointer;
}

.screw::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 14%;
  width: 72%;
  height: 1.5px;
  background: rgba(0, 0, 0, 0.65);
  transform: translateY(-50%) rotate(35deg);
}

.screw.tl {
  top: 8px;
  left: 8px;
}
.screw.tr {
  top: 8px;
  right: 8px;
}
.screw.bl {
  bottom: 8px;
  left: 8px;
}
.screw.br {
  bottom: 8px;
  right: 8px;
}

.screw:hover {
  animation: screw-spin 1.4s ease-in-out infinite;
}

@keyframes screw-spin {
  0% {
    transform: rotate(0deg) scale(1);
  }
  50% {
    transform: rotate(180deg) scale(1.15);
  }
  100% {
    transform: rotate(360deg) scale(1);
  }
}

/* Sampler top brand strip */
.sampler-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0.8vw 1vh;
  padding-bottom: 0.8vh;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  gap: 1vw;
}

.brand-mark {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5vw;
  font-family: "Bowlby One", sans-serif;
  font-size: clamp(11px, 0.9vw, 16px);
  letter-spacing: 0.25vw;
  /* Machined-into-chassis: letter color matches the chassis dark tone,
     a hair deeper so the face reads as a recessed surface, not paint */
  color: #0e0b08;
  /* The 3D illusion comes entirely from edge shadows + highlights:
     - dark line on the TOP edge of each letter (recess wall facing away from overhead lamp)
     - subtle warm highlight on the BOTTOM edge (chamfered lip catching the lamp glow above)
     - the lamp on the desk is at top center, so all letters share the same light direction */
  text-shadow:
    0 -1px 0 rgba(0, 0, 0, 0.95),
    -1px -1px 1px rgba(0, 0, 0, 0.55),
    0 1px 0 rgba(255, 230, 200, 0.16),
    1px 1px 1px rgba(255, 220, 180, 0.08);
  cursor: default;
  user-select: none;
}

.brand-mark .dot {
  width: 0.5vw;
  height: 0.5vw;
  min-width: 7px;
  min-height: 7px;
  max-width: 10px;
  max-height: 10px;
  border-radius: 50%;
  /* Recessed LED-in-chassis look: dark well + glowing dome inside */
  background: radial-gradient(circle at 35% 30%, #ffb46e 0%, #ff7a2b 45%, #c2410c 90%);
  box-shadow:
    inset 0 1px 1px rgba(255, 220, 180, 0.5),
    inset 0 -1px 1px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.6),
    0 0 10px rgba(255, 122, 43, 0.55);
  animation: pulse 1.4s ease-in-out infinite;
}

.brand-mark::after {
  content: "MADE IN DETROIT · '00";
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  font-family: "JetBrains Mono", monospace;
  font-size: 9px;
  color: rgba(255, 200, 100, 0.7);
  letter-spacing: 0.2vw;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(-4px);
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
  pointer-events: none;
}

.brand-mark:hover::after {
  opacity: 1;
  transform: translateY(0);
}

.brand-meta {
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(8px, 0.55vw, 10px);
  letter-spacing: 0.15vw;
  color: rgba(255, 255, 255, 0.35);
  text-transform: uppercase;
  white-space: nowrap;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
    box-shadow: 0 0 10px rgba(255, 122, 43, 0.7);
  }
  50% {
    opacity: 0.4;
    box-shadow: 0 0 4px rgba(255, 122, 43, 0.2);
  }
}

.sampler:hover .brand-mark .dot {
  animation-duration: 0.6s;
}

/* LCD display */
.lcd {
  position: relative; /* positioning context for .lcd-boot overlay */
  background:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.18) 0 2px, transparent 2px 3px),
    linear-gradient(180deg, #b8d896 0%, #9bbb78 100%);
  color: #1f2913;
  font-family: "VT323", monospace;
  font-size: clamp(14px, 1.3vw, 22px);
  line-height: 1;
  padding: 0.7vh 1vw;
  border-radius: 4px;
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.4),
    inset 0 -1px 0 rgba(255, 255, 255, 0.25),
    0 1px 0 rgba(255, 255, 255, 0.06);
  text-shadow: 0 0 4px rgba(60, 90, 40, 0.5);
  letter-spacing: 1px;
  display: flex;
  gap: 1.2vw;
  align-items: center;
  transition: filter 0.2s;
  overflow: hidden; /* keep the boot text clipped to the LCD bounds */
}

.lcd .v {
  color: #2a3a16;
  display: inline-block;
}

/* Fixed-width value cells so the LCD never resizes when its values change
   (e.g. mode switching FRICTION → LIMP → LIVE).
   ch counts characters but the LCD also applies letter-spacing: 1px, so
   we add a small calc() padding to keep the cell stable even at the
   longest expected content. */
.lcd .v[data-bind="bpm"] {
  min-width: calc(3ch + 4px);
  text-align: right;
}
.lcd .v[data-bind="step"] {
  min-width: calc(2ch + 3px);
  text-align: right;
}
.lcd .v[data-bind="mode"] {
  /* "FRICTION" = 8 chars + 7 letter-spacing gaps + safety margin */
  min-width: calc(8ch + 12px);
  text-align: left;
}
.lcd .v[data-bind="humanize"] {
  min-width: calc(4ch + 5px);
  text-align: right;
}

.lcd .lbl {
  font-size: clamp(7px, 0.55vw, 10px);
  opacity: 0.6;
  letter-spacing: 1.5px;
  font-family: "JetBrains Mono", monospace;
  margin-bottom: 2px;
}

.lcd-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1;
  min-width: 3.5vw;
  white-space: nowrap;
}

.lcd-cell:not(:last-child) {
  border-right: 1px solid rgba(30, 50, 20, 0.25);
  padding-right: 1vw;
}

.sampler:hover .lcd {
  animation: lcd-flicker 0.18s ease-in-out 2;
  filter: brightness(1.08);
}

@keyframes lcd-flicker {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.82;
    filter: brightness(1.25) saturate(1.2);
  }
}

/* Detroit sticker on chassis */
.detroit-sticker {
  position: absolute;
  top: 9vh;
  right: -1.5vw;
  font-size: clamp(11px, 0.9vw, 14px);
  transform: rotate(8deg);
  background: #1a0d05;
  color: #ff7a2b;
  border: 1px dashed rgba(255, 122, 43, 0.5);
  font-family: "Permanent Marker", cursive;
  padding: 4px 10px;
  letter-spacing: 1px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: bottom right;
  pointer-events: auto;
  z-index: 11;
}

.detroit-sticker:hover {
  transform: rotate(12deg) translate(-2px, -1px) skewX(-3deg) scale(1.05);
}

/* ---- Track rows (#app populated by Grid.js) ---- */
.tracks,
#app {
  display: flex;
  flex-direction: column;
  gap: 1vh;
  background: transparent;
  padding: 0;
}

.track-row {
  display: grid;
  grid-template-columns:
    clamp(96px, 7.4vw, 140px)
    auto
    auto
    1fr;
  column-gap: 0.7vw;
  align-items: center;
  position: relative;
}

.track-info {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.2vh;
  width: 100%;
  min-width: 0;
}

/* Standalone track-name (only briefly visible before SampleUploader wraps it) */
.track-name {
  position: relative;
  display: block;
  font-family: "Bowlby One", sans-serif;
  font-size: clamp(10px, 0.75vw, 14px);
  letter-spacing: 0.08vw;
  color: #f0e8d8;
  text-transform: uppercase;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The wrapper SampleUploader injects becomes the unified hardware card */
.track-info .track-name-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4vw;
  width: 100%;
  padding: 0.6vh 0.35vw 0.6vh 0.55vw;
  background: linear-gradient(180deg, #3a322a 0%, #2a221a 100%);
  border: none;
  border-left: 3px solid var(--track-color, #ff7a2b);
  border-radius: 3px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 1px 0 rgba(0, 0, 0, 0.5);
}

/* Track-name inside the container: pure typography, no card */
.track-name-container .track-name {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  padding: 0;
  box-shadow: none;
  border-radius: 0;
  text-align: left;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
}

/* Folder icon button — inset hardware-style control */
.track-info .sample-upload-btn {
  flex-shrink: 0;
  width: clamp(20px, 1.7vw, 26px);
  height: clamp(20px, 1.7vw, 26px);
  padding: 0;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition:
    background 0.15s ease,
    border-color 0.15s ease;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    inset 0 -1px 2px rgba(0, 0, 0, 0.6);
}

.track-info .sample-upload-btn:hover {
  background: rgba(255, 122, 43, 0.18);
  border-color: rgba(255, 122, 43, 0.5);
}

.track-info .sample-upload-btn:active {
  transform: translateY(1px);
}

.track-info .folder-icon {
  width: 60%;
  height: 60%;
  color: rgba(255, 255, 255, 0.5);
  transition: color 0.15s ease;
}

.track-info .sample-upload-btn:hover .folder-icon {
  color: #ff7a2b;
}

.track-controls-row {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.4vw;
  margin-top: 0.3vh;
}

/* Ghost mini-dial container — auto-height so the GHOST label sits naturally below */
.track-dial-container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.track-dial-container .mini-dial-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2vh;
}

.mini-dial-svg {
  width: clamp(38px, 3.4vw, 50px);
  height: clamp(38px, 3.4vw, 50px);
  cursor: ns-resize;
  display: block;
}

.mini-dial-svg:active {
  cursor: grabbing;
}

.mini-knob-group {
  transform-origin: 18px 18px;
  transition: transform 0.05s ease-out;
}

.mini-dial-label {
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(6px, 0.48vw, 8px);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.5);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  text-align: center;
  line-height: 1;
  margin-top: 2px;
}

.mini-dial-arc {
  transition: stroke-dashoffset 0.05s ease-out;
}

/* Swing lock button — matches folder icon button for visual rhythm */
.swing-lock-btn {
  width: clamp(22px, 1.9vw, 28px);
  height: clamp(22px, 1.9vw, 28px);
  padding: 2px;
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  justify-self: center;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    inset 0 -1px 2px rgba(0, 0, 0, 0.6);
  transition: all 0.2s ease;
}

.swing-lock-btn:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.25);
}

.swing-lock-btn.locked {
  background: rgba(255, 122, 43, 0.18);
  border-color: #ff7a2b;
}

.swing-lock-btn.locked:hover {
  background: rgba(255, 122, 43, 0.28);
}

.lock-icon {
  width: 75%;
  height: 75%;
  color: rgba(255, 255, 255, 0.45);
  transition: all 0.25s ease;
}

.swing-lock-btn:hover .lock-icon {
  color: rgba(255, 255, 255, 0.7);
}

.swing-lock-btn.locked .lock-icon {
  color: #ff7a2b;
}

.lock-icon .lock-body {
  transition: all 0.2s ease;
}

.swing-lock-btn.locked .lock-icon .lock-body {
  fill: rgba(255, 122, 43, 0.3);
}

.lock-icon .lock-shackle {
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
  transform-origin: center bottom;
}

.swing-lock-btn:not(.locked) .lock-icon .lock-shackle {
  transform: rotate(-25deg) translateX(-1px);
}

.swing-lock-btn.locked .lock-icon .lock-shackle {
  transform: rotate(0deg) translateX(0);
}

.swing-lock-btn.auto-locked {
  cursor: not-allowed;
  opacity: 0.85;
  position: relative;
}

.swing-lock-btn.auto-locked .lock-icon {
  color: #ff7a2b;
}

.swing-lock-btn.auto-locked::after {
  content: "A";
  position: absolute;
  top: -4px;
  right: -4px;
  font-family: "JetBrains Mono", monospace;
  font-size: 7px;
  font-weight: bold;
  background: #ff7a2b;
  color: #0a0805;
  border-radius: 50%;
  width: 11px;
  height: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* ---- Pads (the step cells) ---- */
.track-steps {
  display: grid;
  grid-template-columns: repeat(16, 1fr);
  gap: 0.3vw;
}

.step {
  aspect-ratio: 1;
  border: none;
  border-radius: 7px;
  background: radial-gradient(circle at 30% 25%, #d8cfbd 0%, #a89e8a 70%, #6e6450 100%);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.6),
    inset 0 -3px 6px rgba(0, 0, 0, 0.4),
    0 2px 0 rgba(0, 0, 0, 0.5),
    0 3px 5px rgba(0, 0, 0, 0.4);
  cursor: pointer;
  transition:
    transform 0.06s,
    box-shadow 0.06s,
    filter 0.06s;
  position: relative;
}

.step:hover {
  filter: brightness(1.05);
}

.step:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.2),
    inset 0 -1px 2px rgba(0, 0, 0, 0.4);
}

.step.active {
  background: radial-gradient(circle at 30% 25%, #ffb46e 0%, #ff7a2b 65%, #c2410c 100%);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.45),
    inset 0 -3px 8px rgba(0, 0, 0, 0.5),
    0 2px 0 rgba(80, 30, 5, 0.7),
    0 3px 5px rgba(255, 122, 43, 0.35),
    0 0 16px rgba(255, 122, 43, 0.3);
}

.step.playing {
  outline: 2px solid rgba(255, 255, 255, 0.7);
  outline-offset: -1px;
  filter: brightness(1.15);
}

.step.beat::before {
  content: "";
  position: absolute;
  bottom: 4px;
  left: 50%;
  width: 4px;
  height: 4px;
  background: rgba(0, 0, 0, 0.35);
  border-radius: 50%;
  transform: translateX(-50%);
}

/* Sample drop overlay — overrides SampleUploader's TR-909 styling */
.track-row.sample-drop-zone .sample-drop-overlay {
  background: rgba(20, 17, 13, 0.92);
  border: 2px solid #ff7a2b;
  border-radius: 4px;
  backdrop-filter: blur(2px);
}

.track-row.sample-drop-zone .sample-drop-overlay-text {
  font-family: "Bowlby One", sans-serif;
  color: #fef3e2;
  font-size: clamp(11px, 0.85vw, 14px);
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

.track-row.sample-drop-zone .sample-drop-overlay-track {
  font-family: "JetBrains Mono", monospace;
  color: #ff7a2b;
  font-size: clamp(9px, 0.65vw, 11px);
  font-weight: 700;
  letter-spacing: 1.5px;
  margin-top: 4px;
}

.track-row.sample-drop-zone.drag-over .sample-drop-overlay {
  animation: dropzone-glow 1.2s ease-in-out infinite;
}

@keyframes dropzone-glow {
  0%,
  100% {
    border-color: #ff7a2b;
    box-shadow: 0 0 12px rgba(255, 122, 43, 0.35);
  }
  50% {
    border-color: #ff9d50;
    box-shadow: 0 0 22px rgba(255, 122, 43, 0.55);
  }
}

/* ---- Transport / footer panel ---- */
.transport {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 9vh;
  z-index: 30;
  background:
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.02) 0 1px, rgba(0, 0, 0, 0.02) 1px 2px),
    linear-gradient(180deg, #14110d 0%, #0a0805 100%);
  padding: 0 3vw;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2vw;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 -10px 25px rgba(0, 0, 0, 0.5);
  border-top: 1px solid rgba(255, 122, 43, 0.18);
}

.transport-group {
  display: flex;
  align-items: center;
  gap: 1vw;
}

.transport-btn {
  font-family: "Bowlby One", sans-serif;
  letter-spacing: 0.2vw;
  font-size: clamp(10px, 0.78vw, 13px);
  padding: 1.2vh 1.4vw;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  text-transform: uppercase;
  background: linear-gradient(180deg, #3a322a 0%, #2a221a 100%);
  color: #f0e8d8;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.7),
    0 4px 8px rgba(0, 0, 0, 0.5);
  transition:
    transform 0.08s,
    box-shadow 0.08s,
    filter 0.08s;
}

.transport-btn:hover {
  filter: brightness(1.1);
}

.transport-btn:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 0 0 rgba(0, 0, 0, 0);
}

.transport-btn.primary {
  background: linear-gradient(180deg, #ff8b3e 0%, #d9531b 100%);
  color: #1a0d05;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(120, 40, 0, 0.7),
    0 2px 0 rgba(80, 30, 0, 0.7),
    0 4px 12px rgba(255, 122, 43, 0.45);
}

.transport-btn.primary.is-playing {
  background: linear-gradient(180deg, #c2410c 0%, #8a2f0a 100%);
}

.reset-samples-btn.has-custom {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(0, 0, 0, 0.7),
    0 4px 8px rgba(0, 0, 0, 0.5),
    0 0 12px rgba(255, 122, 43, 0.4);
}

.tempo-display {
  display: flex;
  align-items: center;
  gap: 0.6vw;
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(9px, 0.7vw, 12px);
  letter-spacing: 0.2vw;
  color: rgba(255, 255, 255, 0.55);
  text-transform: uppercase;
}

.tempo-num {
  font-family: "VT323", monospace;
  font-size: clamp(20px, 1.7vw, 30px);
  background: #1a0d05;
  color: #ff7a2b;
  padding: 0.4vh 1vw;
  border-radius: 3px;
  min-width: 4.2vw;
  text-align: center;
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.8),
    inset 0 -1px 0 rgba(255, 122, 43, 0.2),
    0 1px 0 rgba(255, 255, 255, 0.06);
  text-shadow: 0 0 8px rgba(255, 122, 43, 0.6);
  cursor: ns-resize;
  user-select: none;
  border: none;
  outline: none;
}

.tempo-num:focus {
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.8),
    inset 0 -1px 0 rgba(255, 122, 43, 0.2),
    0 0 0 2px rgba(255, 122, 43, 0.5);
}

/* Mode toggle */
.mode-toggle {
  display: flex;
  background: #0a0805;
  border-radius: 4px;
  padding: 0.3vh 0.3vw;
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.7),
    0 1px 0 rgba(255, 255, 255, 0.06);
}

.mode-toggle .lbl,
.mode-toggle .mode-label {
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(9px, 0.7vw, 11px);
  letter-spacing: 0.15vw;
  color: rgba(255, 255, 255, 0.45);
  padding: 0.8vh 0.8vw;
  text-transform: uppercase;
  align-self: center;
}

.mode-btn {
  font-family: "Bowlby One", sans-serif;
  font-size: clamp(10px, 0.78vw, 12px);
  letter-spacing: 0.15vw;
  padding: 0.8vh 1vw;
  background: transparent;
  color: rgba(255, 255, 255, 0.5);
  border: none;
  border-radius: 3px;
  cursor: pointer;
  text-transform: uppercase;
  transition: all 0.15s ease;
}

.mode-btn:hover {
  color: rgba(255, 255, 255, 0.85);
}

.mode-btn.active {
  background: linear-gradient(180deg, #ff8b3e 0%, #d9531b 100%);
  color: #1a0d05;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    0 1px 0 rgba(0, 0, 0, 0.5);
}

/* ============================================================
   Humanize potentiometer — mounted on the sampler chassis,
   right of the LCD. Chassis-matched dark metal with a modern
   orange LED progress ring.
   ============================================================ */
.chassis-pot {
  /* CSS variables consumed by Dial.js's SVG so the knob reads as
     chassis-machined hardware rather than TR-909 silver. */
  --dial-bezel: #14110d;
  --dial-bezel-stroke: #0a0805;
  --dial-bezel-inner: #1c1814;
  --dial-bezel-inner-stroke: #0a0805;
  --dial-track-bg: #0a0805;
  --dial-track-inactive: #1c1814;
  --dial-accent: #ff7a2b;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Wrapper: knob only, no vertical stacking — keeps strip horizontally balanced */
.chassis-pot .dial-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 0;
  margin: 0;
}

/* Hide the embedded label and value — the LCD's SWING cell already shows the % */
.chassis-pot .dial-label,
.chassis-pot .dial-value {
  display: none;
}

/* Knob sized to match the LCD's vertical extent so the strip reads as one row */
.chassis-pot .dial-container {
  position: relative;
  width: clamp(38px, 3.4vw, 50px);
  height: clamp(38px, 3.4vw, 50px);
  padding: 0;
  margin: 0;
}

.chassis-pot .dial-svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Inset bezel ring so the pot looks bolted INTO the chassis surface */
.chassis-pot .dial-container::before {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 35%,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(0, 0, 0, 0.3) 60%,
    rgba(0, 0, 0, 0.6) 100%
  );
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.06),
    inset 0 -1px 1px rgba(0, 0, 0, 0.7),
    0 1px 0 rgba(255, 255, 255, 0.04);
  z-index: -1;
}

/* Soft halo behind the active ring — modern LED glow that bleeds into the chassis */
.chassis-pot .dial-glow {
  filter: drop-shadow(0 0 4px rgba(255, 122, 43, 0.55)) drop-shadow(0 0 1px rgba(255, 122, 43, 0.9));
}

/* ---- Vinyl record (SIDE A) ---- */
.vinyl {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at center, #c2410c 0 19%, transparent 19.2%),
    radial-gradient(circle at center, #0a0805 0 2%, transparent 2.2%),
    repeating-radial-gradient(circle at center, #0a0805 0 1px, #15110a 1px 3px), #0a0805;
  box-shadow:
    0 2vh 4vh -1vh rgba(0, 0, 0, 0.8),
    0 1vh 2vh -0.5vh rgba(0, 0, 0, 0.5),
    inset 0 0 60px rgba(0, 0, 0, 0.4);
  transform: rotate(-4deg);
  transition: transform 0.4s ease;
}

.vinyl::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(
    135deg,
    transparent 30%,
    rgba(255, 255, 255, 0.1) 45%,
    transparent 55%,
    rgba(255, 255, 255, 0.06) 70%,
    transparent 80%
  );
  pointer-events: none;
}

.vinyl::after {
  content: "DT-001";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fef3e2;
  font-family: "Bowlby One", sans-serif;
  font-size: 14px;
  letter-spacing: 2px;
  z-index: 2;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}

.sleeve {
  position: absolute;
  inset: -0.6vh -1vw -1vh -0.8vw;
  background: linear-gradient(135deg, #1a1815 0%, #2a2520 100%);
  z-index: -1;
  transform: rotate(-2deg);
  box-shadow:
    0 2vh 4vh -1vh rgba(0, 0, 0, 0.6),
    inset 0 0 30px rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.prop-vinyl {
  transition: transform 0.3s ease;
}

.prop-vinyl:hover {
  transform: translateY(-3px);
}

.prop-vinyl:hover .vinyl {
  animation: vinyl-spin 3.5s linear infinite;
  transform: rotate(0deg);
}

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

.prop-vinyl .sticker {
  transition:
    transform 0.25s ease,
    opacity 0.25s;
}

.prop-vinyl:hover .sticker {
  opacity: 0;
  pointer-events: none;
}

/* ---- Polaroid ---- */
.polaroid {
  background: #f4ecd6;
  padding: 0.7vw 0.7vw 2.2vw 0.7vw;
  box-shadow:
    0 2vh 3vh -1vh rgba(0, 0, 0, 0.6),
    0 0.8vh 1.6vh -0.5vh rgba(0, 0, 0, 0.4);
  transform: rotate(2.5deg);
  position: relative;
  width: 100%;
  transition:
    transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 0.3s;
}

.polaroid:hover {
  transform: rotate(1deg) translateY(-4px) scale(1.03);
  box-shadow:
    0 3vh 4vh -1vh rgba(0, 0, 0, 0.65),
    0 1.2vh 2vh -0.4vh rgba(0, 0, 0, 0.45);
}

.polaroid-photo {
  width: 100%;
  aspect-ratio: 1.1 / 1;
  background: linear-gradient(135deg, #3a2a1a 0%, #1a1208 100%);
  overflow: hidden;
}

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

.polaroid-caption {
  position: absolute;
  bottom: 0.4vw;
  left: 0;
  right: 0;
  text-align: center;
  font-family: "Permanent Marker", cursive;
  color: #2a1f10;
  font-size: clamp(10px, 0.75vw, 13px);
}

/* ---- Sticky note ---- */
.sticky {
  background: linear-gradient(180deg, #fde047 0%, #facc15 100%);
  color: #1a1208;
  padding: 1.2vh 1vw;
  font-family: "Permanent Marker", cursive;
  font-size: clamp(11px, 0.85vw, 14px);
  line-height: 1.4;
  width: 100%;
  box-shadow:
    0 1.5vh 2.5vh -0.5vh rgba(0, 0, 0, 0.55),
    0 0.5vh 1vh -0.2vh rgba(0, 0, 0, 0.4);
  transform: rotate(-2deg);
  position: relative;
  transition:
    transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 0.25s;
}

.sticky::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 50%;
  transform: translateX(-50%) rotate(-3deg);
  width: 40%;
  height: 12px;
  background: rgba(255, 250, 220, 0.7);
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.25);
}

.sticky:hover {
  transform: rotate(-2deg) translateY(-6px) scale(1.04);
  box-shadow:
    0 2.5vh 4vh -0.5vh rgba(0, 0, 0, 0.55),
    0 1vh 1.5vh -0.2vh rgba(0, 0, 0, 0.4);
}

/* ---- Cassette = MIDI Export ---- */
.cassette {
  position: relative;
  width: 100%;
  aspect-ratio: 1.55;
  background: linear-gradient(180deg, #1a120a 0%, #0a0805 100%);
  border-radius: 6px;
  padding: 0.9vh 0.7vw;
  border: none;
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 2vh 3vh -0.8vh rgba(0, 0, 0, 0.7),
    0 0.6vh 1.2vh rgba(0, 0, 0, 0.5),
    0 0 22px rgba(255, 122, 43, 0.18);
  transform: rotate(-2.5deg);
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
}

.cassette:hover {
  transform: rotate(-2.5deg) translateY(-3px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 2.6vh 4vh -0.8vh rgba(0, 0, 0, 0.75),
    0 1vh 1.8vh rgba(0, 0, 0, 0.55),
    0 0 32px rgba(255, 122, 43, 0.32);
}

.cassette:focus-visible {
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 2vh 3vh -0.8vh rgba(0, 0, 0, 0.7),
    0 0 0 3px #ff7a2b,
    0 0 24px rgba(255, 122, 43, 0.45);
}

.cassette-label {
  background: linear-gradient(180deg, #f4ecd6 0%, #e6d8ba 100%);
  height: 55%;
  border-radius: 2px;
  padding: 0.6vh 0.7vw;
  font-family: "Permanent Marker", cursive;
  color: #2a1f10;
  font-size: clamp(10px, 0.7vw, 12px);
  position: relative;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 1px 2px rgba(0, 0, 0, 0.3);
}

.cassette-label .tagline {
  font-family: "JetBrains Mono", monospace;
  font-size: clamp(7px, 0.5vw, 9px);
  letter-spacing: 1.5px;
  color: #6b4a2a;
  margin: 0;
  text-transform: uppercase;
}

.cassette-label .title {
  font-size: clamp(13px, 1.1vw, 18px);
  letter-spacing: 1px;
  line-height: 1.1;
  transition: text-shadow 0.3s;
}

.cassette-label .cassette-action {
  font-family: "Permanent Marker", cursive;
  font-size: clamp(9px, 0.7vw, 12px);
  color: #c2410c;
  margin: 0;
  letter-spacing: 0.5px;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
  animation: cassette-action-pulse 2.4s ease-in-out infinite;
}

@keyframes cassette-action-pulse {
  0%,
  100% {
    opacity: 0.85;
  }
  50% {
    opacity: 1;
  }
}

.cassette:hover .cassette-label .title {
  text-shadow: 0 0 6px rgba(255, 200, 80, 0.5);
}

.cassette-reels {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0.8vh;
  padding: 0 0.8vw;
  height: 35%;
}

.reel {
  width: 2.2vw;
  height: 2.2vw;
  max-width: 38px;
  max-height: 38px;
  min-width: 24px;
  min-height: 24px;
  border-radius: 50%;
  background:
    radial-gradient(circle at center, #c2410c 0 24%, transparent 24.4%),
    radial-gradient(circle at center, #0a0805 0 8%, transparent 8.4%),
    repeating-conic-gradient(from 0deg, #2a2520 0 30deg, #1a1510 30deg 60deg);
  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7);
  transition: transform 0.3s ease;
}

.cassette:hover .reel {
  animation: reel-spin 3.2s linear infinite;
}

.cassette:hover .reel:nth-child(2) {
  animation-direction: reverse;
}

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

.cassette-window {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 50%;
  height: 60%;
  background: linear-gradient(180deg, rgba(180, 140, 90, 0.4), rgba(120, 90, 60, 0.4));
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.cassette-confirm {
  position: absolute;
  top: 22%;
  left: 10%;
  right: 10%;
  padding: 0.6vh 0.6vw;
  background: #ff7a2b;
  color: #0a0805;
  font-family: "Permanent Marker", cursive;
  font-size: clamp(10px, 0.85vw, 14px);
  text-align: center;
  border-radius: 2px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  z-index: 10;
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
}

.cassette.is-confirming .cassette-confirm {
  opacity: 1;
  transform: translateY(0);
}

.cassette.is-confirming .cassette-confirm::before {
  content: "MIDI EXPORTED · donut-sessions.mid";
}

.cassette.is-confirming .reel {
  animation: reel-spin 0.8s linear 2;
}

/* Stickers/labels */
.sticker {
  position: absolute;
  font-family: "Permanent Marker", cursive;
  color: #fef3e2;
  font-size: 12px;
  letter-spacing: 1px;
  background: #c2410c;
  padding: 4px 10px;
  transform: rotate(-6deg);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

/* ====================================================
   LP sleeves
   ==================================================== */
.lp-with-peek {
  position: relative;
}

.lp-with-peek .lp {
  position: relative;
  z-index: 2;
  transition: transform 0.45s cubic-bezier(0.3, 0.7, 0.4, 1.4);
}

.lp-vinyl-peek {
  position: absolute;
  top: 4%;
  right: 4%;
  width: 92%;
  height: 92%;
  border-radius: 50%;
  background:
    radial-gradient(circle at center, #c2410c 0 18%, transparent 18.2%),
    radial-gradient(circle at center, #15110a 0 2%, transparent 2.2%),
    repeating-radial-gradient(circle at center, #0a0805 0 1px, #1a1510 1px 3px), #0a0805;
  box-shadow:
    0 4px 14px rgba(0, 0, 0, 0.6),
    inset 0 0 40px rgba(0, 0, 0, 0.4);
  transform: translate(0, 0) rotate(0deg);
  transition: transform 0.55s cubic-bezier(0.3, 0.7, 0.4, 1.4);
  z-index: 1;
  pointer-events: none;
}

.lp-with-peek:hover .lp-vinyl-peek {
  transform: translate(55%, 6%) rotate(18deg);
}

.lp-with-peek:hover .lp {
  transform: translate(-3%, -1%);
}

.lp {
  position: relative;
  aspect-ratio: 1;
  background: #1a1510;
  box-shadow:
    0 18px 30px -10px rgba(0, 0, 0, 0.7),
    0 6px 14px -4px rgba(0, 0, 0, 0.5),
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    inset 0 -3px 6px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  user-select: none;
}

.lp::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 80% 30px at 50% 0%, rgba(255, 255, 255, 0.06), transparent 60%),
    radial-gradient(ellipse 30px 80% at 0% 50%, rgba(0, 0, 0, 0.45), transparent 60%),
    radial-gradient(ellipse 30px 80% at 100% 50%, rgba(0, 0, 0, 0.45), transparent 60%);
  mix-blend-mode: overlay;
  opacity: 0.7;
}

.lp::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    135deg,
    transparent 35%,
    rgba(255, 255, 255, 0.12) 45%,
    transparent 55%,
    rgba(255, 255, 255, 0.04) 65%,
    transparent 80%
  );
  z-index: 5;
}

/* Photo LP variant */
.lp--photo {
  background: #15110a;
  display: flex;
  flex-direction: column;
}

.lp-photo-img {
  flex: 1;
  background: #2a1810;
  overflow: hidden;
  position: relative;
}

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

.lp--photo .footer {
  background: #1a0d05;
  color: #ff7a2b;
  padding: 8px 12px;
  font-family: "Bowlby One", sans-serif;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  border-top: 1px solid rgba(255, 122, 43, 0.3);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.lp--photo .footer small {
  font-family: "JetBrains Mono", monospace;
  font-size: 8px;
  opacity: 0.6;
  letter-spacing: 1.5px;
}

/* Circles variant */
.lp--circles {
  background:
    radial-gradient(circle at 30% 35%, #f59e0b 0 90px, transparent 92px),
    radial-gradient(circle at 65% 60%, #c2410c 0 60px, transparent 62px),
    radial-gradient(circle at 75% 30%, #fef3e2 0 30px, transparent 32px),
    linear-gradient(135deg, #2a1810 0%, #4a2818 100%);
  padding: 14px 14px 18px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  color: #f4ecd6;
}

.lp--circles .meta {
  font-family: "JetBrains Mono", monospace;
  font-size: 9px;
  letter-spacing: 2px;
  opacity: 0.7;
  text-transform: uppercase;
}

.lp--circles .title {
  font-family: "Bowlby One", sans-serif;
  font-size: clamp(16px, 1.5vw, 22px);
  letter-spacing: 1px;
  margin-top: 4px;
  text-transform: uppercase;
  line-height: 0.95;
}

/* Stripes variant */
.lp--stripes {
  background: repeating-linear-gradient(45deg, #c2410c 0 18px, #1a0d05 18px 36px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.lp--stripes .badge {
  background: #fef3e2;
  color: #1a0d05;
  padding: 12px 14px;
  font-family: "Bowlby One", sans-serif;
  font-size: clamp(12px, 1.2vw, 18px);
  letter-spacing: 1px;
  text-align: center;
  line-height: 1;
  transform: rotate(-3deg);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
}

.lp--stripes .badge small {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: 9px;
  margin-top: 6px;
  letter-spacing: 2px;
  font-weight: 400;
  opacity: 0.7;
}

/* Portrait variant */
.lp--portrait {
  background: linear-gradient(180deg, #c2410c 0%, #7a2810 100%);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lp-portrait-img {
  flex: 1;
  background: rgba(0, 0, 0, 0.4);
  overflow: hidden;
}

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

.lp--portrait .text {
  font-family: "Bowlby One", sans-serif;
  color: #fef3e2;
  font-size: 13px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-align: center;
}

.lp--portrait .text small {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: 8px;
  font-weight: 400;
  letter-spacing: 2px;
  margin-top: 2px;
  opacity: 0.75;
}

/* Fanned LP cluster */
.lp-fan {
  position: relative;
  aspect-ratio: 1.6;
  flex-shrink: 0;
  width: 100%;
}

.lp-fan > .lp-with-peek {
  position: absolute;
  top: 0;
  left: 0;
  width: 55%;
  aspect-ratio: 1;
}

.lp-fan > .lp-with-peek > .lp {
  width: 100%;
  height: 100%;
}

.prop-funk {
  transition: transform 0.3s ease;
}

.prop-funk:hover {
  transform: rotate(2deg) translateY(-3px);
}

/* ---- Avatar canvas (head-bob character) — fixed to bottom of screen ---- */
#avatar-canvas {
  position: fixed;
  bottom: 9.5vh;
  left: 50%;
  transform: translateX(-50%);
  width: clamp(100px, 10vw, 160px);
  height: clamp(100px, 10vw, 160px);
  display: block;
  background: transparent;
  pointer-events: none;
  z-index: 25;
  filter: drop-shadow(0 0.8vh 1.6vh rgba(0, 0, 0, 0.6));
}
