/* ===========================================================================
 * THE BOOT VEIL — the loading screen that covers the SHELL coming up.
 * ===========================================================================
 *
 * Reported: *"the initial load screen theres a few seconds where menu is not
 * interactive bc i guess stuff is loading?... in that case we should have a
 * loading screen... not an uninteractive menu"*.
 *
 * ITS OWN SHEET, not a block in style.css, for the reason final-killcam.css,
 * gate.css, cheats.css and voice-hud.css each give at the top of index.html:
 * style.css is a 4,600-line file several sessions write at once, and two agents
 * appending to it is how a rule lands inside somebody else's media query.
 *
 * WHY THE DEFAULT STATE IS *UP*, AND WHY THE ATTRIBUTE IS IN THE MARKUP.
 * `data-boot-veil="up"` is written on <html> in index.html, exactly the way
 * `data-shell="booting"` is, so it is true from the FIRST PAINT rather than from
 * whenever a module got round to saying so. AGENTS.md records a prewarm that would
 * have run in front of a CLEAR veil because the element rested at `opacity: 0` in
 * the stylesheet and the first write arrived one rAF later. A veil that is up only
 * once JavaScript says so is not up during the part of the boot that JavaScript is.
 *
 * WHY IT IS NOT `#loading`. `startGame()` owns that element — it resets the bar and
 * `data-phase` on entry and `hideLoading()` is the single exit every path takes. Two
 * owners of one veil is two sources of truth about whether the screen is covered.
 *
 * LAYERING, AS A RELATIONSHIP. Above the loading overlay and the toast, because it
 * covers the whole shell; BELOW `#gate`, because the access code has to be typeable
 * and the gate is its own door with its own reason for being on top. Written as a
 * derivation, never as a literal — AGENTS.md: that is precisely how `--z-fx` came to
 * equal `--z-modal`.
 */
#boot-veil {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-toast) + 1);
  display: grid;
  align-content: end;
  /* A FLAT COLOUR, NOT A GRADIENT, AND THAT IS NOT A STYLE PREFERENCE.
   *
   * `js/overlay-flash-limiter.js` is the photosensitivity guard for DOM overlays. It
   * discovers viewport-covering elements rather than being told about them — which is
   * the right design and means this element is in its set — and it treats any candidate
   * carrying a `background-image` as **luminance 1**, deliberately, because a gradient
   * is not parseable. So the first version of this rule, which copied `#loading`'s faint
   * gold radial, registered as a full-brightness flash and was ramped in at the guard's
   * per-frame step limit. Measured from inside the page: the veil sat between 0.53 and
   * 0.94 opacity for its first two seconds with the menu showing through it, and only
   * reached 1 at t = 2209 ms — about 250 ms before it lifted.
   *
   * It still ate every press throughout (the guard scales alpha, not `pointer-events`),
   * so the defect was cosmetic — but a translucent loading screen with a dead menu
   * legible behind it is very close to a picture of the bug this whole round is about.
   *
   * `--s0` is the page floor at #06080a, a relative luminance of about 0.002, so the
   * guard's own arithmetic leaves it alone. The right fix is a veil that is not a flash,
   * not an exemption in the guard. */
  background: var(--s0, #06080a);
  padding: clamp(24px, 6vh, 64px) clamp(22px, 6vw, 90px);
  /* The lift. `visibility` as well as `opacity`, so a veil at zero opacity cannot
   * still be eating the first click of the session — an invisible sheet over the menu
   * would be the reported defect wearing a different coat. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 240ms linear, visibility 0s linear 240ms;
}

html[data-boot-veil="up"] #boot-veil {
  opacity: 1;
  visibility: visible;
  /* IT MUST EAT INPUT WHILE IT IS UP. That is the whole difference between a veil and
   * a tint: a press that lands on the menu behind it is exactly the press this exists
   * to stop, and it would arrive at a control that is not yet wired. */
  pointer-events: auto;
  /* NO TRANSITION INTO "up". The fade belongs on the way OUT and nowhere else: this
   * state is the one the document is BORN in, and a transition on it is an invitation
   * for the veil to be half-there during the exact window it exists to cover. */
  transition: none;
}

/* The device gate replaces the page wholesale on a phone; a veil over its message is
 * a blank screen with an explanation behind it. Same list `style.css` already blanks. */
html.device-blocked #boot-veil { display: none !important; }

.boot-veil-inner { width: min(760px, 100%); text-align: left; }

.boot-veil-top {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; margin-bottom: 14px;
}

#boot-veil h2 {
  margin: 0;
  font-family: var(--display, sans-serif);
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink, #eef1f3);
}
#boot-veil h2 em { font-style: normal; color: var(--gold, #e0a437); }

/* AN INDETERMINATE SWEEP, NOT A PERCENTAGE.
 *
 * `#load-bar` moves only on real completion and says so in its own comment. This veil
 * has no completion fraction to report — it is waiting on a shell wiring itself, a
 * control painting and a map building, and inventing a percentage over those would be
 * the one thing the loading screen next door deliberately refuses to do. A sweep says
 * "working" and claims nothing.
 *
 * It animates `transform` only, so it runs on the compositor and keeps moving THROUGH
 * the synchronous blocks this veil exists to cover. A bar animated on `width` would
 * freeze during exactly the 750 ms it is there to explain. */
.boot-veil-track { height: 2px; background: var(--rule, rgba(238,241,243,0.085)); overflow: hidden; }
.boot-veil-track i {
  display: block; height: 100%; width: 34%;
  background: var(--gold, #e0a437);
  transform: translateX(-100%);
  animation: bootVeilSweep 1350ms cubic-bezier(0.65, 0, 0.35, 1) infinite;
  will-change: transform;
}
@keyframes bootVeilSweep {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(400%); }
}

#boot-veil-note {
  margin: 18px 0 0;
  font-family: var(--ui, sans-serif);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3, #78838a);
  min-height: 1em;
}

@media (prefers-reduced-motion: reduce) {
  .boot-veil-track i { animation: none; transform: none; width: 100%; opacity: 0.5; }
  #boot-veil { transition: none; }
}
