/* Shared fixed header + spacing system (pages, wraps, overlays).
   Stack (top → bottom): #lanternTicker (full width) then #lanternAppBarRoot (nav).
   Combined chrome height for content offset: ticker strip (48px in lantern-ticker.css) + app bar (52px) = --lantern-header-h-ticker.
   Pages with ticker: body.page-has-ticker so .lanternContent uses --lantern-header-h-ticker.
   Contract + audit: docs/ui/LANTERN_TOP_CHROME.md — do not add one-off header/ticker stacks per page. */
:root {
  --lantern-header-h: 52px;
  /* Ticker strip (fixed px in lantern-ticker.css) + app bar 52px */
  --lantern-header-h-ticker: 100px;
  /* Prompt #116 — Display (and any marquee-only shell): ticker strip alone, no app-bar row */
  --lantern-header-h-marquee: 48px;
  --lantern-space-below-header: 24px;
  --lantern-space-xs: 8px;
  --lantern-space-sm: 12px;
  --lantern-space-md: 16px;
  --lantern-space-lg: 24px;
  --lantern-space-xl: 32px;
  --lantern-space-2xl: 40px;
  /* Single page shell: Lantern / Locker / Create / Play (and other student pages) */
  --lantern-page-max-width: 980px;
  --lantern-pad-x: 12px;
  --lantern-pad-bottom: 48px;
  /* Canonical horizontal rail — single source; consumed by lantern-cards.css `.wrap.lanternContent .lanternScroller` (Phase 1 rail unification) */
  /* WebKit horizontal scrollbar thickness (thumb + track); larger = easier grab for children. */
  --lantern-rail-scrollbar-size: 24px;
  --lantern-rail-gap: var(--lantern-space-lg);
  --lantern-rail-pad-y-start: var(--lantern-space-sm);
  --lantern-rail-pad-y-end: var(--lantern-space-md);
  --lantern-rail-pad-x: var(--lantern-pad-x);
  /* Contract v2 rail cards: fixed width + 16:9 aspect (height derived in lantern-cards.css). */
  --lantern-card-width: 280px;
  --lantern-card-aspect-ratio: 16 / 9;
  --lantern-rail-card-outer-width: var(--lantern-card-width);

  /*
   * Prompt #156 — canonical ordinary Lantern page background.
   * Source of truth: Play (`games.html`) / Teacher / store-panel radial stack
   * (Locker already resolves to this stack via lantern-store-panel.css load order).
   * Do not invent alternate navy/black fills on ordinary shells; reuse these tokens.
   * Exceptions: Display/Hallway TV page-local bg, game canvases, locker cosmetic skins.
   */
  --lantern-page-bg-color: #05070b;
  --lantern-page-bg:
    radial-gradient(1200px 600px at 50% 0%, #0b244f 0%, rgba(11, 36, 79, 0) 55%),
    radial-gradient(900px 500px at 20% 30%, rgba(46, 105, 214, 0.18) 0%, rgba(46, 105, 214, 0) 60%),
    linear-gradient(180deg, #070b12, #05070b);
  /* Prompt #174 — opaque sticky chrome (ticker + app bar). Matches lantern-nav NAV.navy / ticker. */
  --lantern-chrome-bg: #0f2744;
}

/* Canonical page shell fill — full viewport; pages may override only for intentional exceptions. */
html {
  background-color: var(--lantern-page-bg-color);
}
body {
  background: var(--lantern-page-bg);
  background-color: var(--lantern-page-bg-color);
  background-attachment: fixed;
  background-repeat: no-repeat;
  background-position: center;
}

#lanternHeader {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  /* Prompt #174 — fully opaque chrome so scrolling content cannot bleed through. */
  background-color: var(--lantern-chrome-bg);
  background: var(--lantern-chrome-bg);
}

#lanternHeader > #lanternTicker {
  flex-shrink: 0;
  width: 100%;
}

/* App bar slot: same vertical footprint on every page; do not let flex or media stretch this row */
#lanternHeader > #lanternAppBarRoot {
  flex-shrink: 0;
  min-height: 0;
  width: 100%;
  background-color: var(--lantern-chrome-bg);
  background: var(--lantern-chrome-bg);
}

/* Header avatar: keep nav row height stable (matches .lanternAppBarAvatarWrap in lantern-nav.js) */
#lanternAppBarRoot .lanternAppBarAvatarWrap {
  flex-shrink: 0;
  align-self: center;
  overflow: hidden;
}
#lanternAppBarRoot .lanternAppBarAvatarWrap img {
  display: block;
  max-width: 36px;
  max-height: 36px;
  width: 32px;
  height: 32px;
  object-fit: cover;
}

/* Main scrollable column: starts below fixed header + breathing room */
.lanternContent {
  box-sizing: border-box;
  padding-top: calc(var(--lantern-header-h) + var(--lantern-space-below-header));
}
body.page-has-ticker .lanternContent {
  padding-top: calc(var(--lantern-header-h-ticker) + var(--lantern-space-below-header));
}

/*
 * Prompt #116 — marquee-only shell (Display): keep #lanternTicker, omit app bar controls.
 * Hide #lanternAppBarRoot with zero footprint so no blank second-row gap remains.
 */
body.page-marquee-only #lanternHeader > #lanternAppBarRoot {
  display: none !important;
  height: 0 !important;
  min-height: 0 !important;
  max-height: 0 !important;
  overflow: hidden !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  pointer-events: none !important;
}
body.page-marquee-only.page-has-ticker .lanternContent,
body.page-marquee-only .lanternContent {
  padding-top: calc(var(--lantern-header-h-marquee) + var(--lantern-space-below-header));
}
body.page-marquee-only.page-has-ticker .lanternOverlayBelowNav {
  padding-top: calc(var(--lantern-header-h-marquee) + var(--lantern-space-below-header));
}

/* Global app shell — single centered column for all major pages (Explore, Locker, Create,
   Games, Teacher, Verify, …). Page background and #lanternHeader may be full viewport;
   main content lives only inside .wrap.lanternContent. Do not duplicate max-width/padding
   on .wrap in page CSS; link this stylesheet and add class "lanternContent" to the outer wrap. */
.wrap.lanternContent {
  box-sizing: border-box;
  max-width: var(--lantern-page-max-width);
  margin-left: auto;
  margin-right: auto;
  min-width: 0;
  padding-left: var(--lantern-pad-x);
  padding-right: var(--lantern-pad-x);
  padding-bottom: var(--lantern-pad-bottom);
}

/* Display (and any page using .mainStage without .wrap): same column width/gutters as other app pages */
.mainStage.lanternContent {
  max-width: var(--lantern-page-max-width);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--lantern-pad-x);
  padding-right: var(--lantern-pad-x);
  padding-bottom: var(--lantern-pad-bottom);
}

/* First block below fixed chrome: no stray top margin on the main column’s first child */
.wrap.lanternContent > :first-child {
  margin-top: 0;
}

/*
 * Full-screen overlays with z-index below #lanternHeader (10000): pad top so
 * content clears the app bar. Add this class next to the overlay’s own class.
 */
.lanternOverlayBelowNav {
  box-sizing: border-box;
  padding-left: var(--lantern-pad-x);
  padding-right: var(--lantern-pad-x);
  padding-bottom: var(--lantern-space-lg);
  padding-top: calc(var(--lantern-header-h) + var(--lantern-space-below-header));
}
body.page-has-ticker .lanternOverlayBelowNav {
  padding-top: calc(var(--lantern-header-h-ticker) + var(--lantern-space-below-header));
}

/* Nugget balance “reward hit” — scale + glow on increase (JS toggles .nuggetHit) */
.nuggetHit {
  display: inline-block;
  animation: nuggetPop 400ms ease-out;
}

@keyframes nuggetPop {
  0% {
    transform: scale(1);
    filter: brightness(1);
  }
  40% {
    transform: scale(1.3);
    filter: brightness(1.8);
  }
  100% {
    transform: scale(1);
    filter: brightness(1);
  }
}

/* Explore feed: new post / news card arrival (JS toggles .postArrival on first paint after hydration) */
.postArrival {
  animation: postIn 420ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes postIn {
  0% {
    transform: translateY(12px) scale(0.92);
    opacity: 0;
    box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  }

  60% {
    transform: translateY(-2px) scale(1.04);
    opacity: 1;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
  }

  100% {
    transform: translateY(0) scale(1);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  }
}
