/* Night motion, all three venue previews (Egie 2026-10-27: "Build ideas 1 to 3 (stacked card
   deck, tilted card out of the hero, film grain) on all three venue previews"), after
   makeitniche.com, measured 2026-10-26.
   1. Film grain: a still noise texture over every page (makeitniche: fractal noise at 5%).
   2. Stacked card deck: each home card pins when its end reaches the bottom of the screen, and
      the next one slides over it while it shrinks to 92% about its centre and darkens.
   3. Tilted card: the first card under the hero rises tilted back 15 degrees and flattens over
      600 px of scroll (makeitniche: rotateX 15deg, scale .95, perspective 1400px).
   2 and 3 are scroll-driven animations of transform and opacity only, so the browser runs them
   off the main thread (the 2026-10-21 "jittery and unstable" rule). night-motion.js only marks
   the cards and measures where a tall card pins. Without support, or with motion off, the page
   is the plain page: no pinning, no tilt. The grain stays: it does not move.
   Second round, same day ("Build all four new effects (glide, hero hand-off, gold numbers,
   gold word fill) as a preview"):
   4. Glide: tapping a home row's link grows its photo into the next page's cover (a
      cross-document view transition; page-glide.js names the photo as the page leaves).
   5. Hero hand-off: the hero film shrinks into a card and darkens as it scrolls away.
   6. Card numbers: 01, 02, 03 in the venue colour on the three home cards. Upright, because
      none of the three venue display fonts has an italic, and a faked slant looks cheap.
   7. Word fill: the venue's name in each home heading fills with the venue colour as the
      heading scrolls in (night-motion.js marks the word). */

/* 1. Grain. Fixed, still, and never in the way of a click. Plain blending, not overlay: an
   overlay layer over the whole page makes the browser re-blend everything under it as it scrolls. */
body::after{content:"";position:fixed;inset:0;z-index:2147483000;pointer-events:none;background:url(/codex/assets/grain.svg?v=74492ab949) 0 0/220px 220px repeat;opacity:.055}
html[data-venue=sy] body::after{opacity:.07}

/* 2. Deck. The card colours are each venue's own section colours, so a covered card never
   shows through the one on top. */
html[data-venue=ab] .night-deck{--deck-bg:#30151f}
html[data-venue=st] .night-deck{--deck-bg:#13161a}
html[data-venue=sy] .night-deck{--deck-bg:#eee7d9}
/* Pinned only where the shrink and the darkening can run too (Codex, design panel 2026-10-29: a
   browser without scroll timelines pinned the cards with nothing to show the depth). The shadow on
   each covering card stays (Egie 2026-10-29, after the panel removed it: "revert all these"). */
@supports (animation-timeline:view()) and (timeline-scope:--a){
 @media(prefers-reduced-motion:no-preference){
  html:not([data-motion=off]) .night-deck>.deck-card{position:sticky;top:var(--deck-top,0px);background-color:var(--deck-bg)}
  html:not([data-motion=off]) .night-deck>.deck-card~.deck-card{box-shadow:0 -28px 56px rgba(0,0,0,.38)}
  html:not([data-motion=off]) .night-deck>.deck-card::after{content:"";position:absolute;inset:0;z-index:6;pointer-events:none;background:#07080a;opacity:0}
 }
}
@supports (animation-timeline:view()) and (timeline-scope:--a){
 @media(prefers-reduced-motion:no-preference){
  html:not([data-motion=off]) .night-deck>.deck-has-next{animation:deck-recede linear both;animation-timeline:var(--deck-next);animation-range:entry 0% entry 100%}
  html:not([data-motion=off]) .night-deck>.deck-has-next::after{animation:deck-dim linear both;animation-timeline:var(--deck-next);animation-range:entry 0% entry 100%}
  /* 3. Tilt. The first card can also be a deck card, so its two animations are listed together:
     the tilt moves transform, the deck moves scale, and they never overlap in time. */
  html:not([data-motion=off]) .deck-tilt{animation:deck-tilt linear both;animation-timeline:view();animation-range:entry 0% entry 600px}
  html:not([data-motion=off]) .night-deck>.deck-tilt.deck-has-next{animation:deck-tilt linear both,deck-recede linear both;animation-timeline:view(),var(--deck-next);animation-range:entry 0% entry 600px,entry 0% entry 100%}
 }
}
@keyframes deck-recede{from{scale:1}to{scale:.92}}
@keyframes deck-dim{from{opacity:0}to{opacity:.5}}
/* The tilt turns about the card's bottom edge (the two 50% moves), so the top, the part that is
   on screen as it rises, leans away and stands up. makeitniche turns about the top edge, which
   works there because its whole card is on screen; ours starts below a full-screen hero. */
@keyframes deck-tilt{from{transform:perspective(1400px) translateY(50%) rotateX(15deg) translateY(-50%) scale(.95)}to{transform:none}}

/* 4. Glide. Every page change on a venue preview cross-fades; a cover photo with the shared
   name grows out of the home row photo it was opened from. Under reduced motion the browser
   changes pages as before. */
/* The opt-in itself is inline at the top of every page's <head> (GLIDE_OPT_IN in
   site_content.py): read from here, Chrome often decided before this file arrived. */
::view-transition-old(root),::view-transition-new(root){animation-duration:.32s}
::view-transition-group(venue-cover){animation-duration:.7s;animation-timing-function:cubic-bezier(.2,.7,.15,1)}
::view-transition-old(venue-cover),::view-transition-new(venue-cover){height:100%;object-fit:cover}
.editorial-cover:has(figure) figure,.editorial-cover:not(:has(figure)){view-transition-name:venue-cover}
/* The bottle menu has no cover photo, so the photo grows into its hero (Egie 2026-10-27). The
   name is on only while the glide runs: a named element is its own layer, which would put the
   hero's words under the floating bottle (z-index 3). The bottle gets a layer of its own, so it
   stays on top as the photo grows. A rule of its own: a browser that cannot read
   :active-view-transition drops only this rule, not the covers above. Only on arrival: the
   leaving page also matches :active-view-transition, and its hero flew down from 9,900 px above
   into the gallery cover (smoking-section 2026-10-28). page-glide.js marks a leaving page. */
html:active-view-transition:not(.glide-out) .bm-hero{view-transition-name:venue-cover}
html:active-view-transition:not(.glide-out) .bm-float{view-transition-name:bm-bottle}

/* 5. Hero hand-off. The whole hero shrinks about its bottom edge, so it never overlaps the
   page below it and the logo stays exactly where it sits on the film; the film darkens over
   the hero's own dark ground. */
@supports (animation-timeline:view()){
 @media(prefers-reduced-motion:no-preference){
  html[data-venue]:not([data-motion=off]) .hero{view-timeline:--hero block;animation:hero-recede linear both;animation-timeline:--hero;animation-range:exit 0% exit 100%;transform-origin:50% 100%}
  html[data-venue]:not([data-motion=off]) .hero .hero-visual{animation:hero-dim linear both;animation-timeline:--hero;animation-range:exit 0% exit 90%}
 }
}
@keyframes hero-recede{to{scale:.9}}
@keyframes hero-dim{to{opacity:.35}}

/* 6. Card numbers. Strand's cyan and Abigail's gold sit on their own dark cards; Saint Yves
   numbers its three photo panels, whose labels sit on the photographs. */
html[data-venue=ab] .ab-home-rows,html[data-venue=st] .st-home-rows{counter-reset:night-card}
html[data-venue=ab] .ab-home-row,html[data-venue=st] .st-home-row{counter-increment:night-card}
html[data-venue=ab] .ab-home-copy::before,html[data-venue=st] .st-home-copy::before{content:counter(night-card,decimal-leading-zero);content:counter(night-card,decimal-leading-zero) / "";display:block;margin:0 0 18px;font:400 20px/1 var(--display);letter-spacing:.12em}
html[data-venue=ab] .ab-home-copy::before{color:#dba950;font-family:Italiana,serif}
html[data-venue=st] .st-home-copy::before{color:#8fe3ff;font-family:"Big Shoulders",sans-serif;font-weight:700}
/* Saint Yves writes its three numbers out: a counter does not reach the label inside the panel
   button (measured 2026-10-27, every panel read 00). */
html[data-venue=sy] .st-apertures>.st-pane .st-panel-label strong::before{color:#d9c08f;font-size:.62em;letter-spacing:.12em;vertical-align:.25em}
html[data-venue=sy] .st-apertures>.st-pane:nth-child(1) .st-panel-label strong::before{content:"01\2003";content:"01\2003" / ""}
html[data-venue=sy] .st-apertures>.st-pane:nth-child(2) .st-panel-label strong::before{content:"02\2003";content:"02\2003" / ""}
html[data-venue=sy] .st-apertures>.st-pane:nth-child(3) .st-panel-label strong::before{content:"03\2003";content:"03\2003" / ""}

/* 7. Word fill. The colour only, on a few words, so the redraw it costs is tiny. Saint Yves
   fills to a deeper brass than its accent: the accent on cream is too faint for a heading. */
.venue-body{--fx-accent:#dba950}
html[data-venue=st] .venue-body{--fx-accent:#8fe3ff}
html[data-venue=sy] .venue-body{--fx-accent:#8a6d3b}
@supports (animation-timeline:view()){
 @media(prefers-reduced-motion:no-preference){
  html:not([data-motion=off]) .fx-word{animation:word-fill linear both;animation-timeline:view();animation-range:entry 80% cover 42%}
  /* Saint Yves' split text puts each word in a box with overflow hidden, which is a scroll
     container: view() on the word measured that box and sat at 100%, so the name was brass
     before it scrolled in (WebKit and Chromium, 2026-10-27). Such a word follows its heading
     on the page instead. */
  html:not([data-motion=off]) .venue-body h2.title-fx-host{view-timeline:--fx-head block}
  html:not([data-motion=off]) .split-parent .fx-word{animation-timeline:--fx-head}
 }
}
@keyframes word-fill{to{color:var(--fx-accent)}}
