/* ============================================================================
   ASTROVE CANADA — OPENING: loader hand-off and flight bridge
   ----------------------------------------------------------------------------
   The loader itself is /styles/preloader.css, unchanged. These rules add only
   the Canada post-100 state: when the loader goes `is-launching` the star is
   taken over in place by the flight layer underneath (one fixed canvas,
   removed when the bridge ends), so the wordmark, the particle canvas and
   the glow layers fade and the loader's opaque ground becomes transparent.
   No flash, no scroll jump. The bridge holds scroll for ≤1.5 s.
   ========================================================================== */
/* The loader's tokens, exactly as astrove.in's /styles/tokens.css defines them
   (the Canada page does not link that file): without these the loader would
   paint its var() fallbacks (Georgia/Arial), not the deployed typography. */
:root {
  --font-display: "PP Editorial New", Georgia, serif;
  --font-ui: "PP Neue Montreal", Arial, sans-serif;
  --moon: #fff7e6;
  --void-deep: #04020a;
  --electric-ice: #2ee9ff;
}
/* The root keeps its own 520 ms exit fade (preloader.css) so transitionend
   still drives finishExit; only the ground goes transparent at once. */
.celestial-loader.is-launching { background: transparent; transition: background 10ms linear, opacity 520ms cubic-bezier(.76,0,.18,1), visibility 520ms; }
.celestial-loader.is-launching .celestial-loader__core img { opacity: 0; transition: opacity 320ms ease, filter 900ms ease, transform 1300ms cubic-bezier(.23,1,.32,1); }
.celestial-loader.is-launching .celestial-loader__canvas,
.celestial-loader.is-launching .celestial-loader__nebula,
.celestial-loader.is-launching .celestial-loader__grain,
.celestial-loader.is-launching .celestial-loader__flash { opacity: 0 !important; transition: opacity 300ms ease; }
/* The bloom's is-detonating scale transition (620 ms from +100) keeps running. */
.celestial-loader.is-launching .celestial-loader__bloom { opacity: 0 !important; transition: opacity 300ms ease, transform 620ms cubic-bezier(.76,0,.24,1); }
.celestial-loader.is-launching .celestial-loader__core::before { opacity: 0; transition: opacity 300ms ease; }
.celestial-loader.is-launching .celestial-loader__core p,
.celestial-loader.is-launching .celestial-loader__core strong,
.celestial-loader.is-launching .celestial-loader__footer { opacity: 0; }

/* The page chrome (prototype notice, mast, arrival HUD) does not pop in under
   the detaching star: it stays out while html.astrove-bridge is set and fades
   in when the bridge ends (≤1.5 s). It never hides without the bridge. */
.cv-prototype, .cv-mast, .cv-descent__hud { transition: opacity 600ms ease; }
html.astrove-bridge .cv-prototype, html.astrove-bridge .cv-mast, html.astrove-bridge .cv-descent__hud { opacity: 0; transition: none; }
/* The body is day-coloured; behind the held chrome (and while it fades back)
   the space above the arrival stays night, so no cream band shows. */
html.astrove-bridge body, html.astrove-bridge-out body { background-color: var(--cv-night, #06040f); }

/* Journey: from the arrival on, the scroll caption (label, progress, skip) leaves; the DRAFT status
   lives in the header (.cv-mast__draft). Nothing is drawn over the peaks or the products. */
.cv-descent[data-journey-arrival="true"][data-descent-mode] .cv-descent__hud { opacity: 0; visibility: hidden; transition: opacity 300ms ease, visibility 0s linear 300ms; }
.cv-mast__draft { align-self: center; font-size: 0.62rem; letter-spacing: 0.12em; padding: 0.2rem 0.45rem; border-radius: 0.3rem; background: #e2531d; color: #fff; white-space: nowrap; }
@media (max-width: 380px) { .cv-mast__draft { font-size: 0.55rem; padding: 0.15rem 0.35rem; letter-spacing: 0.06em; } }

/* Scroll is held while the star detaches (bridge only, then released). */
html.astrove-bridge, html.astrove-bridge body { overflow: hidden; }

/* The flight layer: one fixed canvas above the page (mast z 10), below the
   loader (z 10000); pointer-transparent; removed when the bridge ends. */
.cv-flight { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10001; } /* above the loader: the star never dims under the fading light ground */
@media (prefers-reduced-motion: reduce) { .cv-flight { display: none !important; } html.astrove-bridge, html.astrove-bridge body { overflow: auto; } }
/* With the DRAFT pill in the header the nav must not wrap: tighter gaps instead (preview only). */
.cv-mast:has(.cv-mast__draft) .cv-mast__nav a { white-space: nowrap; }
@media (max-width: 1240px) { .cv-mast:has(.cv-mast__draft) .cv-mast__nav { gap: 0.75rem; font-size: 0.82rem; } .cv-mast:has(.cv-mast__draft) { gap: 0.9rem; } }
/* Journey default: the hero already presents the five packs on the table, so the table section below
   keeps its heading, text and onward actions but not a second five-pack row (the fruit index chips
   and each product stage carry the same links and "Received, not final" status). */
html.cv-journey .cv-table__packs { display: none; }
/* Narrow phones: the header keeps brand, DRAFT pill, FR and Menu on one line. */
@media (max-width: 400px) { .cv-mast:has(.cv-mast__draft) .cv-mast__lang em { display: none; } .cv-mast:has(.cv-mast__draft) { gap: 0.5rem; } }
@media (max-width: 400px) { .cv-mast:has(.cv-mast__draft) .cv-mast__draft { white-space: normal; max-width: 4.4rem; line-height: 1.05; text-align: center; font-size: 0.5rem; letter-spacing: 0.04em; padding: 0.15rem 0.3rem; } .cv-mast:has(.cv-mast__draft) .cv-mast__brand { font-size: 1.1rem; letter-spacing: 0.08em; } }
@media (max-width: 340px) { .cv-mast:has(.cv-mast__draft) { gap: 0.35rem; } .cv-mast:has(.cv-mast__draft) .cv-mast__brand { font-size: 0.98rem; letter-spacing: 0.06em; } .cv-mast:has(.cv-mast__draft) .cv-mast__lang { padding: 0.3rem 0.5rem; } }

/* ============================================================================
   CANADA LIGHT-MODE LOADER (17 Oct 2026). Same structure, timing and exit as
   the deployed loader; a luminous near-white ground, the exact wordmark in
   graphite, dark legible text, and the five pack colours in the particle
   field (public/ca/js/preloader.js). Overrides are scoped to the loader.
   ========================================================================== */
.celestial-loader { --moon: #22232a; --electric-ice: #3c4a5a; --void-deep: #f8f6f2; color: #22232a; background: #f8f6f2; }
.celestial-loader__nebula {
  background:
    radial-gradient(ellipse at 20% 24%, rgba(249,196,1,.10), transparent 40%),
    radial-gradient(ellipse at 80% 28%, rgba(249,79,136,.09), transparent 36%),
    radial-gradient(ellipse at 76% 80%, rgba(197,242,1,.08), transparent 38%),
    radial-gradient(ellipse at 24% 82%, rgba(249,75,1,.08), transparent 40%),
    radial-gradient(ellipse at 50% 50%, rgba(171,43,88,.06), transparent 46%),
    #f8f6f2;
  filter: none;
}
.celestial-loader__bloom::before, .celestial-loader__bloom::after, .celestial-loader__bloom i { mix-blend-mode: multiply; }
.celestial-loader__bloom::before { background: rgba(249,196,1,.10); }
.celestial-loader__bloom::after { background: rgba(249,79,136,.08); }
.celestial-loader__bloom i:nth-child(1) { background: rgba(171,43,88,.06); }
.celestial-loader__bloom i:nth-child(2) { background: rgba(197,242,1,.08); }
.celestial-loader__grain { opacity: .06; mix-blend-mode: multiply; }
/* clear space around the mark: a soft light field, not a dark halo or a box */
/* quiet space only around the lettering: the earlier wide .94/.62 veil (118% x 260% of the core) laid a cream film over the whole centre */
.celestial-loader__core::before { width: 96%; height: 210%; background: radial-gradient(ellipse, rgba(248,246,242,.86) 0 30%, rgba(248,246,242,.42) 48%, rgba(248,246,242,0) 64%); filter: blur(.8rem); } /* covers the kicker and tagline lines too, so the small text stays legible */
/* the graphite mark stays sharp: no colour glow (transform/opacity motion unchanged) */
.celestial-loader .celestial-loader__core img,
.celestial-loader.is-charged .celestial-loader__core img,
.celestial-loader.is-igniting .celestial-loader__core img { filter: drop-shadow(0 1px 0 rgba(255,255,255,.7)); }
.celestial-loader__footer { color: rgba(34,35,42,.72); }
.celestial-loader__meter > i { background: rgba(34,35,42,.12); }
/* One controlled release (refined 17 Oct): the light ground, the particle canvas (it paints its own
   cream clear colour) and the light layers recede together on one symmetric curve over 1 s; the
   root's own exit fade (is-exiting, unchanged start) uses the same curve over 0.9 s, so the visible
   light falls off across the sparkle and the detach (~200-750 ms) instead of in the first 250 ms. */
.celestial-loader.is-launching { transition: background 1000ms cubic-bezier(.4,0,.6,1), opacity 900ms cubic-bezier(.4,0,.6,1), visibility 0s linear 900ms; }
.celestial-loader.is-launching .celestial-loader__canvas,
.celestial-loader.is-launching .celestial-loader__nebula,
.celestial-loader.is-launching .celestial-loader__grain,
.celestial-loader.is-launching .celestial-loader__core::before { transition: opacity 1000ms cubic-bezier(.4,0,.6,1); }
.celestial-loader.is-launching .celestial-loader__bloom { transition: opacity 1000ms cubic-bezier(.4,0,.6,1), transform 620ms cubic-bezier(.76,0,.24,1); }

/* ============================================================================
   CANADA OPTION 1: IGNITE FROM LIGHT INTO DARK (17 Oct 2026). Loading stays on
   the light ground; at ignition the light is pulled into the wordmark's star
   (a closing iris, --iris/--sx/--sy/--light set by preloader.js over ~300 ms)
   and deep space opens behind it, so the burst explodes the five pack colours
   as emitted light on black and flows straight into the journey. Reduced
   motion never ignites this way and keeps the light identity.
   ========================================================================== */
.celestial-loader { --void-deep: #04030c; background: #04030c; }
/* a feathered iris, not a hard circle: the light thins toward its edge as it is drawn into the star */
.celestial-loader__nebula {
  -webkit-mask-image: radial-gradient(circle var(--iris, 400vmax) at var(--sx, 50%) var(--sy, 50%), #000 0, #000 38%, transparent 100%);
  mask-image: radial-gradient(circle var(--iris, 400vmax) at var(--sx, 50%) var(--sy, 50%), #000 0, #000 38%, transparent 100%);
}
.celestial-loader.is-dark .celestial-loader__nebula { visibility: hidden; }
.celestial-loader.is-detonating .celestial-loader__nebula { filter: none; transform: none; }
.celestial-loader.is-collapsing .celestial-loader__core::before { opacity: var(--light, 1); transition: none; }
.celestial-loader.is-collapsing .celestial-loader__grain { opacity: calc(.06 * var(--light, 1)); transition: none; }
/* the exact wordmark: graphite on the light ground, white with pack-colour light once it is in space
   (same filter function list in both states, so the change interpolates instead of snapping) */
.celestial-loader .celestial-loader__core img,
.celestial-loader.is-charged .celestial-loader__core img,
.celestial-loader.is-igniting .celestial-loader__core img { filter: brightness(1) invert(0) drop-shadow(0 1px 0 rgba(255,255,255,.7)) drop-shadow(0 0 0 rgba(249,79,136,0)); }
.celestial-loader.is-collapsing .celestial-loader__core img {
  filter: brightness(0) invert(1) drop-shadow(0 0 1.6rem rgba(249,196,1,.6)) drop-shadow(0 0 4.2rem rgba(249,79,136,.5));
  transition: filter 300ms cubic-bezier(.55,0,.8,.3), transform 1300ms cubic-bezier(.23,1,.32,1), opacity 320ms ease;
}
/* in space the bloom becomes pack-coloured light above the particles */
.celestial-loader.is-dark .celestial-loader__bloom { z-index: 3; }
.celestial-loader.is-dark .celestial-loader__bloom::before,
.celestial-loader.is-dark .celestial-loader__bloom::after,
.celestial-loader.is-dark .celestial-loader__bloom i { mix-blend-mode: screen; clip-path: none; filter: blur(1.2rem); }
/* soft round glows (the star-polygon clip read as hard diamonds on black) */
.celestial-loader.is-dark .celestial-loader__bloom::before { background: radial-gradient(closest-side, rgba(249,196,1,.34), rgba(249,196,1,0)); }
.celestial-loader.is-dark .celestial-loader__bloom::after { background: radial-gradient(closest-side, rgba(249,79,136,.30), rgba(249,79,136,0)); }
.celestial-loader.is-dark .celestial-loader__bloom i:nth-child(1) { background: radial-gradient(closest-side, rgba(171,43,88,.36), rgba(171,43,88,0)); }
.celestial-loader.is-dark .celestial-loader__bloom i:nth-child(2) { background: radial-gradient(closest-side, rgba(197,242,1,.22), rgba(197,242,1,0)); }
.celestial-loader.is-dark.is-detonating .celestial-loader__bloom { opacity: .5; }

/* Brighter heart of the burst (17 Oct): as the light finishes collapsing, a warm core glow in the pack
   colours swells behind the wordmark and fades as the ejecta clears. Centred, behind the white mark,
   no white full-screen flash; reduced motion never reaches is-dark. */
.celestial-loader__core::after { position: absolute; z-index: -1; top: 50%; left: 50%; width: 130vmin; height: 130vmin; content: ""; opacity: 0; pointer-events: none;
  background: radial-gradient(circle closest-side, rgba(255,246,222,.95) 0, rgba(255,222,140,.8) 12%, rgba(249,160,40,.5) 24%, rgba(249,79,136,.3) 40%, rgba(171,43,88,.14) 58%, rgba(171,43,88,0) 76%);
  transform: translate(-50%,-50%) scale(.3); }
.celestial-loader.is-dark .celestial-loader__core::after { animation: canada-core-flare 600ms linear forwards; }
/* peaks ~85 ms after the light has gone, mostly spent by the time the star detaches, so it never sits beside the star or over Earth */
@keyframes canada-core-flare {
  0% { opacity: 0; transform: translate(-50%,-50%) scale(.3); animation-timing-function: cubic-bezier(.2,.7,.3,1); }
  14% { opacity: 1; transform: translate(-50%,-50%) scale(.85); animation-timing-function: cubic-bezier(.3,0,.6,1); }
  55% { opacity: .14; transform: translate(-50%,-50%) scale(1.35); }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(1.7); }
}
/* in space the bloom is spent quickly after the star detaches, so no warm haze sits beside the star or over Earth */
.celestial-loader.is-dark.is-launching .celestial-loader__bloom { transition: opacity 380ms cubic-bezier(.3,0,.6,1), transform 620ms cubic-bezier(.76,0,.24,1); }

/* ============================================================================
   SUPERNOVA OPENING (17 Oct 2026; the Canada default, ?loader=light for
   comparison only; the markup ships .is-supernova). Dark from the first frame; the shader draws space, the gathering star and the explosion;
   the exact wordmark is white with a quiet warm light; the light-mode layers
   (cream ground, veil, multiply bloom, core flare) are off in this mode only.
   ========================================================================== */
.celestial-loader.is-supernova { --moon: #fff7e6; --electric-ice: #ffd9a8; --void-deep: #04030c; color: #fff7e6; background: #04030c; }
.celestial-loader.is-supernova .celestial-loader__nebula,
.celestial-loader.is-supernova .celestial-loader__bloom,
.celestial-loader.is-supernova .celestial-loader__flash,
.celestial-loader.is-supernova .celestial-loader__core::before,
.celestial-loader.is-supernova .celestial-loader__core::after { display: none; }
.celestial-loader.is-supernova .celestial-loader__grain { opacity: .05; mix-blend-mode: soft-light; }
.celestial-loader.is-supernova .celestial-loader__core img,
.celestial-loader.is-supernova.is-charged .celestial-loader__core img,
.celestial-loader.is-supernova.is-igniting .celestial-loader__core img { filter: brightness(0) invert(1) drop-shadow(0 0 1.4rem rgba(160,196,255,.32)); }
.celestial-loader.is-supernova .celestial-loader__footer { color: rgba(255,247,230,.72); }
.celestial-loader.is-supernova .celestial-loader__meter > i { background: rgba(255,247,230,.14); }
.celestial-loader.is-supernova .celestial-loader__core p { color: rgba(186,210,255,.86); }
/* The supernova event (rev. 3): the view trembles as the star shudders, quakes at breakout, and the
   wordmark is blown away (opacity and blur only, so its measured position, the star anchor, never moves).
   Scaled a little while it shakes so no edge of the page shows. */
.celestial-loader.is-supernova.is-shuddering { animation: sn-shudder 550ms linear both; }
.celestial-loader.is-supernova.is-breakout { animation: sn-quake 900ms cubic-bezier(.2,.7,.3,1) both; }
.celestial-loader.is-supernova.is-breakout .celestial-loader__core img { opacity: 0; filter: brightness(0) invert(1) blur(8px); transition: opacity 650ms cubic-bezier(.3,0,.6,1), filter 650ms ease-out; }
@keyframes sn-shudder {
  0% { transform: translate(0,0) scale(1.03); } 20% { transform: translate(1px,-1px) scale(1.03); } 40% { transform: translate(-2px,1px) scale(1.03); }
  60% { transform: translate(2px,2px) scale(1.03); } 80% { transform: translate(-3px,-2px) scale(1.03); } 100% { transform: translate(3px,-1px) scale(1.03); }
}
/* scale covers the largest offset on a 320 px phone (1.5 % of 320 = 4.8 px a side > 7 px total only with 1.045) */
@keyframes sn-quake {
  0% { transform: translate(0,0) scale(1.045); } 8% { transform: translate(-7px,5px) scale(1.045); } 16% { transform: translate(6px,-6px) scale(1.045); }
  26% { transform: translate(-4px,-3px) scale(1.04); } 38% { transform: translate(3px,3px) scale(1.035); } 55% { transform: translate(-2px,1px) scale(1.025); }
  75% { transform: translate(1px,-1px) scale(1.012); } 100% { transform: translate(0,0) scale(1); }
}

/* ============================================================================
   HOLD TO IGNITE (prototype, 17 Oct 2026; ?ignite=hold). A charge ring around
   the wordmark's star, one quiet instruction, a sound toggle, the shards the
   wordmark breaks into, and the one line in the quiet after the breakout.
   ========================================================================== */
.celestial-loader.is-armed { cursor: pointer; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: none; }
.sn-hold { position: absolute; z-index: 8; pointer-events: none; transition: opacity 260ms ease, transform 260ms ease; }
.sn-hold svg { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.sn-hold circle { fill: none; stroke: rgba(255,247,230,.18); stroke-width: 1.2; }
.sn-hold .sn-hold__fill { stroke: #fff7e6; stroke-width: 1.8; stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--charge, 0)); filter: drop-shadow(0 0 6px rgba(170,205,255,.75)); }
.celestial-loader.is-armed .sn-hold { animation: sn-breathe 2.4s ease-in-out infinite; }
@keyframes sn-breathe { 0%, 100% { opacity: .75; transform: scale(1); } 50% { opacity: 1; transform: scale(1.06); } }
.sn-hold__label { position: absolute; z-index: 8; left: 0; right: 0; margin: 0; text-align: center; pointer-events: none; color: rgba(255,247,230,.92); font-size: clamp(.62rem, .9vw, .78rem); letter-spacing: .32em; text-transform: uppercase; animation: sn-label-in 900ms ease both; }
.sn-hold__label small { display: block; margin-top: .7em; font-size: .78em; letter-spacing: .22em; color: rgba(255,247,230,.5); }
@keyframes sn-label-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.sn-sound { position: absolute; z-index: 9; right: max(1.2rem, env(safe-area-inset-right, 0px)); top: max(1.1rem, env(safe-area-inset-top, 0px)); padding: .45rem .8rem; border: 1px solid rgba(255,247,230,.28); border-radius: 999px; background: rgba(4,3,12,.4); color: rgba(255,247,230,.85); font: inherit; font-size: .66rem; letter-spacing: .18em; text-transform: uppercase; cursor: pointer; }
.sn-hold.is-gone, .sn-hold__label.is-gone, .sn-sound.is-gone { opacity: 0 !important; transition: opacity 160ms ease; animation: none; }
.sn-shards { position: absolute; z-index: 7; pointer-events: none; }
.sn-shard { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: none; will-change: transform, opacity; }
.sn-line { position: absolute; z-index: 8; left: 0; right: 0; top: 62%; margin: 0; padding: 0 1.5rem; text-align: center; pointer-events: none; color: #fff7e6; opacity: 0;
  font-family: var(--font-display, Georgia, serif); font-size: clamp(1.15rem, 2.6vw, 2rem); letter-spacing: .04em; text-shadow: 0 0 24px rgba(4,3,12,.9); transition: opacity 1100ms ease, letter-spacing 2600ms cubic-bezier(.2,.7,.3,1); }
.sn-line.is-shown { opacity: 1; letter-spacing: .1em; }
.sn-line.is-gone { opacity: 0; transition: opacity 500ms ease; }

/* ============================================================================
   THE FILM (version 1, 17 Oct 2026). After the explosion the journey plays by
   itself; the page is held still, the descent HUD steps aside, one caption at
   a time, "Skip to the fruit" always there, and at the end the line and a
   call to shop. Lines are DRAFT copy pending Jay's choice.
   ========================================================================== */
html.cv-filming, html.cv-filming body { overflow: hidden; overscroll-behavior: none; }
html.cv-filming .cv-descent__hud, html.cv-filmed .cv-descent__hint { opacity: 0; pointer-events: none; transition: opacity 300ms ease; }
.cv-film { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.cv-film.is-arrived .cv-film__line { bottom: auto; top: 16%; } /* the last line rides above the packs, never over them */
.cv-film__line { position: absolute; left: 0; right: 0; bottom: 22%; margin: 0; padding: 0 1.5rem; text-align: center; color: #fff7e6; opacity: var(--line, 0);
  font-family: var(--font-display, Georgia, serif); font-size: clamp(1.1rem, 2.4vw, 1.9rem); letter-spacing: .03em; text-shadow: 0 2px 22px rgba(4,3,12,.85), 0 0 2px rgba(4,3,12,.6); }
.cv-film__skip { position: absolute; right: max(1rem, env(safe-area-inset-right, 0px)); bottom: max(1.1rem, env(safe-area-inset-bottom, 0px)); pointer-events: auto; padding: .55rem .95rem; border: 1px solid rgba(255,247,230,.35); border-radius: 999px; background: rgba(4,3,12,.45); color: #fff7e6; font: inherit; font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; cursor: pointer; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.cv-film.is-ended .cv-film__skip { opacity: 0; pointer-events: none; }
/* captions stay legible over bright cloud: a soft dark band behind them while one is up */
.cv-film::before { content: ""; position: absolute; left: 0; right: 0; bottom: 12%; height: 26%; background: radial-gradient(ellipse 70% 60% at 50% 60%, rgba(4,3,12,.55), rgba(4,3,12,0)); opacity: var(--line, 0); }


.cv-film.is-ended { display: none; }

/* ============================================================================
   THE LIVING HERO (17 Oct 2026). The brand line and the theme over the valley
   once the packs have formed; the title forms like frost, letter by letter;
   the descent HUD steps aside; each pack is a real link that lifts and names
   itself. Copy approved by Jay (FR pending a native check).
   ========================================================================== */
.cv-hero { position: absolute; z-index: 5; left: 0; right: 0; top: clamp(5.5rem, 13vh, 9rem); padding: 0 1.25rem; text-align: center; color: #fff7e6; pointer-events: none; opacity: 0; transition: opacity 500ms ease; }
.cv-hero::before { content: ""; position: absolute; z-index: -1; left: 50%; top: 50%; width: min(56rem, 120%); height: 190%; transform: translate(-50%, -50%); background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(6,10,26,.55), rgba(6,10,26,0)); }
[data-hero="on"] .cv-hero { opacity: 1; pointer-events: auto; }
.cv-hero__eyebrow { margin: 0 0 .9rem; font-size: .72rem; letter-spacing: .3em; text-transform: uppercase; color: rgba(255,247,230,.82); opacity: 0; transition: opacity 700ms ease 900ms; }
.cv-hero__title { margin: 0 auto; max-width: 18ch; font-size: clamp(2rem, 5.2vw, 4.4rem); line-height: 1.04; color: #fffaf0; text-shadow: 0 2px 30px rgba(4,8,22,.55); }
.cv-hero__sub { margin: 1rem 0 0; font-size: clamp(1rem, 1.6vw, 1.3rem); letter-spacing: .02em; color: rgba(255,247,230,.9); text-shadow: 0 1px 16px rgba(4,8,22,.7); opacity: 0; transform: translateY(6px); transition: opacity 800ms ease 1300ms, transform 800ms cubic-bezier(.2,.7,.3,1) 1300ms; }
.cv-hero__cta { margin-top: 1.5rem; opacity: 0; transform: translateY(6px); transition: opacity 700ms ease 1700ms, transform 700ms cubic-bezier(.2,.7,.3,1) 1700ms; }
[data-hero="on"] .cv-hero__eyebrow, [data-hero="on"] .cv-hero__sub, [data-hero="on"] .cv-hero__cta { opacity: 1; transform: none; }
/* the title forms like frost: each letter sharpens out of a cold blur */
.cv-hero__word { display: inline-block; white-space: nowrap; }
.cv-hero__ch { display: inline-block; opacity: 0; filter: blur(10px); transform: translateY(.18em) scale(1.12); text-shadow: 0 0 18px rgba(205,232,255,.9); }
[data-hero="on"] .cv-hero__ch { animation: cv-frost 900ms cubic-bezier(.2,.7,.3,1) both; animation-delay: calc(var(--i) * 26ms); }
@keyframes cv-frost { 0% { opacity: 0; filter: blur(10px); transform: translateY(.18em) scale(1.12); text-shadow: 0 0 22px rgba(205,232,255,1); } 60% { opacity: 1; filter: blur(0); text-shadow: 0 0 14px rgba(205,232,255,.7); } 100% { opacity: 1; filter: none; transform: none; text-shadow: 0 2px 30px rgba(4,8,22,.55); } }
[data-hero="on"] .cv-descent__hud { opacity: 0; pointer-events: none; transition: opacity 300ms ease; }
@media (orientation: portrait) { .cv-hero__cta { position: fixed; left: 50%; bottom: max(1.4rem, env(safe-area-inset-bottom, 0px)); transform: translate(-50%, 6px); margin: 0; } [data-hero="on"] .cv-hero__cta { transform: translate(-50%, 0); } .cv-hero { top: clamp(5rem, 11vh, 7rem); } }
/* the packs as links */
.cv-hero__packs { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
[data-hero="on"] .cv-hero__packs { pointer-events: auto; }
[data-hero="off"] .cv-pack-hit { visibility: hidden; }
.cv-pack-hit { position: absolute; display: block; border-radius: 6px; outline-offset: 4px; -webkit-tap-highlight-color: transparent; }
.cv-pack-tag { position: absolute; left: 50%; bottom: calc(100% + .5rem); transform: translate(-50%, 6px); display: inline-flex; gap: .55rem; align-items: center; white-space: nowrap; padding: .4rem .75rem; border-radius: 999px; background: rgba(8,10,24,.72); color: #fff7e6; font-size: .72rem; letter-spacing: .08em; opacity: 0; pointer-events: none; transition: opacity 220ms ease, transform 220ms ease; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.cv-pack-tag b { font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: #ffd76a; }
.cv-pack-hit.is-lift .cv-pack-tag, .cv-pack-hit.is-on .cv-pack-tag, .cv-pack-hit:focus-visible .cv-pack-tag { opacity: 1; transform: translate(-50%, 0); }
@media (orientation: portrait) { .cv-past-hero .cv-hero__cta { opacity: 0 !important; pointer-events: none; transition: opacity 250ms ease !important; } } /* scrolled past the hero: the floating shop button steps aside */
@media (prefers-reduced-motion: reduce) { .cv-hero__ch { opacity: 1; filter: none; transform: none; animation: none !important; } .cv-hero__eyebrow, .cv-hero__sub, .cv-hero__cta { transition: none; } }
/* landscape: the pack's name sits on the stone below it (above it would meet the shop button) */
@media (orientation: landscape) { .cv-pack-tag { bottom: auto; top: calc(100% + .7rem); transform: translate(-50%, -6px); } .cv-pack-hit.is-lift .cv-pack-tag, .cv-pack-hit.is-on .cv-pack-tag, .cv-pack-hit:focus-visible .cv-pack-tag { transform: translate(-50%, 0); } }
/* The seamless descent: the header stays out of the story until the hero; the loader steps away quickly on the
   identical frame (nothing changes on screen). */
html.cv-prefilm .cv-mast, html.cv-filming .cv-mast { opacity: 0; pointer-events: none; transition: opacity 300ms ease; }
.celestial-loader.is-handoff.is-exiting { transition: opacity 420ms cubic-bezier(.3,0,.2,1), visibility 0s linear 420ms; } /* out of the star's light, the film already falling */
