/* ============================================================
   Ported from the Seven on Seven site (Shelby's system) for Attraction Lab, 2026-09-30.
   Only change: the ground is white instead of paper.
   SHARED FADE-DECK ENGINE  (css/deck.css)

   PROGRESSIVE ENHANCEMENT — READ THIS FIRST.
   The BASE state in this file is a plain, readable, natively
   scrolling stack: every slide is an in-flow section — position
   static, fully visible, in slide order, top to bottom. That is
   what renders with NO JavaScript, with FAILED JavaScript, on a
   browser that chokes on the deck, and under prefers-reduced-motion.

   EVERY deck behaviour — the fixed stage, absolutely stacked
   slides, opacity management, the scroll driver, the cue — lives
   behind `html.deck-active`, a class that ONLY js/deck.js adds,
   and only after it has initialised without throwing (it removes
   the class again if it throws). NEVER move a deck rule out from
   under .deck-active: unscoped, the slides all stack on top of one
   another and the page renders as an unreadable pile.

   LEGACY FLOOR: iOS Safari 13. No `inset` shorthand (unsupported
   until iOS 14.5 — its absence is what turned the deck into soup
   on older phones); offsets are always written longhand.

   LOCKED uniform fade envelope (production standard, do not alter
   without an explicit instruction quoting this rule):
     outgoing slide  -> opacity 0 over 0.3s
     incoming slide  -> after 0.15s delay, opacity 1 over 0.7s
   Content slides fade as one unit. Moment (brand interlude) slides
   share the identical envelope, plus their own internal staged
   choreography that triggers on activation and runs on fixed clocks.
   ============================================================ */
:root{--deck-ink:#0c0a07;--deck-bone:#fff}

/* ============================================================
   1. BASE STATE — no JS, failed JS, reduced motion.
   A normal document: stacked sections, native scrolling.
   ============================================================ */

/* the scroll driver only means anything to the engine */
.deck-driver{display:none}

/* the stage is just a wrapper here; relative so its own grain/::after
   overlays stay bound to it instead of escaping to the viewport */
.deck-stage{position:relative;overflow:visible;background:var(--paper,#fff)}

/* a slide: an ordinary in-flow section, visible and interactive */
.deck-slide{position:static;opacity:1;pointer-events:auto;overflow:visible;
  display:flex;flex-direction:column;justify-content:center}

/* slide interior — comfortable margins, free to be as tall as it needs */
.deck-slide-inner{width:100%;max-width:1180px;margin:0 auto;
  padding:60px 6vw;padding:clamp(50px,8vh,90px) 6vw}

/* moment slides are full-bleed (their own art fills the stage) */
.deck-slide.moment,.deck-slide.moment .deck-slide-inner{padding:0;max-width:none;margin:0}

/* the cue is wayfinding for a driven deck; a scrolling page doesn't need it */
.deck-cue{display:none}
.deck-chrome.hide{opacity:1;pointer-events:auto}

/* MOMENTS IN THE READABLE STACK.
   A moment's art is a 100vh stage of absolutely positioned layers whose
   choreography only plays on activation — dumped in-flow it is a pile of
   overlapping fragments, most of them still at opacity 0. So in the
   fallback each moment collapses to what it actually says: a simple
   full-width section carrying its numbered caption plate. */
/* height:auto also undoes the legacy `.interlude{height:260vh}` from the old
   scroll-driven build, which would otherwise leave eight empty screens-worth
   of white between the readable sections */
html:not(.deck-active) .deck-slide.moment{display:block;height:auto;min-height:0;
  background:var(--paper,#fff)}
html:not(.deck-active) .deck-slide.moment > *{position:static;display:block;
  width:auto;height:auto;min-height:0;overflow:visible;text-align:left;
  background:var(--paper,#fff);padding:40px 6vw;padding:clamp(34px,6vh,58px) 6vw;
  border-top:1px solid rgba(12,10,7,.14)}
html:not(.deck-active) .deck-slide.moment > * > *{display:none}
html:not(.deck-active) .deck-slide.moment .plate{position:static;display:inline-block;
  left:auto;right:auto;top:auto;bottom:auto;margin:0;
  border:1px solid var(--deck-ink);background:#fff;color:var(--deck-ink);opacity:1}
html:not(.deck-active) .deck-slide.moment *{animation:none!important}

/* ============================================================
   2. DECK STATE — js/deck.js initialised cleanly. Fixed stage,
   cross-fading slides, scroll selects the active index.
   ============================================================ */

/* driver gives the page its scroll height; JS sets it to N * 100vh */
.deck-active .deck-driver{display:block;position:absolute;top:0;left:0;
  width:1px;height:100vh;pointer-events:none;opacity:0}

/* the one fixed stage every slide lives inside — white ground (Attraction Lab: white by design) */
.deck-active .deck-stage{position:fixed;top:0;right:0;bottom:0;left:0;
  overflow:hidden;background:var(--paper,#fff);z-index:1}

/* a slide: absolutely stacked, invisible until active */
.deck-active .deck-slide{position:absolute;top:0;right:0;bottom:0;left:0;
  opacity:0;pointer-events:none;overflow:hidden;
  transition:opacity .3s ease}                 /* OUTGOING: 0.3s */
.deck-active .deck-slide.on{opacity:1;pointer-events:auto;
  transition:opacity .7s ease .15s}            /* INCOMING: 0.15s delay + 0.7s */
/* CRITICAL: descendants of an INACTIVE slide (draggable polaroids, stickers, links) explicitly
   re-enable pointer-events, so — since every slide is stacked at all four edges — the LATER
   moments' invisible polaroids sat on top of the active moment and swallowed every drag.
   Hard-disable all pointer interaction inside any slide that isn't currently on. (Deck state
   only: in the readable stack every slide is live and its links must work.) */
.deck-active .deck-slide:not(.on) *{pointer-events:none!important}

/* content slide interior — one screen, comfortable margins, never scrolls */
.deck-active .deck-slide-inner{padding:80px 6vw 70px;padding:clamp(70px,10vh,120px) 6vw clamp(60px,8vh,100px);
  max-height:100vh;display:flex;flex-direction:column;justify-content:center}

/* chrome (header): stays visible through transitions; only hides once a
   moment slide's backdrop is actually up (0.15s delay + short fade),
   and returns immediately when leaving a moment */
.deck-active .deck-chrome{transition:opacity .3s ease}
.deck-active .deck-chrome.hide{opacity:0;pointer-events:none;transition:opacity .3s ease .15s}

/* scroll cue — wayfinding, not decoration: a hairline over the word SCROLL,
   breathing opacity only. Ink on light slides, bone on dark/moment. */
.deck-active .deck-cue{display:flex;position:absolute;left:50%;bottom:28px;
  transform:translateX(-50%);z-index:60;
  flex-direction:column;align-items:center;gap:8px;color:var(--deck-ink);
  opacity:0;pointer-events:none;transition:opacity .15s ease}
.deck-active .deck-cue.dark{color:var(--deck-bone)}
.deck-active .deck-cue.show{opacity:1;transition:opacity .8s ease;animation:deckcue 2.5s ease-in-out infinite}
.deck-cue .cue-line{width:1px;height:24px;background:currentColor}
.deck-cue .cue-word{font-family:"Hanken Grotesk",sans-serif;font-size:9px;font-weight:700;
  letter-spacing:.24em;text-transform:uppercase}
@keyframes deckcue{0%,100%{opacity:.45}50%{opacity:.9}}

/* ============================================================
   3. REDUCED MOTION — the SAME readable stack, never absolutely
   positioned slides shown together. deck.js already declines to
   activate under this preference; this block is the belt-and-braces
   so the stack stands even if .deck-active is somehow present.
   ============================================================ */
@media(prefers-reduced-motion:reduce){
  html.deck-active .deck-driver{display:none}
  html.deck-active .deck-stage{position:relative;top:auto;right:auto;bottom:auto;left:auto;
    height:auto;overflow:visible}
  html.deck-active .deck-slide{position:static;top:auto;right:auto;bottom:auto;left:auto;
    opacity:1;pointer-events:auto;overflow:visible;transition:none}
  html.deck-active .deck-slide:not(.on) *{pointer-events:auto!important}
  html.deck-active .deck-slide-inner{max-height:none}
  html.deck-active .deck-slide *{animation:none!important}
  html.deck-active .deck-cue{display:none}
  html.deck-active .deck-chrome.hide{opacity:1;pointer-events:auto}
  html.deck-active .deck-slide.moment{display:block;height:auto;min-height:0;
    background:var(--paper,#fff)}
  html.deck-active .deck-slide.moment > *{position:static;display:block;
    width:auto;height:auto;min-height:0;overflow:visible;text-align:left;
    background:var(--paper,#fff);padding:40px 6vw;padding:clamp(34px,6vh,58px) 6vw;
    border-top:1px solid rgba(12,10,7,.14)}
  html.deck-active .deck-slide.moment > * > *{display:none}
  html.deck-active .deck-slide.moment .plate{position:static;display:inline-block;
    left:auto;right:auto;top:auto;bottom:auto;margin:0;
    border:1px solid var(--deck-ink);background:#fff;color:var(--deck-ink);opacity:1}
}
