/* Balius Partners: base and the color layers.
   Layer structure (bottom → top), measured from Figma frame 1 (1512 × 865 design units, scaled by --u):
   1. #backdrop  fixed, screen-anchored brown → near-black gradient: the layer "underneath" and the letter's background
   2. #colpaint  content-locked paint, visible only through the frame window (narrow column + both pillar shapes);
                 transparent through the letter, then the color arc (see layout() in main.js)
   3. #pillarDark / #cover / .pgap  the switch to beige around the frame window
   4. main       scrolling content
   5. #rails, nav, frame lines and labels (nav.css)
   Color comes from these layers, never from faked shapes; see docs/design-decisions.md. */
:root {
  --u: 1; --sl: 0px; --heroH: 534;
  /* Local aliases onto the design tokens (tokens.css, generated by design/tokens.py) */
  --beige: var(--c-ground); --taupe: var(--c-frame); --ink: var(--c-ink); --paper: var(--c-on-dark); --silver: var(--argent-300); --label: var(--argent-500);
}
* { box-sizing: border-box; }
html { scrollbar-gutter: stable; }
/* No rubber-band bounce at the page's ends: the fixed color layers (photo, column paint) can't follow the bounce, so the
   page's shapes and the layers under them came apart while it bounced (user's iPhone test, 2026-10-08) */
html, body { overscroll-behavior: none; }
/* Nav links and the hero button scroll to their section instead of jumping (native; off for reduced motion) */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; color: var(--ink); background: var(--beige); font-family: var(--f-text); }
.fixed { position: fixed; inset: 0; pointer-events: none; }

/* The brown underneath: solid at the top; the panel's gradient starts at the reveal edge (the hero's bottom), moved by
   a scroll-driven (compositor) animation so it stays locked to that edge, then rests under the nav. */
#backdrop { z-index: 0; background: var(--c-deep); overflow: hidden; }
#bdPanel { position: absolute; left: 0; right: 0; top: 0; will-change: transform; }
#colpaint { z-index: 1; overflow: hidden; mask-size: 100% 100%; -webkit-mask-size: 100% 100%; }
#colpaint .paint { position: absolute; left: 0; right: 0; top: 0; will-change: transform; }
/* Screen-anchored light on the column paint from the companies on: stays put while content scrolls over it; slightly
   deeper toward the bottom of the screen. Opacity is scroll-driven per section. */
#cpLight { position: absolute; inset: 0; opacity: 0;
  background: linear-gradient(180deg, rgba(237,233,227,.06) 0%, rgba(0,0,0,0) 35%, rgba(46,36,28,.14) 80%, rgba(46,36,28,.2) 100%); }
/* Before the footer the column cools into dark gunmetal; this screen-anchored Argent sheen (lit at the top of the
   screen, deeper at the bottom, built in layout() from SHEEN) makes it read as polished metal catching a fixed light */
#cpSheen { position: absolute; inset: 0; opacity: 0; }

/* The switch (scroll-linked, see setupScrollAnims): the beige comes in from the screen sides toward the column, so the
   brown reads as being drawn into the column and pillars. --sweep drives a soft horizontal mask (see layout()). */
@property --sweep { syntax: '<number>'; inherits: false; initial-value: 0; }
/* --floor: beige left over the not-yet-swept brown (0 = full brown); rises during the switch (see setupScrollAnims) */
@property --floor { syntax: '<number>'; inherits: false; initial-value: 0; }
#coverSvg { display: none; }
#cover { z-index: 2; opacity: 0; --sweep: 0; mask-size: 100% 100%; -webkit-mask-size: 100% 100%; }
/* Pillars appear first, slightly darker than the brown (masked to the pillar shapes); the darkening releases as the
   beige reaches them */
#pillarDark { z-index: 1; background: var(--earth-950); opacity: 0; mask-size: 100% 100%; -webkit-mask-size: 100% 100%; }
/* The 1px beige dividers between the column and the pillars arrive with the pillars. Same beige as the cover, which
   later covers them exactly, so there's no seam. */
/* They run to the screen bottom: below the pillars the same gap shows once the frame's bottom curves are drawn */
.pgap { position: fixed; z-index: 2; pointer-events: none; width: 1px; top: calc(var(--pt) * 1px); bottom: 0;
  background: var(--beige); opacity: 0; }
.pgap.l { left: calc(var(--xnl) - 1px); }
.pgap.r { left: var(--xnr); }

/* The cover's beige is content-locked (moved like the column paint), so the footer's side windows, cut into it, scroll.
   Both paints come in two parts: the footer's holes are cut into a short part covering the last two screens, because a
   mask on a page-tall layer is drawn at reduced resolution (soft edges). */
#cover .cpaint { position: absolute; left: 0; right: 0; top: 0; background: var(--beige); will-change: transform; }
/* The footer photo, in the layer underneath (shown only through the footer's windows); tinted in CSS so the color can
   be tuned (Figma: a Color-blend layer in Slate 400 over the photo) */
#bdPhoto { position: absolute; inset: 0; opacity: 0; isolation: isolate; }
#bdPhoto img { width: 100%; height: 100%; object-fit: cover; display: block; }
#bdPhoto i { position: absolute; inset: 0; background: var(--slate-400); mix-blend-mode: color; }

main { position: relative; z-index: 3; }
/* Text for screen readers only */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.row { position: relative; width: 100%; }
.stage { position: relative; width: calc(1512px * var(--u)); height: 100%; margin: 0 auto; }
.col { width: calc(var(--xnr) - var(--xnl)); margin: 0 0 0 var(--xnl); }

/* Until the first layout (main.js), the page is plain beige: the bare markup (the phone's pill nav, unsized rows) showed
   while the script loaded. A fallback shows it anyway after 3 s, should the script fail. */
html.loading body { visibility: hidden; animation: loadShow 0s 3s forwards; }
html.loading { background: var(--beige); }
@keyframes loadShow { to { visibility: visible; } }
