/* Occasion Beam invitation pre-roll (beam-view receiver, 2026-08).
   A short opening card shown once before the invite: category visual,
   "For <name>", the buyer's message, always-visible Skip. CSS-only art —
   no assets to load, nothing to spoil in a link preview.
   Reduced motion: every animation collapses to its final frame. */

.bv-occ {
    position: fixed;
    inset: 0;
    /* Above the card frame (30), BELOW the exit X (40): the accountless
       receiver must never be trapped, even for the 5s intro (edge-case
       hunt 2026-08-21). */
    z-index: 35;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Centered while it fits, scrollable when it does not: a 280-char
       message on a landscape phone must never push Skip off-screen. The
       spacer pseudos replace justify-content:center, which clips a
       flex column off BOTH ends when content overflows. */
    overflow-y: auto;
    gap: 16px;
    padding: 32px 24px;
    text-align: center;
    background: var(--color-bg, #1A1A1A);
    color: var(--color-text-primary, #FFFFFF);
    animation: bv-occ-in 0.4s ease-out;
}
.bv-occ::before,
.bv-occ::after {
    content: '';
    flex: 1 0 8px;
}
.bv-occ.leaving {
    opacity: 0;
    transition: opacity 0.25s ease-out;
}

.bv-occ-eyebrow {
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-secondary, #A0A0A0);
}

.bv-occ-for {
    font-size: 28px;
    font-weight: 700;
}

.bv-occ-msg {
    max-width: 420px;
    font-size: 16px;
    line-height: 1.5;
    color: var(--color-text-secondary, #A0A0A0);
    overflow-wrap: anywhere; /* unbroken 280-char strings stay in-viewport */
}
.bv-occ-for { overflow-wrap: anywhere; max-width: 100%; }

/* The copy reveals are gated on .open (the envelope, 2026-08-25): as
   mount-time animations they would fire invisibly inside the sealed card.
   Delays are relative to the moment the envelope opens. */
.bv-occ.open .bv-occ-for { animation: bv-occ-rise 0.7s ease-out 0.55s backwards; }
.bv-occ.open .bv-occ-msg { animation: bv-occ-rise 0.7s ease-out 0.85s backwards; }

/* Photo on the card (2026-09-05): replaces the category art when present.
   Intrinsic-ratio scaling, NO object-fit crop — an ultrasound must never
   lose content to a frame. Leads the reveal ladder (0.35s, then for, msg). */
.bv-occ-photo {
    max-width: 100%;
    max-height: 200px;   /* respects the 440px .bv-occ-scene card width */
    width: auto;
    height: auto;
    border-radius: 12px;
    flex-shrink: 0;
    margin-bottom: 8px;
}
.bv-occ.open .bv-occ-photo { animation: bv-occ-rise 0.7s ease-out 0.35s backwards; }

/* ── Reveal systems two + three (phase 3, 2026-09-06) ─────────────────────
   Three choreographies on ONE envelope frame, resolved client-side
   (revealSystem in beam-view.js; the rehearsal duplicates it):
   classic = no modifier (byte-identical to before), --story = photo leads,
   --surprise = the whole screen celebrates. Everything stays .open-gated. */

/* PHOTO-STORY: the photo IS the story — bigger stage, slower entrance,
   the copy waits its turn. beam-view stretches the auto-advance to 8s. */
.bv-occ--story .bv-occ-photo { max-height: 260px; }
@keyframes bv-occ-story-photo {
    from { opacity: 0; transform: scale(1.04); }
    to   { opacity: 1; transform: scale(1); }
}
.bv-occ--story.open .bv-occ-photo { animation: bv-occ-story-photo 1.1s ease-out 0.45s backwards; }
.bv-occ--story.open .bv-occ-for  { animation: bv-occ-rise 0.7s ease-out 1.7s backwards; }
.bv-occ--story.open .bv-occ-msg  { animation: bv-occ-rise 0.7s ease-out 2.5s backwards; }

/* SURPRISE: full-screen confetti on open. Pieces ride the landing page's
   brickfetti idiom — per-piece vectors as custom properties, one shared
   forwards keyframe, self-cleaning spans spawned by JS (never spawned
   under reduced motion). The card lands with a touch of overshoot. */
.bv-occ-fetti {
    position: fixed;
    z-index: 3; /* over the scene; pointer-events none keeps Skip clickable */
    width: 12px;
    height: 7px;
    border-radius: 2px;
    pointer-events: none;
    animation: bv-occ-fetti-fly 1.1s cubic-bezier(0.2, 0.6, 0.4, 1) forwards;
}
@keyframes bv-occ-fetti-fly {
    from { opacity: 1; transform: translate(0, 0) rotate(0deg); }
    to   { opacity: 0; transform: translate(var(--dx, 0px), var(--dy, -120px)) rotate(var(--rot, 240deg)); }
}
.bv-occ--surprise.open .bv-occ-card {
    transition: opacity 0.5s cubic-bezier(0.34, 1.4, 0.5, 1) 0.2s,
                transform 0.5s cubic-bezier(0.34, 1.4, 0.5, 1) 0.2s;
}
/* Same gate for the category art: its one-shot pseudos (footprint steps,
   confetti burst) must not play while the card is still sealed. Switching
   from `animation: none` back to the class rules on .open restarts them. */
.bv-occ:not(.open) .bv-occ-art::before,
.bv-occ:not(.open) .bv-occ-art::after { animation: none; }

/* ── The envelope (virtual card, 2026-08-25) ─────────────
   A sealed coral envelope the receiver taps open; the card rises out.
   The envelope face is GENERIC — the printed-card rule: nothing hints
   the occasion before it opens. Flap is the only 3D-transformed element,
   so `perspective` sits on the envelope itself (its pseudo is the child)
   and no preserve-3d is needed — the Two Doors idiom. */
.bv-occ-scene {
    position: relative;
    width: 100%;
    max-width: 440px;
    min-height: 190px;
    flex-shrink: 0;
    display: flex;
    justify-content: center;
}
.bv-occ-env {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 220px;
    height: 150px;
    margin: -75px 0 0 -110px;
    z-index: 2;
    background: var(--color-accent, #FF6B6B);
    border: none;
    border-radius: 10px;
    cursor: pointer;
    perspective: 600px;
    transition: opacity 0.4s ease 0.3s, transform 0.4s ease 0.3s;
}
.bv-occ-env::before {
    /* the flap */
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 78px;
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    background: var(--color-accent, #FF6B6B);
    filter: brightness(0.85);
    border-radius: 10px 10px 0 0;
    transform-origin: top center;
    transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.bv-occ-env::after {
    /* the seal */
    content: '';
    position: absolute;
    top: 66px;
    left: 50%;
    width: 20px;
    height: 20px;
    margin-left: -10px;
    border-radius: 50%;
    background: #FFFFFF;
    transition: opacity 0.15s ease;
}
.bv-occ-env:focus {
    /* the envelope is focused programmatically on mount — an offset ring
       reads as focus, while the default outline hugged the envelope edge
       and looked like a white border on it */
    outline: 2px solid rgba(255, 255, 255, 0.7);
    outline-offset: 6px;
}
.bv-occ.open .bv-occ-env {
    opacity: 0;
    transform: translateY(30px);
    pointer-events: none;
}
.bv-occ.open .bv-occ-env::before { transform: rotateX(-160deg); }
.bv-occ.open .bv-occ-env::after { opacity: 0; }

.bv-occ-card {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 28px 24px;
    background: var(--color-surface, #252525);
    border: 1px solid var(--color-border, #333333);
    border-radius: 16px;
    opacity: 0;
    transform: translateY(46px) scale(0.92);
    transition: opacity 0.6s cubic-bezier(0.65, 0, 0.35, 1) 0.25s,
                transform 0.6s cubic-bezier(0.65, 0, 0.35, 1) 0.25s;
}
.bv-occ.open .bv-occ-card {
    opacity: 1;
    transform: none;
}

.bv-occ-hint {
    font-size: 14px;
    color: var(--color-text-secondary, #A0A0A0);
    animation: bv-occ-hint-pulse 1.8s ease-in-out infinite;
    transition: opacity 0.2s ease;
}
.bv-occ.open .bv-occ-hint { opacity: 0; animation: none; }

.bv-occ-skip {
    margin-top: 24px;
    padding: 10px 24px;
    font-size: 14px;
    color: var(--color-text-secondary, #A0A0A0);
    background: transparent;
    border: 1px solid var(--color-border, #333333);
    border-radius: 12px;
    cursor: pointer;
}
.bv-occ-skip:hover {
    color: var(--color-text-primary, #FFFFFF);
    border-color: var(--color-text-secondary, #A0A0A0);
}

/* --- Category art (CSS-only) --- */
.bv-occ-art {
    position: relative;
    width: 120px;
    height: 120px;
    flex-shrink: 0; /* the absolute-positioned footprints do not squash */
    margin-bottom: 8px;
}

/* Generic: a soft coral pulse ring around a heart-ish dot */
.bv-occ-art.occ-generic::before {
    content: '';
    position: absolute;
    inset: 40px;
    border-radius: 50%;
    background: var(--color-accent, #FF6B6B);
    animation: bv-occ-pulse 1.6s ease-in-out infinite;
}
.bv-occ-art.occ-generic::after {
    content: '';
    position: absolute;
    inset: 24px;
    border-radius: 50%;
    border: 2px solid var(--color-accent, #FF6B6B);
    opacity: 0.35;
    animation: bv-occ-ring 1.6s ease-out infinite;
}

/* Pregnancy: two tiny footprints stepping in, one after the other */
.bv-occ-art.occ-pregnancy::before,
.bv-occ-art.occ-pregnancy::after {
    content: '';
    position: absolute;
    width: 26px;
    height: 40px;
    border-radius: 50% 50% 46% 46%;
    background: var(--color-accent, #FF6B6B);
    /* five little toes */
    box-shadow:
        -10px -22px 0 -8px var(--color-accent, #FF6B6B),
        -3px -26px 0 -8px var(--color-accent, #FF6B6B),
        4px -26px 0 -8.5px var(--color-accent, #FF6B6B),
        10px -24px 0 -9px var(--color-accent, #FF6B6B),
        15px -20px 0 -9.5px var(--color-accent, #FF6B6B);
}
.bv-occ-art.occ-pregnancy::before {
    left: 22px;
    top: 34px;
    transform: rotate(-12deg);
    animation: bv-occ-step 0.9s ease-out 0.2s backwards;
}
.bv-occ-art.occ-pregnancy::after {
    right: 22px;
    top: 52px;
    transform: rotate(10deg);
    animation: bv-occ-step 0.9s ease-out 0.9s backwards;
}

/* Birthday: a balloon rising on its string */
.bv-occ-art.occ-birthday::before {
    content: '';
    position: absolute;
    width: 44px;
    height: 54px;
    left: calc(50% - 22px);
    top: 18px;
    background: var(--color-accent, #FF6B6B);
    border-radius: 50% 50% 50% 50% / 55% 55% 45% 45%;
    animation: bv-occ-float 2.4s ease-in-out infinite;
}
.bv-occ-art.occ-birthday::after {
    content: '';
    position: absolute;
    width: 2px;
    height: 26px;
    left: calc(50% - 1px);
    top: 72px;
    background: var(--color-accent, #FF6B6B);
    opacity: 0.5;
    border-radius: 2px;
    animation: bv-occ-float 2.4s ease-in-out infinite;
}

/* Congratulations: a confetti burst popping out */
.bv-occ-art.occ-congrats::before {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    left: calc(50% - 8px);
    top: 52px;
    border-radius: 50%;
    background: var(--color-accent, #FF6B6B);
}
.bv-occ-art.occ-congrats::after {
    content: '';
    position: absolute;
    width: 9px;
    height: 9px;
    left: calc(50% - 4.5px);
    top: 55px;
    border-radius: 50%;
    box-shadow:
        -34px -22px 0 var(--color-accent, #FF6B6B),
        28px -28px 0 -1px var(--color-accent, #FF6B6B),
        40px 10px 0 -3px var(--color-accent, #FF6B6B),
        -40px 12px 0 -3px var(--color-accent, #FF6B6B),
        -12px -38px 0 -3px var(--color-accent, #FF6B6B),
        12px 34px 0 -3px var(--color-accent, #FF6B6B),
        36px -6px 0 -4px var(--color-accent, #FF6B6B),
        -28px 30px 0 -4px var(--color-accent, #FF6B6B);
    animation: bv-occ-burst 1.2s ease-out 0.2s backwards;
}

/* Anniversary: two rings finding their overlap */
.bv-occ-art.occ-anniversary::before,
.bv-occ-art.occ-anniversary::after {
    content: '';
    position: absolute;
    width: 46px;
    height: 46px;
    top: 37px;
    border: 4px solid var(--color-accent, #FF6B6B);
    border-radius: 50%;
}
.bv-occ-art.occ-anniversary::before {
    left: calc(50% - 42px);
    animation: bv-occ-step 0.9s ease-out 0.2s backwards;
}
.bv-occ-art.occ-anniversary::after {
    left: calc(50% - 8px);
    opacity: 0.55;
    animation: bv-occ-step 0.9s ease-out 0.9s backwards;
}

/* Coming home: an arched doorway, door swinging open */
.bv-occ-art.occ-cominghome::before {
    content: '';
    position: absolute;
    width: 52px;
    height: 74px;
    left: calc(50% - 26px);
    top: 20px;
    border: 4px solid var(--color-accent, #FF6B6B);
    border-bottom: none;
    border-radius: 26px 26px 0 0;
}
.bv-occ-art.occ-cominghome::after {
    content: '';
    position: absolute;
    width: 22px;
    height: 62px;
    left: calc(50% - 17px);
    top: 32px;
    background: var(--color-accent, #FF6B6B);
    opacity: 0.55;
    border-radius: 11px 4px 0 0;
    transform: skewY(-6deg);
    transform-origin: bottom left;
    animation: bv-occ-step 0.9s ease-out 0.5s backwards;
}

@keyframes bv-occ-in {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes bv-occ-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}
@keyframes bv-occ-hint-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}
@keyframes bv-occ-burst {
    from { transform: scale(0.4); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}
@keyframes bv-occ-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes bv-occ-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.12); }
}
@keyframes bv-occ-ring {
    from { transform: scale(0.9); opacity: 0.35; }
    to { transform: scale(1.35); opacity: 0; }
}
@keyframes bv-occ-step {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ── Rehearsal (sender-side, create page): the same overlay hands its stage
      to the buyer's own video after the open ─────────────── */
.bv-occ-rehearse-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000000;
}
.bv-occ.rehearsing .bv-occ-scene,
.bv-occ.rehearsing .bv-occ-eyebrow,
.bv-occ.rehearsing .bv-occ-hint { display: none; }
.bv-occ.rehearsing .bv-occ-skip {
    position: absolute;
    left: 50%;
    bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 2;
    margin: 0;
    background: rgba(0, 0, 0, 0.55);
}
.bv-occ-endcard {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px;
    text-align: center;
    background: rgba(0, 0, 0, 0.78);
}

/* ── Sealed reveal (receiver, pre-date): generic envelope + countdown.
      NO occasion art here — art on a sealed envelope is the spoiler. ── */
.bv-occ-sealed-line {
    font-size: 20px;
    font-weight: 700;
    overflow-wrap: anywhere;
    max-width: 100%;
}
.bv-occ-count {
    font-size: 15px;
    color: var(--color-text-secondary, #A0A0A0);
    font-variant-numeric: tabular-nums;
}
.bv-occ-env.wiggle {
    animation: bv-occ-wiggle 0.5s ease-in-out;
}
@keyframes bv-occ-wiggle {
    0%, 100% { transform: rotate(0deg); }
    25% { transform: rotate(-3deg); }
    50% { transform: rotate(2.5deg); }
    75% { transform: rotate(-1.5deg); }
}

/* Reduced motion: the card is the message; the motion is decoration.
   beam-view.js also mounts the overlay already-.open here, so the sealed
   envelope is never a wait. Transitions are NOT covered by animation:none —
   collapse them explicitly (the Two Doors idiom).
   SPECIFICITY RULE (phase 3 fix): a media query adds NO specificity of its
   own, so every entry here must MATCH the animating selector's specificity
   or it silently loses — the bare `.bv-occ-for` entries were losing to
   `.bv-occ.open .bv-occ-for` and the rise ladder played under reduced
   motion. The `.open`-qualified twins below are the fix. */
@media (prefers-reduced-motion: reduce) {
    /* .bv-occ-photo joins the animation list only — it declares no
       transition, so the transition-collapse list below gains no entry.
       .bv-occ-fetti is belt-and-braces: JS never spawns pieces under
       reduced motion in the first place. */
    .bv-occ,
    .bv-occ-for,
    .bv-occ-msg,
    .bv-occ-photo,
    .bv-occ.open .bv-occ-for,
    .bv-occ.open .bv-occ-msg,
    .bv-occ.open .bv-occ-photo,
    .bv-occ--story.open .bv-occ-photo,
    .bv-occ--story.open .bv-occ-for,
    .bv-occ--story.open .bv-occ-msg,
    .bv-occ-fetti,
    .bv-occ-hint,
    .bv-occ-art.occ-generic::before,
    .bv-occ-art.occ-generic::after,
    .bv-occ-art.occ-pregnancy::before,
    .bv-occ-art.occ-pregnancy::after,
    .bv-occ-art.occ-birthday::before,
    .bv-occ-art.occ-birthday::after,
    .bv-occ-art.occ-congrats::after,
    .bv-occ-art.occ-anniversary::before,
    .bv-occ-art.occ-anniversary::after,
    .bv-occ-art.occ-cominghome::after,
    .bv-occ-env.wiggle {
        animation: none;
    }
    .bv-occ-env,
    .bv-occ-env::before,
    .bv-occ-env::after,
    .bv-occ-card,
    .bv-occ--surprise.open .bv-occ-card,
    .bv-occ-hint {
        transition-duration: 0.01s;
        transition-delay: 0s;
    }
}
