/* ═══════════════════════════════════════════════════════════════
 * spotify-now-playing.css
 * ═══════════════════════════════════════════════════════════════
 * Real-time "Now Playing" module styles
 *
 * Design tokens: matches aegis.css (void/rust/blood palette)
 * Animation: 100% CSS transforms, zero JS animation frames
 * Performance: will-change on animated properties only, GPU-composited
 * ═══════════════════════════════════════════════════════════════ */

/* ─── Container ─────────────────────────────────────────────── */
.now-playing {
  --np-void: #050505;
  --np-rust: #F15A24;
  --np-blood: #DA2C38;
  --np-slate: #1a1a2e;
  --np-dim: #8b8f98; /* #666 was 3.4:1 on void — below WCAG AA */
  --np-text: #ccc;

  /* genre-mood accent (JS swaps these per-track via track.toptags) */
  --np-accent: var(--np-rust);
  --np-accent-soft: rgba(241, 90, 36, 0.4);
  --np-accent-faint: rgba(241, 90, 36, 0.07);

  padding: 12px 16px;
  border-top: 1px solid var(--np-slate);
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 11px;
  line-height: 1.4;
  color: var(--np-text);
  user-select: none;
  overflow: hidden;
  transition: background-color 0.6s ease;
}

.now-playing--fixed {
  position: fixed;
  bottom: 16px;
  right: 16px;
  left: auto;
  width: 320px;
  max-width: calc(100vw - 32px);
  z-index: 9999;
  background: rgba(5, 5, 5, 0.95);
  border: 1px solid var(--np-slate);
  box-shadow: 6px 6px 0 rgba(34, 34, 42, 0.9);
}

/* ─── Living layer: ambient aurora in the genre color ───────── */
.now-playing--fixed {
  animation: np-in 1s cubic-bezier(0.2, 0.9, 0.25, 1) backwards;
}

.now-playing--fixed::before {
  content: "";
  position: absolute;
  inset: -40%;
  z-index: 0;
  background:
    radial-gradient(45% 45% at 20% 20%, var(--np-accent-faint), transparent 70%),
    radial-gradient(40% 40% at 80% 70%, var(--np-accent-faint), transparent 70%);
  animation: np-aurora 22s ease-in-out infinite alternate;
  pointer-events: none;
}

.now-playing--fixed > * {
  position: relative;
  z-index: 1;
}

@keyframes np-aurora {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(3%, -2%) scale(1.05); }
  100% { transform: translate(-3%, 2%) scale(1); }
}

@keyframes np-in {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to { opacity: 1; transform: none; }
}

/* ─── Label ─────────────────────────────────────────────────── */
.np-label {
  color: var(--np-dim);
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-bottom: 6px;
  transition: color 0.6s ease;
}

.np-label--active {
  color: var(--np-accent);
  text-shadow: 0 0 8px var(--np-accent-soft);
  transition: color 1.2s ease;
  position: relative;
  padding-left: 10px;
}

/* live dot: heartbeat in the genre color */
.np-label--active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  background: var(--np-accent);
  box-shadow: 0 0 6px var(--np-accent-soft);
  animation: np-dot 2.4s ease-in-out infinite;
}

@keyframes np-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.8); }
}

/* ─── Status Row ────────────────────────────────────────────── */
.np-status {
  display: flex;
  align-items: center;
  gap: 10px;
}
.np-status > * {
  min-width: 0;
}

/* ─── Equalizer (CSS-only, 5 bars) ─────────────────────────── */
.np-equalizer {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 18px;
  flex-shrink: 0;
}

.eq-bar {
  display: block;
  width: 3px;
  height: 4px;
  background: var(--np-accent);
  border-radius: 1px;
  transform-origin: bottom;
  will-change: transform;
  transition: height 0.15s ease, background-color 0.6s ease;
}

/* Playing state: each bar animates independently via CSS keyframes */
.np-playing .eq-bar:nth-child(1) {
  animation: eq-bounce 0.9s ease-in-out infinite alternate;
  animation-delay: 0s;
}
.np-playing .eq-bar:nth-child(2) {
  animation: eq-bounce 0.76s ease-in-out infinite alternate;
  animation-delay: 0.16s;
}
.np-playing .eq-bar:nth-child(3) {
  animation: eq-bounce 1.04s ease-in-out infinite alternate;
  animation-delay: 0.3s;
}
.np-playing .eq-bar:nth-child(4) {
  animation: eq-bounce 0.82s ease-in-out infinite alternate;
  animation-delay: 0.1s;
}
.np-playing .eq-bar:nth-child(5) {
  animation: eq-bounce 0.96s ease-in-out infinite alternate;
  animation-delay: 0.24s;
}
.np-playing .eq-bar:nth-child(6) {
  animation: eq-bounce 0.72s ease-in-out infinite alternate;
  animation-delay: 0.38s;
}
.np-playing .eq-bar:nth-child(7) {
  animation: eq-bounce 1s ease-in-out infinite alternate;
  animation-delay: 0.06s;
}

/* Idle state: bars collapse to minimum height */
.np-idle .eq-bar {
  height: 3px;
  opacity: 0.3;
}

/* Paused state (Last.fm "last scrobbled", not playing now): freeze bars */
.np-playing.np-paused .eq-bar {
  animation: none;
  height: 6px;
  opacity: 0.5;
}
.np-playing.np-paused {
  background: none;
}

/* Equalizer bounce keyframes — two-wave motion so bars never look
   mechanically synced; pure CSS transform/height, GPU-composited. */
@keyframes eq-bounce {
  0% { height: 4px; opacity: 0.55; }
  20% { height: 13px; opacity: 0.9; }
  45% { height: 6px; opacity: 0.65; }
  65% { height: 17px; opacity: 1; }
  80% { height: 9px; opacity: 0.75; }
  100% { height: 14px; opacity: 0.9; }
}

/* ─── Track Info ────────────────────────────────────────────── */
.np-track-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

/* ─── Marquee (CSS-only text scroll) ────────────────────────── */
.np-marquee-wrapper {
  overflow: hidden;
  white-space: nowrap;
}

/* Edge fade only while actually looping — static (fit) titles stay
   crisp and keep a clean 10px visual gap from the icon. */
.np-marquee-wrapper.is-looping {
  mask-image: linear-gradient(
    to right,
    transparent 0%,
    black 5%,
    black 95%,
    transparent 100%
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0%,
    black 5%,
    black 95%,
    transparent 100%
  );
}

.np-marquee {
  display: inline-block;
  color: var(--np-text);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.5px;
  padding-right: 40px; /* gap before repeat */
}

.np-marquee--loop {
  animation: marquee-loop 28s linear infinite;
}

.np-m-chunk {
  display: inline-block;
}

.np-idle .np-marquee {
  color: var(--np-dim);
  font-style: italic;
  animation: none;
}

/* Seamless loop: JS duplicates the content once; shifting -50% moves
   exactly one chunk, so there is never an empty gap in view. */
@keyframes marquee-loop {
  0% {
    transform: translateX(0%);
  }
  100% {
    transform: translateX(-50%);
  }
}

/* ─── Artist ────────────────────────────────────────────────── */
.np-artist {
  color: var(--np-dim);
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.np-playing .np-artist {
  color: var(--np-accent);
  opacity: 0.7;
}

/* ─── Fallback ──────────────────────────────────────────────── */
.np-fallback {
  display: flex;
  align-items: center;
  gap: 10px;
  opacity: 0.5;
}

.np-fallback-icon {
  color: var(--np-dim);
  font-size: 10px;
  animation: pulse-idle 6s ease-in-out infinite;
}

.np-fallback-text {
  color: var(--np-dim);
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

@keyframes pulse-idle {
  0%, 100% {
    opacity: 0.3;
  }
  50% {
    opacity: 0.8;
  }
}

/* ─── Artwork (hidden by default) ───────────────────────────── */
.np-artwork {
  display: none;
  margin-top: 8px;
}

.np-artwork img {
  width: 100%;
  max-width: 48px;
  height: auto;
  border-radius: 2px;
  border: 1px solid var(--np-slate);
  opacity: 0.8;
  transition: opacity 0.6s ease;
}

.np-playing .np-artwork img {
  opacity: 1;
}

/* ─── Playing State: subtle glow ────────────────────────────── */
.np-playing {
  background: linear-gradient(
    180deg,
    rgba(241, 90, 36, 0.03) 0%,
    transparent 100%
  );
}

.now-playing--fixed.np-playing {
  border-color: var(--np-accent);
  box-shadow: 6px 6px 0 var(--np-accent-soft);
  transition: border-color 0.6s ease, box-shadow 0.6s ease;
}

/* ─── Hover effect ──────────────────────────────────────────── */
.now-playing:hover .np-label {
  color: var(--np-accent);
}

.now-playing:hover .eq-bar {
  opacity: 1 !important;
}

/* ─── Artwork thumbnail + clickability ──────────────────────── */
.np-art-thumb {
  width: 36px;
  height: 36px;
  object-fit: cover;
  border: 1px solid var(--np-slate);
  flex-shrink: 0;
  transition: border-color 1.2s ease, transform 0.3s ease;
}

/* artwork breathes with the genre-colored glow while playing */
.np-playing .np-art-thumb {
  animation: np-artglow 6.4s ease-in-out infinite;
}

@keyframes np-artglow {
  0%, 100% { box-shadow: 0 0 5px var(--np-accent-soft); }
  50% { box-shadow: 0 0 14px var(--np-accent-soft); }
}

.now-playing--fixed.np-playing .np-art-thumb {
  border-color: var(--np-accent);
}

.np-clickable {
  cursor: pointer;
}

.np-clickable:hover {
  transform: translate(-1px, -1px);
}

.np-clickable:hover .np-art-thumb {
  transform: scale(1.06);
}

.np-clickable::after {
  content: "↗";
  position: absolute;
  top: 6px;
  right: 8px;
  font-size: 9px;
  color: var(--np-dim);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.np-clickable:hover::after {
  opacity: 1;
  color: var(--np-accent);
}

/* ─── Track-change animation ────────────────────────────────── */
/* Border flash on the card + slide-in of the text row. Colors follow
   the current genre accent. JS retriggers via class + reflow. */
@keyframes np-flash {
  0% {
    border-color: var(--np-accent);
    box-shadow: 6px 6px 0 var(--np-accent-soft), 0 0 26px var(--np-accent-soft);
  }
  100% {
    border-color: var(--np-slate);
    box-shadow: 6px 6px 0 rgba(34, 34, 42, 0.9);
  }
}

.np-track-change {
  animation: np-flash 1.8s ease-out;
}

/* title swap: slide + de-blur feels like a station change */
@keyframes np-swap {
  0% { opacity: 0; transform: translateY(7px); filter: blur(2px); }
  100% { opacity: 1; transform: none; filter: blur(0); }
}

.np-track-change .np-marquee-wrapper,
.np-track-change .np-artist {
  animation: np-swap 0.8s cubic-bezier(0.2, 0.9, 0.25, 1);
}

/* accent-follow: keep .np-track-change's border in the current genre
   color (the animation end state must not hardcode rust — the class
   stays applied until the next track change). */
.np-playing.np-track-change {
  border-color: var(--np-accent);
  box-shadow: 6px 6px 0 var(--np-accent-soft);
}

/* ─── Accessibility ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .now-playing *,
  .now-playing *::before,
  .now-playing *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .np-track-change,
  .np-track-change .np-marquee-wrapper,
  .np-track-change .np-artist {
    animation: none;
  }
  .np-marquee--loop {
    animation: none;
  }
  .np-playing .eq-bar {
    animation: none;
    height: 8px;
    opacity: 0.6;
  }
  .np-fallback-icon,
  .now-playing--fixed,
  .now-playing--fixed::before,
  .np-playing .np-art-thumb,
  .np-label--active::before {
    animation: none;
  }
  .now-playing--fixed::before {
    opacity: 0.6;
  }
}

/* ─── Dark theme consistency ────────────────────────────────── */
.now-playing {
  background: var(--np-void);
}

/* When inside the aegis nav rail */
.aegis-nav-rail .now-playing,
.nav-rail .now-playing {
  border-top-color: var(--np-slate);
}

/* NOTE: CRT scanline overlay is provided globally by .aegis-crt
   (aegis.css) — do NOT add a second overlay here. */
