/*
 * Landing page (#64).
 *
 * Linked, not injected, and built entirely on the tokens in tokens.css so the
 * front door paints correctly on a fresh clone where static/js has never been
 * built. Nothing here may depend on the bundle: if /js/app-main.js 404s, every
 * rule below still applies and the page still reads.
 */

/*
 * Boot visibility.
 *
 * `data-auth` on <html> is written by the inline script in index.html (from a
 * localStorage hint, before first paint) and then corrected by app-main once
 * /api/auth/status answers. The four states:
 *
 *   absent          - no JS, or JS hasn't run yet. Show the landing. This is
 *                     the default on purpose: the visitor is the common case,
 *                     and a visitor must never get a blank page.
 *   "probable-in"   - this browser logged in before, so skip the marketing and
 *                     show a neutral skeleton instead of flashing a landing
 *                     page at someone who just wants their library.
 *   "in"            - confirmed logged in. app-main owns the screen.
 *   "out"           - confirmed logged out. Show the landing.
 */
#boot-skeleton {
  display: none;
}

html[data-auth="probable-in"] #landing,
html[data-auth="in"] #landing {
  display: none;
}

html[data-auth="probable-in"] #boot-skeleton {
  display: block;
}

.landing {
  max-width: 68rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
  color: var(--color-text);
}

.landing section + section {
  margin-top: var(--space-8);
}

/* Hero -------------------------------------------------------------- */

.landing-hero {
  text-align: center;
  padding: var(--space-7) 0 var(--space-6);
}

.landing-hero h1 {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-3);
}

.landing-lede {
  font-size: var(--font-size-lg);
  line-height: 1.5;
  max-width: 34rem;
  margin: 0 auto var(--space-4);
}

.landing-sub {
  color: var(--color-text-muted);
  max-width: 38rem;
  margin: 0 auto;
  line-height: 1.6;
}

/* Calls to action --------------------------------------------------- */

.landing-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-6);
}

.landing-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-pill);
  font-weight: var(--font-weight-bold);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: var(--font-size-md);
  font-family: inherit;
  transition: filter var(--duration-base) var(--easing-standard);
}

/*
 * `display` on a class beats the UA stylesheet's `[hidden] { display: none }`,
 * so any .landing-button carrying the `hidden` attribute renders anyway
 * without this rule. Found the hard way in #64, where a feature-flagged CTA
 * shipped visible and pointed at a route that did not exist. Keep it: the
 * next hidden button will hit the same thing.
 */
.landing-button[hidden] {
  display: none;
}

.landing-button--primary {
  /*
   * The brand green, not --color-accent: this button carries the Spotify mark,
   * so it is brand surface and must not drift with the theme. Same reasoning
   * as components/spotify-attribution.ts.
   */
  background-color: var(--brand-spotify-green);
  color: var(--color-on-scrim);
}

.landing-button:hover {
  filter: brightness(1.08);
}

.landing-button:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/*
 * Pending state. The click navigates away to Spotify, but not instantly, and
 * an unacknowledged click reads as a dead button (#64).
 */
.landing-button[aria-disabled="true"] {
  pointer-events: none;
  opacity: 0.7;
  cursor: progress;
}

.landing-cta-note {
  margin-top: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Feature cards ------------------------------------------------------ */

.landing h2 {
  font-size: var(--font-size-xl);
  margin: 0 0 var(--space-2);
}

.landing-section-intro {
  color: var(--color-text-muted);
  margin: 0 0 var(--space-5);
  max-width: 44rem;
  line-height: 1.6;
}

.landing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-4);
}

.landing-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

.landing-card h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-md);
}

.landing-card p {
  margin: 0;
  color: var(--color-text-muted);
  line-height: 1.6;
  font-size: var(--font-size-sm);
}

/* Preview figures ---------------------------------------------------- */

.landing-previews {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--space-5);
}

.landing-figure {
  margin: 0;
}

.landing-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.landing-figure figcaption {
  margin-top: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* Access story ------------------------------------------------------- */

.landing-access {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: var(--space-5);
}

.landing-panel {
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

.landing-panel h3 {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-md);
}

.landing-panel ul {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
  color: var(--color-text-muted);
  line-height: 1.7;
  font-size: var(--font-size-sm);
}

.landing-panel p {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  line-height: 1.6;
  font-size: var(--font-size-sm);
}

.landing-panel p:last-child {
  margin-bottom: 0;
}

/*
 * The 5-user cap. Stated before OAuth, never discovered as an error code.
 *
 * The warning hue is carried by the border alone. Text keeps the ordinary
 * foreground colours: --color-on-status is sized for a *saturated* status
 * fill, and on --color-warning-soft (16% warning mixed into the surface) it
 * resolves to near-black on dark brown in the dark theme — illegible, and on
 * the one paragraph that most needs reading.
 */
.landing-panel--limit {
  border-color: var(--color-warning);
  border-width: 1px;
  border-left-width: 4px;
  background-color: var(--color-warning-soft);
}

.landing-panel--limit h3 {
  color: var(--color-text);
}

.landing-panel--limit p {
  color: var(--color-text);
}

.landing-panel a {
  color: var(--color-accent-text);
}

/* Spotify attribution ------------------------------------------------ */

.landing-attribution {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  justify-content: center;
  text-align: center;
}

/*
 * The mandated mark and link-back (#58). The icon is 24px — above Spotify's
 * 21px digital minimum — and the link text is one of the prescribed strings,
 * not our own wording.
 */
.spotify-attribution-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--brand-spotify-green);
  text-decoration: none;
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  letter-spacing: 0.02em;
}

.spotify-attribution-link:hover {
  text-decoration: underline;
}

.spotify-attribution-link:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.spotify-attribution-link svg {
  display: block;
  fill: currentColor;
  flex-shrink: 0;
}

.landing-disclaimer {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-subtle);
  max-width: 34rem;
  line-height: 1.6;
}

/* Boot skeleton ------------------------------------------------------ */

/*
 * Deliberately content-free: shape only, no copy. A returning user is about
 * to get their library, and guessing at a message here ("Loading your
 * library…") would be wrong for the case where the session turns out to be
 * dead.
 */
.boot-skeleton {
  max-width: 68rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5);
}

.boot-skeleton__bar {
  height: 1.25rem;
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-raised);
  margin-bottom: var(--space-4);
  max-width: 18rem;
}

.boot-skeleton__grid {
  display: grid;
  grid-template-columns: minmax(10rem, 1fr) 3fr;
  gap: var(--space-5);
}

.boot-skeleton__block {
  height: 20rem;
  border-radius: var(--radius-md);
  background-color: var(--color-surface-raised);
}

@media (prefers-reduced-motion: no-preference) {
  .boot-skeleton__bar,
  .boot-skeleton__block {
    animation: boot-skeleton-pulse 1.4s ease-in-out infinite;
  }
}

@keyframes boot-skeleton-pulse {
  0%,
  100% {
    opacity: 0.55;
  }

  50% {
    opacity: 0.9;
  }
}

/* Small screens ------------------------------------------------------ */

@media (max-width: 40rem) {
  .landing {
    padding: var(--space-4) var(--space-4) var(--space-7);
  }

  .landing-hero {
    padding: var(--space-5) 0 var(--space-4);
  }

  .landing-hero h1 {
    font-size: var(--font-size-xl);
  }

  .landing-button {
    width: 100%;
    justify-content: center;
  }

  .boot-skeleton__grid {
    grid-template-columns: 1fr;
  }
}
