/* ===============================================================
   RACING NEXUS — LEADERBOARD
   Page layout for the public board at "/": podium, then card grid.
   The driver cards themselves are styled in cards.css.

   SCOPE / SAFETY
   All selectors here are namespaced `lb-` (card animation rules are
   scoped under .lb-board). templates/admin.html also loads
   index.css, so this file is kept separate and prefixed to make it
   structurally impossible to affect /admin, /rank or /login. Do not
   add unprefixed element or class selectors.

   Tuned for a venue TV first: every size is fluid via clamp(), so
   the same board reads correctly from a phone to a 4K wall panel.
   =============================================================== */

/* ---------------------------------------------------------------
   1. TOKENS
   --------------------------------------------------------------- */
:root {
  /* surfaces — near-black, so lap times carry the contrast */
  --lb-bg: #08080c;
  --lb-surface: #101017;
  --lb-surface-hi: #16161f;
  --lb-hairline: rgba(255, 255, 255, 0.07);
  --lb-hairline-strong: rgba(255, 255, 255, 0.14);

  /* text */
  --lb-text: #f2f3f5;
  --lb-text-dim: #9aa0aa;
  --lb-text-faint: #5d636e;

  /* rank accents */
  --lb-gold: #d4af37;
  --lb-silver: #c8cdd2;
  --lb-bronze: #c97b3c;
  --lb-iconic: #e10600; /* positions 4..N */
  --lb-neutral: #3a3a46; /* overflow columns */
  --lb-live: #35d07f;

  /* type — overridden wholesale by fonts-local.css when MODE=local.
     ui-monospace resolves to SF Mono / Cascadia / DejaVu Sans Mono
     per platform, all of which have true tabular figures. */
  --font-display: "Vercetti", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Vercetti", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-numeric: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

}

/* ---------------------------------------------------------------
   2. PAGE CHROME
   --------------------------------------------------------------- */
.lb-page {
  background: var(--lb-bg);
}

/* Desktop: header, board and footer share exactly one screen. */
@media (min-width: 901px) {
  .lb-page {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    min-height: 0;
  }
}

/* The background photo previously sat at 0.25 opacity and competed
   with the text at viewing distance. Dropped to 0.10 and paired
   with a vignette so the type stays the brightest thing on screen. */
.lb-page .bg-img {
  opacity: 0.15;
}

.lb-vignette {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(225, 6, 0, 0.09), transparent 62%),
    linear-gradient(180deg, rgba(8, 8, 12, 0.55) 0%, rgba(8, 8, 12, 0.92) 100%);
}

/* ---------------------------------------------------------------
   3. HEADER
   --------------------------------------------------------------- */
.lb-header {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  flex: none;
  padding: clamp(0.35rem, 0.55vw, 0.7rem) clamp(1rem, 3vw, 2.75rem);
  overflow: hidden;
  background: linear-gradient(180deg, rgba(20, 20, 28, 0.82), rgba(8, 8, 12, 0.62));
  border-bottom: 1px solid var(--lb-hairline);
  /* blur is kept here only — see the note on row performance below */
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.lb-header .lb-streaks {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  opacity: 0.2;
  z-index: 0;
  pointer-events: none;
}

.lb-brand {
  position: relative;
  z-index: 1;
  grid-column: 2;
  text-align: center;
}

.lb-eyebrow {
  font-family: var(--font-body);
  font-size: clamp(0.55rem, 0.62vw, 0.75rem);
  font-weight: 400;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--lb-text-faint);
  margin-bottom: 0.2em;
}

.lb-title {
  font-family: "F1", var(--font-display);
  font-size: clamp(1.1rem, 1.6vw, 1.9rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  margin: 0;
}

/* Red underscore under the wordmark — the one piece of brand colour
   in the chrome, so the accent reads as deliberate rather than
   decorative. */
.lb-title::after {
  content: "";
  display: block;
  width: clamp(2.5rem, 5vw, 5rem);
  height: 2px;
  margin: 0.3em auto 0;
  background: linear-gradient(90deg, transparent, var(--lb-iconic), transparent);
}

/* ---------------------------------------------------------------
   4. BOARD LAYOUT
   ---------------------------------------------------------------
   Two separate sections, stacked:
     podium   P2 P1 P3 side by side, P1 centred and raised
     grid     P4 .. P15, two rows of six
   separated by a labelled hairline. On desktop the board fills the
   screen and every card stretches to its cell; the cards size their
   contents from both width and height (--u, see cards.css), so a
   wide or short cell never overflows.
   --------------------------------------------------------------- */
.lb-board {
  --lb-gap: clamp(0.5rem, 0.7vw, 0.9rem);
  display: flex;
  flex-direction: column;
  gap: var(--lb-gap);
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  padding: clamp(0.5rem, 0.9vw, 1.1rem) clamp(0.75rem, 1.4vw, 1.75rem);
  box-sizing: border-box;
}

.lb-podium {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(0.75rem, 1.4vw, 1.75rem);
  width: min(100%, 80rem);
  margin: 0 auto;
  min-height: 0;
}

/* DOM order is P1, P2, P3 (reads correctly to screen readers);
   visual order puts P1 in the middle. */
.lb-podium-slot[data-rank="1"] { order: 2; flex-grow: 1.15; }
.lb-podium-slot[data-rank="2"] { order: 1; }
.lb-podium-slot[data-rank="3"] { order: 3; }

.lb-podium-slot {
  flex: 1 1 0;
  min-width: 0;
}

.lb-podium-slot:empty {
  aspect-ratio: 470 / 360;
}

/* Hairline with a small label between the podium and the field. */
.lb-divider {
  display: flex;
  align-items: center;
  gap: 1em;
  flex: none;
  margin: clamp(0.15rem, 0.4vw, 0.5rem) 0;
  font-family: var(--font-body);
  font-size: clamp(0.55rem, 0.62vw, 0.75rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--lb-text-faint);
}

.lb-divider::before,
.lb-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--lb-hairline-strong);
}

.lb-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--lb-gap);
}

/* Desktop: one screen. The podium takes the larger share of the
   height; P1 is the widest and tallest step, P2/P3 a little lower. */
@media (min-width: 901px) {
  .lb-podium { flex: 1.35 1 0; }
  .lb-grid {
    flex: 2 1 0;
    min-height: 0;
    grid-template-rows: repeat(2, minmax(0, 1fr));
  }

  .lb-podium-slot { height: 88%; }
  .lb-podium-slot[data-rank="1"] { height: 100%; }
  .lb-podium-slot:empty { aspect-ratio: auto; }

  .lb-board .rn-card,
  .lb-board .lb-skeleton-card {
    height: 100%;
    aspect-ratio: auto;
  }

  .lb-board .rn-card {
    --u: min(1cqw, 1.3056cqh); /* 470×360 */
    container-type: size;
  }
}

/* ---------------------------------------------------------------
   5. CARD MOTION
   ---------------------------------------------------------------
   Slot changes glide via FLIP in index.js (Web Animations), so the
   CSS here never animates `transform` on a card that may be gliding,
   except .is-new, which has no previous slot to glide from.

   .is-new       a driver enters: drops in just after the displaced
                 cards start moving, with a team-colour glow and a
                 light sweep.
   .promoted     own lap improved: green pulse.
   .demoted      own lap edited slower: red pulse.
   .is-revealed  team/photo set in admin (styled in cards.css).
   --------------------------------------------------------------- */
.lb-board .rn-card.is-new {
  animation: lb-new-entry 1.1s cubic-bezier(0.16, 1, 0.3, 1) 0.16s both;
}

.lb-board .rn-card.is-new::after {
  content: "";
  position: absolute;
  z-index: 20;
  inset: 0 auto 0 -40%;
  width: 40%;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55) 48%, var(--team-spot, var(--lb-iconic)));
  opacity: 0;
  transform: skewX(-18deg);
  animation: lb-new-swoosh 0.95s cubic-bezier(0.2, 0.75, 0.35, 1) 0.36s both;
}

@keyframes lb-new-entry {
  0% {
    opacity: 0;
    transform: translate3d(0, 32px, 0) scale(0.92);
    filter: brightness(1.8) saturate(0.4);
    outline: 2px solid var(--team-spot, var(--lb-iconic));
    outline-offset: 6px;
  }
  45% {
    opacity: 1;
    transform: translate3d(0, -5px, 0) scale(1.015);
    filter: none;
    outline: 2px solid var(--team-spot, var(--lb-iconic));
    outline-offset: 0;
  }
  70% {
    transform: translate3d(0, 1px, 0) scale(1);
  }
  100% {
    opacity: 1;
    transform: none;
    outline: 2px solid transparent;
    outline-offset: 0;
  }
}

@keyframes lb-new-swoosh {
  0% { opacity: 0; transform: translateX(-120%) skewX(-18deg); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translateX(390%) skewX(-18deg); }
}

.lb-board .rn-card.promoted {
  animation: lb-promoted 1.2s ease-out;
}

.lb-board .rn-card.demoted {
  animation: lb-demoted 1.2s ease-out;
}

@keyframes lb-promoted {
  0%, 45% { outline: 2px solid var(--lb-live); outline-offset: 3px; }
  100% { outline: 2px solid transparent; outline-offset: 0; }
}

@keyframes lb-demoted {
  0%, 45% { outline: 2px solid var(--lb-iconic); outline-offset: 3px; }
  100% { outline: 2px solid transparent; outline-offset: 0; }
}

/* ---------------------------------------------------------------
   6. SKELETON / EMPTY STATE
   --------------------------------------------------------------- */
.lb-skeleton-card {
  width: 100%;
  aspect-ratio: 470 / 360;
  border-radius: 12px;
  background: linear-gradient(90deg, #0d0d14 0%, #16161f 50%, #0d0d14 100%);
  background-size: 200% 100%;
  animation: lb-shimmer 1.4s ease-in-out infinite;
}

.lb-podium-slot .lb-skeleton-card {
  border-radius: 16px;
}

@keyframes lb-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.lb-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: clamp(3rem, 12vh, 8rem) 1rem;
  text-align: center;
  border: 1px dashed var(--lb-hairline);
  border-radius: 8px;
  background: rgba(16, 16, 23, 0.45);
}

.lb-empty-title {
  font-family: var(--font-display);
  font-size: clamp(0.95rem, 1.6vw, 1.6rem);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lb-text-dim);
}

.lb-empty-sub {
  font-family: var(--font-body);
  font-size: clamp(0.7rem, 0.9vw, 0.95rem);
  color: var(--lb-text-faint);
  letter-spacing: 0.04em;
}

.lb-hidden {
  display: none !important;
}

/* ---------------------------------------------------------------
   7. FOOTER
   --------------------------------------------------------------- */
.lb-footer {
  flex: none;
  padding: 0.35rem clamp(1rem, 4vw, 3rem);
  border-top: 1px solid var(--lb-hairline);
  text-align: center;
}

.lb-footer p {
  max-width: none;
  margin: 0 auto;
  font-family: var(--font-body);
  font-size: clamp(0.55rem, 0.6vw, 0.7rem);
  line-height: 1.4;
  color: var(--lb-text-faint);
}

/* ---------------------------------------------------------------
   8. RESPONSIVE
   --------------------------------------------------------------- */
/* Below desktop the board scrolls and cards size by width. */
@media (max-width: 900px) {
  .lb-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .lb-footer p { max-width: 70ch; }
}

@media (max-width: 720px) {
  .lb-header {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }

  .lb-brand { grid-column: 1; }

  .lb-board {
    gap: clamp(1rem, 4vw, 1.5rem);
    padding: clamp(0.75rem, 3vw, 1rem);
  }

  .lb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Phones: P1, P2, P3 stack at full width, then one card per row. */
@media (max-width: 520px) {
  .lb-podium {
    flex-direction: column;
    align-items: stretch;
    gap: var(--lb-gap);
  }

  .lb-podium-slot[data-rank] { order: 0; flex: none; }

  .lb-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------
   9. ACCESSIBILITY
   --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lb-board .rn-card.is-new,
  .lb-board .rn-card.is-new::after,
  .lb-board .rn-card.is-revealed,
  .lb-board .rn-card.promoted,
  .lb-board .rn-card.demoted,
  .lb-skeleton-card {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .lb-board .rn-card.is-new::after {
    display: none;
  }
}
