/* ══════════════════════════════════════════════════════════════
   ADMIRALTY · THE DESCENT
   Mockup stylesheet for admiralty-home.html. Separate from
   styles.css on purpose — nothing here touches the live site.

   The organising idea: no section owns a background. The whole
   dark run is one gradient field, so there are no rectangles to
   butt against each other. Sections are marked by light, overlap
   and rule instead of by a colour change.
   ══════════════════════════════════════════════════════════════ */

/* Bodoni Moda, self-hosted. These pages do not load styles.css, so the
   faces have to be declared here as well — same files, so the browser
   fetches them once whichever stylesheet asks first. Both cuts: the
   two-tone headline sets its second clause in italic, and a synthesised
   oblique of a didone looks wrong.
   SIL OFL — see assets/fonts/OFL-bodoni-moda.txt. */
@font-face {
  font-family: "Bodoni Moda";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/bodoni-moda-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Bodoni Moda";
  font-style: italic;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/bodoni-moda-latin-italic.woff2") format("woff2");
}

:root {
  --n0: #0d1f3a;            /* shallow */
  --n1: #0a1830;            /* mid     */
  --n2: #071022;            /* deep    */
  --gold: #d9b04a;
  --gold2: #e4c570;
  --tx: #e8eef9;
  --mu: #9db0ce;

  --pw: #f7f8fb;            /* surfaced */
  --pink: #0a1424;
  --proy: #1b3f8b;
  --pgold: #6f5515;         /* deep enough for AA on white AND on the
                              1px grid line, which the number boxes clip */
  --pmu: #4a5568;

  /* Georgia is the swap-time fallback only — the one serif on every
     platform, so nothing changes family mid-load. */
  --disp: "Bodoni Moda", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --max: 1080px;
}

* { box-sizing: border-box; }
/* clip on html as well as body — body alone still let the root report a
   wider scrollWidth when a decorative layer overhung the edge */
html { scroll-behavior: smooth; overflow-x: clip; }
body {
  margin: 0;
  background: var(--n0);
  color: var(--tx);
  font-family: var(--sans);
  line-height: 1.6;
  overflow-x: clip;
}
img, video { display: block; max-width: 100%; }
a { color: inherit; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--gold2); outline-offset: 3px; }

.skip-link {
  position: absolute; left: 16px; top: -64px; z-index: 30;
  background: var(--gold); color: #1a1204; padding: 10px 14px;
  border-radius: 2px; text-decoration: none; font-weight: 700;
  transition: top 160ms ease;
}
.skip-link:focus { top: 12px; }

/* ── header ──────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; min-height: 66px;
  padding: 12px clamp(18px, 4vw, 40px);
  background: rgba(8, 18, 38, 0.86);
  border-bottom: 1px solid rgba(232, 238, 249, 0.10);
  backdrop-filter: blur(14px);
}
.brand {
  display: inline-flex; align-items: center; gap: 11px;
  font-weight: 700; text-decoration: none; font-size: 15px; white-space: nowrap;
}
.brand-logo { width: 34px; height: 34px; }
.nav-links { display: flex; flex-wrap: wrap; gap: clamp(12px, 1.8vw, 26px); }
.nav-links a {
  text-decoration: none; font-size: 14px; color: #c3d1e8;
  padding: 4px 0; border-bottom: 1px solid transparent;
}
.nav-links a:hover { color: var(--tx); }
.nav-links a[aria-current="page"] { color: var(--tx); border-bottom-color: var(--gold); }
.nav-cta {
  text-decoration: none; font-size: 13.5px; font-weight: 700;
  color: #1a1204; background: var(--gold);
  padding: 10px 16px; border-radius: 2px; white-space: nowrap;
}

/* "What we do" disclosure — ported from styles.css so the live nav keeps
   working, restyled for the dark shell. The offer pages are grouped behind
   it (f4c0049); a flat nav here would have quietly dropped four of them. */
.nav-menu { position: relative; }
.nav-menu > summary {
  display: inline-flex; align-items: center; gap: 7px;
  cursor: pointer; white-space: nowrap; list-style: none;
  font-size: 14px; color: #c3d1e8; padding: 4px 0;
  border-bottom: 1px solid transparent;
}
/* Both are needed: ::marker for standards-compliant engines, the -webkit
   pseudo-element for Safari, which still ignores list-style here. */
.nav-menu > summary::marker { content: ""; }
.nav-menu > summary::-webkit-details-marker { display: none; }
.nav-menu > summary:hover,
.nav-menu > summary:focus-visible { color: var(--tx); }
.nav-menu-current > summary { color: var(--tx); border-bottom-color: var(--gold); }
.nav-caret {
  width: 6px; height: 6px;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 160ms ease;
}
.nav-menu[open] > summary .nav-caret { transform: translateY(1px) rotate(-135deg); }
.nav-panel {
  position: absolute; top: calc(100% + 14px); left: 50%;
  transform: translateX(-50%); z-index: 30;
  display: grid; gap: 2px; min-width: 216px; padding: 8px;
  background: #0d1f3a;
  border: 1px solid rgba(232, 238, 249, 0.16);
  border-radius: 3px;
  box-shadow: 0 18px 40px rgba(4, 10, 22, 0.55);
}
.nav-panel a {
  display: block; padding: 9px 12px; border-radius: 2px;
  white-space: nowrap; text-decoration: none; font-size: 14px; color: #c3d1e8;
}
.nav-panel a:hover, .nav-panel a:focus-visible { background: rgba(232, 238, 249, 0.09); color: var(--tx); }
@media (max-width: 720px) {
  .nav-panel {
    position: static; transform: none; min-width: 0;
    box-shadow: none; background: transparent; border: 0; padding: 6px 0 0 12px;
  }
}
@media (max-width: 1080px) { .nav-cta { display: none; } }
/* Sticky is dropped on small screens, matching what styles.css already does
   at 680px. Seven links plus a disclosure wrap to about 144px here, and a
   sticky bar that tall costs roughly a fifth of every phone screen for the
   whole scroll. It stays sticky on desktop, where it is one 66px row. */
@media (max-width: 720px) {
  .site-header {
    position: relative;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  .nav-links { width: 100%; gap: 14px; }
  .nav-links a, .nav-menu > summary { font-size: 13px; }
}

/* ── the continuous column ───────────────────────────────── */
.col { position: relative; isolation: isolate; }
/* one gradient for the entire dark run — this is what kills the boxes */
.col::before {
  content: ""; position: absolute; inset: 0; z-index: -3;
  background: linear-gradient(180deg,
    var(--n0) 0%, #0c1c35 16%, var(--n1) 38%,
    #081527 64%, var(--n2) 86%, #060e1e 100%);
}
/* carried over from the live site's vocabulary: big soft radials, no hard stops */
.col::after {
  content: ""; position: absolute; inset: 0; z-index: -3; pointer-events: none;
  background:
    radial-gradient(1100px 620px at 70% 6%, rgba(31, 79, 168, 0.30) 0%, transparent 62%),
    radial-gradient(760px 520px at 10% 32%, rgba(217, 176, 74, 0.08) 0%, transparent 60%),
    radial-gradient(900px 700px at 84% 60%, rgba(31, 79, 168, 0.20) 0%, transparent 64%),
    radial-gradient(700px 480px at 18% 88%, rgba(217, 176, 74, 0.06) 0%, transparent 60%);
}
.col-close::before { background: linear-gradient(180deg, #0a1830 0%, #071022 100%); }

canvas[data-graph-field] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: -2; pointer-events: none;
}
/* A gentle, even knock-back over the whole field. This used to be a
   left-heavy veil — dark under the text column, open on the right — which
   worked until the alternating rows put text on the right too, and the
   lede there measured 1.09:1 against a hub node. Nothing that depends on
   which side the copy is on can survive a layout that swaps sides, so the
   even veil handles the field and the scrim below handles the text. */
.veil {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(10, 24, 48, 0.55) 0%, rgba(10, 24, 48, 0.34) 9%,
      rgba(10, 24, 48, 0.34) 100%);
}
.veil-centre { background: linear-gradient(180deg, rgba(10, 24, 48, 0.38), rgba(10, 24, 48, 0.38)); }

/* Local scrim behind every block of copy, so a full-brightness hub node
   landing behind a glyph still leaves the text above 4.5:1. The graph stays
   visible in the margins and between blocks, which is where it was doing
   the work anyway.

   Solid, then masked to feather only in the outer margin. A radial was the
   obvious move and it does not work: an ellipse cannot cover a rectangle
   of text, so it had already fallen to ~0.4 at the left edge of the copy
   and a hub node there measured 2.94:1. This holds full strength to 10px
   past the text on every side and does its fading outside it. */
.col .in, .col .row .txt, .col .steps,
.col .wide-photo, .col .embed, .col .contact-layout { position: relative; }
.col .in::before, .col .row .txt::before, .col .steps::before,
.col .wide-photo::before, .col .embed::before, .col .contact-layout::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  /* Generous inset with a long feather. At a 76px inset and a 66px fade the
     scrim was reading as a soft-edged rectangle behind the closing block —
     a box, which is the one thing this layout is trying not to have. The
     fade is now long enough to dissolve, and the inset grows with it so
     full strength still reaches ~20px past the text on every side. */
  left: -128px; right: -128px; top: -84px; bottom: -84px;
  background: rgba(10, 24, 48, 0.93);
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 108px, #000 calc(100% - 108px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
  mask-image:
    linear-gradient(90deg, transparent 0, #000 108px, #000 calc(100% - 108px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* On a phone the copy already runs nearly edge to edge, so a 76px bleed
   just pushes the page sideways (measured: 432px of scrollWidth in a 375px
   viewport). Take it to the viewport edges instead and feather vertically
   only — there is no side margin left to fade into. */
@media (max-width: 760px) {
  .col .in::before, .col .row .txt::before, .col .steps::before,
  .col .wide-photo::before, .col .embed::before, .col .contact-layout::before {
    left: -18px; right: -18px;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
    -webkit-mask-composite: source-over;
    mask-composite: add;
  }
}

/* ── the barnacle plate ──────────────────────────────────── */
/* Sits in the open right-hand side of the hero, opposite the headline.
   z-index 0 is deliberate and does the layering: it puts the plate above
   the graph canvas (-2), the veil (-1) and the copy's scrim (-1), but
   under .in, which paints later at the same level — so the mark never
   washes out the headline and never gets washed out by the scrim.

   Capped at 340px because the artwork's real extent is only 380x334; sized
   any larger it is being upscaled and the engraved hatching goes soft.
   Multiply blend lets the navy come through the plate's white fills so it
   reads as printed on the field rather than pasted over it, and the
   brightness lift keeps the linework from closing up once it does. */
.hero-mark {
  position: absolute; z-index: 0; pointer-events: none;
  /* Anchored to the content column and tucked just inside it: the mark's
     right edge lands 20px in from .in's right edge, so it sits in the dead
     space beside the copy instead of drifting into the margin. Anchoring to
     the viewport pushes it further out the wider the monitor gets, which is
     what stranded it on its own. The +20px was measured off Brian's mark-up
     at ~2000px; it holds a steady 165px gap to the headline from 1440 up,
     and below the column width it falls back to the viewport edge. */
  right: max(clamp(12px, 5vw, 76px), calc(50% - var(--max) / 2 + 20px));
  /* Opposite the lede and buttons rather than the headline. Not lower: the
     chat widget is fixed to the bottom-right and at 1280 it starts clipping
     the plate's corner past about 62%. */
  top: 60%; transform: translateY(-50%);
  width: clamp(190px, 24vw, 340px); height: auto;
  /* 0.80 against 0.62 and 0.95: the lower value reads as an accidental
     watermark, the higher one starts to look pasted on and pushes the
     plinth under the cluster forward. */
  opacity: 0.80;
  mix-blend-mode: screen;
  filter: brightness(0.92) contrast(1.06);
}
/* Below this the headline reflows to the full width and there is no open
   space left to sit in — the plate would land on top of the copy. */
@media (max-width: 900px) { .hero-mark { display: none; } }

.z { position: relative; padding: clamp(72px, 9vw, 128px) clamp(18px, 5vw, 40px); }
.z.tight { padding-bottom: clamp(38px, 5vw, 60px); }
.hero { padding-top: clamp(72px, 11vw, 150px); padding-bottom: clamp(80px, 11vw, 150px); }
.in { max-width: var(--max); margin: 0 auto; }
.narrow { max-width: 760px; }
/* the surfacing wash reaches 260px up, so the last dark section has to end
   at least that far above it or its copy sits in the falloff */
.z-last { padding-bottom: clamp(300px, 30vw, 380px); }

/* ── type ────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 9px; margin: 0 0 26px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: #d6e0f2;
  border: 1px solid rgba(217, 176, 74, 0.45); border-radius: 100px;
  padding: 7px 16px;
}
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); }
h1 {
  font-family: var(--disp); font-weight: 400;
  font-size: clamp(38px, 6.4vw, 74px); line-height: 1.03;
  letter-spacing: -0.018em; margin: 0 0 24px; max-width: 15ch; text-wrap: balance;
}
h1 i, h2 i { font-style: italic; color: var(--gold2); }
h2 {
  font-family: var(--disp); font-weight: 400;
  font-size: clamp(28px, 4.2vw, 50px); line-height: 1.08;
  letter-spacing: -0.012em; margin: 0 0 20px; max-width: 19ch; text-wrap: balance;
}
.kick {
  display: flex; align-items: center; gap: 13px; margin: 0 0 20px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--gold);
}
.kick .no { color: var(--gold2); }
.kick s { flex: 0 1 88px; height: 1px; background: currentColor; opacity: 0.32; text-decoration: none; }
.lede { color: var(--mu); font-size: 16.5px; line-height: 1.68; max-width: 58ch; margin: 0 0 28px; }
.cta { display: flex; gap: 12px; flex-wrap: wrap; }
.b1 {
  background: var(--gold); color: #1a1204; font-weight: 700; font-size: 15px;
  padding: 15px 26px; border-radius: 2px; text-decoration: none;
}
.b1:hover { background: var(--gold2); }
.b2 {
  color: var(--tx); border: 1px solid rgba(232, 238, 249, 0.34); font-size: 15px;
  padding: 15px 26px; border-radius: 2px; text-decoration: none;
}
.b2:hover { border-color: var(--tx); }
.trust {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em;
  text-transform: uppercase; color: rgba(232, 238, 249, 0.78); margin: 28px 0 0;
}
.contact-note { color: var(--mu); font-size: 14px; margin: 22px 0 0; }

/* ── horizon rule ────────────────────────────────────────── */
/* The bloom's vertical radius must be smaller than the box half-height, or
   the gradient is still visible when it hits the box edge and clips to a
   hard line. 50% ends the falloff well inside the box so it bleeds out on
   all four sides, not just left and right. */
.horizon { position: relative; height: 0; }
.horizon::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(217, 176, 74, 0.55) 22%,
    rgba(217, 176, 74, 0.55) 78%, transparent);
}
.horizon::after {
  content: ""; position: absolute; left: 0; right: 0; top: -110px; height: 220px;
  pointer-events: none;
  background: radial-gradient(58% 50% at 50% 50%, rgba(217, 176, 74, 0.12), transparent 72%);
}

/* ── panorama ────────────────────────────────────────────── */
/* Full-bleed, with the field bleeding into the plate on all four sides
   rather than framing it. */
.pano { position: relative; margin: 0; line-height: 0; }
.pano img { width: 100%; height: clamp(240px, 32vw, 420px); object-fit: cover; filter: brightness(1.18) contrast(1.04); }
/* The captures are near-neutral, so dropped onto navy they read as a grey
   box pasted in. mix-blend-mode:color takes hue from this layer and
   luminance from the photo — a duotone, so it is lit in the page's blue. */
.pano .tint { position: absolute; inset: 0; background: #16356f; mix-blend-mode: color; pointer-events: none; }
.pano .bleed {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(180deg, var(--n1) 0%, transparent 24%, transparent 72%, var(--n1) 100%),
    linear-gradient(90deg, var(--n1) 0%, transparent 15%, transparent 85%, var(--n1) 100%);
}
.pano figcaption {
  position: absolute; left: clamp(18px, 5vw, 40px); bottom: 18px; z-index: 2;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: #c8d6ef; line-height: 1.5;
  text-shadow: 0 1px 10px rgba(6, 14, 30, 0.95);
}

/* ── straddle cards ──────────────────────────────────────── */
/* The rule runs full width behind the grid so the cards interrupt it.
   That interruption is the technique — with no line to cross this would
   just be a row of cards. */
.straddle-wrap { position: relative; padding: 0 clamp(18px, 5vw, 40px); }
.straddle-rule {
  position: absolute; left: 0; right: 0; top: 50%; height: 1px; z-index: 1;
  background: linear-gradient(90deg, transparent, rgba(217, 176, 74, 0.5) 18%,
    rgba(217, 176, 74, 0.5) 82%, transparent);
}
.straddle-rule::after {
  content: ""; position: absolute; left: 0; right: 0; top: -100px; height: 200px;
  background: radial-gradient(55% 50% at 50% 50%, rgba(217, 176, 74, 0.11), transparent 72%);
}
.straddle {
  position: relative; z-index: 3; display: grid; gap: 1px;
  /* 300px, not 260: the grid draws its own background through the 1px gaps,
     so a trailing empty cell shows up as a broken translucent panel. At
     260 the six cards laid out 4+2 and left two of them. 300 forces three
     columns, which divides exactly. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  max-width: var(--max); margin: 0 auto;
  background: rgba(232, 238, 249, 0.13);
  border: 1px solid rgba(232, 238, 249, 0.13);
}
.straddle article { background: #0a1830; padding: 26px 24px; }
.straddle b {
  display: block; font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: 0.2em; color: var(--gold); margin-bottom: 12px;
}
.straddle h3 { font-family: var(--disp); font-weight: 400; font-size: 21px; line-height: 1.2; margin: 0 0 9px; }
/* Three of the six cards have a page behind them. The link is marked by a
   gold underline on hover rather than by colour, so the cards that lead
   somewhere and the cards that do not still read as one set. */
.straddle h3 a {
  text-decoration: none; color: inherit;
  border-bottom: 1px solid rgba(217, 176, 74, 0.42);
  padding-bottom: 1px;
}
.straddle h3 a:hover, .straddle h3 a:focus-visible { border-bottom-color: var(--gold); color: var(--gold2); }
.straddle p { margin: 0; font-size: 14px; color: var(--mu); line-height: 1.6; }

/* ── alternating rows ────────────────────────────────────── */
/* Text and image swap sides so the eye zig-zags instead of tracking one
   left margin the whole way down. */
.row {
  display: grid; gap: clamp(28px, 4vw, 60px); align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  max-width: var(--max); margin: 0 auto;
}
/* Masked, not vignetted. An overlay in the ground colour still ends in a
   rectangle you can find; a mask removes the image's own pixels so it
   dissolves into whatever is behind it, graph included. The falloff has to
   reach zero at the edge midpoints or the rectangle stays legible — which
   makes the shape circular, and a vault graph is round anyway. */
.row .fig {
  position: relative; margin: 0; line-height: 0;
  -webkit-mask-image: radial-gradient(52% 52% at 50% 50%, #000 46%, transparent 99%);
  mask-image: radial-gradient(52% 52% at 50% 50%, #000 46%, transparent 99%);
}
.row .fig img, .row .fig video {
  width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover;
  filter: brightness(1.22) contrast(1.05);
}
.row .fig .tint { position: absolute; inset: 0; background: #16356f; mix-blend-mode: color; pointer-events: none; }
.row.flip .fig { order: 2; }
.row.flip .txt { order: 1; }
.row .txt h2 { font-size: clamp(26px, 3.2vw, 40px); max-width: none; }
/* :last-child, not every lede — flattening the margin on all of them ran
   consecutive paragraphs together with no gap between them */
.row .txt .lede { margin-bottom: 18px; }
.row .txt .lede:last-child { margin-bottom: 0; }
@media (max-width: 820px) {
  .row { grid-template-columns: 1fr; }
  .row.flip .fig, .row.flip .txt { order: initial; }
}

/* ══ light-at-the-top variant (About) ═══════════════════════
   About opens on white and drops into the field, rather than the other
   way round. Same .surface rules, minus the incoming wash — there is
   nothing above it to surface out of. */
.surface-top::before { content: none; }
.surface-top { padding-top: clamp(56px, 7vw, 92px); }
.surface h1 { color: var(--pink); font-size: clamp(34px, 5.4vw, 60px); max-width: 16ch; }
.surface h1 i { color: var(--proy); }

/* The descent: white into navy, the mirror of .surface's wash. Sits above
   the canvas and veil but under the copy, so the graph fades in beneath
   it. The first section below needs the same clearance the surfacing rule
   needs — text must not sit in the falloff, because the ground under it
   keeps moving. */
.descent {
  position: absolute; left: 0; right: 0; top: 0; height: 280px;
  z-index: -1; pointer-events: none;
  background: linear-gradient(180deg,
    var(--pw) 0%, rgba(247, 248, 251, 0.74) 15%, rgba(247, 248, 251, 0.34) 38%,
    rgba(247, 248, 251, 0.08) 66%, transparent 100%);
}
.z-first { padding-top: clamp(320px, 32vw, 400px); }

/* founder row, carried over from the old page's 5fr/7fr split */
.founder {
  display: grid; gap: clamp(28px, 5vw, 56px); align-items: start;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  max-width: var(--max); margin: 0 auto;
}
@media (max-width: 820px) { .founder { grid-template-columns: 1fr; } }
/* Held well under the column width so the portrait sits beside the copy
   rather than towering over it — the two columns should finish at roughly
   the same depth, the way the old page balanced them. */
.portrait-plate { margin: 0; display: grid; gap: 14px; max-width: 360px; }
.portrait-plate figcaption {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--pmu);
}

/* ── photographs ─────────────────────────────────────────── */
/* Photographs keep their own proportions. Forcing aspect-ratio on them is
   what squeezed the founder portrait: object-fit:cover then crops to fill
   the box, so a 900x1342 portrait jammed into 3/4 lost its head and feet,
   and the 1100x618 desk shot lost its sides. width/height come from the
   real files so the ratio is right before the image lands. */
/* Deliberately no aspect-ratio and no object-fit here. Both were the bug:
   a forced ratio plus object-fit:cover crops to fill, and writing
   aspect-ratio:auto to undo it also stops the browser reserving space from
   the width/height attributes, collapsing the unloaded image to 2px and
   shifting the layout when it lands. width + height:auto is all it needs. */
.photo img { width: 100%; height: auto; }
/* No mask, no border, no plate. brian-cutout.webp is a real extraction —
   the studio background floodfilled out to transparency and the frame cut
   at the waist — so Brian sits directly on the page and there is no photo
   edge anywhere to soften. The fade this replaces existed only to hide the
   frame's bottom cut, and it climbed too far up his body to be worth it.
   The source's baked-in dark right-hand stripe was trimmed before the
   extraction, so that edge is gone too. */
.portrait-plate img { width: 100%; height: auto; }
/* full-width documentary photo — the desk shot is 16:9 and belongs wide */
.wide-photo { margin: clamp(32px, 4vw, 48px) auto 0; max-width: var(--max); }
.wide-photo img {
  width: 100%; height: auto;
  border: 1px solid rgba(232, 238, 249, 0.14); border-radius: 3px;
}
.wide-photo figcaption {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--mu); margin-top: 12px;
}

/* ── stacked stage figures (old About layout) ────────────── */
/* Three stages read as a progression only if each is big enough to see the
   difference. The old page stacked them full width; a 3-across grid made
   stages one and two indistinguishable. */
.stage { margin: 0 0 clamp(36px, 5vw, 56px); max-width: var(--max); }
.stage:last-of-type { margin-bottom: 0; }
.stage .frame {
  position: relative; overflow: hidden; border-radius: 3px;
  border: 1px solid rgba(232, 238, 249, 0.14); aspect-ratio: 3 / 2;
}
/* No duotone. Measured, the three sources are not equally colourful: the
   scaffold and production captures are literally 0.0 mean saturation, and
   only the mature vault carries any (4.7) — its teal and green node types.
   That is the section's own argument, so it should be visible: grey while
   the system is being built, colour once it has enough structure to
   classify anything. Saturate lifts the one asset that has colour and does
   nothing to the two that do not, since zero times anything is zero. */
.stage .frame img, .stage .frame video {
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(1.16) contrast(1.06) saturate(1.5);
}
/* Phase chips over the stage recordings — ported from site-motion.css so
   About keeps them without loading that whole sheet. motion.js swaps .on as
   the video passes each data-from mark; without these the viewer is left
   guessing which stage of the build they are watching. */
.stage .bv-phases {
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  display: flex; gap: 6px; flex-wrap: wrap;
}
.stage .bv-phases span {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em;
  color: #d6e0f2; background: rgba(6, 14, 30, 0.78);
  border: 1px solid rgba(232, 238, 249, 0.28); border-radius: 3px;
  padding: 4px 9px;
  transition: background 0.4s ease, color 0.4s ease, border-color 0.4s ease;
}
.stage .bv-phases span.on {
  background: var(--gold); color: #1a1204; border-color: var(--gold); font-weight: 700;
}
@media (prefers-reduced-motion: reduce) { .stage .bv-phases span { transition: none; } }
@media (max-width: 560px) { .stage .bv-phases span { font-size: 9.5px; padding: 3px 7px; } }

.stage b {
  display: block; font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); margin: 16px 0 8px;
}
.stage figcaption { font-size: 14.5px; color: var(--mu); line-height: 1.6; max-width: 62ch; }
.stage-note { font-size: 13.5px; color: var(--mu); line-height: 1.6; max-width: 62ch; margin: clamp(28px,4vw,40px) 0 0; }

/* ── video embed ─────────────────────────────────────────── */
.embed { margin: clamp(32px, 4vw, 48px) auto 0; max-width: var(--max); }
.embed .frame {
  position: relative; aspect-ratio: 16 / 9; border-radius: 3px; overflow: hidden;
  border: 1px solid rgba(232, 238, 249, 0.14); background: #060e1e;
}
.embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.embed figcaption {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--mu); margin-top: 12px;
}


/* ── plain lists ─────────────────────────────────────────── */
.bullets { list-style: none; padding: 0; margin: 0 0 26px; display: grid; gap: 9px; max-width: 58ch; }
.bullets li { position: relative; padding-left: 20px; color: var(--mu); font-size: 15.5px; }
.bullets li::before {
  content: ""; position: absolute; left: 2px; top: 0.62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--gold); opacity: 0.85;
}
.surface .bullets li { color: var(--pmu); }
.surface .bullets li::before { background: var(--pgold); }

/* values: two columns of short lines, no card chrome */
.vals {
  list-style: none; padding: 0; max-width: var(--max);
  margin: clamp(34px, 4vw, 50px) auto 0;
  display: grid; gap: 0 clamp(24px, 4vw, 56px);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.vals li {
  padding: 16px 0; border-top: 1px solid rgba(232, 238, 249, 0.14);
  font-family: var(--disp); font-size: 19px; color: var(--tx); line-height: 1.3;
}
.surface .vals li { border-top-color: rgba(10, 20, 36, 0.12); color: var(--pink); }

/* ── numbered steps (dark) ───────────────────────────────── */
.steps { list-style: none; padding: 0; margin: clamp(46px, 6vw, 72px) auto 0; display: grid; gap: 0; }
.steps li {
  display: grid; grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
  gap: clamp(14px, 3vw, 40px); align-items: baseline;
  padding: 22px 0; border-top: 1px solid rgba(232, 238, 249, 0.12);
}
.steps li:last-child { border-bottom: 1px solid rgba(232, 238, 249, 0.12); }
.steps b {
  font-family: var(--mono); font-weight: 400; font-size: 12px;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold);
}
.steps p { margin: 0; color: var(--mu); font-size: 15px; line-height: 1.62; }
@media (max-width: 640px) { .steps li { grid-template-columns: 1fr; gap: 6px; } }

/* ── surfacing (dark → white, no seam) ───────────────────── */
.surface {
  position: relative; background: var(--pw); color: var(--pink);
  padding: clamp(90px, 12vw, 160px) clamp(18px, 5vw, 40px) clamp(72px, 10vw, 120px);
}
.surface::before {
  content: ""; position: absolute; left: 0; right: 0; top: -260px; height: 260px;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, rgba(247, 248, 251, 0.06) 34%,
    rgba(247, 248, 251, 0.30) 62%, rgba(247, 248, 251, 0.72) 84%, var(--pw) 100%);
}
.surface .kick { color: var(--pgold); }
.surface .kick .no { color: var(--proy); }
.surface h2 { color: var(--pink); }
.surface h2 i { color: var(--proy); }
/* The light zone needs its own body colour. Without this the dark-zone
   --mu carries over onto white and the copy lands around 2:1 — it only
   went unnoticed because the first light section built had no prose in it. */
.surface .lede, .surface p { color: var(--pmu); }
.surface .trust { color: var(--pmu); }
.surface .contact-note { color: var(--pmu); }
.surface .b2 { color: var(--pink); border-color: rgba(10, 20, 36, 0.34); }
.surface .b2:hover { border-color: var(--pink); }
.proc {
  list-style: none; padding: 0; max-width: var(--max);
  margin: clamp(38px, 5vw, 60px) auto 0;
  display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  background: rgba(10, 20, 36, 0.12);
  border: 1px solid rgba(10, 20, 36, 0.12);
}
.proc li { background: var(--pw); padding: 26px 24px; }
.proc b {
  display: block; font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: 0.2em; color: var(--pgold); margin-bottom: 12px;
}
.proc h3 { font-family: var(--disp); font-weight: 400; font-size: 20px; line-height: 1.22; margin: 0 0 9px; color: var(--pink); }
.proc p { margin: 0; font-size: 14px; color: var(--pmu); line-height: 1.6; }

/* ── tide line ───────────────────────────────────────────── */
.tide { position: relative; line-height: 0; background: var(--pw); }
.tide svg { display: block; width: 100%; height: clamp(64px, 8vw, 120px); }

/* ── contact panel ───────────────────────────────────────── */
/* The booking details that live beside the closing block on About: the
   real call link, the scheduling note and the email. Carried over from
   styles.css rather than folded into the mega copy, because the mega
   block is centred and this is a list of specifics that wants a left
   edge to line up against. */
.contact-layout {
  display: grid; gap: clamp(28px, 5vw, 56px); align-items: start;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  max-width: var(--max); margin: 0 auto; text-align: left;
}
@media (max-width: 860px) { .contact-layout { grid-template-columns: 1fr; } }
.contact-panel {
  padding: 26px 24px;
  background: rgba(232, 238, 249, 0.05);
  border: 1px solid rgba(232, 238, 249, 0.16);
  border-radius: 3px;
}
.contact-label {
  margin: 0 0 12px; color: var(--gold);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em;
  text-transform: uppercase;
}
.contact-panel > a {
  display: inline-block; font-family: var(--disp); font-weight: 400;
  font-size: 24px; line-height: 1.2; color: var(--tx); text-decoration: none;
  border-bottom: 1px solid rgba(217, 176, 74, 0.5); padding-bottom: 2px;
}
.contact-panel > a:hover, .contact-panel > a:focus-visible {
  color: var(--gold2); border-bottom-color: var(--gold);
}
.contact-panel .contact-note { margin: 16px 0 0; font-size: 13.5px; color: var(--mu); line-height: 1.6; }
.contact-panel .contact-note a { color: var(--gold2); }

/* ── closing block ───────────────────────────────────────── */
.mega { text-align: center; padding-bottom: clamp(80px, 10vw, 130px); }
.mega .in { max-width: 720px; }
.mega .kick { justify-content: center; }
.mega h2 { max-width: none; margin-left: auto; margin-right: auto; }
.mega .lede { margin-left: auto; margin-right: auto; }
.mega .cta { justify-content: center; }

/* ── footer ──────────────────────────────────────────────── */
.site-footer {
  background: #060e1e; color: #c3d1e8;
  padding: clamp(44px, 6vw, 72px) clamp(18px, 5vw, 40px) 40px;
  border-top: 1px solid rgba(232, 238, 249, 0.10);
}
.footer-grid {
  max-width: var(--max); margin: 0 auto;
  display: grid; gap: clamp(28px, 5vw, 64px);
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
}
.footer-id p { margin: 0 0 8px; font-size: 13.5px; color: #9db0ce; }
.footer-brand { display: flex; align-items: center; gap: 11px; }
.footer-tagline { font-family: var(--disp); font-size: 19px; color: var(--tx); }
.footer-legal { font-size: 12.5px; color: #7e90ad; }
.footer-cols { display: grid; gap: clamp(20px, 4vw, 48px); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.footer-col-title {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 12px;
}
.footer-cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.footer-cols a { text-decoration: none; font-size: 14px; color: #c3d1e8; }
.footer-cols a:hover { color: var(--tx); text-decoration: underline; }
@media (max-width: 720px) { .footer-grid { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}
