/* =========================================================
   SPLASH + ENTRY (js/splash.js)
   =========================================================
   The splash is plain markup in index.html, so it's on screen from
   the first paint, before any JavaScript has run. It covers the
   app while the first songs load (instead of a leftover header over
   grey placeholder rows), then fades out, and the app's own parts
   arrive in order: sidebar and header, Home's sections one after
   another, the player bar last. Theme-aware through the tokens. */

.app-splash {
  position: fixed;
  inset: 0;

  z-index: 3000;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  gap: 18px;

  background: var(--bg);

  transition:
    opacity 450ms var(--ease-out),
    visibility 0s linear 450ms;
}

.app-splash.is-leaving {
  opacity: 0;
  visibility: hidden;
}

/* Two soft colour fields, pink and violet, slowly breathing behind
   the mark: the brand pairing, kept out of the way of the logo. */
.app-splash-glow {
  position: absolute;
  top: 50%;
  left: 50%;

  width: 340px;
  height: 340px;

  translate: -50% -58%;

  border-radius: 50%;

  background:
    radial-gradient(circle at 35% 40%, rgba(214, 20, 95, 0.45), transparent 60%),
    radial-gradient(circle at 68% 62%, rgba(142, 45, 226, 0.4), transparent 60%);

  filter: blur(40px);

  animation: splash-breathe 2.4s ease-in-out infinite;

  pointer-events: none;
}

:root[data-theme="day"] .app-splash-glow {
  opacity: 0.55;
}

/* ---- The mark draws itself ----
   Researched pattern: a logo that traces its own outline while the app
   loads, then completes (21st.dev "Logo Trace Loader", Framer's logo
   stroke preloaders, Codrops' preloader tutorial). Earloop's mark is
   one spiral stroke, the same one new playlists draw in the sidebar,
   so the brand moves the same way everywhere.
   - 100 to 1000ms: the spiral draws from its tail inward (ease in and
     out, so it gathers speed and lands softly).
   - From 450ms: "earloop" rises in, letter by letter.
   - While loading continues: a soft light runs along the spiral,
     "still working" said in the logo's own shape (it replaces the old
     equaliser bars).
   - Leaving: the mark grows a touch as the screen fades into the app.
   The path has pathLength="100", so the dash maths is in percent. */
.app-splash-mark {
  position: relative;

  width: 80px;
  height: 82px;

  overflow: visible;

  transition: transform 450ms var(--ease-out);
}

.app-splash-mark path {
  fill: none;

  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-splash-draw {
  stroke: #ff4d8d;
  stroke-width: 48;

  stroke-dasharray: 100;
  stroke-dashoffset: 100;

  animation: splash-draw 900ms cubic-bezier(0.65, 0, 0.35, 1) 100ms forwards;
}

.app-splash-comet {
  stroke: rgba(255, 255, 255, 0.7);
  stroke-width: 18;

  stroke-dasharray: 14 86;
  stroke-dashoffset: 100;

  opacity: 0;

  animation:
    splash-comet-in 300ms ease 1000ms forwards,
    splash-comet 1500ms linear 1000ms infinite;
}

.app-splash-word {
  position: relative;

  display: flex;

  color: var(--text);

  font-family: var(--font-sans);
  font-size: var(--fs-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);

  transition: opacity 300ms ease;
}

.app-splash-word span {
  display: inline-block;

  animation: splash-letter 520ms cubic-bezier(0.2, 0, 0, 1) both;
}

.app-splash-word span:nth-child(1) { animation-delay: 450ms; }
.app-splash-word span:nth-child(2) { animation-delay: 495ms; }
.app-splash-word span:nth-child(3) { animation-delay: 540ms; }
.app-splash-word span:nth-child(4) { animation-delay: 585ms; }
.app-splash-word span:nth-child(5) { animation-delay: 630ms; }
.app-splash-word span:nth-child(6) { animation-delay: 675ms; }
.app-splash-word span:nth-child(7) { animation-delay: 720ms; }

/* Leaving: the mark grows a touch, the word goes first. */
.app-splash.is-leaving .app-splash-mark {
  transform: scale(1.08);
}

.app-splash.is-leaving .app-splash-word {
  opacity: 0;
}

@keyframes splash-draw {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes splash-comet-in {
  to {
    opacity: 1;
  }
}

@keyframes splash-comet {
  from {
    stroke-dashoffset: 100;
  }

  to {
    stroke-dashoffset: 0;
  }
}

@keyframes splash-letter {
  from {
    opacity: 0;
    transform: translateY(10px);
    filter: blur(4px);
  }
}

@keyframes splash-breathe {
  50% {
    transform: scale(1.12) rotate(12deg);
  }
}

@keyframes splash-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* ---- Entry, right after the splash leaves ----
   <html> carries .is-entering for about a second. */
.is-entering .sidebar {
  animation: enter-from-left 560ms var(--ease-out) both;
}

.is-entering .header {
  animation: enter-fade 560ms var(--ease-out) 60ms both;
}

.is-entering .home-shelves > * {
  animation: splash-rise 520ms var(--ease-out) both;
}

.is-entering .home-shelves > :nth-child(1) { animation-delay: 80ms; }
.is-entering .home-shelves > :nth-child(2) { animation-delay: 140ms; }
.is-entering .home-shelves > :nth-child(3) { animation-delay: 200ms; }
.is-entering .home-shelves > :nth-child(4) { animation-delay: 260ms; }
.is-entering .home-shelves > :nth-child(5) { animation-delay: 320ms; }
.is-entering .home-shelves > :nth-child(n + 6) { animation-delay: 380ms; }

.is-entering .player {
  animation: enter-from-below 560ms var(--ease-out) 200ms both;
}

.is-entering .tab-bar {
  animation: enter-from-below 560ms var(--ease-out) 260ms both;
}

@keyframes enter-from-left {
  from {
    opacity: 0;
    transform: translateX(-16px);
  }
}

@keyframes enter-from-below {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}

@keyframes enter-fade {
  from {
    opacity: 0;
  }
}

/* Reduced motion: no movement, no looping; the splash just fades. */
@media (prefers-reduced-motion: reduce) {
  .app-splash-draw {
    stroke-dashoffset: 0;
  }

  .app-splash-comet {
    display: none;
  }

  .app-splash-glow,
  .app-splash-draw,
  .app-splash-word span,
  .app-splash-mark,
  .is-entering .sidebar,
  .is-entering .header,
  .is-entering .home-shelves > *,
  .is-entering .player,
  .is-entering .tab-bar {
    animation: none;
  }
}
