/*
 * Spiral hero layer and per-page hero adapters.
 *
 * The layer is the hero section's first child, absolutely filling it. Each page
 * gets a z-index between its own background and its content. Everything that
 * changes the page's own hero is keyed on .spiral-hero--active (added by the
 * script once WebGL is running) or .spiral-hero--pending (added just before,
 * only where WebGL 2 exists, and removed again if the script cannot start).
 * Without either class the page's hero is exactly as it was.
 */

.spiral-hero-layer {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.6s ease;
    /* The fixed navbar is transparent over the hero: cards fade out beneath it
       so its links stay legible. */
    -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.2) 40px, #000 150px);
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.2) 40px, #000 150px);
}

.spiral-hero-canvas {
    display: block;
    width: 100%;
    height: 100%;
}

.spiral-hero--active > .spiral-hero-layer {
    opacity: var(--spiral-opacity, 1);
}

.spiral-hero-host {
    /* The canvas sits under the transparent fixed navbar, so the section must
       contain it rather than let it spill sideways on narrow screens. */
    overflow: hidden;
}

/* While the spiral runs, the hero fills the first screen. svh is the visible
   height on phones (with the browser bars showing); vh is the fallback. */
.spiral-hero-host:is(.spiral-hero--active, .spiral-hero--pending) {
    min-height: 100vh;
    min-height: 100svh;
}

.spiral-hero-host--apa:is(.spiral-hero--active, .spiral-hero--pending) {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* ---------- Readability veil behind the hero text ---------- */

.spiral-hero--active.spiral-hero-host--home .hero-content,
.spiral-hero--active.spiral-hero-host--adults .hero-content,
.spiral-hero--active.spiral-hero-host--vd .hero-content,
.spiral-hero--active.spiral-hero-host--vpd .hero-content,
.spiral-hero--active.spiral-hero-host--apa .apa-hero-copy {
    position: relative;
}

.spiral-hero--active.spiral-hero-host--home .hero-content::before,
.spiral-hero--active.spiral-hero-host--adults .hero-content::before,
.spiral-hero--active.spiral-hero-host--vd .hero-content::before,
.spiral-hero--active.spiral-hero-host--vpd .hero-content::before,
.spiral-hero--active.spiral-hero-host--apa .apa-hero-copy::before {
    position: absolute;
    inset: -70px -110px;
    z-index: -1;
    content: "";
    pointer-events: none;
    background: radial-gradient(closest-side, rgba(10, 14, 26, calc(0.86 * var(--spiral-veil, 0.8))), transparent);
    -webkit-backdrop-filter: blur(calc(10px * var(--spiral-veil, 0.8)));
    backdrop-filter: blur(calc(10px * var(--spiral-veil, 0.8)));
    -webkit-mask-image: radial-gradient(closest-side, #000 50%, transparent 100%);
    mask-image: radial-gradient(closest-side, #000 50%, transparent 100%);
}

/* The anime hero already has its own dark backing; the veil only deepens it. */
.spiral-hero--active.spiral-hero-host--anime .anime-hero-content {
    background: radial-gradient(ellipse at center, rgba(3, 0, 20, calc(0.55 + 0.35 * var(--spiral-veil, 0.8))) 0%, rgba(3, 0, 20, calc(0.3 + 0.4 * var(--spiral-veil, 0.8))) 58%, transparent 80%);
}

@media (max-width: 700px) {
    .spiral-hero--active.spiral-hero-host--home .hero-content::before,
    .spiral-hero--active.spiral-hero-host--adults .hero-content::before,
    .spiral-hero--active.spiral-hero-host--vd .hero-content::before,
    .spiral-hero--active.spiral-hero-host--vpd .hero-content::before,
    .spiral-hero--active.spiral-hero-host--apa .apa-hero-copy::before {
        inset: -40px -16px;
    }
}

/* ---------- Home and Adults: orbs and mockup give way to the spiral ---------- */

.spiral-hero-host--home.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) :is(.hero-bg, .hero-visual),
.spiral-hero-host--adults.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) :is(.hero-bg, .hero-visual) {
    display: none;
}

.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults).spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) > .container {
    justify-content: center;
}

.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults).spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .hero-content {
    flex: 0 1 auto;
    max-width: 760px;
    margin-inline: auto;
    text-align: center;
}

.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults).spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .hero-description {
    margin-inline: auto;
}

.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults).spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) :is(.hero-buttons, .hero-stats) {
    justify-content: center;
}

.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults).spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .hero-stat {
    text-align: center;
}

/* Backdrop mode keeps the orbs; the spiral sits between them and the content. */
.spiral-hero-host:is(.spiral-hero-host--home, .spiral-hero-host--adults) > .container {
    z-index: 2;
}

/* ---------- APA: banner gives way, the copy becomes one centred column ---------- */

.spiral-hero-host--apa.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) :is(.apa-hero-bg, figure.apa-hero-media) {
    display: none;
}

.spiral-hero-host--apa.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .apa-hero-grid {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
}

.spiral-hero-host--apa.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .apa-hero-copy {
    max-width: 820px;
}

.spiral-hero-host--apa.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .apa-hero-copy > * {
    margin-inline: auto;
}

.spiral-hero-host--apa.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) :is(.apa-chip-row, .apa-actions, .apa-stat-row) {
    justify-content: center;
}

.spiral-hero-host--apa > .apa-container {
    z-index: 2;
}

/* ---------- Video Downloader: the screenshot gives way ---------- */

.spiral-hero-host--vd.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .app-screenshot {
    display: none;
}

/* ---------- Gallery Downloader and Anime: the spiral sits above the video's overlay ---------- */

.spiral-hero-host--vpd > .spiral-hero-layer {
    z-index: 2;
}

.spiral-hero-host--vpd > .hero-content {
    z-index: 3;
}

.spiral-hero-host--anime > .spiral-hero-layer {
    z-index: 10;
}

.spiral-hero-host--vpd.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .hero-overlay {
    background: radial-gradient(ellipse at 50% 45%, rgba(10, 14, 26, 0.2), rgba(10, 14, 26, 0.55) 80%);
}

.spiral-hero-host--anime.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) .anime-hero-overlay {
    background: radial-gradient(ellipse at center, rgba(3, 0, 20, 0.15), rgba(3, 0, 20, 0.6));
}

/* Replace mode never loads the decorative player; keep its empty frame out of sight. */
.spiral-hero-host--replace:is(.spiral-hero--active, .spiral-hero--pending) iframe[data-spiral-src] {
    visibility: hidden;
}

/* ---------- Click-to-zoom ---------- */

.spiral-hero--card-hover {
    cursor: zoom-in;
}

/* While a card is enlarged the layer rises above the hero's content and takes
   every click, so nothing hidden under the card (a download button, say) can be
   pressed through it. The navbar fade goes too: the card clears the navbar by itself. */
.spiral-hero--zoomed > .spiral-hero-layer {
    z-index: 20;
    opacity: 1;
    pointer-events: auto;
    cursor: zoom-out;
    -webkit-mask-image: none;
    mask-image: none;
}

.spiral-hero-host :is(.hero-content, .anime-hero-content, .apa-hero-copy) {
    transition: opacity 0.25s ease;
}

.spiral-hero--zoomed :is(.hero-content, .anime-hero-content, .apa-hero-copy) {
    opacity: 0.25;
}

@media (prefers-reduced-motion: reduce) {
    .spiral-hero-layer,
    .spiral-hero-host :is(.hero-content, .anime-hero-content, .apa-hero-copy) {
        transition: none;
    }
}
