/* ──────────────────────────────────────────────────────────────────────────
   Boot sequence — the same animation /play plays on first paint, ported to
   the marketing surface. Timings, easings and keyframe shapes are identical
   to the ones in public/index.html (documented in CLAUDE.md §12.3); only the
   palette is retokenized, because this surface is on Nocturne and the
   adherence rule forbids hard-coded hex. The splash ground maps onto
   --color-section* — the deep-indigo field the system sanctions for exactly
   this kind of full-bleed presence — so the boot stays in the same colour
   family as the app's.

   Pairs with /boot.js, which gates it to once per browsing session.
   ────────────────────────────────────────────────────────────────────── */

#splashScreen {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: grid;
    place-items: center;
    overflow: hidden;
    background: radial-gradient(125% 62% at 50% -4%,
        var(--color-section-ghost) 0%,
        var(--color-section-glow) 28%,
        var(--color-section) 58%,
        var(--color-bg) 100%);
    animation: fadeOut 0.5s ease-in 1.5s forwards;
}

/* Bloom that swells behind the mark */
#splashScreen::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 480px;
    height: 480px;
    margin: -240px 0 0 -240px;
    border-radius: 50%;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--color-accent) 45%, transparent),
        color-mix(in srgb, var(--color-accent) 10%, transparent) 46%,
        transparent 68%);
    opacity: 0;
    animation: splashBloom 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.1s forwards;
    pointer-events: none;
}

.splash-stage {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 30px;
    animation: splashLift 0.55s cubic-bezier(0.5, 0, 0.9, 0.3) 1.48s forwards;
}

.splash-logo {
    position: relative;
    width: 172px;
    height: 172px;
}

.splash-logo img {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    animation: splashLogoIn 0.95s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
}

.splash-ring {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 152px;
    height: 152px;
    margin: -76px 0 0 -76px;
    border-radius: 50%;
    box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--color-accent-300) 55%, transparent),
                0 0 26px color-mix(in srgb, var(--color-accent) 30%, transparent);
    opacity: 0;
    animation: splashRing 1.25s cubic-bezier(0.16, 1, 0.3, 1) 0.5s both;
    pointer-events: none;
}
.splash-ring.two { animation-delay: 0.78s; }

/* Light streak, clipped to the logo's own silhouette */
.splash-shine {
    position: absolute;
    inset: 0;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    background: linear-gradient(100deg, transparent 40%,
        color-mix(in srgb, var(--color-neutral-100) 80%, transparent) 49%,
        color-mix(in srgb, var(--color-neutral-100) 95%, transparent) 51%,
        transparent 60%);
    background-size: 260% 100%;
    background-repeat: no-repeat;
    -webkit-mask: url('/icons/icon-512.png') center / contain no-repeat;
    mask: url('/icons/icon-512.png') center / contain no-repeat;
    mix-blend-mode: screen;
    animation: splashShine 0.72s ease-in-out 0.66s both;
}

/* No mask support → skip the streak rather than paint a white bar */
@supports not ((-webkit-mask: url('/icons/icon-512.png') center / contain no-repeat) or (mask: url('/icons/icon-512.png') center / contain no-repeat)) {
    .splash-shine { display: none; }
}

.splash-loader {
    width: 104px;
    height: 2px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--color-text) 14%, transparent);
    overflow: hidden;
    opacity: 0;
    animation: splashFadeIn 0.4s ease-out 0.45s forwards;
}

.splash-loader::after {
    content: '';
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--color-accent-600), var(--color-accent-300));
    transform-origin: left center;
    animation: splashLoad 1.0s cubic-bezier(0.3, 0.8, 0.4, 1) 0.5s both;
}

@keyframes splashBloom {
    from { opacity: 0; transform: scale(0.5); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes splashLogoIn {
    0%   { opacity: 0; transform: scale(0.66) rotate(-11deg); filter: blur(9px) drop-shadow(0 0 0 rgba(0, 0, 0, 0)); }
    55%  { opacity: 1; transform: scale(1.09) rotate(3.5deg); filter: blur(0) drop-shadow(0 14px 36px rgba(0, 0, 0, 0.45)); }
    76%  { transform: scale(0.975) rotate(-1.2deg); }
    100% { opacity: 1; transform: scale(1) rotate(0deg); filter: blur(0) drop-shadow(0 14px 36px rgba(0, 0, 0, 0.45)); }
}

@keyframes splashRing {
    0%   { opacity: 0; transform: scale(0.55); }
    22%  { opacity: 0.8; }
    100% { opacity: 0; transform: scale(2.15); }
}

@keyframes splashShine {
    0%   { opacity: 0; background-position: -70% 0; }
    18%  { opacity: 1; }
    82%  { opacity: 1; }
    100% { opacity: 0; background-position: 170% 0; }
}

@keyframes splashLoad {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

@keyframes splashFadeIn {
    to { opacity: 1; }
}

@keyframes splashLift {
    from { opacity: 1; transform: scale(1); }
    to   { opacity: 0; transform: scale(1.16); }
}

@keyframes fadeOut {
    from { opacity: 1; }
    to   { opacity: 0; visibility: hidden; }
}

/* ── Staggered reveal ──────────────────────────────────────────────────────
   /play's entryRise, applied to the marketing hero. The content rises in
   behind the lifting splash, which is why the delays start at 1.42s rather
   than 0. body.boot is dropped once the sequence has played, so a later
   in-page re-render never replays it.
   ────────────────────────────────────────────────────────────────────── */

body.boot .topbar,
body.boot .article-hero > div > *,
body.boot .article-hero > .phone-preview {
    animation: entryRise 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}

body.boot .topbar                             { animation-delay: 1.42s; }
body.boot .article-hero > div > *:nth-child(1) { animation-delay: 1.49s; }
body.boot .article-hero > div > *:nth-child(2) { animation-delay: 1.56s; }
body.boot .article-hero > div > *:nth-child(3) { animation-delay: 1.62s; }
body.boot .article-hero > div > *:nth-child(4) { animation-delay: 1.68s; }
body.boot .article-hero > div > *:nth-child(n+5) { animation-delay: 1.74s; }
body.boot .article-hero > .phone-preview       { animation-delay: 1.62s; }

@keyframes entryRise {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Zero the delays as well as the durations — without that the staggered
   content would sit invisible for 1.4s before snapping in. */
@media (prefers-reduced-motion: reduce) {
    #splashScreen, #splashScreen::before,
    .splash-stage, .splash-logo img, .splash-ring,
    .splash-shine, .splash-loader, .splash-loader::after,
    body.boot .topbar,
    body.boot .article-hero > div > *,
    body.boot .article-hero > .phone-preview {
        animation-duration: 0.01ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
    }
}
