/* ═══════════════════════════════════════════
   the-opening: the cover, then the mist clears (pages.md, "the-opening")

   Owns the ARCH SET ([data-sv-set="arch"], 200dvh) and its sticky stack (layers 1-7,
   shared with the-names), plus the page #the-opening-page (the snap area).

   States:
   - Page (written by this module and app.js): no state / pending = the cover;
     [data-sv-state="entering"][data-sv-ready] = the reveal; [data-sv-state="done"] =
     the end state, no animation.
   - Stack (written by this module only, set at the same instant as entering + ready):
     .the-opening-set--play = the stack's half of the reveal; .the-opening-set--end =
     its static end state. The stack is shared with the-names, so it keeps playing to
     its end even if the page is marked done early (it is still on screen there).
   - Loops run only under [data-sv-view="on"]; loop layers are display:none under far.

   Only transform, opacity and clip-path animate. No filter, no blur.
   ═══════════════════════════════════════════ */

/* ───── The arch set ───── */
.the-opening-set {
    position: relative;
    height: 200vh;
    height: 200dvh;
}

/* ───── The sticky stack (layers 1-7) ───── */
.the-opening-stack {
    --the-opening-vh: 100vh;
    /* 0 while the set is stuck (--dp in [-1, 0]); negative by the fraction of a page
       the set has left by. A layer at rate r moves by -r x that (Card contract). */
    --the-opening-leave: min(0, var(--dp, 0) + 1);
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    margin-bottom: -100vh;
    margin-bottom: -100dvh;
    overflow: hidden;
    overflow: clip;
    pointer-events: none;
}

@supports (height: 100dvh) {
    .the-opening-stack {
        --the-opening-vh: 100dvh;
    }
}

/* 1-2: wash + sky */
.the-opening-far {
    position: absolute;
    inset: 0;
    transform: translateY(calc(var(--the-opening-leave) * var(--px-backdrop) * -1 * var(--the-opening-vh)));
}

.the-opening-wash {
    position: absolute;
    inset: 0;
    background: var(--wash-arch);
}

.the-opening-sky {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 100%;
    transform: scale(var(--mist-art-scale-from));
    transform-origin: 50% 40%;
}

/* 3: the arch frame, fit to width, anchored top */
.the-opening-frame {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    transform: translateY(calc(var(--the-opening-leave) * var(--px-frame) * -1 * var(--the-opening-vh)));
}

.the-opening-frame-img {
    display: block;
    width: 100%;
    height: auto;
    opacity: var(--mist-frame-opacity-from);
    transform: scale(var(--mist-art-scale-from));
    /* the page's 50% 40%, measured from the image's top (it is anchored at the page top) */
    transform-origin: 50% calc(var(--the-opening-vh) * 0.4);
}

/* 4-6: the near layers */
.the-opening-fore {
    position: absolute;
    inset: 0;
    transform: translateY(calc(var(--the-opening-leave) * var(--px-fore) * -1 * var(--the-opening-vh)));
}

/* 4: vines, from the bottom corners, the right one mirrored */
.the-opening-vine {
    position: absolute;
    bottom: 0;
    height: 70%;
    aspect-ratio: 390 / 1152;
}

.the-opening-vine--l {
    left: 0;
}

.the-opening-vine--r {
    right: 0;
    transform: scaleX(-1);
}

.the-opening-vine-grow {
    width: 100%;
    height: 100%;
    /* grows from its root; the open edges leave room for the sway */
    clip-path: inset(100% -10% -10% -10%);
}

.the-opening-vine-img {
    --the-opening-sway: 0.5deg;
    display: block;
    width: 100%;
    height: 100%;
    /* the bottom outer corner (the right vine's parent mirrors it) */
    transform-origin: 0 100%;
    animation: the-opening-sway 4.5s var(--ease-breath) -2.25s infinite alternate paused;
}

.the-opening-vine--r .the-opening-vine-img {
    animation-duration: 5.25s;
    animation-delay: -2.625s;
}

/* 5: the lotus band, and the dip between the set's two pages */
.the-opening-lotus-dip {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -3px;
}

@supports (transform: translateY(calc(sin(1rad) * 1px))) {
    .the-opening-lotus-dip {
        /* 18px x sin(pi * p), p = -(the set's --dp) over [0, 1] */
        transform: translateY(calc(18px * sin(clamp(0, var(--dp, 0) * -1, 1) * 3.14159)));
    }
}

.the-opening-lotus {
    opacity: 0;
    transform: translateY(35%);
}

.the-opening-lotus-img {
    display: block;
    width: 100%;
    height: auto;
    animation: the-opening-bob 3.5s var(--ease-breath) -1.75s infinite alternate paused;
}

/* 6: butterflies, y 62-94%, never above 58% */
.the-opening-flutter {
    position: absolute;
    inset: 0;
    opacity: 0;
}

.the-opening-fly {
    --the-opening-s: 28px;
    position: absolute;
    width: var(--the-opening-s);
    margin: calc(var(--the-opening-s) * -0.37) 0 0 calc(var(--the-opening-s) * -0.5);
    animation: the-opening-path-a 12s var(--ease-drift) 1300ms infinite paused;
}

.the-opening-fly-img {
    display: block;
    width: 100%;
    height: auto;
    animation: the-opening-wing 300ms var(--ease-breath) infinite paused;
}

.the-opening-fly--1 {
    left: 14%;
    top: 70%;
}

.the-opening-fly--2 {
    --the-opening-s: 24px;
    left: 76%;
    top: 68%;
    animation-name: the-opening-path-c;
    animation-duration: 14s;
    animation-delay: 1600ms;
}

.the-opening-fly--2 .the-opening-fly-img {
    animation-duration: 340ms;
}

.the-opening-fly--3 {
    --the-opening-s: 30px;
    left: 60%;
    top: 77%;
    animation-name: the-opening-path-b;
    animation-duration: 10s;
    animation-delay: 1900ms;
}

.the-opening-fly--3 .the-opening-fly-img {
    animation-duration: 280ms;
}

.the-opening-fly--4 {
    --the-opening-s: 22px;
    left: 86%;
    top: 87%;
    animation-name: the-opening-path-b;
    animation-duration: 15s;
    animation-delay: 2200ms;
}

.the-opening-fly--4 .the-opening-fly-img {
    animation-duration: 360ms;
}

.the-opening-fly--5 {
    --the-opening-s: 34px;
    left: 8%;
    top: 85%;
    animation-duration: 9s;
    animation-delay: 2500ms;
}

.the-opening-fly--5 .the-opening-fly-img {
    animation-duration: 320ms;
}

/* 7: sparkles (_shared/effects/sparkles.css, light variant). Paused until on screen. */
.the-opening-sparkles {
    position: absolute;
    inset: 0;
    opacity: 0;
}

.the-opening-sparkles .the-opening-spark {
    animation-play-state: paused;
}

/* ───── The page (the snap area) ───── */
.the-opening-page {
    /* the garland's height: its U dips to about 27%, the tassel ends near 33% */
    --the-opening-garland-h: min(33%, calc(min(92cqi, 440px) * 1.181));
    position: relative;
    height: 100vh;
    height: 100dvh;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    overflow: hidden;
    overflow: clip;
    color: var(--ink);
}

.the-opening-page p {
    margin: 0;
}

/* 8: the emblem */
.the-opening-emblem {
    position: absolute;
    top: 18%;
    left: 0;
    right: 0;
    margin: 0 auto;
    width: min(30cqi, 140px);
    height: auto;
    aspect-ratio: 323 / 400;
    object-fit: contain;
    opacity: 0;
    transform: scale(0.86);
}

#sv-card[data-sv-emblem="none"] .the-opening-emblem {
    display: none;
}

/* Opened block: invocation (or "Welcome") at about 37%, blessing at about 46%.
   Never higher than just under the emblem, so a short page cannot overlap them. */
.the-opening-opened {
    position: absolute;
    left: 0;
    right: 0;
    top: max(37%, calc(18% + min(30cqi, 140px) * 1.24 + 10px));
    width: var(--col-arch);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.the-opening-invocation {
    font-family: var(--font-devanagari);
    font-weight: 400;
    font-size: var(--type-invocation);
    line-height: 1.5;
    color: var(--ink-title);
    text-wrap: balance;
    opacity: 0;
}

.the-opening-welcome {
    display: none;
    font-family: var(--font-script);
    font-weight: 400;
    font-size: var(--type-script-hero);
    line-height: var(--leading-script);
    color: var(--ink-script);
    opacity: 0;
}

/* Blank invocation: the line goes and "Welcome" shows (setInvocation writes both the
   text and #sv-card[data-sv-invocation], so the two selectors always agree). */
#sv-card[data-sv-invocation="off"] .the-opening-invocation,
.the-opening-invocation:empty {
    display: none;
}

#sv-card[data-sv-invocation="off"] .the-opening-welcome,
.the-opening-invocation:empty + .the-opening-welcome {
    display: block;
}

.the-opening-blessing {
    margin-top: 1.4em;
    font-family: var(--font-body);
    font-style: italic;
    font-weight: 600;
    font-size: var(--type-detail);
    line-height: var(--leading-detail);
    color: var(--ink);
    opacity: 0;
}

.the-opening-welcome + .the-opening-blessing {
    margin-top: 0.8em;
}

/* 9: the mist */
.the-opening-mist {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.the-opening-veil {
    position: absolute;
    inset: 0;
    background: var(--mist-veil);
}

.the-opening-wisp {
    position: absolute;
    width: 110cqi;
    height: 110cqi;
}

.the-opening-wisp--a {
    left: calc(30% - 55cqi);
    top: calc(45% - 55cqi);
}

.the-opening-wisp--b {
    left: calc(72% - 55cqi);
    top: calc(52% - 55cqi);
}

.the-opening-wisp-puff {
    width: 100%;
    height: 100%;
    background: var(--mist-wisp);
    animation: the-opening-drift 6s var(--ease-drift) -3s infinite alternate paused;
}

.the-opening-wisp--b .the-opening-wisp-puff {
    animation-direction: alternate-reverse;
    animation-delay: -1s;
}

.the-opening-floor {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 40%;
    background: var(--mist-floor);
}

/* 9: the garland, tied ends on the top edge, U dipping to about 27% */
.the-opening-garland {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--the-opening-garland-h);
    display: flex;
    justify-content: center;
    pointer-events: none;
}

.the-opening-garland-img {
    --the-opening-sway: 0.8deg;
    display: block;
    height: 100%;
    width: auto;
    transform-origin: 50% 0;
    animation: the-opening-sway 2.6s var(--ease-breath) -1.3s infinite alternate paused;
}

/* ───── Cover block ───── */
/* Rows: the garland's band, the text (centred in what is left, about 48%), the button
   (centre at 66% of the page: 34% - 24px below it). If a long greeting needs more room,
   the text row grows and the last row gives way, so the button moves down rather than
   overlapping the text. */
.the-opening-cover {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-rows: var(--the-opening-garland-h) minmax(min-content, 1fr) auto minmax(0, calc(34% - 24px));
    justify-items: center;
    align-items: center;
    row-gap: 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.the-opening-cover[hidden] {
    display: none;
}

/* app.js unlocks the scroll at the tap by writing data-sv-opened="true" */
#sv-card[data-sv-opened="false"] .the-opening-cover {
    touch-action: none;
}

.the-opening-cover-text {
    grid-row: 2;
    width: var(--col-arch);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.625rem;
    text-align: center;
}

.the-opening-kicker {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--type-kicker);
    line-height: 1.3;
    letter-spacing: var(--tracking-kicker);
    text-transform: uppercase;
    color: var(--ink-title);
}

.the-opening-hero {
    font-family: var(--font-script);
    font-weight: 400;
    font-size: var(--type-script-hero);  /* 47px at 360; JS fits it down to 34px, 2 lines */
    line-height: var(--leading-script);
    color: var(--ink-script);
    text-wrap: balance;
}

.the-opening-detail {
    font-family: var(--font-body);
    font-style: italic;
    font-weight: 600;
    font-size: var(--type-detail);
    line-height: var(--leading-detail);
    color: var(--ink);
    text-wrap: balance;
}

.the-opening-cta {
    grid-row: 3;
    display: flex;
    justify-content: center;
}

.the-opening-open {
    position: relative;
    margin: 0;
    height: var(--hit-min);
    min-width: var(--hit-min);
    padding: 0 28px;
    border: 1px solid var(--accent-warm);
    border-radius: 24px;
    background: var(--bg-primary);
    color: var(--chrome-ink);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--type-hint);
    line-height: 1;
    letter-spacing: var(--tracking-kicker);
    text-transform: uppercase;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

/* the breathing ring */
.the-opening-open::after {
    content: '';
    position: absolute;
    inset: -1px;
    border: 1px solid var(--accent-warm);
    border-radius: inherit;
    pointer-events: none;
    animation: the-opening-ring 2.4s var(--ease-breath) infinite paused;
}

.the-opening-open:focus {
    outline: none;
}

.the-opening-open:focus-visible {
    outline: 2px solid var(--accent-warm);
    outline-offset: 3px;
}

/* Short pages: a smaller garland leaves the greeting room (checked at 360 x 640, 320 x 568) */
@media (max-height: 680px) {
    .the-opening-page {
        --the-opening-garland-h: min(28%, calc(min(92cqi, 440px) * 1.181));
    }
}

/* ═══════════ Idle loops: on screen only ═══════════ */
.the-opening-page[data-sv-view="on"] .the-opening-garland-img,
.the-opening-page[data-sv-view="on"] .the-opening-wisp-puff,
.the-opening-page[data-sv-view="on"] .the-opening-open::after {
    animation-play-state: running;
}

/* The set's loops run while either of its pages is on screen, once the reveal began */
.the-opening-set[data-sv-view="on"]:is(.the-opening-set--play, .the-opening-set--end) :is(.the-opening-fly, .the-opening-fly-img, .the-opening-lotus-img, .the-opening-vine-img, .the-opening-spark) {
    animation-play-state: running;
}

.the-opening-set[data-sv-view="far"] :is(.the-opening-flutter, .the-opening-sparkles) {
    display: none;
}

.the-opening-page[data-sv-view="far"] {
    content-visibility: auto;
    contain-intrinsic-size: auto 100vh;
}

.the-opening-page[data-sv-view="far"] :is(.the-opening-mist, .the-opening-garland) {
    display: none;
}

/* ═══════════ The reveal: page half (clock = the tap; pages.md steps 1-11) ═══════════ */
.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-cover {
    pointer-events: none;
    animation: the-opening-cover-out 400ms var(--ease-silk) both;           /* 1 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-garland {
    will-change: transform;
    animation: the-opening-lift 1000ms var(--ease-stage) both;              /* 2 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-veil {
    will-change: opacity;
    animation: the-opening-fade-out 1300ms var(--ease-silk) both;           /* 3 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-wisp--a {
    will-change: transform, opacity;
    animation: the-opening-wisp-a-out 1600ms var(--ease-expo-out) both;     /* 4 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-wisp--b {
    will-change: transform, opacity;
    animation: the-opening-wisp-b-out 1600ms var(--ease-expo-out) both;
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-floor {
    will-change: transform, opacity;
    animation: the-opening-floor-out 1400ms var(--ease-silk) both;
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-emblem {
    animation: the-opening-emblem-in 1100ms var(--ease-expo-out) 400ms both;     /* 6 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-invocation {
    animation: the-opening-rise-scale 500ms var(--ease-expo-out) 1000ms both;    /* 9 */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-welcome {
    animation: the-opening-write var(--dur-write) var(--ease-silk) 1000ms both;  /* 9, blank */
}

.the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-blessing {
    animation: the-opening-fade-up 500ms var(--ease-expo-out) 1500ms both;       /* 11 */
}

/* Done: the end state, no animation. (JS also removes the mist and garland nodes.) */
.the-opening-page[data-sv-state="done"] :is(.the-opening-cover, .the-opening-mist, .the-opening-garland) {
    display: none;
}

.the-opening-page[data-sv-state="done"] :is(.the-opening-emblem, .the-opening-invocation, .the-opening-welcome, .the-opening-blessing) {
    opacity: 1;
    transform: none;
    clip-path: none;
    animation: none;
}

/* ═══════════ The reveal: stack half (steps 5, 7, 8, 10, 12) ═══════════ */
/* A no-op 2400ms animation on the stack: its animationend tells the JS the stack's
   entrance is over (it then sets --end and drops will-change). CSS, not a timer. */
.the-opening-set--play .the-opening-stack {
    animation: the-opening-stack-done 2400ms linear both;
}

.the-opening-set--play .the-opening-sky {
    animation: the-opening-focus 1600ms var(--ease-expo-out) both;                        /* 5 */
}

.the-opening-set--play .the-opening-frame-img {
    animation: the-opening-focus-frame 1600ms var(--ease-expo-out) both;
}

.the-opening-set--play:not(.the-opening-set--end) :is(.the-opening-sky, .the-opening-frame-img) {
    will-change: transform, opacity;
}

.the-opening-set--play .the-opening-vine--l .the-opening-vine-grow {
    animation: the-opening-grow 1500ms var(--ease-expo-out) 700ms both;                   /* 7 */
}

.the-opening-set--play .the-opening-vine--r .the-opening-vine-grow {
    animation: the-opening-grow 1500ms var(--ease-expo-out) 850ms both;
}

.the-opening-set--play .the-opening-lotus {
    animation: the-opening-lotus-in 1200ms var(--ease-expo-out) 800ms both;               /* 8 */
}

.the-opening-set--play .the-opening-flutter {
    animation: the-opening-fade-in 600ms var(--ease-silk) 1300ms both;                    /* 10 */
}

.the-opening-set--play .the-opening-sparkles {
    animation: the-opening-fade-in 400ms var(--ease-silk) 1800ms both;                    /* 12 */
}

/* The stack's static end state (after its reveal, or when the page was opened silently) */
.the-opening-set.the-opening-set--end .the-opening-stack {
    animation: none;
}

.the-opening-set.the-opening-set--end .the-opening-stack :is(.the-opening-sky, .the-opening-frame-img, .the-opening-vine-grow, .the-opening-lotus, .the-opening-flutter, .the-opening-sparkles) {
    animation: none;
    transform: none;
    opacity: 1;
    clip-path: none;
}

/* ═══════════ Keyframes ═══════════ */
@keyframes the-opening-cover-out {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(-8px); }
}

@keyframes the-opening-lift {
    from { transform: translateY(0); }
    to { transform: translateY(-115%); }
}

@keyframes the-opening-fade-out {
    from { opacity: 1; }
    to { opacity: 0; }
}

@keyframes the-opening-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes the-opening-wisp-a-out {
    from { opacity: 1; transform: translateX(0) scale(1); }
    to { opacity: 0; transform: translateX(-22cqi) scale(1.3); }
}

@keyframes the-opening-wisp-b-out {
    from { opacity: 1; transform: translateX(0) scale(1); }
    to { opacity: 0; transform: translateX(22cqi) scale(1.3); }
}

@keyframes the-opening-floor-out {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(30%); }
}

@keyframes the-opening-focus {
    from { transform: scale(var(--mist-art-scale-from)); }
    to { transform: scale(1); }
}

@keyframes the-opening-focus-frame {
    from { opacity: var(--mist-frame-opacity-from); transform: scale(var(--mist-art-scale-from)); }
    to { opacity: 1; transform: scale(1); }
}

@keyframes the-opening-frame-clear {
    from { opacity: var(--mist-frame-opacity-from); }
    to { opacity: 1; }
}

@keyframes the-opening-emblem-in {
    from { opacity: 0; transform: scale(0.86); }
    to { opacity: 1; transform: scale(1); }
}

@keyframes the-opening-grow {
    from { clip-path: inset(100% -10% -10% -10%); }
    to { clip-path: inset(-10% -10% -10% -10%); }
}

@keyframes the-opening-lotus-in {
    from { opacity: 0; transform: translateY(35%); }
    to { opacity: 1; transform: translateY(0); }
}

/* "Fade + scale" */
@keyframes the-opening-rise-scale {
    from { opacity: 0; transform: scale(0.92); }
    to { opacity: 1; transform: scale(1); }
}

/* "Write-on": a left-to-right wipe, opacity in over its first 150ms (of 900).
   The open top/bottom/left edges keep Great Vibes' swashes unclipped. */
@keyframes the-opening-write {
    0% { opacity: 0; clip-path: inset(-0.3em 100% -0.3em -0.3em); }
    16.7% { opacity: 1; }
    100% { opacity: 1; clip-path: inset(-0.3em -0.3em -0.3em -0.3em); }
}

/* "Fade-up" */
@keyframes the-opening-fade-up {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Animates nothing visible; it exists for its animationend */
@keyframes the-opening-stack-done {
    from { visibility: visible; }
    to { visibility: visible; }
}

/* Loops. Sways run `alternate` with a negative half-delay so they start mid-swing. */
@keyframes the-opening-sway {
    from { transform: rotate(calc(var(--the-opening-sway) * -1)); }
    to { transform: rotate(var(--the-opening-sway)); }
}

@keyframes the-opening-drift {
    from { transform: translateX(-3cqi); }
    to { transform: translateX(3cqi); }
}

@keyframes the-opening-bob {
    from { transform: translateY(-3px); }
    to { transform: translateY(3px); }
}

@keyframes the-opening-ring {
    from { opacity: 0.5; transform: scale(1); }
    to { opacity: 0; transform: scale(1.12); }
}

@keyframes the-opening-wing {
    0%, 100% { transform: scaleX(1); }
    50% { transform: scaleX(0.32); }
}

/* Flight paths (offsets from each butterfly's base; x in cqi, y in vh = % of the page) */
@keyframes the-opening-path-a {
    0%, 100% { transform: translate(0, 0) rotate(0deg); }
    25% { transform: translate(14cqi, -5vh) rotate(8deg); }
    50% { transform: translate(30cqi, 2vh) rotate(-4deg); }
    75% { transform: translate(12cqi, 8vh) rotate(-10deg); }
}

@keyframes the-opening-path-b {
    0%, 100% { transform: translate(0, 0) rotate(0deg); }
    20% { transform: translate(-16cqi, 4vh) rotate(-8deg); }
    45% { transform: translate(-30cqi, -3vh) rotate(6deg); }
    70% { transform: translate(-12cqi, -6vh) rotate(10deg); }
}

@keyframes the-opening-path-c {
    0%, 100% { transform: translate(0, 0) rotate(0deg); }
    30% { transform: translate(10cqi, -6vh) rotate(9deg); }
    55% { transform: translate(-12cqi, -2vh) rotate(-6deg); }
    80% { transform: translate(-6cqi, 5vh) rotate(-9deg); }
}

/* ═══════════ Reduced motion (pages.md, the-opening, "Reduced motion") ═══════════
   On the tap: the cover block and garland fade out (400ms), the mist fades (800ms), no
   scale or translate. Vines, lotus band, emblem, invocation and blessing fade in
   (400ms, 150ms stagger). Two butterflies rest still on lily pads. No wing beat,
   flights, sparkles or loops. No parallax (tokens.css zeroes the rates), no lotus dip. */
@media (prefers-reduced-motion: reduce) {
    /* pre-states without movement */
    .the-opening-vine-grow {
        clip-path: none;
        opacity: 0;
    }

    .the-opening-lotus,
    .the-opening-emblem,
    .the-opening-lotus-dip {
        transform: none;
    }

    /* loops off */
    .the-opening-stack :is(.the-opening-fly, .the-opening-fly-img, .the-opening-lotus-img, .the-opening-vine-img),
    .the-opening-page :is(.the-opening-garland-img, .the-opening-wisp-puff),
    .the-opening-page .the-opening-open::after {
        animation: none;
    }

    .the-opening-page .the-opening-open::after {
        opacity: 0;
    }

    .the-opening-sparkles,
    .the-opening-fly--3,
    .the-opening-fly--4,
    .the-opening-fly--5 {
        display: none;
    }

    /* two butterflies at rest on the lily pads */
    .the-opening-fly--1 {
        left: 22%;
        top: 88%;
    }

    .the-opening-fly--2 {
        left: 74%;
        top: 90%;
    }

    /* the page's half */
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-cover,
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-garland {
        animation: the-opening-fade-out 400ms var(--ease-silk) both;
    }

    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-veil,
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-wisp--a,
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-wisp--b,
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-floor {
        animation: the-opening-fade-out 800ms var(--ease-silk) both;
    }

    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-emblem {
        animation: the-opening-fade-in 400ms var(--ease-silk) 300ms both;
    }

    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-invocation,
    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-welcome {
        animation: the-opening-fade-in 400ms var(--ease-silk) 450ms both;
    }

    .the-opening-page[data-sv-state="entering"][data-sv-ready] .the-opening-blessing {
        animation: the-opening-fade-in 400ms var(--ease-silk) 600ms both;
    }

    /* the stack's half */
    .the-opening-set--play .the-opening-stack {
        animation-duration: 800ms;
    }

    .the-opening-set--play .the-opening-sky {
        animation: none;
    }

    .the-opening-set--play .the-opening-frame-img {
        animation: the-opening-frame-clear 800ms var(--ease-silk) both;
    }

    .the-opening-set--play .the-opening-vine--l .the-opening-vine-grow,
    .the-opening-set--play .the-opening-vine--r .the-opening-vine-grow {
        animation: the-opening-fade-in 400ms var(--ease-silk) both;
    }

    .the-opening-set--play .the-opening-lotus,
    .the-opening-set--play .the-opening-flutter {
        animation: the-opening-fade-in 400ms var(--ease-silk) 150ms both;
    }

    .the-opening-set.the-opening-set--end .the-opening-stack .the-opening-vine-grow {
        animation: none;
        opacity: 1;
    }
}
