/* SCENES — the site's immersion system (2026-08-05).
 *
 * Operator: "every part of the entire website should be immersed in what is in
 * the screen, and scrolling shift immersion to the next immersive thing so you
 * are sucked in to the site to be productive and provision ecological wealth."
 *
 * The law that follows: ONE screen holds ONE complete thing, and a scroll is
 * not a nudge down a document, it is a move into the next thing. A page is a
 * sequence you pass through, not a wall you scan.
 *
 * This file is the system, not a page. Any page adopts it by putting `scened`
 * on <html> and `class="scene"` on each section it already has. It deliberately
 * needs no wrapper divs and no markup restructuring, so adopting it across the
 * suite before the 2026-08-20 event is a one-line change per section rather
 * than a rewrite of every page.
 *
 * Fail-open by construction: with JavaScript off, every scene is fully visible
 * and the page simply reads as generously spaced. The reveal arms itself only
 * once vealth-scenes.js has run.
 */

/* Proximity, never mandatory. Mandatory snap fights a thumb mid-flick, hijacks
   find-in-page, and traps a screen reader inside a long scene. Proximity guides
   the landing when you are already close and gets out of the way otherwise. */
/* `scroll-padding-top` is the whole fix for the nav overlap described below: it
   tells the scroller that the top `--nav-h` pixels are spoken for, so every
   snap AND every anchor landing clears the bar instead of sliding under it.
   Before this, each scene and each heading carried its own hand-tuned
   `scroll-margin-top` guess (84px / 68px / 96px) against a bar that is actually
   65px on a phone and 73px on a desktop, so the two systems were guessing at
   each other and neither was right. The nav now publishes its measured height
   and the scenes read it. */
html.scened {
  scroll-snap-type: y proximity;
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h, 0px);
}
@media (prefers-reduced-motion: reduce) {
  html.scened { scroll-snap-type: none; scroll-behavior: auto; }
}

/* A scene owns the screen. svh, not vh, so a phone's collapsing URL bar cannot
   leave a scene one bar short and expose the seam of the next one.
 *
 * MEASURED 2026-08-05, and it is why this subtracts: a scene was `100svh` tall
 * while the sticky nav ate the top of the viewport, so on work.html a scene was
 * 877px on a phone with only 779px of it ever visible. No scene EVER fully fit
 * the screen it was supposed to own, on any page, which is precisely the
 * property the scene law is after. Subtracting the nav's own measured height
 * makes a scene exactly the space a reader can actually see.
 *
 * Fail-open: `--nav-h` is set by JS from the live bar, so if the script never
 * runs the fallback is 0px and every scene is 100svh again, which is today's
 * behaviour. Nothing here can hide content if measurement fails. */
.scene {
  position: relative;
  min-height: calc(100svh - var(--nav-h, 0px));
  display: flex;
  flex-direction: column;
  justify-content: center;
  scroll-snap-align: start;
  padding: 92px 0 84px;
  box-sizing: border-box;
}
@media (max-width: 760px) {
  .scene { padding: 76px 0 70px; }
}

/* Long scenes (a full board, a table of receipts) start at the top and run as
   long as they need. They still snap on entry, so arriving still feels like
   stepping into a room rather than drifting into the middle of one. */
/* Authored tall, or measured taller than the screen at runtime (see
   vealth-scenes.js markTall): either way it starts at the top, so arriving
   at its edge does not drop the reader into its middle. */
.scene--tall,
.scene--overflows { justify-content: flex-start; }

/* One idea, one measure. Wider than this and it stops being a scene. */
.scene--narrow > *:not(.scene-cue) { max-width: 660px; }

/* --- the reveal -------------------------------------------------------
   Armed by JS only, and it targets the section's existing direct children, so
   a page adopts scenes without gaining a single wrapper div. Children rise in
   sequence: the eye is walked through the idea in the order it was written
   rather than being handed the whole block at once. */
body.scenes-armed .scene > *:not(.scene-cue) {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.52s cubic-bezier(0.22, 0.61, 0.36, 1), transform 0.52s cubic-bezier(0.22, 0.61, 0.36, 1);
}
body.scenes-armed .scene.is-in > *:not(.scene-cue) { opacity: 1; transform: none; }
body.scenes-armed .scene.is-in > *:nth-child(2) { transition-delay: 0.07s; }
body.scenes-armed .scene.is-in > *:nth-child(3) { transition-delay: 0.13s; }
body.scenes-armed .scene.is-in > *:nth-child(4) { transition-delay: 0.18s; }
body.scenes-armed .scene.is-in > *:nth-child(n + 5) { transition-delay: 0.22s; }

/* The first scene is the hook. It is on screen at first paint and must never
   animate in: the ten seconds we get are not spent watching a transition. */
body.scenes-armed .scene--hook > * { opacity: 1 !important; transform: none !important; transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  body.scenes-armed .scene > *:not(.scene-cue) { opacity: 1; transform: none; transition: none; }
}

/* --- the cue ----------------------------------------------------------
   How a reader knows there is a next thing AND what it is. Naming it is the
   point: a bare arrow says "there is more", a named cue says "there is more and
   it is worth the flick". */
.scene-cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 44px;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--soft);
  text-decoration: none;
  transition: color 0.16s ease;
}
.scene-cue:hover { color: var(--muted); }
.scene-cue:focus-visible { outline: 2px solid var(--link); outline-offset: 4px; border-radius: 999px; }
.scene-cue .scene-cue-arrow {
  display: inline-block;
  font-size: 1.05em;
  line-height: 1;
  animation: scene-drift 2.4s ease-in-out infinite;
}
@keyframes scene-drift {
  0%, 100% { transform: translateY(0); opacity: 0.7; }
  50% { transform: translateY(4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .scene-cue .scene-cue-arrow { animation: none; } }
/* A short viewport has no room to spare, and a long scene's cue would sit in
   the middle of its own content rather than at its foot. */
@media (max-height: 620px) { .scene-cue { display: none; } }
.scene--tall > .scene-cue,
.scene--overflows > .scene-cue { display: none; }

/* --- scene typography -------------------------------------------------
   Headings speak at the scale of the screen they own, not at the scale of a
   document outline. */
.scene-kicker {
  display: block;
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--soft);
  margin: 0 0 14px;
}
/* `:not(.scene-kicker)` is load-bearing: a kicker is an h1 for the document
   outline and a quiet eyebrow for the eye, and without this it inherited the
   scene-heading scale and shouted the page's least important line. */
html.scened .scene > h1:not(.scene-kicker),
html.scened .scene > h2:not(.scene-kicker) {
  font-family: Fraunces, Georgia, serif;
  font-weight: 600;
  font-size: clamp(1.85rem, 5vw, 2.6rem);
  line-height: 1.12;
  letter-spacing: -0.012em;
  color: var(--ink);
  margin: 0 0 16px;
  text-wrap: balance;
}
html.scened .scene > p { max-width: 58ch; }

/* Cues link to the next scene's heading id, and the nav is sticky. Without some
   clearance the flick that a cue invites lands with the heading tucked under the
   bar, so the scene you were promised opens on its second line.
 *
 * That clearance now comes from `scroll-padding-top: var(--nav-h)` on the
 * scroller above, which is measured from the real bar and applies to snaps and
 * anchor landings alike. The hand-tuned 96px/76px that used to live here was a
 * guess at the same number, and keeping both would ADD them: an anchor would
 * land ~160px down, a whole heading's worth of empty space below the nav. */

/* A page that adopts scenes drops the old per-section card washes: two framing
   systems running at once is exactly the stitched-together feel being removed.
 *
 * The padding is restated here, not just in `.scene`, because vealth-next.css
 * carries `main.wrap > section { padding: 26px 24px 28px }` and an element+class
 * selector out-specifies a bare class. Measured 2026-08-05: every adopted page
 * silently ran on 20px of scene padding instead of 76px, which is why a cue's
 * landing put its heading under the sticky nav. */
html.scened main.wrap > section.scene,
html.scened main.wrap > header.scene {
  padding: 92px 0 84px;
  background: none;
  border: 0;
  box-shadow: none;
  margin-top: 0;
}
@media (max-width: 760px) {
  html.scened main.wrap > section.scene,
  html.scened main.wrap > header.scene { padding: 76px 0 70px; }
}
html.scened main.wrap { padding-top: 0; padding-bottom: 0; }
