/*
    Vinyl audio player - two skins off one implementation.

      .wfa-vinyl--wave   waveform runs the width of the bar, the play button
                         swells into a spinning record, progress fills along
                         the bottom edge
      .wfa-vinyl--roll   the record is thrown out of the button and rides a
                         dotted waveform, scattering what it passes into notes

    Everything is scoped under .wfa-vinyl and reset on the way in. This lands
    inside 98 purchased designs whose global CSS is not ours and does things
    like `img { width: 100% }`, `ul li { list-style: none }` and box-sizing
    resets that would otherwise reshape the internals.

    Widths are fluid on purpose: the player replaces a jPlayer container
    wherever a design put one, from a 240px portfolio tile to a full-width
    press kit row, and it is never told which. Anything positional is a
    percentage or a flex rule; only heights are fixed.
*/

.wfa-vinyl {
  --wfa-accent: #d94240;
  --wfa-surface: #ffffff;
  --wfa-ink: #85888d;
  --wfa-disc-dark: #191a1e;

  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: 78px;
  padding: 0 14px 0 16px;
  margin: 0;
  background: var(--wfa-surface);
  box-shadow: 0 6px 18px rgba(41, 55, 84, 0.09), 0 1px 3px rgba(41, 55, 84, 0.06);
  font-family: inherit;
  text-align: left;
  overflow: hidden;
}

.wfa-vinyl *,
.wfa-vinyl *::before,
.wfa-vinyl *::after {
  box-sizing: border-box;
}

/*
    :where() on the descendant, deliberately. It contributes no specificity,
    so this whole rule weighs exactly one class (.wfa-vinyl) - enough to beat
    a design's bare `div { margin: 10px }`, but a tie with the component's own
    single-class rules below, which then win on source order.

    Written as `.wfa-vinyl div, ...` instead, it weighed a class AND an element
    and quietly out-ranked them: the record lost its background to
    `background: none` and the travelling puck lost the negative margins that
    centre it, so it rendered as a bare red dot hanging below the bar.
*/
.wfa-vinyl :where(div, span, i, b, button) {
  float: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  list-style: none;
  text-indent: 0;
  line-height: normal;
  text-transform: none;
  letter-spacing: normal;
}

/* ------------------------------------------------------------- waveform -- */

.wfa-vinyl__stage {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
}

/*
    The waveform is drawn at rest, quietly, rather than hidden until play.

    In the mock this player came from, the resting card carried artwork, a
    title and a duration, so hiding the waveform left something to look at.
    Here the design supplies all three around the player and the bar is what
    is left — hidden, it renders as an empty white box in the middle of a
    portfolio grid. Playing lifts the same waveform to full strength instead
    of introducing it.
*/
.wfa-vinyl__wave {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* wave skin: thin bars, live amplitude */
.wfa-vinyl__wave > i {
  display: block;
  flex: 0 0 2px;
  width: 2px;
  height: var(--h, 10px);
  border-radius: 1px;
  background: var(--wfa-accent);
  opacity: 0.4;
  transform: scaleY(0.4);
  transition:
    opacity 0.3s ease,
    transform 0.4s cubic-bezier(0.2, 0.85, 0.25, 1);
}
.wfa-vinyl.is-playing .wfa-vinyl__wave > i {
  opacity: 1;
}
.wfa-vinyl.is-playing .wfa-vinyl--wave-bars > i {
  animation: wfa-pulse var(--d, 1s) var(--dl, 0s) ease-in-out infinite alternate;
}
@keyframes wfa-pulse {
  from {
    transform: scaleY(0.3);
  }
  to {
    transform: scaleY(1);
  }
}

/* roll skin: columns of dots, magenta -> gold -> red across the track */
.wfa-vinyl__wave.wfa-vinyl--roll-dots > i {
  position: relative;
  display: flex;
  flex: 0 1 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 3px;
  height: 100%;
  background: none;
  transform: none;
}
.wfa-vinyl__wave.wfa-vinyl--roll-dots > i > b {
  display: block;
  width: 3px;
  height: 3px;
  border-radius: 1px;
  background: var(--c, #d94240);
  opacity: 0.4;
  transition: opacity 0.3s ease;
}
.wfa-vinyl.is-playing .wfa-vinyl--roll-dots > i > b {
  animation: wfa-blip var(--d, 1s) var(--dl, 0s) ease-in-out infinite;
}
@keyframes wfa-blip {
  0%,
  100% {
    opacity: 0.18;
    transform: scale(0.7);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* a column the record has rolled past scatters into a music note */
.wfa-vinyl__wave.wfa-vinyl--roll-dots > i::after {
  content: var(--note, "\266A");
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 15px;
  line-height: 1;
  color: var(--c, #d94240);
  opacity: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.wfa-vinyl__wave.wfa-vinyl--roll-dots > i.is-spent > b {
  animation: wfa-vanish 0.3s ease-in forwards !important;
}
.wfa-vinyl__wave.wfa-vinyl--roll-dots > i.is-spent::after {
  animation: wfa-fly 1.15s ease-out forwards;
}
@keyframes wfa-vanish {
  to {
    opacity: 0;
    transform: scale(0.2);
  }
}
@keyframes wfa-fly {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5) rotate(0deg);
  }
  18% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
    transform: translate(-200%, -270%) scale(1) rotate(-18deg);
  }
}

/* ------------------------------------------------ notes off the record --- */

.wfa-vinyl__notes {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.wfa-vinyl__notes > i {
  position: absolute;
  top: 50%;
  font-size: var(--s, 14px);
  font-style: normal;
  line-height: 1;
  color: var(--c, #d94240);
  will-change: transform, opacity;
  animation: wfa-drift var(--d, 1.4s) ease-out forwards;
}
@keyframes wfa-drift {
  0% {
    opacity: 0;
    transform: translate(0, -50%) scale(0.35) rotate(0deg);
  }
  14% {
    opacity: 0.95;
  }
  100% {
    opacity: 0;
    transform: translate(var(--dx, -60px), calc(-50% + var(--dy, -20px))) scale(1) rotate(var(--r, -15deg));
  }
}

/* ---------------------------------------------- the record that travels -- */

.wfa-vinyl__puck {
  position: absolute;
  top: 50%;
  left: 0;
  width: 56px;
  height: 56px;
  margin: -28px 0 0 -28px;
  transform: translateX(var(--x, 0px));
  opacity: 0;
  transition:
    transform 0.25s linear,
    opacity 0.2s ease;
}
.wfa-vinyl__puck.is-travelling {
  transition:
    transform 0.55s cubic-bezier(0.3, 0.9, 0.3, 1),
    opacity 0.2s ease;
  filter: url("#wfa-streak");
}
.wfa-vinyl.is-playing .wfa-vinyl__puck {
  opacity: 1;
}

/* ---------------------------------------------------------- the record --- */

.wfa-vinyl__disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--wfa-disc-dark);
  box-shadow:
    0 8px 20px rgba(20, 26, 40, 0.34),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

/*
    The part that turns. Grooves over a conic sheen sweeping black -> gray ->
    black, which is the only thing that makes the spin readable at all:
    concentric rings are rotationally identical, so a record textured with
    grooves alone looks motionless however fast it turns.
*/
.wfa-vinyl__platter {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    repeating-radial-gradient(
      circle at 50% 50%,
      rgba(255, 255, 255, 0.045) 0 1.1px,
      rgba(0, 0, 0, 0.38) 1.1px 2.3px
    ),
    conic-gradient(
      from 0deg,
      #191a1e 0deg,
      #2c2d33 28deg,
      #43444d 58deg,
      #4a4b55 80deg,
      #2a2b31 112deg,
      #1a1b1f 142deg,
      #26272d 172deg,
      #42434c 212deg,
      #4c4d57 240deg,
      #2d2e34 276deg,
      #1a1b1f 312deg,
      #191a1e 360deg
    );
  animation: wfa-spin 2.6s linear infinite;
  animation-play-state: paused;
}
.wfa-vinyl.is-playing .wfa-vinyl__platter {
  animation-play-state: running;
}
.wfa-vinyl__platter::after {
  content: "";
  position: absolute;
  inset: 30%;
  border-radius: 50%;
  background: var(--wfa-accent);
  box-shadow: inset 0 -2px 5px rgba(0, 0, 0, 0.18);
}
@keyframes wfa-spin {
  to {
    transform: rotate(360deg);
  }
}

/* fixed glass reflection, deliberately outside the turning part */
.wfa-vinyl__gloss {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(
    128deg,
    rgba(255, 255, 255, 0.2) 0%,
    rgba(255, 255, 255, 0.03) 34%,
    rgba(255, 255, 255, 0) 56%,
    rgba(255, 255, 255, 0.1) 100%
  );
  pointer-events: none;
}

/* the note printed on the label of the travelling record, turns with it */
.wfa-vinyl__label {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.6);
  pointer-events: none;
}

/* ---------------------------------------------------------- the button --- */

/*
    Shows the track length at rest and counts down while playing — the mock's
    resting card carried a duration too, and it is the only text the bar has.
*/
.wfa-vinyl__time {
  flex: 0 0 auto;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--wfa-ink);
  font-variant-numeric: tabular-nums;
  opacity: 0.65;
  transition: opacity 0.3s ease;
}
.wfa-vinyl.is-playing .wfa-vinyl__time {
  opacity: 1;
}
/* the roll skin's record is itself the position indicator - a clock beside it
   is saying the same thing twice, and the design it came from has none */
.wfa-vinyl--roll .wfa-vinyl__time {
  display: none;
}

.wfa-vinyl__btn {
  position: relative;
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 8px 18px rgba(41, 55, 84, 0.16);
  cursor: pointer;
  outline: none;
  transition:
    transform 0.4s cubic-bezier(0.34, 1.35, 0.5, 1),
    box-shadow 0.4s ease;
}
.wfa-vinyl__btn .wfa-vinyl__disc {
  opacity: 0;
  transform: scale(0.55);
  transition:
    opacity 0.28s ease,
    transform 0.4s cubic-bezier(0.34, 1.35, 0.5, 1);
}
/* only the wave skin turns its button into the record */
.wfa-vinyl--wave.is-playing .wfa-vinyl__btn {
  transform: scale(1.22);
  box-shadow: none;
}
.wfa-vinyl--wave.is-playing .wfa-vinyl__btn .wfa-vinyl__disc {
  opacity: 1;
  transform: scale(1);
}
.wfa-vinyl--roll .wfa-vinyl__btn .wfa-vinyl__disc {
  display: none;
}

.wfa-vinyl__icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wfa-vinyl__icon svg {
  transition:
    opacity 0.18s ease,
    transform 0.28s ease;
}
.wfa-vinyl__icon .wfa-ico-play {
  margin-left: 3px;
}
.wfa-vinyl__icon .wfa-ico-pause {
  position: absolute;
  opacity: 0;
  transform: scale(0.6);
}
.wfa-vinyl.is-playing .wfa-vinyl__icon .wfa-ico-play {
  opacity: 0;
  transform: scale(0.6);
}
.wfa-vinyl.is-playing .wfa-vinyl__icon .wfa-ico-pause {
  opacity: 1;
  transform: scale(1);
}

/* --------------------------------------------------------- progress bar -- */

.wfa-vinyl__progress {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 3px;
  background: var(--wfa-accent);
  transition: width 0.25s linear;
}
.wfa-vinyl--roll .wfa-vinyl__progress {
  display: none;
}

/* the directional smear, on only while something is being thrown */
.wfa-vinyl.is-entering .wfa-vinyl__wave,
.wfa-vinyl.is-leaving .wfa-vinyl__wave {
  filter: url("#wfa-streak");
}

/* ------------------------------------------------------------- narrower -- */

@media (max-width: 420px) {
  .wfa-vinyl {
    height: 68px;
    gap: 10px;
    padding: 0 10px 0 12px;
  }
  .wfa-vinyl__btn {
    width: 44px;
    height: 44px;
  }
  .wfa-vinyl__puck {
    width: 46px;
    height: 46px;
    margin: -23px 0 0 -23px;
  }
  .wfa-vinyl__time {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .wfa-vinyl.is-playing .wfa-vinyl--wave-bars > i,
  .wfa-vinyl.is-playing .wfa-vinyl--roll-dots > i > b {
    animation: none;
  }
  .wfa-vinyl__platter {
    animation-duration: 14s;
  }
}
