/* ============================================================
   MOSIKY LANDING PAGE — STYLES
   Corporate Colors: #FF5349, #FF7F50, #4B0082
   ============================================================ */

/* ── CSS Variables ──────────────────────────────────────────── */
:root {
  --mosiky-red: #FF5349;
  --mosiky-coral: #FF7F50;
  --mosiky-indigo: #4B0082;
  --bg-primary: #120A08;
  --bg-secondary: #1A100E;
  --bg-card: rgba(255, 255, 255, 0.04);
  --bg-card-hover: rgba(255, 255, 255, 0.08);
  --text-primary: #ffffff;
  --text-secondary: #9ca3af;
  --text-muted: #6b7280;
  --glass-bg: rgba(18, 10, 8, 0.85);
  --glass-border: rgba(255, 255, 255, 0.08);
  --gradient-brand: linear-gradient(135deg, var(--mosiky-red), var(--mosiky-coral), var(--mosiky-indigo));
  --transition-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ── Base ───────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Always reserve space for the vertical scrollbar so opening modals
     (which set body.overflow: hidden) doesn't shift the page ~15px to
     the right. Modern browsers (Firefox 81+, Chromium 94+, Safari 17+)
     support scrollbar-gutter; the `overflow-y: scroll` fallback covers
     the rest. */
  scrollbar-gutter: stable;
  overflow-y: scroll;
}

body {
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  line-height: 1.6;
  overflow-x: hidden;
}

/* Subtle noise texture overlay */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  opacity: 0.02;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  pointer-events: none;
}

body > * { position: relative; z-index: 1; }

a { color: inherit; text-decoration: none; }
button { cursor: pointer; border: none; background: none; font: inherit; color: inherit; }
img { display: block; max-width: 100%; }

/* Custom scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--bg-primary); }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }

/* ── Typography ─────────────────────────────────────────────── */
.gradient-text {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.section-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--mosiky-coral);
  margin-bottom: 0.5rem;
}

.section-title {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: 1rem;
}

@media (max-width: 768px) {
  .section-title { font-size: 1.75rem; }
}

.nav { transition: top 0.6s var(--transition-smooth); }

/* ── Navigation ─────────────────────────────────────────────── */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 1rem 2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: background 0.4s var(--transition-smooth), backdrop-filter 0.4s;
}

.nav.scrolled {
  background: rgba(18, 10, 8, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--glass-border);
}

.nav-logo {
  height: 36px;
  width: auto;
  object-fit: contain;
}

/* Placeholder logo styling when image is missing */
.nav-logo-placeholder {
  height: 36px;
  width: 120px;
  background: var(--gradient-brand);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  color: #fff;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 2rem;
  list-style: none;
}

.nav-links a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-secondary);
  transition: color 0.3s;
  position: relative;
}

.nav-links a:hover,
.nav-links a.active {
  color: var(--text-primary);
}

.nav-links a.active::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--gradient-brand);
  border-radius: 1px;
}

/* Mobile hamburger */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  padding: 4px;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--text-primary);
  border-radius: 1px;
  transition: transform 0.3s, opacity 0.3s;
}

.nav-toggle.open span:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }

@media (max-width: 768px) {
  .nav-toggle { display: flex; }
  .nav-links {
    position: fixed;
    top: 0;
    right: -100%;
    width: 280px;
    height: 100vh;
    flex-direction: column;
    background: rgba(18, 10, 8, 0.97);
    backdrop-filter: blur(30px);
    padding: 5rem 2rem 2rem;
    gap: 1.5rem;
    transition: right 0.4s var(--transition-smooth);
    border-left: 1px solid var(--glass-border);
  }
  .nav-links.open { right: 0; }
  /* Inline links are only as tall as their text — 21px for the primary
     navigation of the whole site once the menu is open. Block plus
     padding gives each row a comfortable target without changing how
     the menu looks. */
  .nav-links a {
    font-size: 1.1rem;
    display: block;
    padding: 10px 0;
  }
  .nav-links li { width: 100%; }

  /* Footer navigation is real navigation. Inline links gave it 18px
     rows; on a touch screen that is a guess, not a target. */
  .footer-links a,
  .footer-legal a {
    display: inline-block;
    padding: 9px 0;
  }
}

/* Below ~400px the row cannot hold the brand, a language label, a
   sign-in button and the hamburger at once — in Arabic least of all. The
   globe alone still reads as "language", so the two-letter code goes
   first; it is the least informative thing in the row. */
@media (max-width: 400px) {
  /* 320px, minus 2rem of nav padding, leaves 288 for brand + language +
     sign-in + hamburger. In Arabic that row wants ~330. Every piece
     gives a little rather than the brand giving everything, and the
     hamburger — the only route into navigation — gives nothing. */
  .nav { padding-left: 0.75rem; padding-right: 0.75rem; }
  #lang-cur { display: none; }
  .lang-btn { padding-left: 9px; padding-right: 9px; }
  .lang-picker { margin-right: 4px; }
  [dir="rtl"] .lang-picker { margin-right: 0; margin-left: 4px; }
  .nav-signin-btn { padding: 6px 10px; font-size: 0.7rem; }
  .nav-logo { width: 92px; height: auto; }
  /* Vertical padding only: it lifts the brand's tap target off a 23px
     image without costing the row any horizontal space. */
  .nav > a:first-child { padding: 8px 0; }
}


/* Elapsed/remaining readouts re-render every second. With proportional
   figures each tick changes their width, nudging whatever shares the row.
   Same fix, same reason as the tracklist. */
.player-time, .player-time-current, .player-time-duration,
.video-time-display, .free-shelf-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ── Hero Slider ────────────────────────────────────────────── */
.hero {
  position: relative;
  width: 100%;
  height: 100vh;
  min-height: 600px;
  max-height: 1000px;
  overflow: hidden;
}

.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s var(--transition-smooth);
  z-index: 1;
}

.hero-slide.active {
  opacity: 1;
  z-index: 2;
}

.hero-slide-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  animation: kenBurns 12s ease-in-out infinite alternate;
}

.hero-slide-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(18, 10, 8, 0.3) 0%,
    rgba(18, 10, 8, 0.1) 40%,
    rgba(18, 10, 8, 0.6) 70%,
    rgba(18, 10, 8, 0.95) 100%
  );
}

.hero-content {
  position: absolute;
  bottom: 15%;
  left: 5%;
  z-index: 3;
  max-width: 600px;
}

.hero-content h1 {
  font-size: 4rem;
  font-weight: 800;
  line-height: 1.05;
  margin-bottom: 0.25rem;
  text-shadow: 0 2px 20px rgba(0,0,0,0.5);
}

.hero-content .hero-artist {
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--mosiky-coral);
  margin-bottom: 0.75rem;
}

.hero-content .hero-tagline {
  font-size: 1.1rem;
  color: var(--text-secondary);
  font-weight: 300;
}

.hero-dots {
  position: absolute;
  bottom: 5%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  /* Wide enough that the enlarged hit areas below sit side by side
     instead of overlapping — an overlapping target catches taps meant
     for its neighbour. */
  gap: 20px;
}

.hero-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.3);
  position: relative;
  transition: all 0.4s var(--transition-smooth);
  cursor: pointer;
}

/* A 10px dot is a 10px touch target, a quarter of what Apple asks for,
   on the control a phone user is most likely to reach for. Padding was
   the obvious fix and the wrong one: it grows the border box, and
   box-shadow and transform follow the border box — so the active dot's
   glow ringed a 34px circle instead of hugging the dot. An overlay
   pseudo-element grows only the hit area. */
.hero-dot::after {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
}

.hero-dot.active {
  background-color: var(--mosiky-coral);
  transform: scale(1.3);
  box-shadow: 0 0 12px rgba(255, 127, 80, 0.5);
}

/* Hero arrows */
.hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: all 0.3s;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.hero-arrow:hover {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(255, 255, 255, 0.2);
}

.hero-arrow.prev { left: 2%; }
.hero-arrow.next { right: 2%; }

@media (max-width: 768px) {
  .hero { min-height: 500px; max-height: 700px; }
  .hero-content { bottom: 20%; left: 6%; right: 6%; }
  .hero-content h1 { font-size: 2.5rem; }
  .hero-content .hero-artist { font-size: 1.15rem; }
  .hero-content .hero-tagline { font-size: 0.95rem; }
  .hero-arrow { display: none; }
}

/* ── Intro Section ──────────────────────────────────────────── */
.intro-section {
  padding: 6rem 2rem;
  max-width: 800px;
  margin: 0 auto;
  text-align: center;
}

.intro-section .intro-heading {
  font-size: 2.5rem;
  font-weight: 700;
  margin-bottom: 2rem;
}

.intro-section .intro-text {
  font-size: 1.05rem;
  line-height: 1.85;
  color: var(--text-secondary);
  white-space: pre-line;
  margin-bottom: 2rem;
}

.intro-section .intro-cta {
  font-size: 1.25rem;
  font-weight: 600;
  font-style: italic;
}

.intro-divider {
  width: 80px;
  height: 3px;
  background: var(--gradient-brand);
  border-radius: 2px;
  margin: 2.5rem auto;
}

.intro-chevron {
  display: block;
  margin: 3rem auto 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  transition: all 0.3s;
  animation: chevronBounce 2s ease-in-out infinite;
}

.intro-chevron:hover {
  color: var(--mosiky-coral);
  border-color: var(--mosiky-coral);
  transform: translateY(2px);
}

@keyframes chevronBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(6px); }
}

/* ── Album Grid ─────────────────────────────────────────────── */
.music-section {
  padding: 4rem 2rem 6rem;
  max-width: 1400px;
  margin: 0 auto;
}

.album-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1.5rem;
}

@media (max-width: 1280px) { .album-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 1024px) { .album-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px)  { .album-grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; } }

.album-card {
  cursor: pointer;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid transparent;
  transition: all 0.4s var(--transition-smooth);
}

.album-card:hover {
  transform: translateY(-6px);
  background: var(--bg-card-hover);
  border-color: var(--glass-border);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), 0 0 30px rgba(255, 83, 73, 0.08);
}

.album-art {
  aspect-ratio: 1;
  width: 100%;
  background-size: cover;
  background-position: center;
  position: relative;
  overflow: hidden;
}

.album-art::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  transition: background 0.3s;
}

.album-card:hover .album-art::after {
  background: rgba(0, 0, 0, 0.2);
}

.album-play-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  transition: transform 0.4s var(--transition-smooth);
  box-shadow: 0 4px 20px rgba(255, 127, 80, 0.4);
}

.album-card:hover .album-play-icon {
  transform: translate(-50%, -50%) scale(1);
}

.album-info {
  padding: 0.85rem 1rem;
}

.album-info .album-title {
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.15rem;
}

.album-info .album-artist {
  font-size: 0.8rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.album-info .album-genre {
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 0.25rem;
}

/* ── Audio Player Modal ─────────────────────────────────────── */
.player-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--transition-smooth);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.player-overlay.open {
  opacity: 1;
  pointer-events: all;
}

/* Ambient glow background */
.player-ambient {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

/* Full-screen accent wash behind the modal — iOS layers a blurred
   accentColor at 0.2 over the whole player, not just the blob. A flat
   fill at similar opacity is visually identical to blurred flat color. */
.player-ambient::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--album-accent, #FF5349);
  opacity: 0.16;
  transition: background 1s;
}

.player-ambient-blob {
  position: absolute;
  /* Sized to the modal, not the viewport. At 60vw the accent was a wash
     across the whole surface rather than a glow behind the artwork, so
     every album read as one muddy colour — iOS keeps it at ~55% of the
     player's own width, and that restraint is the difference. */
  width: min(55%, 460px);
  height: min(55%, 460px);
  border-radius: 50%;
  filter: blur(120px);
  /* Was 0.3 flat. iOS pulses 0.15–0.3 over a much smaller blob, so the
     average tint is far lighter than this was. */
  opacity: 0.18;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: background 1s;
  animation: ambientPulse 8s ease-in-out infinite;
}

.player-modal {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 920px;
  max-height: 90vh;
  overflow-y: auto;
  border-radius: 20px;
  /* Dark glass over an album-accent wash. iOS tints the whole player
     with the accent; here the accent radial sits under a dark gradient
     that stays near-opaque (0.9+) over the tracklist so text keeps its
     contrast — only the top of the panel reads tinted. (Earlier flat
     0.6 tinted the text; flat 0.88 killed the accent entirely.) */
  background:
    linear-gradient(to bottom,
      rgba(12, 10, 10, 0.68) 0%,
      rgba(12, 10, 10, 0.88) 45%,
      rgba(12, 10, 10, 0.93) 100%),
    radial-gradient(140% 70% at 50% 0%,
      var(--album-accent, #FF5349) 0%, transparent 72%),
    #0c0a0a;
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(20px);
  transform: translateY(40px) scale(0.95);
  transition: transform 0.5s var(--transition-smooth);
}

.player-overlay.open .player-modal {
  transform: translateY(0) scale(1);
}

/* Custom scrollbar for modal */
.player-modal::-webkit-scrollbar { width: 4px; }
.player-modal::-webkit-scrollbar-track { background: transparent; }
.player-modal::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; }

/* Audio player branding header */
.player-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  position: sticky;
  top: 0;
  z-index: 10;
}

.player-modal-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.player-modal-header .player-modal-logo,
/* The radio player has its own header wrapper; without this the logo
   rendered at its natural size and dwarfed everything else. */
.radio-modal-header .player-modal-logo {
  height: 22px;
  width: auto;
  max-width: 90px;
  flex-shrink: 0;
  object-fit: contain;
}

.player-modal-now-playing {
  min-width: 0;
}

.player-modal-np-title {
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}

.player-modal-np-artist {
  font-size: 0.7rem;
  color: var(--text-secondary);
}

.player-modal-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.player-modal-actions button {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  transition: all 0.3s;
}

.player-modal-actions button:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

@media (max-width: 480px) {
  .player-modal-np-title { max-width: 120px; }
}

.player-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
}

@media (max-width: 768px) {
  .player-inner { grid-template-columns: 1fr; }
}

/* Left: Art + Controls */
.player-art-section {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

.player-album-art {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 1;
  border-radius: 14px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.player-track-info {
  text-align: center;
  width: 100%;
}

.player-track-title {
  font-size: 1.15rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.player-track-artist {
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.player-track-meta {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.2rem;
}

/* Streaming links pinned bottom-right, aligned with controls */
.player-modal-streaming {
  position: absolute;
  bottom: 2.5rem;
  right: 1.5rem;
  z-index: 5;
}

.player-streaming-section {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
}

.player-streaming-label {
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  line-height: 1;
}

.player-streaming-links {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.streaming-link {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  transition: all 0.3s;
}

.streaming-link:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--mosiky-coral);
  color: var(--mosiky-coral);
  transform: translateY(-2px);
}

.streaming-link svg {
  width: 18px;
  height: 18px;
}

.streaming-link-amazon {
  width: 33px;
  height: 33px;
}

.streaming-link-amazon svg {
  width: 19px;
  height: 19px;
}

/* Progress bar */
.player-progress-wrap {
  width: 100%;
  max-width: 320px;
}

.player-progress-bar {
  width: 100%;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

.player-progress-bar::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  box-shadow: 0 0 8px rgba(255, 127, 80, 0.5);
  cursor: pointer;
}

.player-progress-bar::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  border: none;
  cursor: pointer;
}

.player-time {
  display: flex;
  justify-content: space-between;
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 0.35rem;
}

/* Playback controls */
.player-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Tightened because each button now carries its own 44px box; the
     visual spacing between icons is unchanged. */
  gap: 0.6rem;
}

.player-controls button {
  color: var(--text-secondary);
  transition: all 0.3s;
  /* The transport icons are 20px, so they were 20px targets — shuffle,
     previous, next and repeat all well under the 44px minimum, on a
     control surface used one-handed while walking. The icons keep their
     size; only the tappable box grows. The gap absorbs it, so nothing
     moves. */
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.player-controls button:hover { color: var(--text-primary); transform: scale(1.1); }
.player-controls button svg { width: 20px; height: 20px; }

/* Arrived on a song and nothing has played yet. Browsers forbid starting
   audio without a tap, so visitors from ads landed on a silent player and
   left: 0 of 127 pressed play on day one. Say so where the eye already is
   (the time slot, so nothing moves) and draw it to the button. */
.player-tap-hint { display: none; color: var(--mosiky-coral); font-weight: 600; font-size: 0.78rem; }
.player-overlay.awaiting-tap .player-tap-hint { display: inline; }
.player-overlay.awaiting-tap .player-time-current,
.player-overlay.awaiting-tap .player-time-duration { display: none; }
/* Centred on its own: the only thing in the time row until something
   plays. Both times return with playback. */
.player-overlay.awaiting-tap .player-time { justify-content: center; }
.player-overlay.awaiting-tap .player-play-btn { animation: playPulse 1.8s ease-out infinite; }
@keyframes playPulse {
  0%   { box-shadow: 0 0 0 0 rgba(255, 127, 80, 0.6); }
  70%  { box-shadow: 0 0 0 16px rgba(255, 127, 80, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 127, 80, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .player-overlay.awaiting-tap .player-play-btn {
    animation: none; box-shadow: 0 0 0 4px rgba(255, 127, 80, 0.45);
  }
}

.player-play-btn {
  width: 52px !important;
  height: 52px !important;
  border-radius: 50% !important;
  background: var(--mosiky-coral) !important;
  color: #fff !important;
  box-shadow: 0 4px 20px rgba(255, 127, 80, 0.35);
  transition: all 0.3s !important;
}

.player-play-btn:hover {
  background: var(--mosiky-coral) !important;
  filter: brightness(1.12);
  transform: scale(1.08) !important;
  box-shadow: 0 6px 30px rgba(255, 127, 80, 0.5) !important;
}

.player-play-btn svg { width: 24px !important; height: 24px !important; }

/* Shuffle & Repeat buttons */
.shuffle-btn, .repeat-btn { position: relative; }
/* Repeat-one badge, Spotify-style: a superscript "1" perched on the
   glyph's top-right shoulder. Anchored to the icon (20×20 in both
   players), not the button, whose hit area is much larger — and kept
   outside the artwork because the loop's arrowhead occupies the inner
   top-right, so an overlaid digit would collide with strokes. */
.repeat-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(8px, -16px);
  font-size: 0.5rem;
  line-height: 1;
  font-weight: 700;
  color: var(--mosiky-coral);
  pointer-events: none;
}

/* Video loop button */
.video-loop-btn {
  color: var(--text-secondary);
  transition: color 0.3s;
  display: flex;
  align-items: center;
}
.video-loop-btn:hover { color: #fff; }
.video-loop-btn svg { width: 20px; height: 20px; }

/* Right: Track list */
.player-tracklist-section {
  border-left: 1px solid var(--glass-border);
  max-height: 520px;
  overflow-y: auto;
}

@media (max-width: 768px) {
  /* Phones: the tracklist is part of the player's one scroll, not a
     300px box scrolling inside it. In Instagram's and Facebook's browsers
     people saw 4 or 5 songs and missed that there were more (Saqib,
     2026-10-05); the header says how many there are. */
  .player-tracklist-section {
    border-left: none;
    border-top: 1px solid var(--glass-border);
    max-height: none;
    overflow: visible;
  }
  .player-tracklist-header { position: static; backdrop-filter: none; }
}

.player-tracklist-header {
  padding: 1.5rem 1.5rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  position: sticky;
  top: 0;
  background: transparent;
  backdrop-filter: blur(10px);
  z-index: 2;
}

.player-track-item {
  display: flex;
  align-items: center;
  padding: 0.75rem 1.5rem;
  gap: 1rem;
  cursor: pointer;
  transition: background 0.2s;
  border-bottom: 1px solid rgba(255, 255, 255, 0.03);
}

.player-track-item:hover { background: rgba(255, 255, 255, 0.04); }

.player-track-item.active {
  background: rgba(255, 127, 80, 0.08);
}

.player-track-item.active .track-item-title {
  color: var(--mosiky-coral);
}

.track-item-number {
  width: 24px;
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--text-muted);
  text-align: center;
  flex-shrink: 0;
}

/* EQ bars for active track */
.eq-bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
  width: 24px;
  justify-content: center;
}

.eq-bar {
  width: 3px;
  background: var(--mosiky-coral);
  border-radius: 1px;
  animation: eqBounce 0.8s ease-in-out infinite;
}

.eq-bar:nth-child(1) { animation-delay: 0s; }
.eq-bar:nth-child(2) { animation-delay: 0.15s; }
.eq-bar:nth-child(3) { animation-delay: 0.3s; }

.track-item-title {
  flex: 1;
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-item-duration {
  font-size: 0.8rem;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: color 0.3s;
  /* Inter's default figures are proportional, so "4:39" and "5:08" are
     not the same width. The title is flex:1 and absorbs the difference,
     which pushed the heart and + a pixel or two either way on every row
     — the icons read as a wobbling column rather than a straight one.
     Tabular figures make every digit the same advance width and the
     column locks. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* HD streaming badge (shown on currently playing track when HLS is active) */
.track-hd-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  margin-right: 8px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--mosiky-coral);
  background: rgba(255, 127, 80, 0.12);
  border-radius: 10px;
  flex-shrink: 0;
}
.track-hd-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--mosiky-coral);
}

/* ── Mini Player ────────────────────────────────────────────── */
.mini-player {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 150;
  background: rgba(18, 10, 8, 0.95);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  /* No border. A hard rule here sat a few pixels from the footer's own
     hairline and the progress bar, so three edges stacked in ~60px and the
     bottom of the page read as ruled paper. A shadow plus the blur does the
     separating instead — the bar lifts off the page rather than being fenced
     off from it, which is what the rule was trying to say anyway. */
  box-shadow: 0 -18px 40px -12px rgba(0, 0, 0, 0.75),
              0 -1px 0 0 rgba(255, 255, 255, 0.04);
  padding: 0 1.25rem;
  height: 72px;
  display: flex;
  align-items: center;
  gap: 1rem;
  transform: translateY(100%);
  transition: transform 0.4s var(--transition-smooth);
}

.mini-player.visible {
  transform: translateY(0);
}

.mini-player-art {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
  flex-shrink: 0;
  cursor: pointer;
  transition: opacity 0.3s;
}

.mini-player-art:hover { opacity: 0.8; }

.mini-player-info {
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.mini-player-title {
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mini-player-artist {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mini-player-progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: rgba(255, 255, 255, 0.08);
}

.mini-player-progress-fill {
  height: 100%;
  background: var(--gradient-brand);
  width: 0%;
  transition: width 0.3s linear;
}

.mini-player-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}

.mini-player-controls button {
  color: var(--text-secondary);
  transition: color 0.3s, transform 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mini-player-controls button:hover {
  color: #fff;
  transform: scale(1.1);
}

.mini-player-controls button svg { width: 20px; height: 20px; }

.mini-player-play {
  width: 40px !important;
  height: 40px !important;
  border-radius: 50% !important;
  background: var(--mosiky-coral) !important;
  color: #fff !important;
  box-shadow: 0 2px 12px rgba(255, 127, 80, 0.3);
}

.mini-player-play:hover {
  background: var(--mosiky-coral) !important;
  filter: brightness(1.12);
}

.mini-player-play svg { width: 18px !important; height: 18px !important; }

.mini-player-close {
  color: var(--text-muted) !important;
}


/* The mini player is a transport control at every width — 20px icons are
   a small target for a mouse and an unusable one for a thumb. Icons keep
   their size; the box around them grows and the gap absorbs it. */
.mini-player-controls button {
  min-width: 40px;
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mini-player-controls { gap: 0.25rem; }

/* Offset page content when mini player is visible */
body.has-mini-player .site-footer {
  padding-bottom: calc(4rem + 72px);
}

@media (max-width: 640px) {
  .mini-player { gap: 0.75rem; padding: 0 1rem; }
  .mini-player-art { width: 40px; height: 40px; border-radius: 6px; }
  .mini-player-controls { gap: 0.5rem; }
  .mini-player-controls .mini-prev,
  .mini-player-controls .mini-next,
  .mini-player-controls .mini-shuffle,
  .mini-player-controls .mini-repeat { display: none; }
}

/* ── Video Grid ─────────────────────────────────────────────── */
.video-section {
  padding: 4rem 2rem 6rem;
  max-width: 1200px;
  margin: 0 auto;
}

.video-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
}

@media (max-width: 640px) {
  .video-grid { grid-template-columns: 1fr; gap: 1.5rem; }
}

.video-card {
  cursor: pointer;
  border-radius: 14px;
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid transparent;
  transition: all 0.4s var(--transition-smooth);
}

.video-card:hover {
  transform: translateY(-4px);
  background: var(--bg-card-hover);
  border-color: var(--glass-border);
  box-shadow: 0 16px 50px rgba(0, 0, 0, 0.4);
}

.video-thumbnail {
  aspect-ratio: 16 / 9;
  width: 100%;
  background-size: cover;
  background-position: center;
  position: relative;
  overflow: hidden;
}

.video-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0);
  transition: background 0.3s;
}

.video-card:hover .video-play-overlay { background: rgba(0, 0, 0, 0.3); }

.video-play-btn {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  display: flex;
  align-items: center;
  justify-content: center;
  transform: scale(0);
  transition: transform 0.4s var(--transition-smooth);
  box-shadow: 0 4px 20px rgba(255, 127, 80, 0.5);
}

.video-card:hover .video-play-btn { transform: scale(1); }

.video-duration-badge {
  position: absolute;
  bottom: 10px;
  right: 10px;
  background: rgba(0, 0, 0, 0.75);
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
}

.video-info {
  padding: 1rem 1.25rem;
}

.video-info .video-title {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.video-info .video-artist {
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.video-info .video-subtitle {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.2rem;
}

/* ── Video Player Modal ─────────────────────────────────────── */
.video-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.92);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.video-overlay.open { opacity: 1; pointer-events: all; }

.video-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 1100px;
  padding: 0 0 1rem;
}

.video-modal-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.video-modal-logo {
  height: 28px;
  width: auto;
}

.video-modal-logo-placeholder {
  height: 28px;
  width: 90px;
  background: var(--gradient-brand);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
}

.video-modal-title {
  font-size: 1rem;
  font-weight: 600;
}

.video-modal-artist {
  font-size: 0.85rem;
  color: var(--text-secondary);
}

/* Video header actions (share + close, same style as audio player) */
.video-modal-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.video-modal-actions button {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  transition: all 0.3s;
}

.video-modal-actions button:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

/* Vertical divider between logo and title */
.video-brand-divider {
  width: 2px;
  height: 28px;
  background: var(--mosiky-coral);
  opacity: 0.5;
  margin: 0 0.85rem;
  flex-shrink: 0;
  border-radius: 1px;
}

@media (max-width: 768px) {
  .video-brand-divider { display: block; margin: 0 0.5rem; height: 24px; }
  .video-modal-logo { height: 22px !important; }
  .video-modal-title { font-size: 0.8rem !important; }
  .video-modal-artist { font-size: 0.7rem !important; }
}

.video-player-wrap {
  width: 100%;
  max-width: 1100px;
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  box-shadow: 0 20px 80px rgba(0, 0, 0, 0.6);
}

.video-player-wrap video {
  width: 100%;
  display: block;
  aspect-ratio: 16 / 9;
  background: #000;
}

.video-controls {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1.5rem;
  background: rgba(18, 10, 8, 0.95);
}


.video-controls button {
  color: var(--text-secondary);
  transition: color 0.3s;
  display: flex;
  align-items: center;
}

.video-controls button:hover { color: #fff; }
.video-controls button svg { width: 20px; height: 20px; }

.video-progress {
  flex: 1;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

.video-progress::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  cursor: pointer;
}

.video-progress::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--mosiky-coral);
  border: none;
}

.video-time {
  font-size: 0.75rem;
  color: var(--text-muted);
  min-width: 48px;
  text-align: center;
}

/* ── Footer ─────────────────────────────────────────────────── */
.site-footer {
  /* No edge at all. The footer used to announce itself three ways at once:
     a solid border, a gradient hairline, and a background a full shade
     lighter than the page. Even with the rules hidden the tonal step still
     drew a line. It now rises out of the body colour over ~200px, so the
     page ends rather than stopping. */
  border-top: 0;
  background: linear-gradient(to bottom,
              var(--bg-primary) 0%,
              var(--bg-secondary) 200px);
  padding: 4rem 2rem 2rem;
}

.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.4fr;
  gap: 2.5rem 3rem;
}

@media (max-width: 768px) {
  .footer-inner {
    grid-template-columns: 1fr 1fr;
    gap: 2rem 1.5rem;
    text-align: start;
  }
  .footer-brand { grid-column: 1 / -1; }
  .footer-inner > div:last-child { grid-column: 1 / -1; }
}

.footer-brand p {
  font-size: 0.9rem;
  color: var(--text-secondary);
  line-height: 1.7;
  margin-top: 1rem;
  max-width: 380px;
}

@media (max-width: 768px) {
  .footer-brand p { max-width: 100%; }
}

.footer-heading {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 1.25rem;
}

.footer-links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.footer-links a {
  font-size: 0.9rem;
  color: var(--text-secondary);
  transition: color 0.3s;
}

.footer-links a:hover { color: var(--mosiky-coral); }

/* Newsletter form */
/* The joined input+button pair this replaced lived here; the current
   pill field and circular submit are defined in the footer section at
   the end of this file. Only the placeholder colour survives. */
.newsletter-input::placeholder { color: var(--text-muted); }

.newsletter-success {
  font-size: 0.85rem;
  color: #38ef7d;
  margin-top: 0.5rem;
  display: none;
}

.newsletter-success.show { display: block; }

/* Contact */
.footer-contact a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--text-secondary);
  font-size: 0.9rem;
  transition: color 0.3s;
}

@media (max-width: 768px) {
  .footer-contact a { justify-content: center; }
}

.footer-contact a:hover { color: var(--mosiky-coral); }

/* App store badges */
.app-badges {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

@media (max-width: 768px) {
  .app-badges { justify-content: center; }
}

.app-badge {
  height: 40px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.05);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 12px;
  font-size: 0.7rem;
  color: var(--text-secondary);
  transition: all 0.3s;
  text-decoration: none;
}

.app-badge:hover {
  border-color: var(--mosiky-coral);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.app-badge svg { width: 20px; height: 20px; flex-shrink: 0; }
.app-badge .badge-label { font-size: 0.6rem; line-height: 1.2; }
.app-badge .badge-store { font-size: 0.8rem; font-weight: 600; line-height: 1.2; }

/* Footer bottom */
.footer-bottom {
  max-width: 1200px;
  margin: 3rem auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

.footer-copyright {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.footer-legal {
  display: flex;
  gap: 1.5rem;
}

.footer-legal a {
  font-size: 0.8rem;
  color: var(--text-muted);
  transition: color 0.3s;
}

.footer-legal a:hover { color: var(--text-secondary); }

@media (max-width: 768px) {
  .footer-bottom { flex-direction: column; text-align: center; }
}

/* ── Scroll Animations ──────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.8s var(--transition-smooth), transform 0.8s var(--transition-smooth);
}

.reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Keyframes ──────────────────────────────────────────────── */
@keyframes kenBurns {
  0%   { transform: scale(1) translate(0, 0); }
  100% { transform: scale(1.08) translate(-1%, -1%); }
}

@keyframes ambientPulse {
  0%, 100% { opacity: 0.25; transform: translate(-50%, -50%) scale(1); }
  50%      { opacity: 0.4; transform: translate(-50%, -50%) scale(1.15); }
}

@keyframes eqBounce {
  0%, 100% { height: 4px; }
  50%      { height: 14px; }
}

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

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

.spin { animation: spin 0.8s linear infinite; }

/* ── Social Links ──────────────────────────────────────────── */
.social-links {
  display: flex;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

@media (max-width: 768px) {
  .social-links { justify-content: center; }
}

.social-links a {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  transition: all 0.3s;
}

.social-links a:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--mosiky-coral);
  color: var(--mosiky-coral);
  transform: translateY(-2px);
}

.social-links a svg {
  width: 16px;
  height: 16px;
}

/* Share toast notification */
.share-toast {
  position: fixed;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: rgba(18, 10, 8, 0.95);
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(16px);
  padding: 0.75rem 1.5rem;
  border-radius: 12px;
  font-size: 0.85rem;
  color: var(--text-primary);
  z-index: 300;
  opacity: 0;
  transition: all 0.3s var(--transition-smooth);
  pointer-events: none;
}

.share-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── Signup Prompt ──────────────────────────────────────────── */
.signup-prompt {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  opacity: 0;
  transition: opacity 0.4s var(--transition-smooth);
}

.signup-prompt.open { opacity: 1; }

.signup-prompt-card {
  background: rgba(18, 10, 8, 0.9);
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  padding: 2.5rem;
  max-width: 420px;
  width: 100%;
  text-align: center;
  position: relative;
  transform: translateY(20px) scale(0.95);
  transition: transform 0.4s var(--transition-smooth);
}

.signup-prompt.open .signup-prompt-card {
  transform: translateY(0) scale(1);
}

.signup-prompt-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  font-size: 1.25rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.3s;
}

.signup-prompt-close:hover { background: rgba(255, 255, 255, 0.12); }

.signup-prompt-icon { margin-bottom: 1rem; }

.signup-prompt-card h3 {
  font-size: 1.35rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.signup-prompt-card p {
  font-size: 0.9rem;
  color: var(--text-secondary);
  line-height: 1.6;
  margin-bottom: 1.5rem;
}

.signup-prompt-form {
  display: flex;
  gap: 0;
}

.signup-prompt-form input {
  flex: 1;
  padding: 0.8rem 1rem;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  border-right: none;
  border-radius: 10px 0 0 10px;
  color: #fff;
  font-size: 0.875rem;
  outline: none;
  transition: border-color 0.3s;
}

.signup-prompt-form input::placeholder { color: var(--text-muted); }
.signup-prompt-form input:focus { border-color: var(--mosiky-coral); }

.signup-prompt-form button {
  padding: 0.8rem 1.5rem;
  background: var(--gradient-brand);
  border-radius: 0 10px 10px 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
  transition: opacity 0.3s;
}

.signup-prompt-form button:hover { opacity: 0.9; }

.signup-prompt-alt {
  margin-top: 1rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.3s;
}

.signup-prompt-alt:hover { color: var(--text-secondary); }

/* ── Loading State ──────────────────────────────────────────── */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.6s, visibility 0.6s;
}

.page-loader.hidden {
  opacity: 0;
  visibility: hidden;
}

.loader-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid rgba(255, 255, 255, 0.1);
  border-top-color: var(--mosiky-coral);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* ── Authentication Modal ──────────────────────────────────── */
.auth-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--transition-smooth);
}
.auth-overlay.open { opacity: 1; pointer-events: all; }

.auth-card {
  width: 100%;
  max-width: 420px;
  max-height: 90vh;
  overflow-y: auto;
  background: rgba(18, 10, 8, 0.95);
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  padding: 2rem;
  transform: translateY(20px) scale(0.97);
  transition: transform 0.4s var(--transition-smooth);
}
.auth-overlay.open .auth-card { transform: translateY(0) scale(1); }
.auth-card::-webkit-scrollbar { width: 4px; }
.auth-card::-webkit-scrollbar-track { background: transparent; }
.auth-card::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 2px; }

.auth-view { display: flex; flex-direction: column; align-items: center; gap: 14px; position: relative; }

.auth-logo { width: 140px; height: auto; margin-bottom: 4px; }
.auth-logo-sm { width: 90px; }

.auth-tagline { font-size: 0.9rem; color: var(--text-secondary); font-style: italic; }

.auth-spacer { height: 20px; }

.auth-gate-msg {
  text-align: center;
  margin-top: 12px;
}
.auth-gate-msg p {
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
  margin: 0;
}
.auth-gate-sub {
  font-size: 0.8rem !important;
  font-weight: 400 !important;
  color: var(--text-secondary) !important;
  margin-top: 4px !important;
}

.auth-free-note {
  font-size: 0.75rem;
  color: var(--mosiky-coral);
  margin: 0;
  font-weight: 500;
}

.auth-title { font-size: 1.3rem; font-weight: 700; color: #fff; margin: 0; }

.auth-subtitle { font-size: 0.8rem; color: var(--text-muted); margin: 0; }

.auth-back {
  position: absolute;
  top: 0;
  left: 0;
  background: none;
  color: var(--mosiky-coral);
  font-size: 1.2rem;
  cursor: pointer;
  padding: 4px 8px;
}

.auth-error {
  width: 100%;
  font-size: 0.8rem;
  color: var(--mosiky-red);
  background: rgba(255, 83, 73, 0.1);
  padding: 10px 14px;
  border-radius: 10px;
  text-align: center;
}

.auth-input {
  width: 100%;
  padding: 14px 16px;
  font-size: 0.95rem;
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  outline: none;
  transition: border-color 0.3s;
  font-family: inherit;
  box-sizing: border-box;
}
.auth-input:focus { border-color: var(--mosiky-coral); }
.auth-input::placeholder { color: var(--text-muted); }

/* Chrome paints autofilled fields with an opaque near-white background
   that no `background` declaration can override — the saved email and
   password rendered as two white slabs in the middle of a dark card.
   An inset box-shadow is the only thing that covers it, and the absurd
   transition delay stops Chrome re-applying its colour on interaction. */
.auth-input:-webkit-autofill,
.auth-input:-webkit-autofill:hover,
.auth-input:-webkit-autofill:focus,
.auth-input:-webkit-autofill:active {
  -webkit-text-fill-color: #fff;
  -webkit-box-shadow: 0 0 0 1000px #241713 inset;
  caret-color: #fff;
  transition: background-color 100000s ease-in-out 0s;
}

.auth-password-wrap {
  width: 100%;
  position: relative;
}
.auth-password-wrap .auth-input { padding-right: 44px; }
.auth-eye {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.5;
  padding: 4px;
}

.auth-btn-primary {
  width: 100%;
  padding: 14px;
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
  background: var(--gradient-brand);
  border: none;
  border-radius: 14px;
  cursor: pointer;
  transition: opacity 0.3s, transform 0.2s;
  font-family: inherit;
}
.auth-btn-primary:hover { opacity: 0.9; transform: scale(1.01); }
.auth-btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

.auth-btn-secondary {
  width: 100%;
  padding: 14px;
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  border-radius: 14px;
  cursor: pointer;
  transition: background 0.3s;
  font-family: inherit;
}
.auth-btn-secondary:hover { background: var(--bg-card-hover); }

.auth-btn-apple {
  width: 100%;
  padding: 13px;
  font-size: 0.9rem;
  font-weight: 500;
  color: #000;
  background: #fff;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: opacity 0.3s;
  font-family: inherit;
}
.auth-btn-apple:hover { opacity: 0.9; }

.auth-btn-google {
  width: 100%;
  padding: 13px;
  font-size: 0.9rem;
  font-weight: 500;
  color: #000;
  background: #fff;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: opacity 0.3s;
  font-family: inherit;
}
.auth-btn-google:hover { opacity: 0.9; }

.auth-btn-phone {
  width: 100%;
  padding: 13px;
  font-size: 0.9rem;
  font-weight: 500;
  color: #fff;
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: background 0.3s;
  font-family: inherit;
}
.auth-btn-phone:hover { background: var(--bg-card-hover); }

.auth-divider {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 4px 0;
}
.auth-divider::before, .auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--glass-border);
}
.auth-divider span { font-size: 0.75rem; color: var(--text-muted); }

.auth-phone-icon { margin: 8px 0; }

.auth-phone-row {
  width: 100%;
  display: flex;
  gap: 10px;
}
.auth-country-select {
  width: 130px;
  flex-shrink: 0;
  padding: 14px 8px;
  font-size: 0.85rem;
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  outline: none;
  cursor: pointer;
  font-family: inherit;
}
.auth-country-select option { background: #1a1a1a; color: #fff; }
.auth-phone-input { flex: 1; }

.auth-code-boxes {
  display: flex;
  gap: 8px;
  justify-content: center;
}
.auth-code-box {
  width: 46px;
  height: 56px;
  text-align: center;
  font-size: 1.4rem;
  font-weight: 700;
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  outline: none;
  caret-color: var(--mosiky-coral);
  transition: border-color 0.3s;
  font-family: inherit;
}
.auth-code-box:focus { border-color: var(--mosiky-coral); background: rgba(255, 255, 255, 0.1); }

.auth-link {
  background: none;
  color: var(--mosiky-coral);
  font-size: 0.85rem;
  cursor: pointer;
  border: none;
  font-family: inherit;
}

.auth-copyright {
  margin-top: 16px;
  text-align: center;
}
.auth-copyright p { font-size: 0.65rem; color: var(--text-muted); margin: 2px 0; }
.auth-legal-links a { color: var(--mosiky-coral); text-decoration: none; }
.auth-legal-links a:hover { text-decoration: underline; }

/* ── Account View ────────────────────────────────────────── */
.auth-close {
  position: absolute;
  top: -4px;
  right: -4px;
  background: none;
  color: var(--text-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  transition: color 0.3s;
}
.auth-close:hover { color: #fff; }

.auth-profile-card {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  border-radius: 14px;
}
.auth-profile-avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--gradient-brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
}
.auth-profile-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.auth-profile-name {
  font-size: 0.95rem;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.auth-profile-email {
  font-size: 0.8rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.auth-badge-freemium {
  display: inline-block;
  padding: 3px 10px;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #fff;
  background: var(--gradient-brand);
  border-radius: 10px;
  align-self: flex-start;
  margin-top: 4px;
}

.auth-section {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 0;
}

.auth-section-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.auth-info-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  background: var(--bg-card);
  border-radius: 10px;
  font-size: 0.9rem;
  color: #fff;
}

.auth-hint {
  font-size: 0.72rem;
  color: var(--text-muted);
  margin: 4px 0 0 0;
  line-height: 1.4;
}

.auth-success {
  width: 100%;
  font-size: 0.8rem;
  color: #4ade80;
  background: rgba(74, 222, 128, 0.1);
  padding: 10px 14px;
  border-radius: 10px;
  text-align: center;
}

.auth-danger-zone {
  border-top: 1px solid rgba(255, 83, 73, 0.2);
  margin-top: 8px;
  padding-top: 16px;
}

.auth-danger-btn {
  width: 100%;
  padding: 12px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--mosiky-red);
  background: transparent;
  border: 1px solid var(--mosiky-red);
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.3s, color 0.3s;
  font-family: inherit;
}
.auth-danger-btn:hover { background: var(--mosiky-red); color: #fff; }

/* Transition view */
.auth-transition-view { padding: 60px 0; }
.auth-transition-logo { animation: authFadeScale 0.8s ease-out both; }
.auth-transition-text { font-size: 0.9rem; color: var(--text-secondary); animation: authFadeIn 0.6s 0.4s ease-out both; }

.auth-shimmer-dots { display: flex; gap: 6px; justify-content: center; animation: authFadeIn 0.6s 0.6s ease-out both; }
.auth-shimmer-dots span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--mosiky-coral);
  animation: authShimmer 0.6s ease-in-out infinite alternate;
}
.auth-shimmer-dots span:nth-child(2) { animation-delay: 0.2s; }
.auth-shimmer-dots span:nth-child(3) { animation-delay: 0.4s; }

@keyframes authFadeScale { from { opacity: 0; transform: scale(0.85); } to { opacity: 1; transform: scale(1); } }
@keyframes authFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes authShimmer { from { opacity: 0.2; } to { opacity: 1; } }

/* Nav auth button */
.nav-auth { display: flex; align-items: center; gap: 0.75rem; margin-left: 1rem; }

.nav-signin-btn {
  white-space: nowrap;
  padding: 8px 18px;
  font-size: 0.8rem;
  font-weight: 600;
  color: #fff;
  background: var(--gradient-brand);
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: opacity 0.3s;
  font-family: inherit;
}
.nav-signin-btn:hover { opacity: 0.85; }

.nav-user-menu {
  display: none;
  align-items: center;
  gap: 0.5rem;
  position: relative;
}
.nav-user-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gradient-brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.85rem;
  color: #fff;
  cursor: pointer;
}
.nav-user-dropdown {
  position: absolute;
  top: 44px;
  right: 0;
  background: rgba(18, 10, 8, 0.95);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  padding: 6px;
  min-width: 150px;
  display: none;
  z-index: 500;
}
.nav-user-menu.open .nav-user-dropdown { display: block; }
.nav-user-dropdown button {
  width: 100%;
  padding: 10px 14px;
  text-align: left;
  font-size: 0.85rem;
  color: #fff;
  background: none;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
}
.nav-user-dropdown button:hover { background: var(--bg-card-hover); }

@media (max-width: 768px) {
  /* ── Nav row budget ───────────────────────────────────────
     The brand link is a flex item holding an img with max-width:100% and
     no floor, so flexbox was free to shrink it to nothing. In English
     there was slack and it never showed; in Arabic "تسجيل الدخول" is
     101px against "Sign in"'s 67px, and at 320px that deficit came
     straight out of the logo — 6px wide and untappable. The brand no
     longer shrinks; the row gives way elsewhere. */
  .nav > a:first-child { flex: 0 0 auto; }
  .nav-logo { max-width: none; }

  /* ── Touch targets ────────────────────────────────────────
     Everything below was under the 44px minimum on a phone. The icons
     and bars keep their size; only the tappable box grows. */

  /* The hamburger is the only way into navigation on mobile and it was
     a 30x24 target. */
  .nav-toggle {
    min-width: 44px;
    min-height: 44px;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
  }

  .nav-signin-btn { min-height: 40px; }


  /* min-height does nothing on a non-replaced inline box, and the
     support-portal CTA is an <a>. inline-flex gives it a box to honour. */
  .help-card .help-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 42px;
  }

  /* ── Video transport ──────────────────────────────────────
     Six fixed-width controls plus 24px side padding and 12px gaps need
     365px of a 326px bar, so the fullscreen button was clipped off the
     right edge and the time display wrapped onto two lines. */
  .video-controls {
    gap: 0.4rem;
    padding: 0.6rem 0.75rem;
  }
  .video-controls .video-progress {
    flex: 1 1 auto;
    min-width: 0;
  }
  .video-time-display {
    white-space: nowrap;
    font-size: 0.7rem;
    flex-shrink: 0;
  }
  .video-controls button { flex-shrink: 0; }

  /* Pinned bottom-right, the streaming links sat on top of the tracklist
     once the modal narrowed — the icons landed over track 1. It only
     reads as "pinned to the corner" when there is a corner to spare, so
     on a phone it rejoins the flow above the tracklist.

     Overflow scanning could never have caught this: two elements can
     overlap perfectly without making the page one pixel wider. */
  /* Unpinned it flows where it sits in the DOM — now directly after the
     artwork and controls, before the tracklist. It was the modal's last
     child, which put it below a 21-track list nobody would scroll to;
     CSS ordering could only lift it above the artwork, so the element
     moved instead. Desktop is unaffected: .player-inner is static, so
     the absolute positioning still resolves against .player-modal. */
  .player-modal-streaming {
    position: static;
    margin: 0 0 1rem;
  }
  .player-streaming-section { align-items: center; }

  .auth-card { padding: 1.5rem; max-width: 100%; border-radius: 16px; }
  .auth-code-box { width: 40px; height: 48px; font-size: 1.2rem; }
  .nav-auth { margin-left: 0.5rem; }
  .nav-signin-btn { padding: 6px 14px; font-size: 0.75rem; }
  /* "Sign in / Sign up" wrapped onto three lines in an 82px box once the
     language picker and hamburger had taken their share. The sign-up
     half is redundant here — the modal it opens leads with Create
     Account. */
  .nav-signin-long { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   MULTI-PAGE VIEWS (router) — added with the /music /videos /about
   split. One document; .view.active is the visible "page".
   ══════════════════════════════════════════════════════════════ */
.view { display: none; }
.view.active { display: block; }

/* Fade-in for cards re-rendered by pagination (reveal-on-scroll is
   only used for content rendered once at load). */
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.fade-in { animation: viewFadeIn 0.45s var(--transition-smooth) both; }

/* ── Page header (top of /music and /videos) ────────────────── */
.page-header {
  padding: 8.5rem 2rem 0;
  max-width: 1400px;
  margin: 0 auto;
}
@media (max-width: 768px) {
  .page-header { padding-top: 6.5rem; }
}

/* About page: first element under the fixed nav, needs clearance */
.about-page { padding-top: 9rem; }
@media (max-width: 768px) {
  .about-page { padding-top: 7rem; }
}

/* Home about teaser — tighter than the full about page */
.home-about-teaser { padding: 5rem 2rem 3.5rem; }

/* ── "Browse all" buttons / section-more rows ───────────────── */
.section-more { text-align: center; margin-top: 2.5rem; }
.btn-browse {
  display: inline-block;
  padding: 0.75rem 1.75rem;
  border: 1px solid var(--glass-border);
  border-radius: 999px;
  color: var(--text-primary);
  background: var(--bg-card);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: all 0.25s var(--transition-smooth);
}
.btn-browse:hover {
  background: var(--bg-card-hover);
  border-color: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

/* ── Pagination ─────────────────────────────────────────────── */
.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  margin-top: 3rem;
  flex-wrap: wrap;
}
.page-btn {
  min-width: 40px;
  height: 40px;
  padding: 0 0.75rem;
  border-radius: 10px;
  border: 1px solid var(--glass-border);
  background: var(--bg-card);
  color: var(--text-secondary);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s var(--transition-smooth);
}
.page-btn:hover:not(:disabled):not(.current) {
  background: var(--bg-card-hover);
  color: var(--text-primary);
}
.page-btn.current {
  background: var(--gradient-brand);
  border-color: transparent;
  color: #fff;
  cursor: default;
}
.page-btn:disabled { opacity: 0.35; cursor: default; }

/* ── Catalog search ─────────────────────────────────────────── */
.catalog-search {
  -webkit-appearance: none;
  appearance: none;
  margin-top: 1.4rem;
  width: 100%;
  max-width: 460px;
  padding: 0.85rem 1.3rem 0.85rem 2.9rem;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background-color: rgba(255, 255, 255, 0.05);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.5' y2='16.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 1.15rem center;
  background-size: 16px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  outline: none;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: border-color 0.25s var(--transition-smooth),
              box-shadow 0.25s var(--transition-smooth),
              background-color 0.25s var(--transition-smooth);
}
.catalog-search::placeholder { color: var(--text-muted); }
.catalog-search:hover { border-color: rgba(255, 255, 255, 0.16); }
.catalog-search:focus {
  border-color: rgba(255, 127, 80, 0.55);
  box-shadow: 0 0 0 3px rgba(255, 127, 80, 0.12);
  background-color: rgba(255, 255, 255, 0.07);
}
.catalog-search::-webkit-search-cancel-button { -webkit-appearance: none; }
.catalog-search::-webkit-search-decoration { -webkit-appearance: none; }

/* ── Favorites chip ─────────────────────────────────────────── */
.fav-filter {
  -webkit-appearance: none;
  appearance: none;
  margin-top: 0.9rem;
  margin-left: 0.75rem;
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-secondary);
  font-size: 0.85rem;
  font-family: inherit;
  cursor: pointer;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: all 0.2s var(--transition-smooth);
}
.fav-filter:hover { border-color: rgba(255, 255, 255, 0.16); color: var(--text-primary); }
.fav-filter.active {
  background: var(--mosiky-coral);
  border-color: transparent;
  color: #fff;
}

/* ── Catalog card hearts ────────────────────────────────────── */
.album-meta-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.card-fav-btn {
  background: none; border: none; cursor: pointer; padding: 4px;
  color: var(--text-muted); line-height: 0; border-radius: 50%;
  transition: color 0.2s var(--transition-smooth), transform 0.15s var(--transition-smooth);
}
.card-fav-btn:hover { color: var(--mosiky-coral); transform: scale(1.15); }

/* ── Filter chip pair (All | Favorites) ─────────────────────── */
.filter-row { display: inline-flex; gap: 0.5rem; }
.fav-filter.active {
  background: var(--mosiky-coral);
  border-color: var(--mosiky-coral);
  color: #fff;
}

/* ── Player: artist heart + track-row actions ───────────────── */
.player-artist-row { display: flex; align-items: center; justify-content: center; gap: 6px; }
#artist-fav-btn {
  background: none; border: none; cursor: pointer; padding: 3px;
  color: var(--text-muted); line-height: 0;
  transition: color 0.2s var(--transition-smooth), transform 0.15s var(--transition-smooth);
}
#artist-fav-btn:hover { color: var(--mosiky-coral); transform: scale(1.15); }
.track-item-actions { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.track-fav-btn, .track-add-btn {
  background: none; border: none; cursor: pointer; padding: 5px;
  color: var(--text-muted); line-height: 0; border-radius: 50%;
  transition: color 0.2s var(--transition-smooth), background 0.2s var(--transition-smooth);
}
.track-fav-btn:hover, .track-add-btn:hover { color: var(--mosiky-coral); background: rgba(255,255,255,0.06); }
.player-track-item { display: flex; align-items: center; }
.player-track-item .track-item-duration { margin-left: 8px; }

/* ── Add-to-playlist menu ───────────────────────────────────── */
.playlist-menu {
  position: fixed; z-index: 10000; width: 220px;
  background: rgba(20, 20, 24, 0.97);
  border: 1px solid var(--glass-border);
  border-radius: 12px; padding: 6px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}
.playlist-menu-heading {
  font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted); padding: 8px 10px 6px;
}
.playlist-menu-item {
  display: block; width: 100%; text-align: left;
  background: none; border: none; cursor: pointer;
  color: var(--text-primary); font-family: inherit; font-size: 0.9rem;
  padding: 9px 10px; border-radius: 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background 0.15s var(--transition-smooth);
}
.playlist-menu-item:hover { background: rgba(255,255,255,0.08); }
.playlist-menu-new { color: var(--mosiky-coral); }

/* ── Playlists section (/music) ─────────────────────────────── */
.playlists-title { font-size: 1.5rem; }
#playlists-list { display: flex; flex-direction: column; gap: 10px; max-width: 640px; }
.playlist-row {
  display: flex; align-items: center; gap: 14px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--glass-border);
  border-radius: 14px; padding: 12px 16px;
  transition: border-color 0.2s var(--transition-smooth);
}
.playlist-row:hover { border-color: rgba(255,255,255,0.16); }
.playlist-row-icon { color: var(--mosiky-coral); line-height: 0; }
.playlist-row-info { min-width: 0; flex: 1; }
.playlist-row-name {
  font-weight: 600; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.playlist-row-count { font-size: 0.8rem; color: var(--text-muted); }
.playlist-row-actions { display: flex; gap: 4px; }
.playlist-row-actions button {
  background: none; border: none; cursor: pointer; padding: 8px;
  color: var(--text-secondary); line-height: 0; border-radius: 50%;
  transition: color 0.2s var(--transition-smooth), background 0.2s var(--transition-smooth);
}
.playlist-row-actions button:hover { color: var(--mosiky-coral); background: rgba(255,255,255,0.06); }
.playlist-row-actions .pl-delete:hover { color: #e05252; }

/* ── Shared playlist page ───────────────────────────────────── */
.shared-playlist-meta { color: var(--text-muted); margin-top: 0.5rem; }
.shared-playlist-play { margin-bottom: 1.5rem; cursor: pointer; }
.shared-playlist-empty { color: var(--text-muted); }
.shared-playlist-tracks { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.shared-playlist-track {
  display: flex; align-items: center; gap: 14px; cursor: pointer;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--glass-border);
  border-radius: 12px; padding: 10px 14px;
  transition: border-color 0.2s var(--transition-smooth), background 0.2s var(--transition-smooth);
}
.shared-playlist-track:hover { border-color: rgba(255,127,80,0.4); background: rgba(255,255,255,0.06); }
.spt-art { width: 44px; height: 44px; border-radius: 8px; flex-shrink: 0; }
.spt-info { min-width: 0; }
.spt-title {
  font-weight: 600; color: var(--text-primary); font-size: 0.95rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.spt-artist { font-size: 0.8rem; color: var(--text-muted); }

/* ── Playlist song editor (expandable) ──────────────────────── */
.playlist-row-info { cursor: pointer; }
.playlist-row.expanded { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.playlist-row.expanded .pl-expand svg { transform: rotate(180deg); }
.pl-expand svg { transition: transform 0.2s var(--transition-smooth); }
.playlist-tracks {
  margin: -10px 0 0;
  max-width: 640px;
  border: 1px solid var(--glass-border);
  border-top: none;
  border-radius: 0 0 14px 14px;
  background: rgba(255,255,255,0.02);
  padding: 6px 8px 8px;
}
.playlist-track-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 8px;
}
.playlist-track-row:hover { background: rgba(255,255,255,0.05); }
.ptr-info { min-width: 0; flex: 1; display: flex; align-items: baseline; gap: 8px; }
.ptr-title {
  color: var(--text-primary); font-size: 0.9rem; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ptr-artist { color: var(--text-muted); font-size: 0.78rem; flex-shrink: 0; }
.ptr-remove {
  background: none; border: none; cursor: pointer; padding: 6px;
  color: var(--text-muted); line-height: 0; border-radius: 50%;
  transition: color 0.2s var(--transition-smooth), background 0.2s var(--transition-smooth);
}
.ptr-remove:hover { color: #e05252; background: rgba(255,255,255,0.06); }
.playlist-track-empty { color: var(--text-muted); font-size: 0.85rem; padding: 10px; }

/* ── Catalog card action pair (heart + add-to-playlist) ─────── */
.card-actions { display: flex; align-items: center; gap: 0; flex-shrink: 0; }
.card-add-btn {
  background: none; border: none; cursor: pointer; padding: 4px;
  color: var(--text-muted); line-height: 0; border-radius: 50%;
  transition: color 0.2s var(--transition-smooth), transform 0.15s var(--transition-smooth);
}
.card-add-btn:hover { color: var(--mosiky-coral); transform: scale(1.15); }

/* ── Artwork crossfade ──────────────────────────────────────── */
.player-album-art, #mini-art { position: relative; overflow: hidden; }
.art-ghost {
  position: absolute; inset: 0;
  border-radius: inherit;
  opacity: 1; pointer-events: none;
  transition: opacity 0.45s ease;
}

/* ── Album detail page ──────────────────────────────────────── */
.album-detail-section { padding-top: 8.5rem; }
@media (max-width: 768px) { .album-detail-section { padding-top: 6.5rem; } }
.detail-back-link {
  display: inline-block; margin-bottom: 1.5rem;
  color: var(--text-muted); text-decoration: none; font-size: 0.9rem;
  transition: color 0.2s var(--transition-smooth);
}
.detail-back-link:hover { color: var(--mosiky-coral); }
.detail-layout { display: grid; grid-template-columns: 340px 1fr; gap: 3rem; align-items: start; }
.detail-art-col { position: sticky; top: 100px; }
.detail-art {
  width: 100%; aspect-ratio: 1; border-radius: 18px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
}
.detail-title { font-size: 2.4rem; font-weight: 800; color: var(--text-primary); margin: 0.4rem 0 0.2rem; line-height: 1.1; }
.detail-artist { font-size: 1.1rem; color: var(--text-secondary); margin-bottom: 1rem; }
.detail-description { color: var(--text-secondary); line-height: 1.7; max-width: 640px; margin-bottom: 1rem; }
.detail-meta { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 1.25rem; }
.detail-actions { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 2rem; }
.detail-play { cursor: pointer; }
.detail-icon-btn {
  background: rgba(255,255,255,0.05); border: 1px solid var(--glass-border);
  border-radius: 50%; width: 44px; height: 44px; cursor: pointer;
  display: grid; place-items: center; color: var(--text-secondary);
  transition: color 0.2s var(--transition-smooth), border-color 0.2s var(--transition-smooth);
}
.detail-icon-btn:hover { color: var(--mosiky-coral); border-color: rgba(255,127,80,0.4); }
.detail-tracklist { max-width: 640px; }
.detail-track-row {
  display: flex; align-items: center; gap: 14px; cursor: pointer;
  padding: 12px 14px; border-radius: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  transition: background 0.15s var(--transition-smooth);
}
.detail-track-row:hover { background: rgba(255,255,255,0.05); }
.dtr-number { width: 24px; text-align: right; color: var(--text-muted); font-size: 0.85rem; }
.dtr-title { color: var(--text-primary); font-size: 0.95rem; }
@media (max-width: 820px) {
  .detail-layout { grid-template-columns: 1fr; gap: 1.5rem; }
  .detail-art-col { position: static; max-width: 340px; }
  .detail-title { font-size: 1.8rem; }
}

/* ── Link pills (DSP + socials) ─────────────────────────────── */
.link-pill-row { display: flex; flex-wrap: wrap; gap: 8px; }
.link-pill {
  display: inline-block; padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--glass-border); background: rgba(255,255,255,0.05);
  color: var(--text-secondary); font-size: 0.8rem; font-weight: 500;
  text-decoration: none;
  transition: color 0.2s var(--transition-smooth), border-color 0.2s var(--transition-smooth);
}
.link-pill:hover { color: var(--mosiky-coral); border-color: rgba(255,127,80,0.4); }
.detail-links { margin-bottom: 1.25rem; max-width: 640px; }
.detail-links-label {
  font-size: 0.68rem; letter-spacing: 0.1em; color: var(--text-muted);
  margin: 0 0 0.5rem; font-weight: 600;
}
.detail-artist-link { color: inherit; text-decoration: none; }
.detail-artist-link:hover { color: var(--mosiky-coral); }

/* ── Artist page ────────────────────────────────────────────── */
.artist-page-section { padding-top: 8.5rem; }
@media (max-width: 768px) { .artist-page-section { padding-top: 6.5rem; } }
.artist-hero {
  position: relative; border-radius: 20px; overflow: hidden;
  display: flex; align-items: flex-end;
  /* Grows with the viewport instead of staying 320px tall. At a fixed
     height a wide window makes this a letterbox, and `cover` then crops
     most of the picture away vertically. */
  min-height: clamp(320px, 26vw, 460px);
  background-size: cover;
  background-repeat: no-repeat;
  /* Biased above centre. These are portraits, and a centred crop on a
     wide short box takes the top of the head off first. */
  background-position: center 28%;
}
@media (max-width: 768px) {
  /* Taller and narrower on phones, so the crop is far less severe and the
     subject reads without pulling the framing up. */
  .artist-hero { min-height: 300px; background-position: center 22%; }
}
.artist-hero-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(10,10,10,0.92) 0%, rgba(10,10,10,0.25) 55%, rgba(10,10,10,0.15) 100%);
}
.artist-hero-content { position: relative; padding: 2rem; display: flex; flex-direction: column; gap: 0.4rem; }
.artist-portrait {
  width: 96px; height: 96px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.25);
  box-shadow: 0 8px 30px rgba(0,0,0,0.5); margin-bottom: 0.5rem;
}
.artist-name { font-size: 2.6rem; font-weight: 800; color: #fff; line-height: 1.05; }
.artist-count { color: var(--text-secondary); font-size: 0.9rem; }
.artist-body { padding-top: 1.75rem; }
/* 720px worked out to ~92 characters a line, well past the 60–75 that
   stays comfortable to read. Set in em rather than px so the measure holds
   if the type size changes — and rather than ch, which is the width of "0"
   and so runs ~25% wide of the average proportional character: 68ch landed
   at 686px, barely narrower than what it replaced. At this face the mean
   character is 7.45px, so 32em ≈ 512px ≈ 69 characters. */
.artist-bio {
  color: var(--text-secondary);
  line-height: 1.7;
  max-width: 32em;
  margin-bottom: 1.25rem;
}
.artist-socials-slot { margin-bottom: 2rem; }

.artist-section-title { font-size: 1.5rem; margin-bottom: 1rem; }

/* ON AIR overlaid on the artwork, bottom-right — same placement as the
   iOS radio tab, so the two surfaces read identically. Hidden until audio
   is actually flowing; a loaded-but-paused station is not on air. */
.radio-card-art { position: relative; }
.radio-card-live {
  display: none; align-items: center; gap: 5px;
  position: absolute; right: 10px; bottom: 10px;
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.06em;
  color: var(--mosiky-coral, #FF7F50);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}
.radio-card.is-playing .radio-card-live { display: inline-flex; }
.radio-card-live .radio-eq i { background: var(--mosiky-coral, #FF7F50); width: 3px; }
/* The name takes the brand colour too, so a playing station is readable
   as playing at a glance down a grid of cards. */
.radio-card.is-playing .radio-card-name { color: var(--mosiky-coral, #FF7F50); }


/* ── Artist Top Songs ───────────────────────────────────────── */
.top-songs-list {
  max-width: 640px; margin-bottom: 2.25rem;
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 24px;
}

/* Bio sits above Top Songs, which fills the width in 3-4 columns (see
   the .artist-top-songs override further down).
   A side-by-side split was tried and reverted: artists differ in whether
   they have a bio at all, so the grid reserved an empty 32em column for
   the ones without (SAQIB) and squeezed the list into a strip beside it. */
.artist-intro { display: block; }

@media (min-width: 1024px) {
  /* The bio runs at 70% of the hero width, centred beneath it. Wider than
     the 60-75 character measure used elsewhere — a deliberate call: a
     narrow column under a full-bleed hero read as unfinished. */
  .artist-intro-main { width: 70%; margin-inline: auto; }
  .artist-bio { max-width: none; text-align: center; }
}
@media (max-width: 820px) { .top-songs-list { grid-template-columns: 1fr; } }
.top-song-row {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 8px 10px; border-radius: 10px;
  transition: background 0.15s var(--transition-smooth);
}
.top-song-row:hover { background: rgba(255,255,255,0.06); }
.tsr-rank { width: 18px; text-align: right; color: var(--text-muted); font-size: 0.85rem; flex-shrink: 0;
  font-variant-numeric: tabular-nums; }

.tsr-art { width: 42px; height: 42px; border-radius: 6px; flex-shrink: 0; }
.tsr-info { min-width: 0; }
.tsr-title {
  color: var(--text-primary); font-size: 0.92rem; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tsr-album { color: var(--text-muted); font-size: 0.78rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Charts page ────────────────────────────────────────────── */
.charts-list { max-width: 720px; }
.charts-list .top-song-row { padding: 12px 14px; }
.charts-list .tsr-art { width: 52px; height: 52px; }

/* ── Genre browse chips ─────────────────────────────────────── */
.genre-chips {
  display: flex; gap: 8px; overflow-x: auto; padding: 0.9rem 0 0.2rem;
  scrollbar-width: none; -ms-overflow-style: none;
}
.genre-chips::-webkit-scrollbar { display: none; }
.genre-chip {
  flex-shrink: 0; padding: 7px 15px; border-radius: 999px;
  border: 1px solid var(--glass-border); background: rgba(255,255,255,0.05);
  color: var(--text-secondary); font-size: 0.82rem; font-family: inherit;
  cursor: pointer; white-space: nowrap;
  transition: all 0.2s var(--transition-smooth);
}
.genre-chip:hover { border-color: rgba(255,255,255,0.2); color: var(--text-primary); }
.genre-chip.active { background: var(--mosiky-coral); border-color: var(--mosiky-coral); color: #fff; }

/* ── Top Songs play-all ─────────────────────────────────────── */
.top-songs-header { display: flex; align-items: center; gap: 14px; margin-bottom: 1rem; }
.top-songs-header .artist-section-title { margin-bottom: 0; }
.top-songs-play { width: 38px; height: 38px; }
#charts-play { margin-bottom: 1.5rem; cursor: pointer; }

/* ── Library page ───────────────────────────────────────────── */
.lib-grid { margin-bottom: 2rem; }
#library-body .artist-section-title { margin-top: 0.5rem; margin-bottom: 1rem; }
#lib-fav-songs { margin-bottom: 2rem; }

/* ── Artwork shimmer while images load (matches admin skeleton) ── */
.art-shimmer { position: relative; overflow: hidden; }
.art-shimmer::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%,
    rgba(255,255,255,0.07) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: mosiky-shine 1.6s linear infinite;
}
@keyframes mosiky-shine {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

/* ── Video card heart row ───────────────────────────────────── */
.video-info-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }

/* ── Artists directory ──────────────────────────────────────── */
.artists-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 28px 20px; padding-top: 0.5rem;
}
.artist-card { text-decoration: none; text-align: center; display: block; }
.artist-card-img {
  width: 100%; aspect-ratio: 1; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.08);
  transition: transform 0.25s var(--transition-smooth), border-color 0.25s var(--transition-smooth);
}
.artist-card:hover .artist-card-img { transform: scale(1.04); border-color: rgba(255,127,80,0.5); }
.artist-card-name {
  margin-top: 0.8rem; color: var(--text-primary); font-weight: 600; font-size: 0.95rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.artist-card-count { color: var(--text-muted); font-size: 0.78rem; margin-top: 2px; }

/* Artist Top Songs and Library favorites: fill the full width — 3-4
   columns on desktop. Favorites grow with the listener, so two columns
   pushed the rest of the Library far down the page. */
.artist-top-songs .top-songs-list,
#lib-fav-songs {
  max-width: none;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

/* Album detail tracklist: fill the width, numbered down the columns */
.detail-tracklist {
  max-width: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 0 32px;
  align-items: start;
}

/* Video card actions: keep + and heart together at the right edge */
.video-info-row { justify-content: flex-start; gap: 2px; }
.video-info-row .video-subtitle { flex: 1; min-width: 0; }

/* Library playlists: multicolumn grid; the song editor spans full width */
#playlists-list {
  max-width: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 10px 20px;
}
#playlists-list .playlist-tracks { grid-column: 1 / -1; margin-top: -6px; max-width: none; }

/* Library favorite videos: multicolumn, sane card size */
#lib-fav-videos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 20px;
}

/* Charts: full-width columns for the Top 20 */
.charts-list {
  max-width: none;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

/* ── Branded splash: Mosiky mark with a soft pulse ──────────── */
.loader-mark-wrap { position: relative; width: 110px; height: 110px; max-width: 35vw; }
.loader-mark {
  width: 100%; height: 100%;
  border-radius: 50%;   /* crop the square canvas to the mandala circle */
  animation: mosiky-splash-spin 2.4s linear infinite;
}
/* Stationary center: the same image cropped to the inner disc, overlaid
   so the petals spin around a fixed play button. */
.loader-mark-center {
  position: absolute; inset: 30%;
  border-radius: 50%;
  background: url('../images/loader-mark.png') center / 250% no-repeat;
}
@keyframes mosiky-splash-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ── Newsletter consent ─────────────────────────────────────── */
.newsletter-consent {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 0.7rem; font-size: 0.78rem; color: var(--text-muted);
  cursor: pointer; line-height: 1.45;
}
.newsletter-consent input { margin-top: 2px; accent-color: var(--mosiky-coral); }
.newsletter-consent a { color: var(--text-secondary); }
.newsletter-consent a:hover { color: var(--mosiky-coral); }

/* ── Explicit badge ─────────────────────────────────────────── */
.e-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; margin-left: 7px; vertical-align: 1px;
  border-radius: 3px;
  background: #000;
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  font-size: 9px; font-weight: 700; line-height: 1;
}



/* ══ Help & Support (/help) — premium ═══════════════════════ */
.help-section { max-width: 1120px; }
.help-row {
  display: grid;
  grid-template-columns: minmax(300px, 5fr) minmax(340px, 7fr);
  gap: 28px;
  margin-bottom: 28px;
}
@media (max-width: 860px) { .help-row { grid-template-columns: 1fr; } }

.help-card {
  position: relative;
  border-radius: 22px;
  padding: 36px;
  background:
    linear-gradient(rgba(20, 12, 10, 0.92), rgba(14, 9, 8, 0.96)) padding-box,
    linear-gradient(135deg, rgba(255, 83, 73, 0.55), rgba(255, 127, 80, 0.18) 40%, rgba(75, 0, 130, 0.45)) border-box;
  border: 1px solid transparent;
  overflow: hidden;
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}
.help-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 24px 60px -24px rgba(255, 83, 73, 0.35);
}
.help-glow {
  position: absolute; top: -80px; right: -80px;
  width: 260px; height: 260px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 127, 80, 0.22), transparent 65%);
  pointer-events: none;
}
.help-icon {
  width: 52px; height: 52px; border-radius: 15px;
  display: grid; place-items: center;
  background: var(--gradient-brand);
  color: #fff;
  box-shadow: 0 10px 26px -10px rgba(255, 83, 73, 0.65);
  margin-bottom: 20px;
}
.help-card h3 { color: #fff; font-size: 1.45rem; letter-spacing: -0.01em; margin-bottom: 10px; }
.help-card > p, .help-card-contact > p {
  color: rgba(255, 255, 255, 0.62);
  font-size: 0.98rem; line-height: 1.6; margin-bottom: 18px;
}
.help-list { list-style: none; padding: 0; margin: 0 0 26px; }
.help-list li {
  position: relative;
  padding: 6px 0 6px 30px;
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.95rem;
}
.help-list li::before {
  content: '';
  position: absolute; left: 0; top: 9px;
  width: 18px; height: 18px; border-radius: 50%;
  background: linear-gradient(135deg, rgba(255, 83, 73, 0.25), rgba(75, 0, 130, 0.25));
  border: 1px solid rgba(255, 127, 80, 0.5);
}
.help-list li::after {
  content: '';
  position: absolute; left: 5px; top: 13.5px;
  width: 8px; height: 5px;
  border-left: 2px solid var(--mosiky-coral);
  border-bottom: 2px solid var(--mosiky-coral);
  transform: rotate(-45deg);
}
.help-cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 0.85rem 1.7rem;
  background: var(--gradient-brand);
  border: none; border-radius: 999px;
  color: #fff; font-size: 0.92rem; font-weight: 600;
  cursor: pointer;
  transition: transform 0.25s ease, box-shadow 0.25s ease, opacity 0.25s;
  box-shadow: 0 10px 30px -12px rgba(255, 83, 73, 0.6);
}
.help-cta:hover { transform: translateY(-1px); box-shadow: 0 14px 36px -12px rgba(255, 83, 73, 0.75); }
.help-cta:disabled { opacity: 0.55; cursor: default; transform: none; }
.help-hint { margin-top: 14px; font-size: 0.8rem; color: rgba(255, 255, 255, 0.4); }

/* Forms */
.help-form { display: flex; flex-direction: column; gap: 16px; }
.help-grid-2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
@media (max-width: 560px) { .help-grid-2 { grid-template-columns: 1fr; } }
.help-field { display: block; }
/* Direct child only: the label text itself now sits in a nested <span>
   so it can carry its own data-i18n next to the <em> hint. A descendant
   selector here made that inner span display:block, which broke the
   label onto two lines. */
.help-field > span {
  display: block;
  font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 7px;
}
.help-field > span em {
  font-style: normal; text-transform: none; letter-spacing: 0;
  font-weight: 400; color: rgba(255, 255, 255, 0.35);
}
.help-field input, .help-field textarea {
  width: 100%;
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 0.8rem 1rem;
  color: #fff;
  font-size: 0.95rem;
  font-family: inherit;
  line-height: 1.5;
  transition: border-color 0.25s, box-shadow 0.25s, background 0.25s;
}
.help-field textarea { resize: vertical; }
.help-field input::placeholder, .help-field textarea::placeholder { color: rgba(255, 255, 255, 0.28); }
.help-field input:focus, .help-field textarea:focus {
  outline: none;
  border-color: rgba(255, 127, 80, 0.65);
  background: rgba(255, 127, 80, 0.05);
  box-shadow: 0 0 0 3px rgba(255, 127, 80, 0.14);
}
.help-submit-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 4px; }
.help-privacy {
  flex: 1; min-width: 220px;
  font-size: 0.74rem; line-height: 1.55;
  color: rgba(255, 255, 255, 0.38);
}
.help-privacy a { color: rgba(255, 255, 255, 0.55); text-decoration: underline; }
/* Honeypot. left:-9999px is an LTR-only trick: under dir="rtl" the
   scroll origin flips and the field extends the scrollable area instead
   of leaving it — the footer reported a 10,287px scrollWidth on a 320px
   viewport. The clip-rect pattern hides it in either direction while
   keeping it in the DOM and submittable, which is what makes a honeypot
   work. */
.hp-field {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

/* Success / error */
.help-success { text-align: center; padding: 34px 10px 12px; }
.help-success-check {
  width: 62px; height: 62px; margin: 0 auto 18px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--gradient-brand);
  color: #fff;
  box-shadow: 0 14px 40px -14px rgba(255, 83, 73, 0.7);
  animation: helpPop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes helpPop { from { transform: scale(0.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.help-success h4 { color: #fff; font-size: 1.2rem; margin-bottom: 8px; }
.help-success p { color: rgba(255, 255, 255, 0.6); font-size: 0.95rem; line-height: 1.6; max-width: 420px; margin: 0 auto; }
.help-error {
  margin-top: 14px;
  padding: 12px 16px;
  border-radius: 12px;
  background: rgba(255, 107, 97, 0.1);
  border: 1px solid rgba(255, 107, 97, 0.35);
  color: #ff8f87;
  font-size: 0.88rem;
}

/* Artist panel */
.help-card-artist { padding: 44px; }
.help-artist-inner {
  display: grid;
  grid-template-columns: minmax(260px, 4fr) minmax(340px, 7fr);
  gap: 44px;
  align-items: start;
}
@media (max-width: 900px) { .help-artist-inner { grid-template-columns: 1fr; gap: 28px; } }
.help-artist-title {
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  color: #fff; letter-spacing: -0.02em; line-height: 1.1;
  margin: 6px 0 16px;
}
.help-artist-title span {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.help-artist-pitch > p {
  color: rgba(255, 255, 255, 0.62);
  font-size: 0.98rem; line-height: 1.65; margin-bottom: 20px;
}

/* Country / dial-code picker */
.phone-row { display: flex; gap: 8px; }
.phone-row input { flex: 1; }
.dial-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 0.8rem 0.9rem;
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.95rem; white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.25s, box-shadow 0.25s;
}
.dial-btn:hover, .dial-btn:focus {
  outline: none;
  border-color: rgba(255, 127, 80, 0.65);
  box-shadow: 0 0 0 3px rgba(255, 127, 80, 0.14);
}
.country-btn { width: 100%; justify-content: flex-start; color: rgba(255, 255, 255, 0.35); }
.country-btn.country-set { color: #fff; }
.country-panel {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0;
  width: min(320px, 88vw);
  background: #16100d;
  border: 1px solid rgba(255, 127, 80, 0.3);
  border-radius: 14px;
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.85);
  overflow: hidden;
}
.country-search {
  width: 100%;
  background: rgba(255, 255, 255, 0.05);
  border: none; border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0.75rem 1rem; color: #fff; font-size: 0.9rem;
}
.country-search:focus { outline: none; background: rgba(255, 127, 80, 0.06); }
.country-list { max-height: 260px; overflow-y: auto; }
.country-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 0.6rem 1rem;
  background: none; border: none; cursor: pointer;
  color: rgba(255, 255, 255, 0.85); font-size: 0.9rem; text-align: left;
}
.country-row:hover { background: rgba(255, 127, 80, 0.1); }
.country-flag { font-size: 1.1rem; }
.country-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.country-dial { color: rgba(255, 255, 255, 0.45); font-size: 0.85rem; }

/* Fixed rows-per-column ranked lists scroll horizontally (app parity) */
.tsr-hscroll {
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 8px;
}

/* Language picker */
.lang-picker { position: relative; display: inline-block; margin-right: 10px; }
.lang-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  padding: 0.45rem 0.9rem;
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.8rem; font-weight: 600;
  cursor: pointer;
}
.lang-btn:hover { border-color: rgba(255, 127, 80, 0.5); }
.lang-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 90;
  min-width: 160px;
  background: #16100d;
  border: 1px solid rgba(255, 127, 80, 0.3);
  border-radius: 14px;
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.85);
  overflow: hidden;
  padding: 6px 0;
}
.lang-item {
  display: block; width: 100%;
  padding: 0.55rem 1.1rem;
  background: none; border: none; cursor: pointer;
  color: rgba(255, 255, 255, 0.85); font-size: 0.88rem; text-align: left;
}
.lang-item:hover { background: rgba(255, 127, 80, 0.1); }

/* Premium page */
.prem-grad {
  background: var(--gradient-brand);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.prem-row { grid-template-columns: repeat(auto-fit, minmax(300px, 420px)); justify-content: center; }
.prem-card { text-align: left; }
.prem-best { border-color: rgba(255, 127, 80, 0.6); box-shadow: 0 20px 60px -20px rgba(255, 83, 73, 0.4); }
.prem-badge {
  display: inline-block;
  background: var(--gradient-brand);
  color: #fff; font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 12px; border-radius: 999px; margin-bottom: 14px;
}
.prem-plan { color: rgba(255,255,255,0.6); font-size: 0.9rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; }
.prem-price { color: #fff; font-size: 2.6rem; font-weight: 800; letter-spacing: -0.02em; margin: 6px 0 16px; }
.prem-price span { font-size: 1rem; font-weight: 500; color: rgba(255,255,255,0.5); }
/* A locked row reads as unavailable at a glance — the whole row dims,
   not just its title, and the cursor stops promising playback. */
.track-locked { opacity: 0.42; cursor: not-allowed; }
.track-locked:hover { opacity: 0.6; background: rgba(255,255,255,0.03); }
.track-locked .track-item-title, .track-locked .dtr-title { opacity: 0.85; }
.lock-badge {
  display: inline-flex; align-items: center; margin-left: 7px;
  color: rgba(255,255,255,0.45); font-size: 0.8em; vertical-align: 1px;
}

/* ── Freemium label ───────────────────────────────────────── */
.freemium-tag {
  /* inset-inline-start, not left: the badge sits top-leading like the
     iOS overlay, so it flips with the layout in Hebrew/Arabic. */
  position: absolute; top: 10px; inset-inline-start: 10px; z-index: 2;
  background: rgba(18, 10, 8, 0.78);
  border: 1px solid rgba(255, 127, 80, 0.55);
  color: var(--mosiky-coral);
  font-size: 0.64rem; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px;
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.freemium-tag-inline {
  position: static; display: inline-block; margin-left: 8px;
  vertical-align: 1px; backdrop-filter: none;
}
.detail-free-count { color: var(--mosiky-coral); font-weight: 700; }
.album-art { position: relative; }

/* ── Account page ─────────────────────────────────────────── */
.account-section { padding-top: 0; }
/* Two columns, not auto-fit. auto-fit with a 320px minimum dealt the
   six cards into four columns on a wide display, each a different
   height, with Sign Out and Danger Zone stranded on a second row. The
   split is editing (left) vs managing (right), and it is capped so the
   fields stay a readable width instead of spanning the whole viewport. */
.account-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 18px; align-items: start;
  max-width: 1040px;
}
.account-grid > .auth-profile-card { grid-column: 1 / -1; }
.account-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

.account-grid .auth-section,
.account-grid > .auth-profile-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  padding: 22px;
  margin: 0;
}
.account-grid .auth-input { width: 100%; box-sizing: border-box; }
.account-grid .auth-danger-zone { border-color: rgba(255, 83, 73, 0.35); }
/* Sign Out stands alone — wrapped in a bordered card it read as an
   empty section with a stray button in it. */
.account-grid .account-signout { margin: 0; }

/* Actions inside a card size to their label. Full-bleed gradient
   buttons are right for the sign-in modal, where each one IS the
   screen's purpose; stacked down a settings page they turned three
   minor confirmations into three brand-coloured slabs. */
.account-grid .auth-section .auth-btn-primary,
.account-grid .auth-section .auth-btn-secondary,
.account-grid .auth-section .auth-danger-btn {
  width: auto;
  align-self: flex-start;
  padding-left: 26px;
  padding-right: 26px;
}
.account-grid .auth-section .auth-link {
  align-self: flex-start;
  padding-left: 0;
  text-align: left;
}

@media (max-width: 900px) {
  .account-grid { grid-template-columns: 1fr; }
}
.account-signed-out {
  grid-column: 1 / -1; text-align: center;
  padding: 48px 22px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
}
.account-signed-out h2 { color: #fff; margin: 0 0 8px; }
.account-signed-out p { color: rgba(255,255,255,0.6); margin: 0 0 20px; }
.account-signed-out .auth-btn-primary { max-width: 280px; margin: 0 auto; }
.auth-badge-premium {
  display: inline-block;
  background: var(--gradient-brand);
  color: #fff; font-size: 0.68rem; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 11px; border-radius: 999px;
  /* The badge is a flex child of .auth-profile-info, a column flex
     container, so it stretched to the full card width — a giant gradient
     bar instead of a pill. inline-block does not help there; only
     align-self does. (.auth-badge-freemium already had this, which is
     why only Premium members ever saw the bar.) */
  align-self: flex-start;
}

/* ── Free on Mosiky shelf ─────────────────────────────────── */
.free-shelf { padding-bottom: 8px; }
.free-shelf-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 18px; flex-wrap: wrap;
}
.free-shelf-title { font-size: clamp(1.3rem, 2.6vw, 1.9rem); margin: 4px 0 0; }
.free-shelf-count {
  color: rgba(255,255,255,0.55); font-size: 0.82rem; font-weight: 600;
  letter-spacing: 0.03em; white-space: nowrap;
}
.free-shelf-row {
  display: flex; gap: 18px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 10px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.18) transparent;
}
.free-shelf-row::-webkit-scrollbar { height: 6px; }
.free-shelf-row::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18); border-radius: 999px;
}
.free-shelf-card {
  flex: 0 0 190px; width: 190px; scroll-snap-align: start;
}
@media (max-width: 640px) {
  .free-shelf-card { flex-basis: 150px; width: 150px; }
}

/* Says WHY the rows below are locked, and is itself the way out. */
.lock-notice {
  display: flex; align-items: center; gap: 9px;
  width: 100%; text-align: left; margin: 0 0 14px;
  padding: 11px 14px;
  background: rgba(255, 83, 73, 0.09);
  border: 1px solid rgba(255, 127, 80, 0.32);
  border-radius: 12px;
  color: rgba(255,255,255,0.86);
  font-size: 0.84rem; line-height: 1.45;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease;
}
.lock-notice:hover {
  background: rgba(255, 83, 73, 0.15);
  border-color: rgba(255, 127, 80, 0.55);
}
.lock-notice svg { flex: 0 0 auto; color: var(--mosiky-coral); }

/* ═══════════════════════════════════════════════════════════════
   RIGHT-TO-LEFT (Urdu today; Arabic/Hebrew/Farsi ready)

   `dir="rtl"` on <html> — set by js/i18n.js — already mirrors text
   direction, flex/grid flow and default text-align. These rules only
   fix the places that hard-code physical left/right, which the browser
   cannot mirror on its own.
   ═══════════════════════════════════════════════════════════════ */

/* Spacing that should follow reading order */
[dir="rtl"] .nav-auth            { margin-left: 0; margin-right: 1rem; }
[dir="rtl"] .lang-picker         { margin-right: 0; margin-left: 10px; }
[dir="rtl"] .track-item-actions  { margin-left: 0; margin-right: auto; }
[dir="rtl"] .player-track-item .track-item-duration { margin-left: 0; margin-right: 8px; }
[dir="rtl"] .explicit-badge      { margin-left: 0; margin-right: 7px; }
[dir="rtl"] .lock-badge          { margin-left: 0; margin-right: 7px; }
[dir="rtl"] .freemium-tag-inline { margin-left: 0; margin-right: 8px; }

/* Text alignment that was pinned left */
[dir="rtl"] .detail-track-row,
[dir="rtl"] .help-card,
[dir="rtl"] .prem-card,
[dir="rtl"] .lock-notice,
[dir="rtl"] .country-row,
[dir="rtl"] .lang-item           { text-align: right; }

/* Numeric gutters flip to the other edge */
[dir="rtl"] .dtr-number,
[dir="rtl"] .tsr-rank            { text-align: left; }

/* Accents and rails drawn on one edge */
[dir="rtl"] .quote-block         { border-left: none; border-right: 2px solid var(--mosiky-coral); }
[dir="rtl"] .footer-inner > div + div,
[dir="rtl"] .split-panel         { border-left: none; border-right: 1px solid var(--glass-border); }

/* Absolutely-positioned chrome: swap the anchored edge */
[dir="rtl"] .freemium-tag        { left: auto; right: 10px; }
[dir="rtl"] .lang-menu           { right: auto; left: 0; }
[dir="rtl"] .country-panel       { left: auto; right: 0; }
[dir="rtl"] .nav-user-dropdown   { right: auto; left: 0; }

/* Glyphs that encode direction must not be mirrored by the layout —
   a play triangle still points at the "next" edge, which in RTL is
   visually left, but chevrons and arrows do flip. */
[dir="rtl"] .page-nav svg,
[dir="rtl"] .detail-back svg,
[dir="rtl"] .back-link svg       { transform: scaleX(-1); }
[dir="rtl"] .album-play-icon svg,
[dir="rtl"] .player-play svg     { transform: none; }

/* Horizontal rails scroll from the right in RTL; the browser handles
   the flow, but snap alignment has to follow. */
[dir="rtl"] .free-shelf-card     { scroll-snap-align: end; }

/* Urdu/Arabic scripts need a little more line height to breathe and
   sit better with a font stack chosen for Latin. */
[dir="rtl"] body                 { line-height: 1.75; }
[dir="rtl"] .section-title,
[dir="rtl"] .detail-title        { line-height: 1.4; }

/* Catalogue content stays in its own language — album titles, artist
   names and taglines are English (or Spanish, or Punjabi) regardless of
   the interface language. `unicode-bidi: plaintext` is the CSS form of
   dir="auto": each string picks its own direction from its first strong
   character, so an English sentence inside an Urdu page keeps its
   punctuation at the correct end instead of flipping the full stop to
   the front. */
[dir="rtl"] .hero-content h1,
[dir="rtl"] .hero-artist,
[dir="rtl"] .hero-tagline,
[dir="rtl"] .album-title,
[dir="rtl"] .album-artist,
[dir="rtl"] .album-genre,
[dir="rtl"] .detail-title,
[dir="rtl"] .detail-artist,
[dir="rtl"] .detail-description,
[dir="rtl"] .dtr-title,
[dir="rtl"] .track-item-title,
[dir="rtl"] .player-track-item .track-item-title,
[dir="rtl"] .video-title,
[dir="rtl"] .video-artist,
[dir="rtl"] .artist-name,
[dir="rtl"] .free-shelf-count,
[dir="rtl"] .playlist-name {
  unicode-bidi: plaintext;
  text-align: start;
}

/* ═══════════════════════════════════════════════════════════════
   FOOTER — four balanced columns.

   The old layout was 1.5fr 1fr 1fr with seven links AND a contact block
   stacked in column two, so a single overloaded column set the footer's
   height while the others sat half empty. Splitting Explore / Support
   ends every column near the same baseline.

   Written with logical properties (inline-start/end) so it mirrors
   correctly in Arabic without a separate RTL block.
   ═══════════════════════════════════════════════════════════════ */
.site-footer { position: relative; overflow: hidden; }

/* The hairline is gone: it was the last hard edge between body and footer,
   and a blend cannot have one. The colour it carried now lives in the
   footer glow below, which reads as light rather than as a rule. */
.site-footer::before { content: none; }

/* Ambient wash — the same treatment as the player, tying the page together */
.footer-glow {
  position: absolute; top: -30%; inset-inline-start: 50%;
  width: min(900px, 90vw); aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(255,83,73,0.10), transparent 62%);
  pointer-events: none;
}
[dir="rtl"] .footer-glow { transform: translateX(50%); }

.footer-inner { position: relative; z-index: 1; }
.footer-col { min-width: 0; }
.footer-logo { height: 26px; width: auto; margin-bottom: 0.85rem; }
.footer-brand p {
  max-width: 34ch;
}

/* App "coming soon" marks. Deliberately NOT lookalikes of the Apple or
   Google badges — their guidelines only permit those once an app is
   actually live in the store. */
.app-soon { display: flex; gap: 10px; margin-top: 1.25rem; flex-wrap: wrap; }
.app-soon-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 16px 9px 13px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 12px;
  color: var(--text-primary);
  font-family: inherit; cursor: pointer;
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
/* iOS is live: give its tile the accent so it reads as a destination
   rather than another "notify me" chip sitting beside it. */
.app-live-btn {
  text-decoration: none;
  border-color: rgba(255, 127, 80, 0.45);
  background: rgba(255, 127, 80, 0.10);
}
.app-live-btn:hover {
  border-color: var(--mosiky-coral);
  background: rgba(255, 127, 80, 0.16);
}
.app-live-btn strong { color: var(--mosiky-coral); }

.app-soon-btn:hover {
  transform: translateY(-2px);
  background: rgba(255,255,255,0.09);
  border-color: rgba(255,127,80,0.45);
}
.app-soon-btn svg { width: 20px; height: 20px; flex: none; }
.app-soon-btn span { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2; }
.app-soon-btn em {
  font-style: normal; font-size: 0.62rem; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--mosiky-coral);
}
.app-soon-btn strong { font-size: 0.92rem; font-weight: 600; }
.app-soon-note {
  margin-top: 0.7rem; font-size: 0.78rem; color: var(--text-secondary);
  min-height: 1.1em; opacity: 0; transition: opacity 0.25s ease;
}
.app-soon-note.show { opacity: 1; }

/* Artist funnel — the footer is prime real estate for it */
.footer-cta {
  display: block; margin-top: 1.25rem; padding: 12px 14px;
  border-radius: 12px;
  background: rgba(255,83,73,0.10);
  border: 1px solid rgba(255,127,80,0.30);
  transition: background 0.18s ease, border-color 0.18s ease;
}
.footer-cta:hover { background: rgba(255,83,73,0.17); border-color: rgba(255,127,80,0.55); }
.footer-cta span { display: block; font-size: 0.74rem; color: var(--text-secondary); }
.footer-cta strong { display: block; font-size: 0.9rem; color: var(--mosiky-coral); margin-top: 2px; }

.footer-note {
  font-size: 0.82rem; color: var(--text-secondary);
  line-height: 1.6; margin-bottom: 0.9rem; max-width: 30ch;
}

/* Newsletter as one inline field */
.newsletter-form { display: flex; gap: 8px; position: relative; }
.newsletter-input {
  flex: 1; min-width: 0;
  padding: 11px 14px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 999px;
  color: var(--text-primary); font-size: 0.86rem; font-family: inherit;
}
.newsletter-input:focus {
  outline: none; border-color: rgba(255,127,80,0.55);
  background: rgba(255,255,255,0.08);
}
.newsletter-btn {
  /* Explicit padding:0 — a stale rule elsewhere used to set 0.75rem
     1.5rem, which no 42px box can contain, so the button inflated into
     an oversized circle. */
  flex: none; width: 42px; height: 42px; padding: 0;
  display: grid; place-items: center;
  border: none; border-radius: 50%;
  background: var(--gradient-brand); color: #fff; cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.newsletter-btn:hover { transform: scale(1.06); box-shadow: 0 6px 18px -6px rgba(255,83,73,0.7); }
.newsletter-btn svg { width: 17px; height: 17px; }
.newsletter-btn[aria-busy="true"] { opacity: 0.55; cursor: progress; transform: none; }
[dir="rtl"] .newsletter-btn svg { transform: scaleX(-1); }

/* Social as circular glass buttons */
.social-links { display: flex; gap: 10px; margin-top: 1.4rem; flex-wrap: wrap; }
.social-links a {
  width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.10);
  color: var(--text-secondary);
  transition: transform 0.18s ease, color 0.18s ease,
              background 0.18s ease, box-shadow 0.18s ease;
}
.social-links a svg { width: 16px; height: 16px; }
.social-links a:hover {
  transform: translateY(-3px);
  color: #fff;
  background: rgba(255,83,73,0.18);
  box-shadow: 0 8px 20px -8px rgba(255,83,73,0.8);
}


/* ── Player: album description ──────────────────────────────── */
/* The player is the album page now, so the blurb lives here. Clamped to
   two lines so it can never push the transport below the fold; expanding
   reflows everything under it, which is the intended behaviour. */
/* A direct child of the art column now, so the column's gap spaces it. */
.player-desc-wrap { margin-top: 0; text-align: center; }
.player-desc {
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-secondary);
  margin: 0 auto;
  max-width: 46ch;
}
.player-desc {
  /* Pure max-height clipping, not line-clamp.
     line-clamp DETERMINES the element's height, so max-height never got
     to constrain anything and the transition had nothing to animate — the
     text simply snapped between two clamp values. Clipping by height
     instead makes the open and close easable.
     The cost is the "…" ellipsis, which line-clamp provided for free. A
     soft fade at the cut line replaces it: it says "there is more" without
     punctuation, and unlike an ellipsis it can animate away. */
  overflow: hidden;
  transition: max-height 0.42s var(--transition-smooth),
              -webkit-mask-position 0.3s ease;
}
.player-desc[data-clamped="1"] {
  /* The fade has to cover the whole second line to read as a fade at all.
     Two earlier attempts missed on opposite sides: starting at 45% ate the
     line and looked broken, then 82% only touched the descenders and was
     invisible. The stop sits at 50% instead — the exact line-1/line-2
     boundary at this line-height — so line one stays fully opaque and line
     two carries the entire gradient. It lands at 0.15 rather than 0 so the
     text trails off while staying legible. */
  -webkit-mask-image: linear-gradient(to bottom,
            #000 0%, #000 50%, rgba(0,0,0,0.15) 100%);
          mask-image: linear-gradient(to bottom,
            #000 0%, #000 50%, rgba(0,0,0,0.15) 100%);
}
.player-desc-toggle {
  background: none; border: 0; padding: 4px 6px; margin-top: 2px;
  font-size: 0.75rem; font-weight: 600; cursor: pointer;
  /* Coral, matching the seekbar, the active track title and shuffle/repeat
     when on. --accent was never defined anywhere in this stylesheet, so this
     silently fell back to red and made the toggle the only interactive text
     in the player wearing the primary-action colour. iOS uses .mosikyCoral
     here. Red is reserved for the play button alone. */
  color: var(--mosiky-coral);
}
.player-desc-toggle:hover { text-decoration: underline; }

/* Artist name is a link now — it opens the artist page. */
.player-track-artist.is-linked {
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
}
.player-track-artist.is-linked:hover { color: #fff; }


/* The footer's gradient hairline is the page's closing flourish. With the
   mini player docked over it, it becomes a second line a few pixels from
   the first — so it stands down while the player is up. */
/* The per-bar overrides that used to hide the footer's edges are gone with
   the edges themselves — there is nothing left to stand down. */

/* ── Radio ──────────────────────────────────────────────────── */
.radio-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 1.5rem;
  padding: 0 2rem 3rem;
}
.radio-card { cursor: pointer; }
.radio-card-art {
  position: relative; width: 100%; aspect-ratio: 1;
  border-radius: 16px; overflow: hidden;
  border: 1px solid var(--glass-border);
  box-shadow: 0 10px 30px rgba(0,0,0,0.45);
  transition: transform 0.35s var(--transition-smooth), box-shadow 0.35s var(--transition-smooth);
}
.radio-card:hover .radio-card-art {
  transform: translateY(-4px);
  box-shadow: 0 18px 44px rgba(0,0,0,0.6);
}
.radio-card-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.35); opacity: 0; transition: opacity 0.3s ease;
}
.radio-card:hover .radio-card-play { opacity: 1; }
.radio-card-name { margin-top: 0.7rem; font-weight: 600; color: #fff; }
.radio-card-desc { font-size: 0.82rem; color: var(--text-secondary); margin-top: 0.15rem; }

/* Now-playing bar. Sits above the music mini player's slot and uses the
   same elevation-not-a-border treatment, so the bottom of the page never
   collects a stack of rules. */
.radio-bar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 151;
  overflow: hidden;
  display: none; align-items: center; gap: 1rem;
  height: 72px; padding: 0 1.25rem;
  background: rgba(18, 10, 8, 0.95);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  box-shadow: 0 -18px 40px -12px rgba(0,0,0,0.75),
              0 -1px 0 0 rgba(255,255,255,0.04);
}
.radio-bar.open { display: flex; }
.radio-bar-art {
  width: 48px; height: 48px; border-radius: 8px; flex-shrink: 0;
  background: linear-gradient(135deg, #FF5349 0%, #4B0082 100%);
}
.radio-bar-text { flex: 1; min-width: 0; }
.radio-bar-station { font-size: 0.78rem; color: var(--text-secondary); }
.radio-bar-track {
  font-weight: 600; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ON AIR badge — the iOS radio mini player's live treatment.
   Tinted capsule rather than a solid red block: the bar already carries a
   red strip along its top edge, and two saturated reds side by side read
   as an error state rather than "this is live". */
.radio-bar-live {
  display: none; align-items: center; gap: 6px; flex-shrink: 0;
  font-size: 0.64rem; font-weight: 800; letter-spacing: 0.1em;
  color: var(--mosiky-red, #FF5349);
  background: rgba(255, 83, 73, 0.15);
  padding: 4px 10px; border-radius: 999px;
}
/* Only while audio is actually flowing — a paused stream is not on air. */
.radio-bar.is-live .radio-bar-live { display: inline-flex; }

/* Three bars that rise and fall, so the badge reads as sound rather than
   a static label. Heights and stagger match the iOS splash equaliser. */
.radio-eq { display: inline-flex; align-items: flex-end; gap: 2px; height: 10px; }
.radio-eq i {
  display: block; width: 2px; border-radius: 1px;
  background: var(--mosiky-red, #FF5349);
  animation: radio-eq-bounce 0.9s ease-in-out infinite;
}
.radio-eq i:nth-child(1) { height: 4px;  animation-delay: 0s; }
.radio-eq i:nth-child(2) { height: 10px; animation-delay: 0.15s; }
.radio-eq i:nth-child(3) { height: 6px;  animation-delay: 0.3s; }

@keyframes radio-eq-bounce {
  0%, 100% { transform: scaleY(0.35); }
  50%      { transform: scaleY(1); }
}

/* Pulsing strip along the top edge — the web twin of the iOS LIVE strip. */
.radio-bar::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--gradient-brand);
  opacity: 0; transition: opacity 0.3s ease;
}
.radio-bar.is-live::before {
  opacity: 1;
  /* Same brand gradient as the audio mini player's progress fill, so the
     two bars are visibly the same component in two modes rather than two
     different widgets. A live stream has no progress to show, so it fills
     the width and breathes instead of advancing. */
  background: var(--gradient-brand);
  animation: radio-strip-pulse 2.4s ease-in-out infinite;
}
@keyframes radio-strip-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* Respect a reduced-motion preference: keep the badge, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .radio-eq i,
  .radio-bar.is-live::before { animation: none; }
}
.radio-bar-btn {
  background: none; border: 0; color: #fff; cursor: pointer;
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
}
.radio-bar-btn:hover { background: rgba(255,255,255,0.08); }
.radio-bar-close { color: var(--text-secondary); }

/* Keep the footer clear of the radio bar, same as the music mini player. */
body.has-radio-bar .site-footer { padding-bottom: calc(4rem + 72px); }
body.has-radio-bar .site-footer::before { opacity: 0; }

@media (max-width: 768px) {
  .radio-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; padding: 0 1rem 2rem; }
  .radio-bar { gap: 0.75rem; padding: 0 1rem; }
  .radio-bar-art { width: 40px; height: 40px; }
  .radio-bar.is-live .radio-bar-live { padding: 4px 7px; }
  .radio-bar-live .radio-eq-label { display: none; }
}

/* ── Radio full player ──────────────────────────────────────── */
.radio-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: none; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.72);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
}
.radio-overlay.open { display: flex; }
.radio-modal {
  position: relative; overflow: hidden;
  width: min(560px, 94vw); max-height: 92vh; overflow-y: auto;
  border-radius: 24px;
  background: #0A0A0A;
  border: 1px solid var(--glass-border);
  box-shadow: 0 30px 90px rgba(0,0,0,0.7);
}
/* Ambient wash in the station's colour — the same treatment as the music
   player, so the two read as one family. */
.radio-modal-glow {
  position: absolute; top: -20%; left: 50%; transform: translateX(-50%);
  width: 120%; aspect-ratio: 1; border-radius: 50%;
  background: #FF5349; filter: blur(120px); opacity: 0.18; pointer-events: none;
}
.radio-modal-header {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  padding: 1rem 1.25rem;
}
.radio-modal-actions { display: flex; gap: 0.5rem; }
.radio-modal-actions button {
  width: 34px; height: 34px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(255,255,255,0.06); color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
}
.radio-modal-actions button:hover { background: rgba(255,255,255,0.12); color: #fff; }
.radio-modal-body { position: relative; padding: 0 1.75rem 1.75rem; text-align: center; }

/* Flip card: song art on the front, station logo on the back. */
.radio-flip { width: min(300px, 70vw); aspect-ratio: 1; margin: 0 auto; perspective: 1000px; cursor: pointer; }
.radio-flip-inner {
  position: relative; width: 100%; height: 100%;
  transition: transform 0.6s var(--transition-smooth); transform-style: preserve-3d;
}
.radio-flip.flipped .radio-flip-inner { transform: rotateY(180deg); }
.radio-flip-face {
  position: absolute; inset: 0; border-radius: 16px;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background-size: cover; background-position: center;
  box-shadow: 0 20px 50px rgba(0,0,0,0.5);
}
.radio-flip-back { transform: rotateY(180deg); }
.radio-flip-hint {
  font-size: 0.72rem; color: var(--text-muted); margin-top: 0.6rem;
  transition: opacity 0.6s ease;
}
/* Faded rather than removed: collapsing it would shift everything
   below by a line ten seconds after opening, which reads as a jolt. */
.radio-flip-hint.is-faded { opacity: 0; }

.radio-live-badge {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 0.9rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
  color: var(--mosiky-red, #FF5349);
  background: rgba(255,83,73,0.14); padding: 5px 12px; border-radius: 999px;
}
/* The arcs pulse rather than a bare dot — same read as the app's
   dot.radiowaves.left.and.right, which is what signals "this is live"
   rather than "this is a track you scrubbed to". */
.radio-live-icon {
  flex-shrink: 0;
  animation: radioPulse 1.6s ease-in-out infinite;
}
@keyframes radioPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }

.radio-modal-station { margin-top: 0.85rem; font-size: 0.9rem; color: var(--text-secondary); }
.radio-modal-title { margin-top: 0.35rem; font-size: 1.35rem; font-weight: 700; color: #fff; }
.radio-modal-artist { margin-top: 0.2rem; color: var(--text-secondary); }
.radio-modal-album { margin-top: 0.15rem; font-size: 0.82rem; color: var(--text-muted); }

.radio-modal-controls { margin-top: 1.5rem; }
.radio-modal-play {
  width: 68px; height: 68px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--mosiky-red, #FF5349); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 30px rgba(255,83,73,0.4);
  transition: transform 0.2s ease;
}
.radio-modal-play:hover { transform: scale(1.05); }

.radio-banner {
  display: flex; align-items: center; gap: 0.85rem; margin-top: 1.75rem;
  padding: 0.85rem; border-radius: 14px; text-decoration: none;
  background: rgba(255,255,255,0.05); border: 1px solid var(--glass-border);
  text-align: start;
}
.radio-banner:hover { background: rgba(255,255,255,0.08); }
.radio-banner-art { width: 46px; height: 46px; border-radius: 10px; flex-shrink: 0; background-size: cover; background-position: center; }
.radio-banner-text { flex: 1; min-width: 0; }
.radio-banner-title { font-weight: 600; color: #fff; font-size: 0.9rem; }
.radio-banner-sub { font-size: 0.78rem; color: var(--text-secondary); }
.radio-banner-cta {
  flex-shrink: 0; font-size: 0.78rem; font-weight: 600; color: #fff;
  background: var(--mosiky-red, #FF5349); padding: 7px 14px; border-radius: 999px;
}
@media (max-width: 768px) {
  .radio-modal { width: 100vw; height: 100vh; max-height: 100vh; border-radius: 0; }
  .radio-modal-body { padding: 0 1.25rem 2rem; }
}

/* ── Inbox ──────────────────────────────────────────────────
   Card shape mirrors the iOS inbox: optional 150px image, unread
   coral rim + dot, 3-line body that expands on tap, ✕ to delete. */
.inbox-badge {
  display: inline-block;
  min-width: 18px;
  margin-left: 8px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--mosiky-red, #FF5349);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.inbox-list { display: flex; flex-direction: column; gap: 12px; max-width: 720px; }

.inbox-card {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.05);
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease, opacity .2s ease, transform .2s ease;
}
.inbox-card:hover { background: rgba(255, 255, 255, 0.07); }
.inbox-card.unread { border-color: rgba(255, 83, 73, 0.35); }
.inbox-card.removing { opacity: 0; transform: translateX(12px); }

.inbox-card-img { height: 150px; background-size: cover; background-position: center; }
.inbox-card-main { padding: 14px; }
.inbox-card-head { display: flex; align-items: flex-start; gap: 8px; }
.inbox-dot {
  flex: none;
  width: 7px; height: 7px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--mosiky-red, #FF5349);
}
.inbox-card-title { margin: 0; font-size: 0.95rem; font-weight: 600; color: #fff; }

.inbox-card-body {
  margin: 6px 0 0;
  color: var(--text-secondary);
  font-size: 0.85rem;
  line-height: 1.6;
  white-space: pre-line;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
/* line-clamp drives the height, so the expanded state has to drop it
   entirely rather than animate a max-height against it. */
.inbox-card-body.expanded { -webkit-line-clamp: unset; overflow: visible; }

.inbox-cta {
  margin-top: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--mosiky-red, #FF5349);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.inbox-cta:hover { text-decoration: underline; }

.inbox-del {
  position: absolute;
  top: 8px; right: 8px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 0.72rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity .18s ease, background .18s ease;
}
.inbox-card:hover .inbox-del,
.inbox-del:focus-visible { opacity: 1; }
.inbox-del:hover { background: var(--mosiky-red, #FF5349); }
/* Touch devices never hover, so the control would be unreachable. */
@media (hover: none) { .inbox-del { opacity: 1; } }

.inbox-empty { padding: 48px 16px; text-align: center; color: var(--text-secondary); }
.inbox-empty-icon { font-size: 2rem; opacity: .5; margin-bottom: 12px; }
.inbox-empty-title { margin: 0 0 6px; font-size: 1rem; color: #fff; font-weight: 600; }
.inbox-empty-body { margin: 0 0 18px; font-size: .875rem; }

/* Standard label-copy warning under the copyright line — smaller and dimmer
   than the © line it qualifies, the way it sits on a printed sleeve.
   Named footer-dup, NOT footer-legal: that class already belongs to the
   links row below, and reusing it overrode its `display: flex` with
   inline-block, which killed the 1.5rem gap and ran the links together. */
.footer-dup {
  display: inline-block;
  margin-top: 4px;
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* Ecosystem line under the copyright — same quiet register as the
   legal links, with the Spell Solutions link brightening on hover. */
.footer-eco {
  display: inline-block;
  margin-top: 4px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.footer-eco a {
  color: var(--text-secondary);
  transition: color 0.3s;
}

.footer-eco a:hover { color: var(--mosiky-coral); }

/* Separator between the legal links. Its own element rather than an
   ::before inside the anchor, so clicking the bar does not follow a link.
   Flex `gap` already spaces it evenly and flips for RTL. */
.footer-sep {
  font-size: 0.8rem;
  color: var(--text-muted);
  opacity: 0.4;
  user-select: none;
}

/* Per-release rights line under the tracklist — deliberately quiet, the way
   label copy sits on a sleeve rather than competing with the music. */
.player-rights {
  /* 1.5rem horizontal to sit on the same left edge as the tracklist header
     and every track row. Without it the block had no horizontal padding at
     all, so the copy hugged the panel edge and the rule above it ran the
     full width — neither lined up with anything above. */
  margin-top: 1.25rem;
  padding: 0.9rem 1.5rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.68rem;
  line-height: 1.6;
  color: var(--text-muted);
}


/* ── Cookie consent ──────────────────────────────────────────────
   Bottom sheet rather than a full-screen interstitial: the visitor
   arriving from a social link should see the music first and answer
   this second. Declining is one tap and as prominent as accepting. */
.cookie-banner {
  position: fixed;
  left: 1rem; right: 1rem; bottom: 1rem;
  z-index: 9000;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1rem 1.25rem;
  border-radius: 14px;
  background: rgba(20, 13, 10, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
}
.cookie-banner[hidden] { display: none; }
.cookie-banner-text {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-secondary);
}
.cookie-banner-text strong {
  color: var(--text-primary);
  margin-right: 0.4rem;
}
.cookie-banner-text a {
  color: var(--mosiky-coral);
  margin-left: 0.4rem;
  white-space: nowrap;
}
.cookie-banner-actions {
  display: flex;
  gap: 0.6rem;
  margin-left: auto;
  flex-shrink: 0;
}
.cookie-btn {
  border-radius: 999px;
  padding: 0.55rem 1.3rem;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.25s;
  white-space: nowrap;
}
.cookie-btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid rgba(255, 255, 255, 0.22);
}
.cookie-btn-ghost:hover { color: var(--text-primary); border-color: rgba(255,255,255,0.4); }
.cookie-btn-accept {
  background: var(--mosiky-coral);
  color: #1a0f0a;
  border: 1px solid var(--mosiky-coral);
}
.cookie-btn-accept:hover { filter: brightness(1.08); }

.cookie-banner-short { display: none; }

/* Phones: one row, not a stacked sheet. The stacked version stood 156px
   tall on a 375px phone and sat squarely on the album player's play
   button, which is the one control a visitor arriving from an ad came
   to press. Same two facts as the long sentence, fewer words. */
@media (max-width: 680px) {
  .cookie-banner {
    left: 0.6rem; right: 0.6rem; bottom: 0.6rem;
    flex-direction: row; align-items: center;
    gap: 0.7rem; padding: 0.65rem 0.75rem;
  }
  .cookie-banner-text { font-size: 0.72rem; line-height: 1.35; min-width: 0; }
  .cookie-banner-text strong,
  .cookie-banner-body { display: none; }
  .cookie-banner-short { display: inline; }
  .cookie-banner-text a { margin-left: 0.3rem; }
  .cookie-banner-actions { gap: 0.4rem; }
  .cookie-btn { flex: none; padding: 0.5rem 0.8rem; font-size: 0.76rem; }
}

/* While the sheet is up, the player ends above it rather than under it.
   --consent-h is the sheet's height plus its gap from the bottom edge,
   kept current by initCookieBanner and zeroed once it is answered, so
   the reservation can never outlive the banner. Any screen height, any
   language, anything still reachable by scrolling the modal. */
.player-overlay { padding-bottom: calc(2rem + var(--consent-h, 0px)); }
.player-modal { max-height: calc(90vh - var(--consent-h, 0px)); }

/* Short phones (iPhone SE, most budget Androids): once the player ends
   above the sheet, a full-width square of artwork pushes the play button
   below the fold of the modal. Everything else in the single-column
   player takes ~339px down to the controls, so the art yields whatever
   height is left, never below 160px. On taller phones the cap never
   binds; dvh follows the real visible height as mobile toolbars
   collapse. */
@media (max-width: 768px) {
  .player-album-art {
    max-width: max(160px, min(320px, calc(100vh - var(--consent-h, 0px) - 26rem)));
    max-width: max(160px, min(320px, calc(100dvh - var(--consent-h, 0px) - 26rem)));
  }
  /* Phones spent ~39px on a 2rem gap above the sheet plus a 90vh cap.
     That margin is what a two-line meta row ("Dance in the Dust ·
     Alternative Rock · 1 hr 9 min") needs to keep play on screen. */
  .player-overlay { padding-top: 1rem; padding-bottom: calc(0.75rem + var(--consent-h, 0px)); }
  .player-modal {
    max-height: calc(100vh - 1.75rem - var(--consent-h, 0px));
    max-height: calc(100dvh - 1.75rem - var(--consent-h, 0px));
  }
}
/* Two-column player on desktop: the artwork shares its column with the
   title, scrubber and controls (~368px of it), inside a modal capped at
   90vh. On a 768px-tall window with the sheet up, full-size art pushed
   the play button out of the modal's visible area. Tall windows never
   hit this cap. */
@media (min-width: 769px) {
  .player-album-art {
    max-width: max(180px, min(320px, calc(90vh - var(--consent-h, 0px) - 23rem)));
    max-width: max(180px, min(320px, calc(90dvh - var(--consent-h, 0px) - 23rem)));
  }
}


/* Hero call to action. The homepage hero carried a title, an artist and
   a tagline but nothing to press: a visitor arriving from an ad saw a
   photograph and no way to reach the music. On a phone this is the only
   thing above the fold that leads anywhere. */
.hero-cta {
  display: inline-block;
  margin-top: 1.4rem;
  padding: 0.85rem 2.1rem;
  border-radius: 999px;
  background: var(--mosiky-coral);
  color: #1a0f0a;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  box-shadow: 0 8px 24px rgba(255, 127, 80, 0.32);
  transition: transform 0.2s, filter 0.2s;
}
.hero-cta:hover { filter: brightness(1.08); transform: translateY(-1px); }

@media (max-width: 680px) {
  .hero-cta { margin-top: 1rem; padding: 0.8rem 1.9rem; }
}

/* Sign-up line under the player controls (deep-link arrivals, signed
   out). An outline button so play stays the one filled call to action. */
.player-signup-cta {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 0.35rem 0.6rem; margin: 0.45rem 0 0.1rem; text-align: center;
  font-size: 0.78rem; color: var(--text-secondary);
}
/* The line sits above the controls, so the artwork gives up its height
   (~2.5rem, one line of text plus the pill) to keep play on screen —
   the same budget as the caps above, just with this row counted. */
.psb-compact { display: none; }
.player-signup-text:empty { display: none; }
@media (max-width: 768px) {
  /* Phones: one pill that carries the whole message. */
  .player-signup-text, .psb-full { display: none; }
  .psb-compact { display: inline; }
  .player-overlay.has-signup-cta .player-album-art {
    max-width: max(120px, min(320px, calc(100vh - var(--consent-h, 0px) - 28.5rem)));
    max-width: max(120px, min(320px, calc(100dvh - var(--consent-h, 0px) - 28.5rem)));
  }
}
@media (min-width: 769px) {
  .player-overlay.has-signup-cta .player-album-art {
    max-width: max(170px, min(320px, calc(90vh - var(--consent-h, 0px) - 25.5rem)));
    max-width: max(170px, min(320px, calc(90dvh - var(--consent-h, 0px) - 25.5rem)));
  }
}
.player-signup-cta[hidden] { display: none; }
.player-signup-btn {
  background: transparent; color: var(--mosiky-coral, #FF7F50);
  border: 1px solid rgba(255, 127, 80, 0.6); border-radius: 999px;
  padding: 0.32rem 0.9rem; font-size: 0.78rem; font-weight: 600; cursor: pointer;
}
.player-signup-btn:hover { background: rgba(255, 127, 80, 0.12); }

/* Inside Facebook/Instagram/Messenger's browser (html.in-app-browser):
   Google refuses sign-in there and pop-ups fail, so only email and phone
   are offered, with a note for people whose account uses Google/Apple. */
.in-app-browser .auth-btn-google,
.in-app-browser .auth-btn-apple { display: none; }
.auth-inapp-note { display: none; margin: 0.5rem 0 0; font-size: 0.75rem; color: var(--text-muted); text-align: center; }
.in-app-browser .auth-inapp-note { display: block; }

/* Android inside Facebook/Instagram: hand the page to Chrome, where
   Google sign-in works. Hidden everywhere else. */
.auth-open-chrome { display: none; margin: 0.6rem auto 0; padding: 0.55rem 1rem; border-radius: 999px;
  border: 1px solid rgba(255, 127, 80, 0.6); color: var(--mosiky-coral, #FF7F50); font-weight: 600;
  font-size: 0.85rem; text-align: center; text-decoration: none; width: fit-content; }
.in-app-browser.is-android .auth-open-chrome { display: block; }

/* Android has no Apple sign-in to speak of, and "Continue with Apple" was
   the first big button under the form: 6 ad visitors tapped it in a week
   and none finished. Sign-in keeps it for anyone who joined on an iPhone. */
.is-android #auth-signup .auth-btn-apple { display: none; }

/* Sign-up and sign-in say what is wrong under the exact box, in place of
   one message at the top of the card (2026-10-04: 15 of 16 email sign-up
   attempts stopped on "Please fill in email and password", often tapped
   4 to 8 times, likely without seeing it). */
.auth-input.auth-input-invalid { border-color: #ff6b6b; box-shadow: 0 0 0 1px #ff6b6b inset; }
/* .auth-view is a centred flex column with a 14px gap: pull the line up
   to its box and give it the box's full width. */
.auth-field-hint,
.auth-field-error { width: 100%; box-sizing: border-box; margin: -8px 0 0; padding: 0 4px;
  font-size: 0.75rem; line-height: 1.35; text-align: start; }
.auth-field-hint { color: var(--text-muted); }
.auth-field-error,
.auth-field-hint.is-error { color: #ff8a80; }
.auth-field-error .auth-link { display: inline; margin: 0 0 0 4px; padding: 0; font-size: inherit; }

/* Phone code screen: resend (counts down, then one tap) and change number
   stack under Verify. */
#auth-phone-code .auth-link { display: block; margin: 12px auto 0; }
.auth-link:disabled { opacity: 0.5; cursor: default; }

/* "The player moves left to right" on Android (2026-10-01). The phone
   layout's single column was 1fr, which cannot shrink below its widest
   row: the five transport buttons (253px) plus the artwork section's 2rem
   padding needed ~330px, more than a 360–412px phone leaves inside the
   modal (~305px). The modal scrolls vertically, so it also scrolled
   sideways by the difference — to the right in English, to the left in
   Arabic. The column now shrinks, phones give the player more width, and
   the modal never scrolls sideways. */
.player-modal { overflow-x: hidden; }
@media (max-width: 768px) {
  .player-inner { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 480px) {
  .player-overlay { padding-left: 0.75rem; padding-right: 0.75rem; }
  .player-art-section { padding: 1.5rem 1rem; }
}
@media (max-width: 340px) {
  .player-controls { gap: 0.15rem; }
}


/* ── Get the app + official store badges (2026-10-04) ─────────
   Apple's and Google's own artwork (their badge services), shown at the
   same visible height as their guidelines ask. Google's PNG carries its
   own clear space (the badge is about 67% of the image height), hence
   the taller image and negative margin. */
.store-badges { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.store-badge { display: inline-flex; line-height: 0; border-radius: 10px; transition: transform 0.2s, filter 0.2s; }
.store-badge:hover { transform: translateY(-1px); filter: brightness(1.12); }
.store-badge:focus-visible { outline: 2px solid var(--mosiky-coral); outline-offset: 3px; }
.store-badge-apple img { height: 48px; width: auto; }
.store-badge-google img { height: 71px; width: auto; margin: -11.5px -11.5px; }
.store-badges-footer { margin-top: 1.25rem; gap: 10px; }
.store-badges-footer .store-badge-apple img { height: 40px; }
.store-badges-footer .store-badge-google img { height: 59.5px; margin: -9.75px -9.75px; }

.get-app { padding: 3rem 2rem 0; }
.get-app-card {
  max-width: 1100px; margin: 0 auto;
  display: flex; align-items: center; gap: 1.5rem;
  padding: 1.5rem 1.75rem; border-radius: 20px;
  background: linear-gradient(135deg, rgba(255, 83, 73, 0.10), rgba(75, 0, 130, 0.12));
  border: 1px solid var(--glass-border);
}
.get-app-icon { width: 64px; height: 64px; border-radius: 15px; flex: none; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); }
.get-app-text { flex: 1; min-width: 0; }
.get-app-text .section-label { margin-bottom: 0.25rem; }
.get-app-heading { font-size: 1.5rem; font-weight: 700; line-height: 1.2; margin: 0 0 0.35rem; }
.get-app-body { color: var(--text-secondary); font-size: 0.95rem; line-height: 1.5; margin: 0; }
.get-app-features { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0.75rem 0 0; padding: 0; }
.get-app-features li {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0.3rem 0.75rem; border-radius: 999px;
  background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85); font-size: 0.75rem; font-weight: 600; line-height: 1.3;
}
.get-app-features svg { width: 14px; height: 14px; flex: none; color: var(--mosiky-coral); }
@media (max-width: 768px) {
  .get-app { padding: 2rem 1rem 0; }
  .get-app-card { flex-direction: column; align-items: flex-start; gap: 1rem; padding: 1.25rem; }
  .get-app-icon { width: 56px; height: 56px; border-radius: 13px; }
  .get-app-heading { font-size: 1.25rem; }
}

/* "No credit card required" under the sign-up buttons (2026-10-04). */
.auth-nocard { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 0; font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); text-align: center; }
.auth-nocard svg { color: #5CCB95; flex: none; }

.player-tracklist-count { letter-spacing: 0.06em; opacity: 0.85; }
.player-modal-header { transition: background 0.2s; }
.player-modal-header.is-scrolled {
  background: rgba(12, 10, 10, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--glass-border);
}
