/* ===== CD Player (home page section + top of /music/allMusic.html) =====

   cdplayer.png is 208 x 160 px, drawn at half scale and shown at up to 2x (416 x 320), the same way
   tv.png works. It is drawn over everything, so its windows must be transparent. Everything below is
   positioned as a percentage of that image, so it keeps lining up as the player shrinks.
   Positions in the 208 x 160 image (top-left corner, size):
     disc window   x 12,  y 12    96 x 96   (the disc spins in here; the hole can be round)
     album cover   x 132, y 12    48 x 48
     display       x 116, y 68    80 x 40   (title, artist, time)
     seek slider   x 12,  y 114  128 x 10
     volume        x 148, y 114   48 x 10
     previous      x 12,  y 130   32 x 20
     play / pause  x 48,  y 130   44 x 20
     next          x 96,  y 130   32 x 20
     See All       x 132, y 130   64 x 20
   Save it as /images/music/cdplayer.png. Until that file exists, the grey CSS body below is shown. */

/* ----- Home page section title: centred, with a CD shine and an equalizer ----- */

#music h2 {
  display: flex;
  align-items: flex-end;
  gap: 0.6em;
  margin: 0 0 1rem; /* full width: the equalizer fills the space either side of the title */
}

/* Mostly green, with a band of rainbow sliding through the letters like light across a disc */
.cd-heading-text {
  background: linear-gradient(100deg,
    #33ff7a 0%, #33ff7a 38%,
    #7df9ff 43%, #b9a8ff 48%, #ff8ad8 53%, #ffe27a 58%,
    #33ff7a 63%, #33ff7a 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: cdShine 6s linear infinite;
}

@keyframes cdShine {
  from { background-position: 100% 0; }
  to   { background-position: 0 0; }
}

/* Equalizer: bars that sit low while paused and move while a song plays. scripts/musicPlayer.js
   adds as many bars as fit either side of the title (change the width and gap below to taste).
   scripts/musicPlayer.js puts cd-is-playing on the section. The bounce below is only the fallback
   for browsers without Web Audio; normally the bars follow the real song (see cd-eq-live). */
.cd-eq {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 1em;
  padding-bottom: 0.15em; /* lines the bars up with the bottom of the letters */
  box-sizing: content-box;
}

/* Bars hug the title: the left group is packed to the right, the right group to the left */
.cd-eq:first-child {
  justify-content: flex-end;
}

.cd-eq i {
  display: block;
  flex: none;
  width: 3px;
  height: 100%;
  background: #33ff7a;
  transform: scaleY(0.15);
  transform-origin: bottom;
}

.cd-is-playing .cd-eq i {
  animation: cdEq 0.9s steps(5) infinite alternate;
}

/* With a live equalizer, scripts/musicPlayer.js sets each bar's height from the song itself */
.cd-eq-live .cd-eq i {
  animation: none;
}

/* Each bar gets its own speed and starting point, so they don't move together */
.cd-eq i:nth-child(4n + 1) { animation-duration: 0.7s;  animation-delay: -0.2s; }
.cd-eq i:nth-child(4n + 2) { animation-duration: 0.5s;  animation-delay: -0.4s; }
.cd-eq i:nth-child(4n + 3) { animation-duration: 0.85s; animation-delay: -0.1s; }
.cd-eq i:nth-child(4n + 4) { animation-duration: 0.6s;  animation-delay: -0.5s; }

@keyframes cdEq {
  from { transform: scaleY(0.15); }
  to   { transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
  .cd-heading-text,
  .cd-is-playing .cd-eq i {
    animation: none;
  }
}

/* ----- The player ----- */

#music-container {
  display: flex;
  justify-content: center;
}

.cd-player {
  position: relative;
  width: 100%;
  max-width: 416px;
  aspect-ratio: 208 / 160;
  container-type: inline-size; /* text and buttons scale with the player */

  /* LCD filter: dark corners, scanlines and faint RGB stripes. Same recipe as the CRT filter on the
     Hallucinations pictures (.hallu-pic::after). It goes over the display and the album cover.
     To turn it down on both, lower the 0.28 (scanlines). */
  --lcd-filter:
    radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, 0.45) 100%),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.28) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(255, 0, 0, 0.05) 0 1px, rgba(0, 255, 0, 0.05) 1px 2px, rgba(0, 0, 255, 0.05) 2px 3px);

  /* The sliders only get vertical lines: no scanlines, no dark corners, no RGB stripes.
     Lower the 0.28 to soften them; change the 3px to space them further apart. */
  --lcd-columns: repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.28) 0 1px, transparent 1px 3px);

  /* Stand-in body, used only while cdplayer.png is missing */
  background: #6f6f6f;
  border: 2px solid #4a4a4a;
  box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.22), inset -2px -2px 0 rgba(0, 0, 0, 0.25);
}

/* scripts/musicPlayer.js adds has-art once cdplayer.png has loaded */
.cd-player.has-art {
  background: none;
  border: none;
  box-shadow: none;
}

.cd-player.has-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url('/images/music/cdplayer.png') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  pointer-events: none; /* clicks pass through to the controls underneath */
  z-index: 3;
}

/* ----- Disc ----- */

.cd-disc-window {
  position: absolute;
  left: 5.7692%;   /* 12 / 208 */
  top: 7.5%;       /* 12 / 160 */
  width: 46.1538%; /* 96 / 208 */
  height: 60%;     /* 96 / 160 */
  background: #101010;
  overflow: hidden;
  z-index: 1;
}

.cd-disc {
  position: absolute;
  inset: 0;
  background: center / contain no-repeat;
  image-rendering: pixelated;
  animation: cdSpin var(--cd-spin-time, 2.4s) linear infinite;
  animation-play-state: paused; /* pausing keeps the disc at its current angle */
}

.cd-player.is-playing .cd-disc {
  animation-play-state: running;
}

/* No disc in the player (between songs on the All Music page) */
.cd-player.is-empty .cd-disc {
  opacity: 0;
  transition: opacity 0.2s ease; /* fades out only; a landing disc appears at once, with no flicker */
}

@keyframes cdSpin {
  to { transform: rotate(360deg); }
}

/* Plain silver disc, used when a song has no songname-d.png */
.cd-disc-fallback {
  border-radius: 50%;
  background-image: conic-gradient(#cfd6d2, #f5f5f5, #9fe8bd, #cfd6d2, #f5f5f5, #b9c2ff, #cfd6d2);
  -webkit-mask: radial-gradient(circle, transparent 0 8%, #000 8.5%);
  mask: radial-gradient(circle, transparent 0 8%, #000 8.5%);
}

/* ----- Album cover ----- */

.cd-cover {
  position: absolute;
  left: 63.4615%;  /* 132 / 208 */
  top: 7.5%;       /* 12 / 160 */
  width: 23.0769%; /* 48 / 208 */
  height: 30%;     /* 48 / 160 */
  background: #101010;
  z-index: 1;
}

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

.cd-cover img.is-missing {
  visibility: hidden;
}

/* ----- Display ----- */

.cd-lcd {
  position: absolute;
  left: 55.7692%;  /* 116 / 208 */
  top: 42.5%;      /* 68 / 160 */
  width: 38.4615%; /* 80 / 208 */
  height: 25%;     /* 40 / 160 */
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 3%;
  overflow: hidden;
  background: #0d1a12;
  z-index: 1;
}

/* LCD filter over the display and the album cover (--lcd-filter is defined on .cd-player).
   Delete this rule to remove it from these two. */
.cd-lcd::after,
.cd-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: var(--lcd-filter);
}

/* Softer on the album art, so the cover stays easy to see (1 = same strength as the display) */
.cd-cover::after {
  opacity: 0.4;
}

/* Display text. scripts/musicPlayer.js wraps the title and artist in a <span> and, when a line is
   too long for the display, adds is-scrolling plus --scroll (how far to slide) and --scroll-time. */
.cd-title,
.cd-artist,
.cd-time {
  font-family: "Press Start 2P", monospace;
  font-weight: normal; /* Press Start 2P only has one weight */
  line-height: 1.6;
  white-space: nowrap;
  overflow: hidden;
}

.cd-title {
  font-size: clamp(0.5rem, 3.2cqw, 0.85rem);
  color: #33ff7a;
}

.cd-artist,
.cd-time {
  font-size: clamp(0.45rem, 2.7cqw, 0.7rem);
  color: #8fc9a6;
}

.cd-lcd span {
  display: inline-block;
}

/* Slides to the end of the line, waits, slides back, waits */
.cd-lcd .is-scrolling span {
  animation: cdLcdScroll var(--scroll-time, 6s) linear infinite alternate;
}

@keyframes cdLcdScroll {
  0%, 15%   { transform: translateX(0); }
  85%, 100% { transform: translateX(var(--scroll, 0px)); }
}

@media (prefers-reduced-motion: reduce) {
  .cd-lcd .is-scrolling span {
    animation: none;
  }
}

/* ----- Sliders ----- */

.cd-seek,
.cd-volume {
  position: absolute;
  top: 71.25%;    /* 114 / 160 */
  height: 6.25%;  /* 10 / 160 */
  margin: 0;
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
  /* The green fill is the slider's position; --fill is set by scripts/musicPlayer.js.
     The vertical lines are layered on top of it (a slider can't have an ::after like the display does). */
  background:
    var(--lcd-columns),
    linear-gradient(to right, #33ff7a 0 var(--fill, 0%), #1b1b1b var(--fill, 0%) 100%);
  border: 2px solid #4a4a4a;
  cursor: pointer;
  z-index: 1;
}

.cd-seek   { left: 5.7692%;  width: 61.5385%; } /* 12 / 208, 128 / 208 */
.cd-volume { left: 71.1538%; width: 23.0769%; } /* 148 / 208, 48 / 208 */

.cd-seek:disabled,
.cd-volume:disabled {
  cursor: default;
}

/* The handle is invisible; the fill shows where it is */
.cd-seek::-webkit-slider-thumb,
.cd-volume::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  opacity: 0;
}

.cd-seek::-moz-range-thumb,
.cd-volume::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: none;
  opacity: 0;
}

.cd-seek::-moz-range-track,
.cd-volume::-moz-range-track {
  background: transparent;
}

/* ----- Buttons: plastic, like the TV's ----- */

.cd-btn {
  position: absolute;
  top: 81.25%;   /* 130 / 160 */
  height: 12.5%; /* 20 / 160 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-family: inherit;
  font-size: clamp(0.6rem, 3.6cqw, 0.95rem);
  line-height: normal;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  z-index: 1;

  color: #f0f0f0;
  background: #6f6f6f;
  border: 2px solid #4a4a4a;
  box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.22), inset -2px -2px 0 rgba(0, 0, 0, 0.25);
  text-shadow: 1px 1px 0 #3a3a3a;
}

.cd-btn:hover:not(:disabled) {
  color: #ffffff;
  background: #4a4a4a;
  border-color: #6f6f6f;
  box-shadow: inset 2px 2px 0 rgba(0, 0, 0, 0.3), inset -2px -2px 0 rgba(255, 255, 255, 0.12);
  text-decoration: none;
}

.cd-btn:active:not(:disabled) {
  transform: translateY(1px);
}

.cd-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.cd-prev   { left: 5.7692%;  width: 15.3846%; } /* 12 / 208, 32 / 208 */
.cd-play   { left: 23.0769%; width: 21.1538%; } /* 48 / 208, 44 / 208 */
.cd-next   { left: 46.1538%; width: 15.3846%; } /* 96 / 208, 32 / 208 */
.cd-seeall { left: 63.4615%; width: 30.7692%; } /* 132 / 208, 64 / 208 */

/* Button icons, drawn in CSS so they match on every device */
.cd-icon {
  display: block;
  width: 1em;
  height: 1em;
  background: currentColor;
}

/* The play triangle is made from borders, not clip-path: on the sloped home page a clip-path
   that touches the top edge of its box leaves a stray line there in some browsers */
.cd-icon-play {
  box-sizing: border-box;
  width: 0.85em;
  height: 1em;
  margin-left: 0.15em;
  background: none;
  border-style: solid;
  border-color: transparent transparent transparent currentColor;
  border-width: 0.5em 0 0.5em 0.85em;
}

/* Play turns into pause while a song is playing */
.cd-player.is-playing .cd-icon-play {
  width: 1em;
  margin-left: 0;
  border: 0;
  background: linear-gradient(to right, currentColor 0 36%, transparent 36% 64%, currentColor 64% 100%);
}

.cd-icon-next,
.cd-icon-prev {
  clip-path: polygon(0 10%, 50% 50%, 50% 10%, 100% 50%, 50% 90%, 50% 50%, 0 90%);
}

.cd-icon-prev {
  transform: scaleX(-1);
}