/* ==========================================================================
   Hexagon — v2: the Wall Street firm financing the frontier
   One page, natural scroll. A live Western vista runs behind everything;
   content fades up over it as the scrim deepens. No slides, no chevrons.
   Type: IBM Plex Serif / Sans / Mono · Archivo Expanded (wordmark) · Mrs Saint Delafield (names)
   ========================================================================== */

@font-face {
  font-family: "IBM Plex Serif";
  font-style: normal;
  font-weight: 400;
  src: url("../assets/fonts/IBMPlexSerif-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "IBM Plex Serif";
  font-style: italic;
  font-weight: 400;
  src: url("../assets/fonts/IBMPlexSerif-Italic.ttf") format("truetype");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  src: url("../assets/fonts/IBMPlexSans-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  src: url("../assets/fonts/IBMPlexSans-Medium.ttf") format("truetype");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  src: url("../assets/fonts/IBMPlexMono-Regular.ttf") format("truetype");
}

:root {
  --copper: #b2713d;
  --ink-black: #0d0f0e;
  --paper: #f3f1ea;
  /* Scroll gradient (Sep 26 sync): the tinted field at the bottom of the
     vista (#a37c49 under the 50% hero tint) -> dark sage -> dark brown
     (built from brand copper-dark #905e37) -> ink */
  --field-tint: #58462c;
  --sage-dark: #353d2d;
  --brown-dark: #2e2016;
  --paper-dim: rgba(243, 241, 234, .68);
  --paper-faint: rgba(243, 241, 234, .42);
  --serif: "IBM Plex Serif", Georgia, serif;
  --sans: "IBM Plex Sans", Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", Consolas, monospace;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* The canvas colour is what iOS Safari shows where there is no page
     content (the status bar at the very top of the page) */
  /* one canvas colour: the sky at the top of the screen (status bar at the
     top of the page, where there is no page content above to show), then
     the rising tone once it covers the screen */
  background-color: #2a4d68;        /* sky; kept matched by js/v2.js setTone() */
}

html, body { margin: 0; padding: 0; }

body {
  position: relative;               /* the pin tracks and grain span the page */
  font-family: var(--sans);
  font-size: 16px;
  color: var(--paper);
  background: transparent;          /* the html canvas colour shows instead (see html) */
}

::selection { background: var(--copper); color: #fff; }

a { color: inherit; text-decoration: none; }

/* --------------------------------------------------------------------------
   The vista — fixed full-viewport video, always moving behind the page
   -------------------------------------------------------------------------- */

/* Pinning = position:fixed (iOS scrolls fixed layers perfectly smoothly;
   a scroll-driven-animation pin jittered on George's iPhone, Sep 26). The
   .pin wrappers from that attempt are inert. */
.pin-track, .pin { display: contents; }

/* Colour carriers for iOS Safari's top and bottom strips (see index.html).
   Colours are set by js/v2.js to match what is right beside them, so the
   hairlines are invisible. Above the video, below the page content. */
.edge {
  position: fixed;
  left: 0;
  right: 0;
  height: 6px;
  z-index: 1;
  pointer-events: none;
  background: #2a4d68;
  /* Only iOS shows browser strips, and the touch block below hides these
     there too — with the video scrolling (Sep 28) they'd just mismatch */
  display: none;
}
.edge-top { top: 0; }
.edge-bottom { bottom: 0; background: #a37c49; }

.vista {
  /* Ordinary content on every screen (Sep 28, George): the video scrolls
     away with the page instead of sitting pinned under a rising cover.
     It runs 120px past the cover's bottom; the fade into the field colour
     happens inside that overlap. */
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  height: calc(100lvh + 120px);
  object-fit: cover;
  object-position: 50% 52%;          /* wide-margin source, scene centered */
  z-index: 0;                        /* natural color, untouched */
  pointer-events: none;
}
/* iOS Low Power Mode refuses autoplay and paints a dead play button over
   the poster; hide every native control so a blocked video reads as a still */
.vista::-webkit-media-controls,
.vista::-webkit-media-controls-start-playback-button,
.vista::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
}

/* The hero tint is baked into the video file (see index.html). */
/* The tinted loop plays in a second <video> stacked on the intro; it is
   shown once it is actually playing (js/v2.js) */
.vista-loop { opacity: 0; }
.vista-loop.is-on { opacity: 1; }

/* Anti-banding grain. Dimming the vista leaves too few dark shades, so
   skies step into bands. Overlay-blended mid-grey noise nudges pixels both
   lighter and darker: it dithers the steps without lifting the average,
   and it vanishes on pure black, so it can never leave a grey haze or a
   seam against the dark zone. JS drives --grain: 0 on the opening screen,
   strongest mid-fade, 0 again once the page is solid black. */
.grain {
  position: absolute;               /* page-long noise: it needn't stay put */
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 60;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='.33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
  opacity: 0;                       /* set by js/v2.js on scroll (max .3) */
}

/* --------------------------------------------------------------------------
   Top bar — an invisible back-to-top target where the spinning mark docks
   -------------------------------------------------------------------------- */

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  padding: 20px 0 14px;
  pointer-events: none;
}
.topbar .mark-small {
  display: block;
  width: 48px;               /* 48px tap target; the visible mark is the
                                docked 32px hero-mark, unaffected */
  height: 48px;
  margin: -8px 0;
  pointer-events: none;
}
body.scrolled .topbar .mark-small { pointer-events: auto; }

/* --------------------------------------------------------------------------
   Hero — the vista alone; the mark surfaces, slowly turning
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  height: 100vh;
  height: 100dvh;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
}

/* The mark waits out the 3s intro, then fades up with the tint. It is
   fixed: scrolling glides it from screen center up into the top bar and
   shrinks it there, still turning (JS drives --mark-y and --mark-s). */
.hero-mark {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 41;
  pointer-events: none;
  transform: translate(-50%, -50%) translateY(var(--mark-y, 0px)) scale(var(--mark-s, 1));
  will-change: transform;
  width: clamp(68px, 8.5vw, 112px);
  height: clamp(68px, 8.5vw, 112px);
  color: var(--paper);
  perspective: 900px;
  opacity: 0;
  transition: opacity 1.8s ease .15s;
}
body.hero-tinted .hero-mark { opacity: 1; }
/* Once docked, the mark ghosts while a section label passes beneath it
   (js/v2.js adds .dodge); quick fade, separate from the intro's slow one */
body.scrolled .hero-mark { transition: opacity .35s ease; }
body.hero-tinted .hero-mark.dodge { opacity: .12; }
.hero-mark svg {
  display: block;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 4px 30px rgba(0, 0, 0, .45));
}
/* Extruded spinning mark (three.js); flat SVG is the no-WebGL fallback */
.hero-mark.has-3d { width: clamp(72px, 9vw, 120px); height: clamp(72px, 9vw, 120px); }
.hero-mark.has-3d svg { display: none; }
.hero-mark-canvas { display: block; width: 100%; height: 100%; }
/* Context lost: hide the frozen canvas entirely; the SVG takes over */
.hero-mark:not(.has-3d) .hero-mark-canvas { display: none; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Content column — everything vertically aligned, scrolling over the vista
   -------------------------------------------------------------------------- */

main { position: relative; z-index: 2; }

.block {
  position: relative;
  max-width: 900px;
  margin: 0 auto;
  padding: clamp(120px, 18vh, 200px) 28px;
  text-align: center;
}

/* Scroll reveal: pure fade — no vertical motion, so scrolling feels
   constant; letter-spacing still settles as headings land */
.reveal {
  opacity: 0;
  transition: opacity 1s ease;
}
.reveal.in { opacity: 1; }

.kicker {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .42em;
  text-indent: .42em;
  text-transform: uppercase;
  color: var(--paper-faint);
  margin-bottom: 34px;
  transition: letter-spacing 1.2s cubic-bezier(.22, .61, .36, 1), color .4s ease;
}
.reveal.in .kicker { letter-spacing: .24em; text-indent: .24em; }
/* Labels stay paper-white on the light band too (George, Sep 28) */

/* Statement */
.statement {
  margin: 0;
  font-family: "Times New Roman", Times, serif;   /* Sep 26 sync: financial gravitas */
  font-size: clamp(19px, 2.1vw, 31px);
  font-weight: 400;
  line-height: 1.4;
  color: var(--paper);
}

.statement-flag {
  display: block;
  width: 56px;
  margin: 38px auto 0;
  opacity: .92;
}
.statement-block { padding-bottom: clamp(60px, 9vh, 90px); }

/* --------------------------------------------------------------------------
   The dark zone — starts at the bottom of the hero and fades up to black,
   and everything sits in boxes (Section 32 language) instead of floating
   over the image like text on glass
   -------------------------------------------------------------------------- */

.dark-zone {
  position: relative;
  overflow-x: clip;               /* bars slide in from past the edge; clip keeps sticky heads working */
  /* Clear at the hero's bottom edge, then field -> dark sage -> dark brown
     -> ink down the page (--fade-len = the eased hand-off from the video,
     inside the video's 120px overlap below the cover) */
  --fade-len: 120px;
  padding-top: 9vh;   /* a little headroom under the video before the statement (George, Sep 28; was 5vh) */
  /* One solid colour below the fade, changing with scroll (Sep 26):
     --tone-rgb is set by js/v2.js setTone(): field -> sage -> brown -> ink */
  --tone-rgb: 88 70 44;
  background: linear-gradient(to bottom, transparent var(--fade-len), rgb(var(--tone-rgb)) var(--fade-len));
}
/* The hand-off: a sine-eased ramp from the (tinted) video into the field
   color it already shows, so there is no edge where the gradient begins */
.dark-zone::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--fade-len);
  pointer-events: none;
}
.dark-zone::before {
  background: linear-gradient(to bottom,
    rgb(var(--tone-rgb) / 0.000) 0%,
    rgb(var(--tone-rgb) / 0.006) 5%,
    rgb(var(--tone-rgb) / 0.024) 10%,
    rgb(var(--tone-rgb) / 0.054) 15%,
    rgb(var(--tone-rgb) / 0.095) 20%,
    rgb(var(--tone-rgb) / 0.146) 25%,
    rgb(var(--tone-rgb) / 0.206) 30%,
    rgb(var(--tone-rgb) / 0.273) 35%,
    rgb(var(--tone-rgb) / 0.345) 40%,
    rgb(var(--tone-rgb) / 0.422) 45%,
    rgb(var(--tone-rgb) / 0.500) 50%,
    rgb(var(--tone-rgb) / 0.578) 55%,
    rgb(var(--tone-rgb) / 0.655) 60%,
    rgb(var(--tone-rgb) / 0.727) 65%,
    rgb(var(--tone-rgb) / 0.794) 70%,
    rgb(var(--tone-rgb) / 0.854) 75%,
    rgb(var(--tone-rgb) / 0.905) 80%,
    rgb(var(--tone-rgb) / 0.946) 85%,
    rgb(var(--tone-rgb) / 0.976) 90%,
    rgb(var(--tone-rgb) / 0.994) 95%,
    rgb(var(--tone-rgb) / 1.000) 100%);
}
.dark-zone > * { position: relative; z-index: 1; }
/* Film-grain texture in the page colour (George, Sep 28, from a grainy
   gradient reference): grain.png = 192px gaussian noise, white and black
   specks with noise-driven alpha (strength baked in: |v|x16, halved Sep 28 "more pure"). Overlay blend: bold
   on the mid tones, faint but present on the ink (normal blend made the
   light specks shout on black). Behind the content (z 0 under the
   children's z 1), fading in with the hand-off so the video above never
   gets speckled. The footer carries the same grain (no seam). */
.dark-zone::after,
.footer::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: url("../assets/graphics/grain.png?v=3") repeat;
  background-size: 192px 192px;
  mix-blend-mode: overlay;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-len));
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-len));
}
/* The footer used to carry the grain as a background-blend-mode image,
   which iOS Safari drew much stronger than the pseudo-element above, so the
   join read as a hard line (George's iPhone, Oct 5). Now it is the very same
   layer, unmasked, so the grain runs straight across. */
.footer::after { -webkit-mask-image: none; mask-image: none; }
.footer > * { position: relative; z-index: 1; }

/* Centered sections (per Christian, Sep 24): the label sits centered on
   top and the bars/boxes below cover the width of the content column */
.split {
  max-width: 1120px;
  margin: 0 auto;
  padding: clamp(44px, 7vh, 84px) 40px;
}
.split[hidden] { display: none; }
.split-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  margin-bottom: 38px;
}
.split-head .kicker { margin: 0; text-indent: .42em; }
.reveal.in .kicker, .split-head.in .kicker { letter-spacing: .24em; text-indent: .24em; }
.split-note {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  color: rgba(243, 241, 234, .3);
  transition: color .4s ease;
}

/* Portfolio: one flat list of bars — name · sector · link.
   Rows slide in from the right and settle into a straight left edge as
   they rise (JS sets --slide); hover flips a bar to paper. */
.co-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.co-list li,
.person-grid li {
  transform: translateX(var(--slide, 0px));
  opacity: var(--fade, 1);
  will-change: transform, opacity;
}
.co {
  display: grid;
  grid-template-columns: 1fr auto 20px;
  align-items: center;
  gap: 24px;
  padding: 22px 26px;
  background: #171a18;                    /* fallback */
  background: color-mix(in srgb, rgb(var(--tone-rgb)) 72%, #000);  /* a shade darker than the page tone, so tiles follow the gradient (Sep 27) */
  color: var(--paper);
  transition: background-color .35s ease, color .35s ease;
}
.co-name {
  font-family: var(--serif);
  font-size: clamp(17px, 1.5vw, 21px);
  line-height: 1.3;
  transition: transform .35s cubic-bezier(.22, .61, .36, 1);
}
.co-sector {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--paper-faint);
  text-align: right;
  transition: color .35s ease;
}
.co-arrow {
  font-family: var(--sans);
  font-size: 15px;
  color: var(--paper-faint);
  text-align: right;
  transition: color .35s ease, transform .35s ease;
}
a.co:hover { background: var(--paper); color: var(--ink-black); }
a.co:hover .co-name { transform: translateX(10px); }
a.co:hover .co-sector { color: rgba(13, 15, 14, .55); }
a.co:hover .co-arrow { color: var(--copper); transform: translate(2px, -2px); }

/* Team & Advisors: boxed names, Team three across, Advisors two by two;
   they ride the same scroll-linked slide as the portfolio bars */
.person-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.person-grid-3 { grid-template-columns: repeat(3, 1fr); }
.person-grid-2 { grid-template-columns: repeat(2, 1fr); }

.person-box {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 38px 18px 32px;
  background: #171a18;                    /* fallback */
  background: color-mix(in srgb, rgb(var(--tone-rgb)) 72%, #000);  /* a shade darker than the page tone, so tiles follow the gradient (Sep 27) */
  text-align: center;
  transition: background-color .35s ease;
}
.person-name {
  font-family: "Mrs Saint Delafield", cursive;
  font-size: clamp(30px, 2.6vw, 42px);   /* small x-height face: reads smaller than its px size */
  line-height: 1.15;
  white-space: nowrap;
  color: var(--paper);
  transition: color .35s ease;
}
.person-title {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper-faint);
  transition: color .35s ease;
}
a.person-box:hover { background: var(--paper); }
a.person-box:hover .person-name { color: var(--ink-black); }
a.person-box:hover .person-title { color: rgba(13, 15, 14, .55); }

/* --------------------------------------------------------------------------
   Footer — closing line, portal, colophon; all centered on the same axis
   -------------------------------------------------------------------------- */

.footer {
  position: relative;
  z-index: 2;
  background: var(--ink-black);     /* js/v2.js sets the page tone */
  padding: clamp(40px, 6vh, 70px) 28px clamp(70px, 10vh, 110px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 54px;
  text-align: center;
}

.closing-line {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(15px, 1.3vw, 18px);
  color: var(--copper);
}

.portal-link {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-indent: .12em;
  color: var(--paper-dim);
  padding: 14px 30px;        /* 44px-tall tap target */
  border: 1px solid rgba(243, 241, 234, .28);
  border-radius: 2px;
  transition: color .25s ease, border-color .25s ease;
}
.portal-link:hover { color: var(--copper); border-color: var(--copper); }

.colophon {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  color: rgba(243, 241, 234, .3);
}

/* --------------------------------------------------------------------------
   Motion preferences & small screens
   -------------------------------------------------------------------------- */

html.noanim { scroll-behavior: auto; }
html.noanim .hero-mark { transition: none; }
html.noanim .reveal { transition: none; opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-mark { transition: none; }
  .reveal { transition: none; opacity: 1; transform: none; }
  .co-list li, .person-grid li { transform: none; opacity: 1; }
}

@media (max-width: 600px) {
  .vista { object-position: 50% 55%; }
  .block { padding: clamp(84px, 13vh, 130px) 24px; }
  /* The desktop line breaks force ragged wraps on a phone; let the
     tagline flow and balance its own lines instead */
  .statement { font-size: 19px; line-height: 1.5; text-wrap: balance; max-width: 22em; margin: 0 auto; }
  .statement br { display: none; }
  .statement-flag { width: 46px; margin-top: 30px; }
  .kicker { margin-bottom: 26px; }
  .statement-block { padding-bottom: 44px; }
  .dark-zone { --fade-len: 120px; padding-top: 9vh; }
  .split { padding: 44px 16px; }
  .split-head { margin-bottom: 24px; }
  .co { grid-template-columns: 1fr 16px; grid-template-areas: "name arrow" "sector arrow"; gap: 6px 14px; padding: 18px 18px; }
  .co-name { grid-area: name; font-size: 17px; }
  .co-sector { grid-area: sector; text-align: left; font-size: 9.5px; }
  .co-arrow { grid-area: arrow; }
  .person-grid-3, .person-grid-2 { grid-template-columns: 1fr; }
  .person-box { padding: 30px 16px 26px; }
  .person-name { font-size: 36px; }
  .person-title { font-size: 10px; letter-spacing: .14em; }
  .footer { gap: 40px; padding-left: 24px; padding-right: 24px; }
}

/* Phones and tablets (Sep 27, George): the cover scrolls with the page like
   apple.com's hero instead of being pinned. iOS Safari only draws the page
   behind its status bar and toolbar when nothing fixed touches those edges,
   and a pinned-but-not-fixed video shook on iPhone. So on touch screens the
   video is ordinary content that runs 60px above the page top and 60px past
   the cover's bottom (behind the clock and the toolbar), the fade into the
   field colour happens inside that overlap, and the edge hairlines and the
   full-width top bar are off. Desktop keeps the pinned vista. */
@media (hover: none) and (pointer: coarse) {
  .vista {
    position: absolute;
    top: -60px;
    height: calc(100lvh + 180px);   /* 60px above the page, 120px below the cover */
    width: 100%;
  }
  /* iOS Safari fills its status-bar strip and its home-indicator strip with
     the page canvas. George (Sep 27): top white, bottom with no border. The
     canvas colour is white (what shows ABOVE the page, i.e. the status bar
     at the top), and a canvas image covering the page itself carries the
     page colour for the bottom strip (grass, then the tone; js/v2.js
     updates the image as you scroll). */
  html {
    /* iOS strips, split (George, Sep 28): the top status bar takes the
       background-COLOUR (white); the home-indicator strip at the bottom
       takes the background-IMAGE covering the page box, which js/v2.js
       keeps on the page tone (ground first, deepening with scroll). */
    background-color: #fff;
    background-image: linear-gradient(rgb(var(--canvas-rgb, 131 104 74)), rgb(var(--canvas-rgb, 131 104 74)));
    background-repeat: no-repeat;
    background-position: 0 0;
    background-size: 100% 100%;
  }
  .dark-zone { --fade-len: 120px; }
  .edge { display: none; }
  .topbar { left: 50%; right: auto; width: 32px; padding: 20px 0 0; transform: translateX(-50%); }
}
