/* static/shared/splash.css — the splash treatment both pages share (#893).
 *
 * One set of rules for the instructor sign-in splash (templates/index.html
 * #modal-username) and the loading splash (templates/_loading_splash.html,
 * included by templates/index.html and templates/student.html). Each page
 * loads this sheet AFTER its own stylesheet, so .splash-overlay outranks
 * .modal-overlay's backdrop at equal specificity.
 *
 * The sign-in splash takes --splash-inner / --splash-outer from the
 * instructor stylesheet's dark palette (static/style.css): static/boot.js
 * applies the dark theme before showing it, in every theme. The loading
 * splash is dark in every theme too — it draws the dark wordmark — so it sets
 * the pair itself, which also gives the student page (whose stylesheet has no
 * splash tokens) its colours.
 */

.splash-overlay {
  background: radial-gradient(ellipse at center, var(--splash-inner) 0%, var(--splash-outer) 100%);
  backdrop-filter: none;
  overflow: hidden;
}

.splash-bg {
  position: absolute;
  inset: 0;
  background-image: url("/static/img/splash-bg.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  filter: invert(1);
  pointer-events: none;
}

/* ─── Loading splash ─────────────────────────────────────────────────
   Drawn from first paint; dismissLoadingSplash (static/shared/a11y.js)
   takes `splash-up` off <html>, adds .is-leaving, then removes it. */
.loading-splash {
  --splash-inner: #1a1d24;
  --splash-outer: #0b0d12;
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  transition: opacity 0.25s ease;
}
.loading-splash.is-leaving { opacity: 0; pointer-events: none; }

/* While <html> carries `splash-up` (set in the served HTML, so from first
   paint), the rest of the page is out of sight, out of the Tab order and out
   of the accessibility tree. Live regions stay, so a message said during boot
   is still heard. Dismissal takes the class off at once, so a dialog opened
   at that moment can take focus. An open native <dialog> stays too: it is
   drawn in the top layer, above the splash, and takes focus as it opens
   (the problem-report dialog, reachable from the role="alert" banner while
   a fast boot's splash is held, #923). */
.splash-up body > :not(.loading-splash):not([role="status"]):not([role="alert"]):not([aria-live]):not(dialog[open]) {
  visibility: hidden;
}

.loading-splash-wordmark { position: relative; width: min(420px, 80vw); height: auto; }
.loading-splash p {
  position: relative;
  margin: 0;
  color: #9aa0a6;
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
}

/* The checkmark is revealed left to right, holds, then starts again. Its
   resting width (the markup's) shows the whole checkmark, which is what a
   reader who asked for reduced motion sees. The reveal is whole at 45%
   (0.81 s); LOADING_SPLASH_MINIMUM_MS (static/shared/a11y.js, #923) keeps a
   fast boot's splash up past it. */
.loading-splash-reveal { animation: loading-splash-reveal 1.8s cubic-bezier(0.4, 0, 0.2, 1) infinite; }
@keyframes loading-splash-reveal {
  0%        { width: 0; }
  45%, 100% { width: 60px; }
}

@media (prefers-reduced-motion: reduce) {
  .loading-splash-reveal { animation: none; }
  .loading-splash { transition: none; }
}
