/* ===========================================================================
   startup.css — AP Chemistry Toolkit startup screen
   ---------------------------------------------------------------------------
   The 12-second lab scene that covers the page while the main script parses.
   Rendered by startup-worker.js on an OffscreenCanvas; this file is the DOM
   layer: the canvas host, the static fallback title, subtitle, skip hint and
   progress line. Colour tokens fall back to the site's own values.
   =========================================================================== */

#splash{
  --sp-black:#0B0A09; --sp-gold:var(--gold,#CDA349); --sp-gold-light:var(--gold-light,#E8C872);
  --sp-gold-dark:var(--gold-dark,#A8832A); --sp-muted:#D9D0C0;   /* fixed: the site's light theme would make it dark on the black scene */
  --sp-T:12s;
  --sp-ease:cubic-bezier(.25,1,.5,1);
  position:fixed; inset:0; z-index:10000; background:var(--sp-black); overflow:hidden; isolation:isolate;
  display:block; color-scheme:dark;
  transition:opacity 1.1s var(--sp-ease), transform 1.1s var(--sp-ease);
}
#splash.leaving{ opacity:0; transform:scale(1.02); pointer-events:none; }
#splash.gone{ display:none; }

#splash .sp-gl{ position:absolute; inset:0; width:100%; height:100%; display:block; opacity:0; z-index:1;
  transition:opacity .9s var(--sp-ease); }
#splash.gl-ready .sp-gl{ opacity:1; }
#splash.is-fallback .sp-gl{ display:none; }

#splash .sp-fallback{ position:absolute; inset:0; display:block;
  background:radial-gradient(70% 55% at 50% 110%, rgba(205,163,73,.18), transparent 60%),
             radial-gradient(80% 50% at 50% -10%, rgba(123,31,46,.4), transparent 70%); }
#splash .sp-fallback canvas{ position:absolute; left:0; top:0; width:100%; height:100%; transition:opacity .6s var(--sp-ease); }
/* While the scene is still loading, show only the dark stage: no still title and no running
   progress bar. Showing them first made the intro look as if it started, then restarted when the
   scene took over. The still title appears only if the page falls back to it (never under the
   scene, where it would show through while the scene fades in). */
#splash:not(.is-fallback) .sp-fallback canvas{ opacity:0; }
#splash:not(.gl-ready):not(.is-fallback) .sp-prog i{ animation-play-state:paused; }

#splash .sp-subtitle{ position:absolute; left:0; right:0; top:35vh; text-align:center; z-index:2; padding:0 16px;
  font:500 clamp(.78rem,1.6vw,1rem)/1.4 'Inter', ui-sans-serif, system-ui, sans-serif;
  letter-spacing:.24em; text-transform:uppercase; color:var(--sp-muted);
  opacity:0; transform:translate3d(0,8px,0); text-shadow:0 0 18px rgba(0,0,0,.8);
  animation:sp-sub-in 1.4s var(--sp-ease) 9.3s both; }
@keyframes sp-sub-in{ to{ opacity:1; transform:none; } }
/* A scene that sends beats (startup-lattice-worker.js) says when the subtitle arrives: just after
   the light sweep. It resolves from wide, soft tracking into place. */
#splash.sp-beats .sp-subtitle{ animation:none; opacity:0; }
#splash.sp-beats.sp-sub .sp-subtitle{ animation:sp-sub-reveal 1.5s var(--sp-ease) both; }
@keyframes sp-sub-reveal{
  from{ opacity:0; letter-spacing:.62em; filter:blur(6px); transform:none; }
  to{ opacity:1; letter-spacing:.24em; filter:blur(0); transform:none; }
}

/* Header handoff (startup.js): a DOM copy of the finished title flies into the page's wordmark.
   These live outside #splash, above it, while the scene dissolves underneath. */
.sp-ghost{ position:fixed; left:0; top:0; z-index:10001; pointer-events:none; transform-origin:50% 50%; will-change:transform, opacity; }
.sp-ghost-sub{ position:fixed; z-index:10001; margin:0; pointer-events:none; transform-origin:50% 50%; white-space:nowrap; will-change:transform, opacity; }
@media (max-width:640px){ #splash .sp-subtitle{ top:30vh; } }

#splash .sp-hint{ position:absolute; z-index:2; left:clamp(16px,3vw,28px); bottom:calc(16px + env(safe-area-inset-bottom,0px));
  font:500 .74rem/1.4 'Inter', ui-sans-serif, system-ui, sans-serif; letter-spacing:.14em; text-transform:uppercase;
  color:var(--sp-muted); opacity:0; animation:sp-hint-in 1s linear 3.5s both; text-shadow:0 0 12px rgba(0,0,0,.9); }
@keyframes sp-hint-in{ to{ opacity:.9; } }
#splash .sp-hint kbd{ font:inherit; border:1px solid rgba(255,255,255,.22); border-radius:4px; padding:1px 6px; margin:0 2px; }

#splash .sp-dbg{ position:absolute; z-index:3; right:clamp(16px,3vw,28px); bottom:calc(16px + env(safe-area-inset-bottom,0px));
  font:500 .68rem/1.4 ui-monospace, Menlo, Consolas, monospace; color:var(--sp-muted); opacity:.7; text-shadow:0 0 10px #000; display:none; }
#splash.sp-debug .sp-dbg{ display:block; }

#splash .sp-prog{ position:absolute; left:0; right:0; bottom:0; height:3px; background:rgba(255,255,255,.07); z-index:2; }
#splash .sp-prog i{ position:absolute; left:0; top:0; bottom:0; width:100%; transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg, var(--sp-gold-dark), var(--sp-gold-light)); animation:sp-fill var(--sp-T) linear both; }
@keyframes sp-fill{ to{ transform:scaleX(1); } }
/* when the site is still loading past the run, the bar pulses instead of sitting full */
#splash.waiting .sp-prog i{ animation:sp-fill var(--sp-T) linear both, sp-pulse 1.4s ease-in-out infinite; }
@keyframes sp-pulse{ 50%{ opacity:.45; } }

@media (max-width:620px){
  #splash .sp-hint span.k{ display:none; }
  #splash .sp-hint{ left:auto; right:14px; bottom:auto; top:calc(14px + env(safe-area-inset-top,0px)); }
  #splash.sp-debug .sp-dbg{ left:14px; right:auto; }
}

@media (prefers-reduced-motion: reduce){
  #splash .sp-subtitle{ animation:sp-sub-in .4s linear .2s both; }
  #splash .sp-hint{ animation:none; opacity:.75; }
  #splash .sp-prog i{ animation:sp-fill 1.2s linear both; }
  #splash{ transition:opacity .35s linear; }
  #splash.leaving{ transform:none; }
}

/* ---- "Tap to begin" (startup.js): with sound on, the intro waits for one tap so it can play
   with sound; the scene loads underneath meanwhile ---- */
#splash.sp-gated .sp-hint, #splash.sp-gated .sp-prog{ visibility:hidden; }
#splash .sp-gate{ position:absolute; inset:0; z-index:4; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:22px;
  padding:0 16px; animation:sp-gate-in .9s var(--sp-ease) both; }
#splash .sp-gate.is-leaving{ animation:sp-gate-out .45s ease-in both; pointer-events:none; }
@keyframes sp-gate-in{ from{ opacity:0; transform:translate3d(0,10px,0); } to{ opacity:1; transform:none; } }
@keyframes sp-gate-out{ to{ opacity:0; transform:scale(.97); } }
#splash .sp-gate-btn{ display:flex; flex-direction:column; align-items:center; gap:18px; padding:12px 20px; border:0; background:transparent; color:var(--sp-gold-light);
  cursor:pointer; -webkit-tap-highlight-color:transparent; }
#splash .sp-gate-ring{ position:relative; display:grid; place-items:center; width:84px; height:84px; border-radius:50%;
  border:1px solid rgba(242,191,94,.55); background:radial-gradient(circle at 50% 40%, rgba(242,191,94,.16), rgba(242,191,94,.02) 70%);
  box-shadow:0 0 40px rgba(242,191,94,.12); transition:transform .3s var(--sp-ease), border-color .3s, box-shadow .3s; }
#splash .sp-gate-ring::after{ content:''; position:absolute; inset:-9px; border-radius:50%; border:1px solid rgba(242,191,94,.25); animation:sp-gate-breathe 2.6s ease-in-out infinite; }
@keyframes sp-gate-breathe{ 0%,100%{ transform:scale(.94); opacity:.2; } 50%{ transform:scale(1.06); opacity:.8; } }
#splash .sp-gate-ring svg{ width:30px; height:30px; margin-left:4px; fill:var(--sp-gold-light); }
#splash .sp-gate-btn:hover .sp-gate-ring, #splash .sp-gate-btn:focus-visible .sp-gate-ring{ transform:scale(1.05); border-color:rgba(255,224,154,.9); box-shadow:0 0 60px rgba(242,191,94,.25); }
#splash .sp-gate-btn:focus-visible{ outline:none; }
#splash .sp-gate-label{ font:500 .82rem/1 'Inter', ui-sans-serif, system-ui, sans-serif; letter-spacing:.32em; text-transform:uppercase; padding-left:.32em; }
#splash .sp-gate-sub{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:10px; margin:0;
  font:500 .72rem/1.4 'Inter', ui-sans-serif, system-ui, sans-serif; letter-spacing:.14em; text-transform:uppercase; color:var(--sp-muted); opacity:.75; }
#splash .sp-gate-mute{ min-height:32px; padding:4px 10px; border:1px solid rgba(255,255,255,.18); border-radius:999px; background:transparent; color:inherit;
  font:inherit; letter-spacing:inherit; text-transform:inherit; cursor:pointer; }
#splash .sp-gate-mute:hover, #splash .sp-gate-mute:focus-visible{ border-color:rgba(242,191,94,.6); color:var(--sp-gold-light); outline:none; }
@media (hover:none){ #splash .sp-gate-k{ display:none; } }
@media (prefers-reduced-motion: reduce){ #splash .sp-gate, #splash .sp-gate.is-leaving{ animation:none; } #splash .sp-gate-ring::after{ animation:none; } }
