/* ═══════════════════════════════════════════
   the-bloom — the wow beat: a spiral tunnel of flowers

   Structure, built once by js/the-bloom.js (never in a cue):
     .the-bloom-container            state classes live here; --the-bloom-c0 (set by
                                     the module from __giftBloom.startAt: 1.7 s)
       .the-bloom-paper              cream paper; crossfades out over f 8.6-10.0
       .the-bloom-field              0x0 origin at the bloom's centre (50%, 46%)
         .the-bloom-ring  x13        one ring: scale (its stream outward), rotate
                                     (spin + spiral twist), opacity; the ring's ONE
                                     layer. Lent to the-gift's core for the bloom's
                                     first 1.7 s, re-parented here at entry.
           .the-bloom-seg  x4        an arc of the ring: still until the fall, then it
                                     drops and tumbles on its own (the loose flowers)
             img.the-bloom-flower    static position, size, spin; never animated

   Each ring's trajectory (born tiny at the vanishing point, streaming out past
   the corners, reborn at the centre, frozen at the fall) is its own
   @keyframes the-bloom-r<i> with its duration, generated once by the module
   from the tunnel's depth curve (<style id="the-bloom-keyframes">); this file
   gives them their clock. Every ring is authored at a modest native size
   (radius 0.36 U; 0.25 U on WebKit, see R_NATIVE in the module) and scales up
   past 1, so its composited backing stays small (~6.8 MB, ~3.2 MB on WebKit, at
   DPR 3 on a phone). --the-bloom-c0 is unset (0s) in the gift's core and 1.7 s here,
   so a ring moved here at the cut continues exactly where it was.
   ═══════════════════════════════════════════ */

.the-bloom-container {
    /* the arcs' tumble: gravity, but letting go at once (the film's --ease-fall
       holds still for the first half of a 1 s drop, which reads as a freeze) */
    --the-bloom-ease-tumble: cubic-bezier(0.4, 0.05, 0.75, 0.6);
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;          /* the bloom ignores taps */
}

/* ───── The cream paper (this beat's own, over the bridge's #gof-ground) ───── */
.the-bloom-paper {
    position: absolute;
    inset: 0;
    background-color: var(--paper);
    /* a 2% tooth, a static tile rastered once */
    background-image:
        radial-gradient(circle, var(--paper-grain) 0.7px, rgba(255, 255, 255, 0) 1.2px),
        radial-gradient(circle, var(--paper-grain) 0.6px, rgba(255, 255, 255, 0) 1.1px);
    background-size: 7px 7px, 11px 13px;
    background-position: 0 0, 3px 5px;
}

/* ───── The field: the tunnel's vanishing point ───── */
.the-bloom-field {
    position: absolute;
    left: var(--bloom-cx);
    top: var(--bloom-cy);
    width: 0;
    height: 0;
    contain: layout style;
}

/* The ring and its arcs hold no pixels of their own. left/top 50% of a 0x0
   parent is the origin; in the gift's core it is that container's centre. */
.the-bloom-ring {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 0;
    height: 0;
    scale: 0.2;                    /* before blooming (opacity 0); the generated keyframes set the real scale */
    opacity: 0;
}
.the-bloom-seg {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    transform-origin: var(--the-bloom-ox, 0px) var(--the-bloom-oy, 0px);   /* the arc's own middle */
}

/* ───── The flowers: static transforms, authored at the ring's largest size (U) ───── */
.the-bloom-flower {
    position: absolute;
    display: block;
    max-width: none;
    max-height: none;
    left: calc(var(--the-bloom-x) * var(--bloom-u));
    top: calc(var(--the-bloom-y) * var(--bloom-u));
    width: calc(var(--the-bloom-d) * var(--bloom-u));
    height: calc(var(--the-bloom-d) * var(--bloom-u));
    margin: calc(var(--the-bloom-d) * var(--bloom-u) * -0.5) 0 0 calc(var(--the-bloom-d) * var(--bloom-u) * -0.5);
    transform: rotate(var(--the-bloom-a));
    user-select: none;
    -webkit-user-select: none;
    -webkit-user-drag: none;
}

/* Static filter, rastered once with the ring's layer; never animated, never on a wrapper. */
.the-bloom-is-white {
    filter: brightness(1.14);      /* the library's whites are drawn in greys */
}

/* ───── The tunnel: .the-bloom-is-blooming (the gift's core, or this container).
         animation-name and -duration come with the generated keyframes. ───── */
.the-bloom-is-blooming .the-bloom-ring {
    /* no will-change: the running animation composites the ring, and nothing
       holds its layer once it stops (iOS's compositing memory is the budget) */
    animation-timing-function: linear;
    animation-delay: calc(0s - var(--the-bloom-c0, 0s));
    animation-fill-mode: both;
}

/* ───── The white lift on swell's hit: 0 -> 0.55 in 0.18 s expo-out, then -> 0 over 1.0 s silk.
         Two nested opacities (outer rises, inner falls), so each segment keeps its own easing. ───── */
.the-bloom-flash {
    position: absolute;
    inset: 0;
    opacity: 0;
}
.the-bloom-flash-light {
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at var(--bloom-cx) var(--bloom-cy),
        var(--bloom-flash) 0%,
        rgba(255, 255, 255, 0.4) 42%,
        rgba(255, 255, 255, 0) 82%);
}
/* Neither fills once finished: both end together at 1.18 s and fall back to their
   base states (outer 0, inner 1: invisible), so no full-screen layer outlives the
   lift. The outer's rise is its first keyframe segment (expo-out), then it holds. */
.the-bloom-is-flash .the-bloom-flash {
    animation: the-bloom-flash-up 1.18s var(--ease-expo-out);
}
.the-bloom-is-flash .the-bloom-flash-light {
    animation: the-bloom-flash-down 1s var(--ease-silk) 0.18s;
}
@keyframes the-bloom-flash-up {
    0%      { opacity: 0; }
    15.254% { opacity: 0.55; }
    100%    { opacity: 0.55; }
}
@keyframes the-bloom-flash-down {
    from { opacity: 1; }
    to   { opacity: 0; }
}

/* ───── The fall: .the-bloom-is-falling (f 8.4). The tunnel freezes; every arc on
         screen drops and tumbles about its own middle on gravity's ease, nearer
         rings first and faster, all gone by f 9.7. Its drop, drift, tumble and
         timing (in the ring's own frame) are set by the module per viewport. ───── */
.the-bloom-is-falling .the-bloom-seg {
    animation: the-bloom-fall var(--the-bloom-fdur, 1s) var(--the-bloom-ease-tumble) var(--the-bloom-fdelay, 0s) both;
}
/* An arc wholly off screen at the fall is hidden instead (invisible, and it holds
   no layer), so nothing sweeps in from above. */
.the-bloom-is-falling .the-bloom-seg.the-bloom-is-far {
    visibility: hidden;
    animation: none;
}
@keyframes the-bloom-fall {
    from { translate: 0 0; rotate: 0deg; }
    to   { translate: var(--the-bloom-fx) var(--the-bloom-fy); rotate: var(--the-bloom-ftilt); }
}

/* the ground under the fall: cream -> blush over f 8.6-10.0 */
.the-bloom-is-falling .the-bloom-paper {
    animation: the-bloom-out 1.4s var(--ease-silk) 0.2s both;
}
@keyframes the-bloom-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}

/* ───── The exit (beat end): the ring DOM leaves the render tree, its layers released ───── */
.the-bloom-is-done .the-bloom-field,
.the-bloom-is-done .the-bloom-flash {
    display: none;
}

/* ───── Lite tier (2.5D path or deviceMemory < 3), chosen at begin / entry: the same
         13 rings and timeline, 19 flowers a ring (247) re-spaced evenly and
         grown 1.3x so each hoop stays closed. ───── */
.the-bloom-is-lite .the-bloom-is-litedrop {
    display: none;
}
.the-bloom-is-lite .the-bloom-flower {
    left: calc(var(--the-bloom-lx, var(--the-bloom-x)) * var(--bloom-u));
    top: calc(var(--the-bloom-ly, var(--the-bloom-y)) * var(--bloom-u));
    width: calc(var(--the-bloom-ld, var(--the-bloom-d)) * var(--bloom-u));
    height: calc(var(--the-bloom-ld, var(--the-bloom-d)) * var(--bloom-u));
    margin: calc(var(--the-bloom-ld, var(--the-bloom-d)) * var(--bloom-u) * -0.5) 0 0 calc(var(--the-bloom-ld, var(--the-bloom-d)) * var(--bloom-u) * -0.5);
}

/* ───── Pre-warm (armed gift, off the film clock): the rings drawn once,
         invisibly, wherever they live, so no image is first decoded on the tap.
         Ended by the prewarm animation's own end. ───── */
.the-bloom-is-prewarm:not(.the-bloom-is-blooming):not(.screen) .the-bloom-ring {
    scale: 1;
    animation: the-bloom-prewarm 0.12s linear both;
}
#screen-the-bloom.the-bloom-is-prewarm:not(.active) {
    display: flex;
    position: absolute;
    inset: 0;
    visibility: visible;
    opacity: 0.001;
    pointer-events: none;
    animation: the-bloom-prewarm 0.12s linear both;
}
#screen-the-bloom.the-bloom-is-prewarm:not(.active) .the-bloom-ring {
    opacity: 1;
    scale: 1;
}
@keyframes the-bloom-prewarm {
    from { opacity: 0.001; }
    to   { opacity: 0.001; }
}

/* ───── Reduced motion: plays in full, calmer. No streaming, spin or tumble:
         the tunnel as it stands at the full moment, static; its rings fade up in
         birth order (opacity only); the lift is an opacity breath; at the fall
         the field fades out over 1.2 s instead. Set by JS (film.reduced()) as
         .the-bloom-is-calm, and by the media query. ───── */
.the-bloom-is-calm .the-bloom-ring {
    scale: var(--the-bloom-cs);
    rotate: var(--the-bloom-cr);
}
.the-bloom-is-calm.the-bloom-is-blooming .the-bloom-ring {
    animation: the-bloom-calm-in 1.2s var(--ease-silk) calc(var(--the-bloom-cb) - var(--the-bloom-c0, 0s)) both;
}
.the-bloom-is-calm.the-bloom-is-falling .the-bloom-seg {
    animation: none;               /* static: the field fades instead */
}
.the-bloom-is-calm.the-bloom-is-falling .the-bloom-field {
    animation: the-bloom-out 1.2s var(--ease-silk) both;
}
@keyframes the-bloom-calm-in {
    from { opacity: 0; }
    to   { opacity: var(--the-bloom-cap); }
}

@media (prefers-reduced-motion: reduce) {
    .the-bloom-ring {
        scale: var(--the-bloom-cs);
        rotate: var(--the-bloom-cr);
    }
    .the-bloom-is-blooming .the-bloom-ring.the-bloom-ring {   /* doubled: outranks the generated animation-name */
        animation: the-bloom-calm-in 1.2s var(--ease-silk) calc(var(--the-bloom-cb) - var(--the-bloom-c0, 0s)) both;
    }
    .the-bloom-is-falling .the-bloom-seg,
    .the-bloom-is-falling .the-bloom-seg.the-bloom-is-far {
        animation: none;
    }
    .the-bloom-is-falling .the-bloom-field {
        animation: the-bloom-out 1.2s var(--ease-silk) both;
    }
}
