/* ng-boot.css — AURORA-X cinematic cold-start (2026-09-06)
 *
 * Additive only. Everything here is scoped behind html.nb-run, which ng-boot.js
 * adds for ~1.6s and then removes. If the JS never runs (kill switch, throw,
 * reduced motion) not one rule in this file applies and the page is untouched.
 *
 * Colours come from the live custom properties so a skin (:root[data-skin=...])
 * repaints the whole sequence for free. No hex literals below.
 */

:root{
  --nb-accent: var(--accent, var(--x-cyan));
  /* Secondary stop. --skin-brain first: every skin defines it alongside
     --accent, so a skinned boot stays inside that skin's palette instead of
     mixing the base sheet's blue into, say, the red Ares ramp. Unskinned it
     falls through to the AURORA-X cyan -> blue gradient. */
  --nb-accent2: var(--skin-brain, var(--x-blue, var(--accent, var(--x-cyan))));
  --nb-ground: var(--s0, var(--bg));
  --nb-ease: var(--ease, cubic-bezier(.2,0,0,1));
}

/* ---- the legacy #boot panel becomes a plain black ground -------------- */
/* We do not restructure its markup; we simply mute its children so the new
   hairline can own the frame. If our JS dies mid-flight the class comes off
   and the original boot mark is visible again. */
html.nb-run #boot{
  background: var(--nb-ground);
  gap: 0;
}
html.nb-run #boot .boot-mark,
html.nb-run #boot .boot-lines{
  opacity: 0 !important;
  animation: none !important;
  visibility: hidden;
}

/* ---- staged shell elements ------------------------------------------- */
/* ng-boot.js tags each element it is about to animate. The animation itself
   is a Web Animation with fill:both, so this rule only covers the gap between
   "class added" and "animation started". */
html.nb-run .nb-stage{ opacity: 0 }

/* ---- our own black ground -------------------------------------------- */
/* The legacy #boot panel is on a fuse lit at parse time; ng-boot.js retires it
   and paints this instead, so stage 1 opens on black no matter how slow the
   load was. z-index 100 matches what #boot used. */
#nb-ground{
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  background: var(--nb-ground);
}

/* ---- the frame layer: hairline + shell strokes ------------------------ */
/* z-index 101 sits one above #boot (100) so the hairline reads on black,
   then survives the boot fade and hands off to the shell strokes. */
#nb-frame{
  position: fixed;
  inset: 0;
  z-index: 101;
  pointer-events: none;
}
#nb-frame > i{
  position: absolute;
  display: block;
  opacity: 0;
}

/* the first hairline: centred, drawn out from nothing */
#nb-frame .nb-hair{
  left: 12vw; right: 12vw;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: linear-gradient(90deg,
    transparent,
    var(--nb-accent) 22%,
    var(--nb-accent2) 50%,
    var(--nb-accent) 78%,
    transparent);
  box-shadow: 0 0 18px 1px color-mix(in srgb, var(--nb-accent) 55%, transparent);
  transform: scaleX(0);
}

/* top status-bar stroke — drawn from the centre outward */
#nb-frame .nb-top{
  left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--nb-accent) 70%, transparent) 18%,
    var(--nb-accent) 50%,
    color-mix(in srgb, var(--nb-accent) 70%, transparent) 82%,
    transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--nb-accent) 45%, transparent);
  transform: scaleX(0);
}

/* left rail stroke — drawn downward */
#nb-frame .nb-left{
  width: 1px;
  background: linear-gradient(180deg,
    var(--nb-accent),
    color-mix(in srgb, var(--nb-accent) 45%, transparent) 60%,
    transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--nb-accent) 40%, transparent);
  transform: scaleY(0);
  transform-origin: 50% 0%;
}
   /* ---- impact flash per panel ----------------------------------------- */
   .nb-impact{ will-change:opacity,transform }
   /* ---- horizontal light sweep finale ----------------------------------- */
   #nb-sweep{
     position:fixed; top:0; left:0; width:60vw; height:100vh; z-index:98;
     pointer-events:none;
     background:linear-gradient(90deg,transparent 0%,
       rgba(var(--ng-hero-rgba),.08) 40%,
       rgba(var(--ng-hero-rgba),.20) 50%,
       rgba(var(--ng-hero-rgba),.08) 60%,
       transparent 100%);
     will-change:transform,opacity;
   }
   /* ---- final bloom ------------------------------------------------------ */
   #nb-bloom{
     position:fixed; inset:0; z-index:99; pointer-events:none;
     background:radial-gradient(ellipse at 50% 50%,
       rgba(var(--ng-hero-rgba),.15) 0%,
       rgba(var(--ng-hero-rgba),.05) 40%,
       transparent 70%);
   }
   @keyframes nb-pulse{ 0%{opacity:0} 40%{opacity:1} 100%{opacity:0} }

/* ---- count-up: hold the digit box still ------------------------------ */
.nb-count{ font-variant-numeric: tabular-nums }

/* ---- NON-NEGOTIABLE: no motion means no sequence --------------------- */
/* ng-boot.js already refuses to start under reduce; this is the belt to that
   braces, so even a stale class from a resurrected bfcache page is inert.
   It extends the page's own @media (prefers-reduced-motion) block, which
   already sets #boot{display:none}. */
@media (prefers-reduced-motion: reduce){
  html.nb-run .nb-stage{ opacity: 1 !important; transform: none !important }
  html.nb-run #boot{ display: none !important }
  html.nb-run #boot .boot-mark,
  html.nb-run #boot .boot-lines{ visibility: visible }
  #nb-frame, #nb-bloom, #nb-ground{ display: none !important }
}
