/* Reading.Web boot splash — the pre-WASM counterpart of the in-app LoadingOverlay.
   The Reader island is render-mode InteractiveWebAssembly with prerender OFF, so the
   server sends only the AppShell chrome and an empty island placeholder; without this
   splash the user stares at a blank (black) content area for the seconds it takes the
   WASM runtime to download + boot. This stylesheet is loaded in App.razor's <head> so
   the orb is fully styled at first paint, before any Blazor code runs.

   The class names mirror LoadingOverlay.razor (.lw-orb-*) on purpose: the same
   lwLoader.start(layer, sky) from lw-loader.js builds the orbiting word-chips here as it
   does in-app, so the boot orb and the in-app orb are visually identical and the handoff
   (boot splash → book) is seamless. Rules are scoped under .lw-boot-loader so they never
   collide with LoadingOverlay's own (component-scoped, loaded later) copy. */

.lw-boot-loader {
    position: fixed;
    inset: 0;
    /* Above the in-app LoadingOverlay (z-index 9999) so, while both exist during WASM
       boot, the fullscreen boot orb stays on top and the seam is invisible. */
    z-index: 10000;
    background:
        radial-gradient(circle at 30% 20%, rgba(var(--accent-rgb, 224, 122, 78), 0.18), transparent 55%),
        radial-gradient(circle at 70% 80%, rgba(var(--accent-rgb, 224, 122, 78), 0.12), transparent 50%),
        var(--bg, #000000);
    color: var(--text, #f4f1ec);
    font-family: var(--font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    opacity: 1;
    transition: opacity 0.25s ease-out;
}

.lw-boot-loader.is-hiding {
    opacity: 0;
    pointer-events: none;
}

/* The loader is a dark starfield with a per-theme HUE regardless of the page theme:
   remap the page tokens the rules below read (--bg / --text / --accent*) to the cosmos
   palette (tokens.css) so it stays a dark sky even under the light cool/paper themes,
   where the stars otherwise washed out. Literal fallbacks are the night values. */
.lw-boot-loader {
    --bg:             var(--loader-bg, #0b0e15);
    --text:           var(--loader-text, #e6e8f0);
    --text-secondary: var(--loader-text-dim, #9298a8);
    --accent-rgb:     var(--loader-accent-rgb, 224, 122, 78);
    --accent:         rgb(var(--loader-accent-rgb, 224, 122, 78));
    --accent-strong:  rgb(var(--loader-accent-rgb, 224, 122, 78));
}

/* Starfield — themed via the --star-* tokens, populated by lw-loader.js. The loader sky is
   dark on every theme (see the token remap above), so white/blue/gold starlight reads on all
   of them — the Reader defaults to the light "cool" theme, where it used to be starless. */
.lw-boot-loader .lw-loader__sky { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.lw-boot-loader .lw-orb-star {
    position: absolute;
    border-radius: 50%;
    background: rgb(var(--star-rgb, 255, 255, 255));
    will-change: opacity, transform;
    animation: lw-boot-twinkle ease-in-out infinite;
}
.lw-boot-loader .lw-orb-star--alt    { background: rgb(var(--star-alt-rgb, 130, 185, 250)); }
.lw-boot-loader .lw-orb-star--bright { box-shadow: 0 0 5px var(--star-glow, rgba(180, 210, 255, 0.8)); }
@keyframes lw-boot-twinkle {
    0%, 100% { opacity: calc(var(--star-peak, 1) * .3); transform: scale(.7); }
    50%      { opacity: var(--star-peak, 1);            transform: scale(1); }
}

/* Comet — streak in the theme hue (--loader-accent-rgb) with a bright leading head
   (--meteor-tip-rgb). No filter: drop-shadow — an animated filter repaints on the main
   thread every frame, which janks while Blazor WASM boots; transform+opacity only keeps
   the comet on the compositor thread, and the bright head carries the glow. */
.lw-boot-loader .lw-orb-meteor {
    position: absolute;
    width: 88px; height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg,
        rgba(var(--loader-accent-rgb, 224, 122, 78), 0) 0%,
        rgba(var(--loader-accent-rgb, 224, 122, 78), 0.55) 65%,
        rgb(var(--meteor-tip-rgb, 255, 255, 255)) 100%);
    opacity: 0;
    will-change: transform, opacity;
    animation: lw-boot-shoot linear infinite;
}
@keyframes lw-boot-shoot {
    0%   { opacity: 0; transform: rotate(150deg) translateX(-140px); }
    7%   { opacity: 0; }
    10%  { opacity: 1; }
    20%  { opacity: 1; }
    26%  { opacity: 0; transform: rotate(150deg) translateX(560px); }
    100% { opacity: 0; transform: rotate(150deg) translateX(560px); }
}

.lw-boot-loader .lw-loader__stage {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    animation: lw-boot-fade-in 0.35s ease-out;
}

/* ── Orbits ───────────────────────────────────────────────────────── */
.lw-boot-loader .lw-orb-orbits { position: relative; width: 300px; height: 300px; }
.lw-boot-loader .lw-orb-layer { position: absolute; inset: 0; }
.lw-boot-loader .lw-orb-orbit {
    position: absolute;
    top: 0; left: 0;
    border-radius: 50%;
    border: 1px solid rgba(var(--accent-rgb, 224, 122, 78), 0.38);
    will-change: opacity;
    animation: lw-boot-dim 12000ms ease-in-out 3000ms infinite backwards;
}
@keyframes lw-boot-dim {
    0%, 100% { opacity: 0.23; }
    50%      { opacity: 0.55; }
}

.lw-boot-loader .lw-orb-core {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    line-height: 1.05;
    font-family: var(--font);
    font-weight: 800;
    letter-spacing: 0.3px;
    z-index: 3;
    pointer-events: none;
}
.lw-boot-loader .lw-orb-core::before {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 120px; height: 120px;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(var(--accent-rgb, 224, 122, 78), 0.32), transparent 65%);
    z-index: -1;
    animation: lw-boot-pulse 2.4s ease-in-out infinite;
}
.lw-boot-loader .lw-orb-core .l1 { display: block; font-size: 22px; color: var(--text, #f4f1ec); }
.lw-boot-loader .lw-orb-core .l2 { display: block; font-size: 22px; color: var(--accent, #e07a4e); }
@keyframes lw-boot-pulse {
    0%, 100% { transform: translate(-50%,-50%) scale(0.92); opacity: 0.8; }
    50%      { transform: translate(-50%,-50%) scale(1.08); opacity: 1; }
}

.lw-boot-loader .lw-orb-pivot {
    position: absolute;
    top: 150px;
    left: 150px;
    width: 0;
    height: 0;
    will-change: transform;
    animation-name: lw-boot-pivot-spin;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
@keyframes lw-boot-pivot-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.lw-boot-loader .lw-orb-word {
    position: absolute;
    left: 0; top: 0;
    padding: 5px 11px;
    border-radius: 999px;
    font-family: var(--font);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.2px;
    white-space: nowrap;
    color: var(--accent-strong, #ec9069);
    background: rgba(var(--accent-rgb, 224, 122, 78), 0.12);
    border: 1px solid rgba(var(--accent-rgb, 224, 122, 78), 0.3);
    isolation: isolate;
    will-change: transform;
    z-index: 2;
    animation-name: lw-boot-chip-spin;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
@keyframes lw-boot-chip-spin {
    from { transform: translate(var(--r, 0px), 0) translate(-50%, -50%) rotate(0deg); }
    to   { transform: translate(var(--r, 0px), 0) translate(-50%, -50%) rotate(-360deg); }
}
.lw-boot-loader .lw-orb-word::before {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    background: rgba(var(--accent-rgb, 224, 122, 78), 0.22);
    border: 1px solid rgba(var(--accent-rgb, 224, 122, 78), 0.55);
    opacity: 0;
    z-index: -1;
    pointer-events: none;
    will-change: opacity;
    animation: lw-boot-glow 12000ms ease-in-out 3000ms infinite;
}
@keyframes lw-boot-glow {
    0%, 100% { opacity: 1; }
    8%, 92%  { opacity: 0; }
}

.lw-boot-loader .lw-loader__text {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: 0.4px;
    text-transform: lowercase;
    color: var(--text-secondary, #a4a09a);
    animation: lw-boot-soft 2.2s ease-in-out infinite;
}
@keyframes lw-boot-soft {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 0.85; }
}

@keyframes lw-boot-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* lwLoader stamps animation-name on the chips/pivots via the .lw-orb-* classes above; the
   keyframe names there are boot-local (lw-boot-*) but the class names match what lw-loader.js
   creates. Reduced motion: keep the identity (core + rings), drop the spin / twinkle. */
@media (prefers-reduced-motion: reduce) {
    .lw-boot-loader .lw-orb-pivot,
    .lw-boot-loader .lw-orb-word,
    .lw-boot-loader .lw-orb-orbit,
    .lw-boot-loader .lw-orb-star,
    .lw-boot-loader .lw-orb-meteor,
    .lw-boot-loader .lw-orb-core::before,
    .lw-boot-loader .lw-loader__text {
        animation: none;
    }
    .lw-boot-loader .lw-orb-word::before,
    .lw-boot-loader .lw-orb-meteor { opacity: 0; }
}

/* (Top navigation progress bar #232 removed: it was an affordance for the server
   round-trip between prerendered-island pages. The app is a client-routed WASM SPA now —
   tab switches are instant in-process route changes, so there's no gap to paper over.) */
