/* ═══════════════════════════════════════════
   gift-of-flowers — beat 4: the-polaroids
   7.8 s · verb swipe · hold `onward` at 5.8 s (one step)

   Their photographs arrive as white polaroids sliding in from the left in
   two tilted rows, float, and lift off the top on a swipe up (or "Or tap to
   go on"), leaving the wash and the top edge of the next beat's note card.

   TRANSPARENT over the bridge-owned #gof-ground (wash, mottling, bubbles):
   this section paints no ground and no bubbles of its own.

   State classes, all on .the-polaroids-container (toggled by the cues and
   the handler; boot never recreates the container, so a keystroke
   re-render keeps whatever the film has revealed):
     --pair / --belts  layout by photo count (boot): N 3-4 / N 5-10
     --in              0 s    the slide-in (per-photo transition delays)
     --floating        4.4 s  each photo breathes on its own phase
     --nudge           4.6 s  the belts nudge left and back (N >= 5)
     --asking          4.8 s  "swipe up", its chevron, "Or tap to go on"
     --dragging        a vertical drag is following the thumb
     --leaving         the payoff: rows lift, the card's edge peeks
     --gone            the payoff has ended (rows hidden, loops parked)
     --instant         prepare(): the entry state, applied with no motion

   Per photo, set inline by the module: --the-polaroids-i (index in its
   row), -delay (entrance), -tilt, -dy (seeded stagger), -lift (exit
   stagger), -phase, -fx, -fy (the float). Per track: -k (its count).
   Only transform, translate and opacity move; the polaroid shadow is static.
   ═══════════════════════════════════════════ */

.the-polaroids-container {
    position: absolute;
    inset: 0;
    overflow: hidden;
    font-family: var(--font-body);
    color: var(--wine);
    -webkit-user-select: none;
    user-select: none;
}

.the-polaroids-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ───── The swipe surface ───── */
.the-polaroids-stage {
    position: absolute;
    inset: 0;
    z-index: 1;
    touch-action: none;              /* a vertical drag is the beat's; nothing here scrolls the page */
}

/* Follows the thumb (--the-polaroids-pull, written per pointermove), springs back on expo-out. */
.the-polaroids-drag {
    position: absolute;
    inset: 0;
    transform: translate3d(0, var(--the-polaroids-pull, 0px), 0);
    transition: transform 0.5s var(--ease-expo-out);
}
.the-polaroids-container.the-polaroids--dragging .the-polaroids-drag { transition: none; }

/* ───── The rows: centred in the band between the mute pill and the ask ─────
   Top: clear of the stage's mute pill (bridge chrome, top-right: 14 px +
   safe area, 44 px tall), plus 10 px of air. Bottom: clear of the ask,
   which keeps its place above the bottom quarter (and so above the badge
   corner).
   The band is a size container, so a polaroid's width answers both the
   screen's width (40 / 34 of it, per shots.md) and its height. Everything a
   polaroid draws outside its own box (the +-6 deg tilt, about 0.06 W top
   and bottom; the +-1.2 vh stagger and the +-0.6 vh float) is reserved
   inside the band, so the rotated corners never leave it:
     per row 1.15 W + 2 * (0.06 W + 1.8 vh)  ->  W <= (band - 7.2 vh - gap) / 2.54
   The shadow (8 px down, 18 px blur) gets 22 px more below each row, given
   back by a negative margin: it may overlap the next row, it never costs
   the band height, and the belt (a scroller, so it clips) no longer cuts it. */
.the-polaroids-rows {
    position: absolute;
    left: 0;
    right: 0;
    top: max(4%, calc(68px + env(safe-area-inset-top, 0px)));
    bottom: calc(25% + 6rem);
    display: flex;
    flex-direction: column;
    justify-content: center;
    container-type: size;
}

.the-polaroids-row {
    flex: none;
    margin-bottom: -22px;            /* the shadow room below, given back */
    /* N = 3-4: 40 vw, centred, no belt (fallback sizing without container units) */
    --the-polaroids-w: min(40vw, calc((75vh - 6rem - 68px - 8.4vh) / 2.54));
    --the-polaroids-gap: 6vw;
    --the-polaroids-edge: 7vw;
    --the-polaroids-view: 100vw;
    --the-polaroids-pt: calc(0.06 * var(--the-polaroids-w) + 1.8vh);
    --the-polaroids-pb: calc(0.06 * var(--the-polaroids-w) + 1.8vh + 22px);
}
.the-polaroids-row + .the-polaroids-row { margin-top: 1.2vh; }
.the-polaroids-container.the-polaroids--belts .the-polaroids-row {
    /* N = 5-10: 34 vw belts */
    --the-polaroids-w: min(34vw, calc((75vh - 6rem - 68px - 8.4vh) / 2.54));
    --the-polaroids-gap: 4vw;
}
@supports (width: 1cqw) {
    .the-polaroids-row {
        --the-polaroids-w: min(40cqw, calc((100cqh - 8.4vh) / 2.54));
        --the-polaroids-gap: 6cqw;
        --the-polaroids-edge: 7cqw;
        --the-polaroids-view: 100cqw;
    }
    .the-polaroids-container.the-polaroids--belts .the-polaroids-row {
        --the-polaroids-w: min(34cqw, calc((100cqh - 8.4vh) / 2.54));
        --the-polaroids-gap: 4cqw;
    }
}

/* Row 2 sits half a polaroid to the right of row 1 on the belts (stitched, not stacked). */
.the-polaroids-row-1 { --the-polaroids-off: 0px; }
.the-polaroids-row-2 { --the-polaroids-off: 0px; }
.the-polaroids-container.the-polaroids--belts .the-polaroids-row-2 { --the-polaroids-off: calc(var(--the-polaroids-w) / 2); }

.the-polaroids-belt {
    overflow: visible;
    touch-action: none;
}
.the-polaroids-container.the-polaroids--belts .the-polaroids-belt {
    overflow-x: auto;
    overflow-y: hidden;
    touch-action: pan-x;             /* a sideways drag is the belt's; a vertical one is the swipe */
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}
.the-polaroids-container.the-polaroids--belts .the-polaroids-belt::-webkit-scrollbar { display: none; }
.the-polaroids-belt:focus-visible {
    outline: 2px solid var(--wine);
    outline-offset: -4px;
}

.the-polaroids-track {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    gap: var(--the-polaroids-gap);
    padding: var(--the-polaroids-pt) 0 var(--the-polaroids-pb);
}
.the-polaroids-container.the-polaroids--belts .the-polaroids-track {
    justify-content: flex-start;
    width: max-content;
    margin-inline: auto;             /* centred when the whole row fits (a wide preview); 0 when it overflows */
    padding-left: calc(var(--the-polaroids-edge) + var(--the-polaroids-off));
    padding-right: var(--the-polaroids-edge);
    /* How far the row really overflows, capped at the 28 vw nudge (0 when it fits). */
    --the-polaroids-nudge: clamp(0px,
        calc(2 * var(--the-polaroids-edge) + var(--the-polaroids-off)
            + var(--the-polaroids-k, 1) * var(--the-polaroids-w)
            + (var(--the-polaroids-k, 1) - 1) * var(--the-polaroids-gap)
            - var(--the-polaroids-view)),
        28vw);
}

/* ───── A polaroid ─────
   The slot carries the slide-in (transform) and the exit lift (translate);
   the float is one level in; the frame is static paper. */
.the-polaroids-slot {
    position: relative;
    flex: none;
    width: var(--the-polaroids-w);
    --the-polaroids-from: -130vw;
    transform: translate3d(var(--the-polaroids-from), var(--the-polaroids-dy, 0vh), 0) rotate(-18deg);
    transition:
        transform 1s var(--ease-expo-out) var(--the-polaroids-delay, 0s),
        translate 1.6s var(--ease-stage) var(--the-polaroids-lift, 0s),
        opacity 0.6s var(--ease-silk) var(--the-polaroids-lift, 0s);
}
/* On a belt the far photos start off the left edge too (each enters from the same place). */
.the-polaroids-container.the-polaroids--belts .the-polaroids-slot {
    --the-polaroids-from: calc(-130vw - var(--the-polaroids-off)
        - var(--the-polaroids-i, 0) * (var(--the-polaroids-w) + var(--the-polaroids-gap)));
}
.the-polaroids-container.the-polaroids--in .the-polaroids-slot {
    transform: translate3d(0, var(--the-polaroids-dy, 0vh), 0) rotate(var(--the-polaroids-tilt, 0deg));
}

.the-polaroids-float { display: block; }

.the-polaroids-frame {
    display: block;
    padding: 5% 5% 20%;              /* % of the polaroid's width: thin sides and top, the thick blank chin */
    background: var(--polaroid-frame);
    border-radius: 2px;
    box-shadow: var(--polaroid-shadow);
}
.the-polaroids-window {
    display: block;
    position: relative;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background: var(--wash-b);       /* under a photo still decoding */
}
.the-polaroids-window::after {      /* the faint print edge */
    content: '';
    position: absolute;
    inset: 0;
    box-shadow: inset 0 0 0 1px rgba(79, 34, 44, 0.07);
    pointer-events: none;
}
.the-polaroids-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 35%;        /* faces survive the 1:1 crop */
    pointer-events: none;
    -webkit-user-drag: none;
}

/* 4.4 s: the photos float, each on its own breath (starting from rest, so nothing jumps). */
.the-polaroids-container.the-polaroids--floating .the-polaroids-float {
    animation: the-polaroids-float 5s var(--ease-breath) var(--the-polaroids-phase, 0s) infinite;
}
@keyframes the-polaroids-float {
    0%, 100% { transform: translate3d(0, 0, 0); }
    25% { transform: translate3d(calc(1.2vw * var(--the-polaroids-fx, 1)), calc(-0.6vh * var(--the-polaroids-fy, 1)), 0); }
    75% { transform: translate3d(calc(-1.2vw * var(--the-polaroids-fx, 1)), calc(0.6vh * var(--the-polaroids-fy, 1)), 0); }
}

/* 4.6 s: the belts nudge left and back, to say "this moves" (row 2 a beat behind). */
.the-polaroids-container.the-polaroids--belts.the-polaroids--nudge .the-polaroids-track {
    animation: the-polaroids-nudge 1.2s var(--ease-drift) both;
}
.the-polaroids-container.the-polaroids--belts.the-polaroids--nudge .the-polaroids-row-2 .the-polaroids-track {
    animation-delay: 0.1s;
}
@keyframes the-polaroids-nudge {
    0%, 100% { transform: translate3d(0, 0, 0); }
    50% { transform: translate3d(calc(-1 * var(--the-polaroids-nudge, 0px)), 0, 0); }
}

/* ───── The payoff: the rows lift off the top ─────
   Row 2 0.15 s after row 1, each polaroid 0.04 s after the last (--the-polaroids-lift).
   A belt stops being a scroller so nothing is clipped on the way up; the
   module pins its scroll position into --the-polaroids-scroll first, so
   nothing jumps when it does. */
.the-polaroids-container.the-polaroids--leaving .the-polaroids-belt { overflow: visible; }
.the-polaroids-container.the-polaroids--leaving .the-polaroids-track {
    translate: var(--the-polaroids-scroll, 0px) 0;
}
.the-polaroids-container.the-polaroids--leaving .the-polaroids-slot {
    translate: 0 -115vh;
}
.the-polaroids-container.the-polaroids--gone .the-polaroids-rows { visibility: hidden; }
.the-polaroids-container.the-polaroids--gone .the-polaroids-float,
.the-polaroids-container.the-polaroids--gone .the-polaroids-track { animation: none; }

/* The next beat's note card: its top edge peeks (translateY 100% -> 92%). */
.the-polaroids-card {
    position: absolute;
    left: 6%;
    right: 6%;
    bottom: 0;
    height: 60%;
    z-index: 0;
    background: var(--note-paper);
    border-radius: 3px;
    box-shadow: var(--note-shadow);
    pointer-events: none;
    opacity: 0;
    transform: translate3d(0, 100%, 0);
    transition:
        transform 1.2s var(--ease-expo-out) 0.4s,
        opacity 0.3s var(--ease-silk) 0.4s;
}
.the-polaroids-container.the-polaroids--leaving .the-polaroids-card {
    opacity: 1;
    transform: translate3d(0, 92%, 0);
}

/* ───── The ask (4.8 s): above the bottom quarter, in wine on the wash ───── */
.the-polaroids-ask {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 25%;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    pointer-events: none;            /* a swipe that starts on the hint still reaches the surface */
    opacity: 0;
    visibility: hidden;
    transform: translate3d(0, 6px, 0);
    transition:
        opacity 0.7s var(--ease-silk),
        transform 0.7s var(--ease-expo-out),
        visibility 0s linear 0.7s;
}
.the-polaroids-container.the-polaroids--asking .the-polaroids-ask {
    opacity: 1;
    visibility: visible;
    transform: translate3d(0, 0, 0);
    transition:
        opacity 0.7s var(--ease-silk),
        transform 0.7s var(--ease-expo-out),
        visibility 0s linear 0s;
}
.the-polaroids-container.the-polaroids--leaving .the-polaroids-ask {
    opacity: 0;
    visibility: hidden;
    transition:
        opacity 0.35s var(--ease-silk),
        visibility 0s linear 0.35s;
}

.the-polaroids-hint {
    margin: 0;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: var(--type-hint);
    line-height: 1.4;
    letter-spacing: 0.14em;
    text-transform: lowercase;
    color: var(--wine);
}

/* A small chevron pointing up, breathing under the hint. */
.the-polaroids-chev {
    display: block;
    width: 9px;
    height: 9px;
    margin-top: 2px;
    border-left: 1.5px solid var(--wine);
    border-top: 1.5px solid var(--wine);
    transform: translate3d(0, 0, 0) rotate(45deg);
    opacity: 0.85;
}
.the-polaroids-container.the-polaroids--asking .the-polaroids-chev {
    animation: the-polaroids-chev 2.4s var(--ease-breath) infinite;
}
.the-polaroids-container.the-polaroids--leaving .the-polaroids-chev { animation: none; }
@keyframes the-polaroids-chev {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(45deg); opacity: 0.55; }
    50% { transform: translate3d(0, -4px, 0) rotate(45deg); opacity: 1; }
}

/* "Or tap to go on": a 44 px ghost pill in the glass. */
.the-polaroids-btn {
    pointer-events: auto;
    margin-top: 0.2rem;
    min-height: 44px;
    padding: 0 1.5rem;
    border: 1px solid var(--glass-border);
    border-radius: 999px;
    background: var(--glass);
    color: var(--wine);
    font-family: var(--font-body);
    font-weight: 400;
    font-size: var(--type-hint);
    line-height: 1;
    letter-spacing: 0.14em;
    text-transform: lowercase;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: border-color 0.3s var(--ease-silk), transform 0.15s var(--ease-snap);
}
.the-polaroids-btn:hover { border-color: var(--glass-border-hover); }
.the-polaroids-btn:active { transform: scale(0.97); }
.the-polaroids-btn:focus-visible {
    outline: 2px solid var(--wine);
    outline-offset: 3px;
}
.the-polaroids-btn:disabled { cursor: default; }

/* ───── Entry states are applied instantly (prepare / goto), never animated in ───── */
.the-polaroids-container.the-polaroids--instant,
.the-polaroids-container.the-polaroids--instant * {
    transition: none !important;
    animation: none !important;
}

/* ───── Reduced motion: plays in full, calmer ─────
   Photos fade in and rise 12 px on the same stagger (no slide, no spin);
   they do not float; the belts do not nudge; the exit is a cross-fade to
   the card instead of a lift. */
@media (prefers-reduced-motion: reduce) {
    .the-polaroids-slot,
    .the-polaroids-container.the-polaroids--belts .the-polaroids-slot {
        opacity: 0;
        transform: translate3d(0, calc(var(--the-polaroids-dy, 0vh) + 12px), 0) rotate(var(--the-polaroids-tilt, 0deg));
        transition:
            transform 0.6s var(--ease-silk) var(--the-polaroids-delay, 0s),
            opacity 0.6s var(--ease-silk) var(--the-polaroids-delay, 0s);
    }
    .the-polaroids-container.the-polaroids--in .the-polaroids-slot {
        opacity: 1;
        transform: translate3d(0, var(--the-polaroids-dy, 0vh), 0) rotate(var(--the-polaroids-tilt, 0deg));
    }
    .the-polaroids-container.the-polaroids--leaving .the-polaroids-slot {
        translate: none;
        opacity: 0;
        transition: opacity 0.8s var(--ease-silk) 0s;
    }
    .the-polaroids-container.the-polaroids--floating .the-polaroids-float,
    .the-polaroids-container.the-polaroids--belts.the-polaroids--nudge .the-polaroids-track,
    .the-polaroids-container.the-polaroids--asking .the-polaroids-chev {
        animation: none;
    }
    .the-polaroids-card {
        transform: translate3d(0, 92%, 0);
        transition: opacity 0.9s var(--ease-silk) 0.4s;
    }
    .the-polaroids-ask { transform: none; }
    .the-polaroids-container.the-polaroids--asking .the-polaroids-ask { transform: none; }
}
