/* ============================================================
   ABHISHEK RUNGTA — SYSTEM LAYER
   Implements the twelve mechanisms in research/findings.md § Gate 1.
   Comments name the mechanism each rule enforces.
   ============================================================ */

*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0 }

/* [hidden] is a UA rule, and ANY author display declaration beats it regardless
   of specificity. Without this, .mgrid{display:grid} kept both podcast tab
   panels on screen at once. Everything that toggles visibility relies on it. */
[hidden]{ display:none !important }

html{ -webkit-text-size-adjust:100% }

body{
  font-family:var(--font);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  letter-spacing:var(--ls-body);
  color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
}

img,svg,video{ display:block; max-width:100%; height:auto }
/* M2 — radius 0 on every rectangle; the only round object is a human face */
img{ border-radius:var(--r-structural) }
.portrait{ border-radius:var(--r-portrait); overflow:hidden }

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

::selection{ background:var(--accent); color:var(--paper) }

:focus-visible{ outline:3px solid var(--accent); outline-offset:3px }

.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--accent); color:var(--paper); padding:.75rem 1.25rem;
}
.skip:focus{ left:0 }

/* ---- shell ------------------------------------------------- */
.shell{ max-width:var(--shell-max); margin-inline:auto; padding-inline:var(--shell-pad) }
.shell--narrow{ max-width:860px }

/* M1 — division is by ground, never by a rule.
   No section carries a border on any edge. */
section{ border:0 }
.band{ padding-block:var(--section-y) }
.band--tight{ padding-block:var(--section-y-tight) }
.band--field{ background:var(--field) }
.band--paper{ background:var(--paper) }

/* ---- type -------------------------------------------------- */
.display{
  font-size:var(--fs-display); line-height:var(--lh-display);
  letter-spacing:var(--ls-display); font-weight:var(--w-bold);
  text-wrap:balance;
}
h1,h2{ font-size:var(--fs-h2); line-height:var(--lh-head); letter-spacing:-.015em; font-weight:var(--w-bold) }
h1.display{ font-size:var(--fs-display) }
h3{ font-size:var(--fs-h3); line-height:1.3; font-weight:var(--w-medium) }

/* M6 — in-headline emphasis on the operative phrase.
   Same size, same weight, italic, accent. Never a whole line. */
h1 em, h2 em, .display em{
  font-style:italic; color:var(--accent); font-weight:inherit;
}

p{ max-width:var(--measure) }
p + p{ margin-top:1.15em }

.lede{ font-size:1.375rem; line-height:1.5; max-width:34ch }
.meta{ font-size:var(--fs-small); color:var(--muted); max-width:none }

/* M7 — kicker, head and body share one left axis. Never centred. */
.kicker{
  display:block; font-size:var(--fs-kicker); font-weight:var(--w-medium);
  letter-spacing:var(--ls-kicker); text-transform:uppercase;
  color:var(--accent); margin-bottom:1.25rem;
}
/* ch units resolve against the element's own font-size — set the measure on
   the heading itself, not on the wrapper, or a 38px head inherits an 18px ch. */
.head{ margin-bottom:2.25rem }
.head h1,.head h2,.head .display,h1.head,h2.head{ max-width:22ch }
.head p{ margin-top:1rem; color:var(--muted); max-width:52ch }
/* a section that needs a label and a count, not a headline */
.head--inline{ display:flex; align-items:baseline; gap:1rem; margin-bottom:1.75rem }
.head--inline .kicker{ margin-bottom:0 }
.head__note{ margin-top:0; color:var(--muted); font-size:var(--fs-small) }

/* ---- title/tabs row + search, right-aligned to the shell -----
   Shared by the four listing pages: the left side (a title, a head--inline
   block, or the podcast tabs) claims the row; the search is pinned right and
   wraps to its own line first, before it ever crowds the title. */
.head--split{
  display:flex; align-items:center; justify-content:space-between;
  flex-wrap:wrap; gap:1rem 1.5rem;
}
.head--split > :first-child{ min-width:0 }
.head--split .search{ margin-top:0; margin-left:auto }
@media (max-width:520px){
  /* Podcasts is the one page where the left side of .head--split (the tabs)
     cannot simply shrink to fit — a flexbox 1fr-vs-fixed split badly
     mis-sized the two here (the switch was measured shrinking BELOW its own
     button text, the search growing well past its own basis, on this
     specific two-item/space-between combination). Grid with an explicit
     column list has no such ambiguity: the fixed column is exactly what it
     says, every time. */
  .head--split:has(.switch){
    display:grid; grid-template-columns:1fr 112px; align-items:stretch;
    gap:.5rem; flex-wrap:nowrap;
  }
  .head--split .switch{ min-width:0; flex-wrap:nowrap }
  .head--split .switch__btn{ font-size:.6875rem; padding:.55rem .4rem; gap:.25rem; flex:1 1 auto }
  .head--split .switch__n{ margin-left:.2rem }
  .head--split .search{ max-width:none; width:100% }
  .search input{ font-size:.8125rem; padding-block:.6875rem }
  .search__icon{ width:16px; height:16px }
  .search__clear{ display:none }   /* no room at this width; Escape still clears */
}
.search--sm{ max-width:320px }
.search--sm input{ font-size:1rem; padding-block:.8125rem }

/* ---- controls ---------------------------------------------- */
/* M2/M5 — radius 0 including the button; accent as a solid fill only */
.btn{
  display:inline-flex; align-items:center; gap:.6rem;
  font-family:inherit; font-size:var(--fs-kicker); font-weight:var(--w-medium);
  letter-spacing:var(--ls-kicker); text-transform:uppercase;
  padding:1.05rem 1.75rem; border-radius:var(--r-interactive);
  /* a transparent 1px border, not border:0 — otherwise .btn--solid is 2px
     shorter than .btn--line and a pair of them never lines up */
  border:1px solid transparent;
  cursor:pointer; transition:background var(--dur) var(--ease), color var(--dur) var(--ease);
}
/* button pairs. Flex, not inline-flex in a <p> with &nbsp; — baseline
   alignment on inline-flex offsets boxes of different heights. */
.actions{ display:flex; flex-wrap:wrap; align-items:stretch; gap:.75rem }
.btn svg{ width:16px; height:16px; flex:none }
.btn--solid{ background:var(--accent); color:var(--paper) }
.btn--solid:hover{ background:var(--accent-deep) }
.btn--line{ background:transparent; color:var(--ink); border-color:var(--ink) }
.btn--line:hover{ background:var(--ink); color:var(--paper) }

/* the inline text link: underline appears, it does not slide */
.tlink{
  display:inline-flex; align-items:center; gap:.4rem;
  font-size:var(--fs-small); font-weight:var(--w-medium); color:var(--accent);
  border-bottom:1px solid transparent; padding-bottom:2px;
  transition:border-color var(--dur) var(--ease);
}
.tlink svg{ width:15px; height:15px }
.tlink:hover{ border-bottom-color:var(--accent) }

/* ---- header ------------------------------------------------ */
/* the masthead is a control, not a section — prohibition #4 governs <section>.
   It carries a hairline so it stays legible over a white band on scroll. */
.masthead{ background:var(--paper); position:sticky; top:0; z-index:40;
  border-bottom:var(--rule-w) solid var(--hair);
  transition:background var(--dur) var(--ease), border-color var(--dur) var(--ease) }

/* Over the video hero the bar is transparent and light; once the hero has
   scrolled past it becomes the ordinary white bar. A ground change, which is
   one of the two motion behaviours mechanism 12 allows — nothing moves. */
.masthead--over{ background:transparent; border-bottom-color:transparent; color:var(--paper) }
.masthead--over .wordmark,
.masthead--over .nav a,
.masthead--over .navtoggle{ color:var(--paper) }
.masthead--over .wordmark span{ color:var(--accent-faint) }
.masthead--over .nav a:hover{ border-bottom-color:var(--paper) }
.masthead--over .nav a[aria-current="page"]{ border-bottom-color:var(--paper) }
/* the accent fill disappears against the night sky — the CTA inverts instead */
.masthead--over .btn--solid{ background:var(--paper); color:var(--ink) }
.masthead--over .btn--solid:hover{ background:var(--accent-faint) }

.masthead__in{
  display:flex; align-items:center; gap:var(--gutter);
  min-height:var(--bar-h);
}
/* the avatar is capped below the bar's own min-height, so adding it cannot
   grow the header — 40px inside an 82px bar leaves the padding untouched */
.wordmark{ font-weight:var(--w-bold); font-size:1.0625rem; letter-spacing:-.01em; white-space:nowrap }
.wordmark span{ color:var(--accent) }

/* M-IA — flat six-item bar. 241 leaves live inside one branch's own
   filter, not in a mega menu the sitemap does not justify. */
.nav{ display:flex; gap:1.75rem; margin-left:auto; align-items:center }
.nav a{
  font-size:var(--fs-small); font-weight:var(--w-medium); color:var(--ink);
  padding-block:.35rem; border-bottom:var(--rule-w) solid transparent;
  transition:border-color var(--dur) var(--ease);
}
.nav a:hover{ border-bottom-color:var(--accent-faint) }
.nav a[aria-current="page"]{ border-bottom:var(--rule-w-live) solid var(--accent) } /* M12 */
/* social cluster — one box per icon, smaller than the CTA it replaces.
   In the transparent state the boxes stay white so they read as controls
   against the video rather than dissolving into it. */
.social{ display:flex; gap:.4rem; margin-left:.75rem }
.social__box{
  display:flex; align-items:center; justify-content:center;
  width:38px; height:38px; flex:none;
  background:var(--paper); color:var(--ink);
  border:1px solid var(--hair); border-radius:var(--r-interactive);
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease),
             border-color var(--dur) var(--ease);
}
.social__box .ico{ width:17px; height:17px }
.social__box:hover{ background:var(--accent); color:var(--paper); border-color:var(--accent) }
.masthead--over .social__box{ background:var(--paper); color:var(--ink); border-color:transparent }
.masthead--over .social__box:hover{ background:var(--accent-faint); color:var(--ink) }
.navtoggle{ display:none; margin-left:auto; background:none; border:0; padding:.5rem; color:var(--ink); cursor:pointer }
.navtoggle svg{ width:26px; height:26px }

/* ---- M4 · THE 64px OFFSET OVERLAP --------------------------
   Where an image meets a text panel, the panel overlaps the image
   by --overlap horizontally and is inset 48px vertically.
   Hard edges. No shadow, no radius. One per band, maximum. */
.overlap{ display:grid; grid-template-columns:7fr 5fr; align-items:center }
/* grid children default to min-content width; without this a 60px display word
   or a 160px mark refuses to shrink and the page overflows at 375px */
.overlap>*,.split>*,.stack__row>*,.serial>*,.wall__cell{ min-width:0 }
.overlap__panel{
  background:var(--paper); padding:3.5rem 3rem;
  margin-right:calc(var(--overlap) * -1); position:relative; z-index:2;
}
.overlap--flip{ grid-template-columns:5fr 7fr }
.overlap--flip .overlap__panel{ margin-right:0; margin-left:calc(var(--overlap) * -1); order:2 }
.overlap--flip .overlap__media{ order:1 }
.overlap__media{ position:relative; z-index:1; align-self:stretch; overflow:hidden }
.overlap__media img{ width:100%; height:100%; object-fit:cover; object-position:center top }

/* ---- THE VIDEO HERO ----------------------------------------
   Client-directed, 2026-08-22: the supplied hero-ar.mp4 as a homepage
   hero background, heading and subtext only, no CTAs, centred, at a
   smaller size so the summit reads clearly below the type.

   This knowingly overrides two derived rules and one mechanism. All three
   are recorded in research/findings.md rather than quietly rewritten:
     · Gate 3 rejection 5  — "no dark band of any size"
     · Gate 3 rejection 12 — "no mountain photograph used literally"
     · Mechanism 7         — "never centred"
   The overrides are contained to this one block. Nothing below the hero
   changes, and the site has no other dark ground and no other centred
   composition.

   Two things make it defensible rather than arbitrary. The clip's sky
   samples at #2b477c, which sits inside the brand's own blue ramp between
   --accent and --accent-deep, so the dark band is the brand's hue rather
   than an imported dark theme. And the composition is symmetric about the
   summit, which is the one case where a centred block is the correct
   answer rather than a default.

   Measured: white on the brightest pixel of the top quarter is 5.6:1 at
   worst across the whole clip, so the type needs no scrim — which keeps
   prohibition 3 (zero gradients) intact. */
.vhero{
  position:relative; overflow:hidden;
  background:var(--accent-deep);
  /* Reverted 2026-09-04 (b): back to the seated cutout, so the band comes back
     down to meet it rather than leaving a void above. */
  min-height:clamp(660px, 92vh, 860px);
  /* Pulled up under the sticky bar and given the height back as padding, so the
     transparent bar has video behind it rather than page ground. --bar-h is the
     bar's INNER height; its box is that plus the hairline, hence + --rule-w. */
  margin-top:calc((var(--bar-h) + var(--rule-w)) * -1);
  padding-block:calc(var(--bar-h) + var(--rule-w) + var(--hero-gap)) 0;
  display:flex; align-items:center;
}
.vhero__media{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:72% bottom;
  transform:scale(var(--hero-zoom)); transform-origin:50% 100%;
  filter:brightness(var(--hero-dim));
  z-index:0; pointer-events:none;
}

/* THE FIGURE — flush to the bottom edge of the band, and right-aligned to the
   CONTENT grid rather than the viewport, so its right edge lands exactly under
   the last icon in the header. That is why it lives inside .shell: an absolutely
   positioned child resolves against the shell's padding box, so right:--shell-pad
   is the content edge.
   No radius, no shadow: it is a cutout standing on the band's floor, and the
   floor is where the next section starts. Height-driven, so the crop at the
   bottom of the source stays exactly on the edge. */
.vhero__figure{
  position:absolute; right:var(--shell-pad); bottom:0; z-index:1;
  /* Reverted 2026-09-04 (b) to the seated ar-heritage.png cutout, near-square
     at 1.011, sized by WIDTH. 500px is the client's chosen cap; the delivered
     file is 1000px so the resample is done once by LANCZOS, not by the
     browser. See findings.md, 2026-09-03 (d). */
  width:clamp(320px, 42%, 500px); height:auto;
  pointer-events:none; user-select:none;
}

/* the type column sits left, on the site's one left axis. Mechanism 7 holds
   again here — the centred hero was a temporary client direction, now reverted.
   align-self:stretch is what lets the figure's bottom:0 reach the band's floor. */
.vhero__in{
  position:relative; z-index:2; text-align:left; align-self:stretch;
  /* a flex item shrinks to fit by default, which left the shell narrower than
     --shell-max and pulled the figure in off the content grid. width:100% makes
     it fill up to the cap, so the figure's right edge lands under the header's
     last icon exactly. */
  width:100%;
  display:grid; grid-template-columns:7fr 5fr;
}
.vhero__col{ align-self:center; padding-bottom:var(--hero-gap) }
.vhero .kicker{ color:var(--accent-faint); margin-bottom:1rem }
.vhero__title{
  color:var(--paper); font-weight:var(--w-bold);
  font-size:clamp(2rem, 3.6vw, 3.25rem);
  line-height:1.16; letter-spacing:-.018em;
  max-width:17ch; text-wrap:balance;
}
.vhero__title em{ font-style:italic; color:var(--accent-faint) }
.vhero__sub{
  color:var(--paper); font-size:1.0625rem; line-height:1.6;
  max-width:44ch; margin-top:1.1rem;
}

/* ---- M8 · THE CREDENTIAL TRIAD -----------------------------
   Three claims, 1px vertical accent rules, no cards, no icons,
   nothing counting up. Taken directly from the reference band cd-01. */
.triad{ display:grid; grid-template-columns:repeat(3,1fr) }
.triad__item{ padding:0 2.5rem; border-left:var(--rule-w) solid var(--accent-faint) }
.triad__item:first-child{ padding-left:0; border-left:0 }
.triad__n{ display:block; font-size:2.25rem; font-weight:var(--w-bold); letter-spacing:-.02em; line-height:1.1 }
.triad__l{ display:block; font-size:var(--fs-small); color:var(--muted); margin-top:.5rem; max-width:22ch }

/* ---- M10 · no split is symmetric ---------------------------
   Two ratios, and only two:
     .split        7fr / 5fr      content beside content
     .split--aside 1fr / 240px    content beside furniture
   A 5fr sidebar holding 180px of metadata is not a column, it is a
   void with a date in it — which is what the first pass shipped. */
.split{ display:grid; grid-template-columns:7fr 5fr; gap:var(--gutter) }
/* the filter rail is furniture too — five items and a caption do not need
   460px. Narrowing it to --aside-w also lets the index use the SAME row
   treatment as everywhere else, so there is one row component, not two. */
.split--rail{ grid-template-columns:var(--aside-w) minmax(0,1fr); gap:3.5rem }
.split--aside{ grid-template-columns:minmax(0,1fr) var(--aside-w); gap:3.5rem }
/* a short pull quote beside a short column centres against it; where the
   heading has been lifted out above the split, the two columns top-align
   instead and .split--quote is not used. */
.split--quote{ align-items:center }
.shell--read{ max-width:var(--shell-read) }
/* Nested inside a plain .shell rather than being one itself: .shell--read's
   own margin:auto centres it independently, which put its left edge ~80px
   inside the title's above it. Undecorated, it is a block that starts at its
   parent's left edge — which is what "aligned to the title" requires. */
/* a form does not stretch. 900 - padding - aside - gutter lands the field
   column exactly on the 34rem input cap, so nothing floats. */
.shell--form{ max-width:900px }
/* a pull quote in a 240px furniture column is a column of syllables —
   it steps down a size and drops its measure cap */
.split--aside .pull{ font-size:1.25rem; max-width:none; padding-left:1.25rem }

/* ---- lists, not cards --------------------------------------
   No card exists in this system. A list row is a row: a hairline
   INSIDE the list (never between sections — see M1), a ground
   change on hover, and a 3px accent rule that grows. */
.stack{ border-top:var(--rule-w) solid var(--hair) }
/* the meta column is furniture: fixed width, anchored to the right edge.
   Two anchored edges leave no floating gap. This is the one place a second
   axis is permitted — M7's single left axis governs section heads, not list
   furniture. */
.stack__row{
  display:grid; grid-template-columns:minmax(0,1fr) 230px; gap:var(--gutter);
  align-items:start; padding:2rem 1.25rem 2rem 1.25rem;
  border-bottom:var(--rule-w) solid var(--hair);
  border-left:var(--rule-w) solid transparent;
  transition:background var(--dur) var(--ease), border-left-color var(--dur) var(--ease);
}
.stack__row:hover{ background:var(--field); border-left:var(--rule-w-live) solid var(--accent) }
.band--field .stack__row:hover{ background:var(--paper) }
.stack__row h3{ text-wrap:balance; max-width:42ch }
.stack__row p{ color:var(--muted); font-size:1rem; margin-top:.6rem; max-width:66ch }
.stack__side{ text-align:right }
.stack__cat{
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker);
  text-transform:uppercase; color:var(--accent); font-weight:var(--w-medium);
}
.stack__date{ display:block; font-size:var(--fs-small); color:var(--muted); margin-top:.4rem }

/* ---- filter rail (Articles) --------------------------------- */
.rail{ position:sticky; top:110px; align-self:start }
.rail__list{ list-style:none; border-top:var(--rule-w) solid var(--hair) }
.rail__list a{
  display:flex; justify-content:space-between; gap:1rem;
  padding:.9rem 0; font-size:var(--fs-small); font-weight:var(--w-medium);
  border-bottom:var(--rule-w) solid var(--hair);
  border-left:var(--rule-w) solid transparent; padding-left:.75rem;
  transition:border-left-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.rail__list a:hover{ border-left-color:var(--accent-faint) }
.rail__list a.is-on{ border-left:var(--rule-w-live) solid var(--accent); color:var(--accent) }
.rail__list span{ color:var(--muted); font-variant-numeric:tabular-nums }

/* ---- framed image ------------------------------------------
   A hairline box, not a shadow and not a radius — the same division
   device the rest of the system uses, applied to a photograph. The
   inset keeps the frame legible as a frame rather than a border. */
.frame{ margin:0; padding:.75rem; border:var(--rule-w) solid var(--hair);
  background:var(--paper); align-self:stretch;
  display:flex; flex-direction:column }
.frame img{ display:block; width:100%; height:100%; object-fit:cover;
  object-position:center }
/* A portrait plate does not stretch to a text column's height — it keeps its
   own proportion and lets the row grow. object-fit:cover on a stretched box
   would crop a standing figure at the knees and the forehead. */
.frame--portrait{ align-self:start }
/* The About hero pairs the display step with a portrait plate. At 1440 the two
   balance; below that the 60px step stops fitting the 7fr column long before
   the mobile breakpoint takes it down to 40, so between roughly 800 and 1200 it
   was crowding the plate. Fluid inside the scale: it still tops out at
   --fs-display and never invents a size above it. */
.abouthero h1.display{ font-size:clamp(2.25rem, 4.2vw, var(--fs-display)) }
.abouthero{ grid-template-columns:8fr 4fr }
/* Single column: the plate must not run the full width of the page. The file is
   880px, so 440 is where it stops being enlarged — past that it is the About
   page repeating the hero's mistake. */
.abouthero .frame{ max-width:440px }
.frame--portrait img{ height:auto; aspect-ratio:880 / 1023 }

/* ---- search ------------------------------------------------
   Narrows an already-present list; it never fetches. With JS off the
   field is inert and the full list is still in the document. */
.search{
  display:flex; align-items:center; gap:.75rem; margin-top:1.75rem;
  max-width:480px; background:var(--paper); padding:0 1.125rem;
  border:var(--rule-w) solid var(--hair);
  transition:border-color var(--dur) var(--ease);
}
.search:focus-within{ border-color:var(--accent) }
.search__icon{ width:20px; height:20px; flex:none; color:var(--muted) }
.search input{
  flex:1; min-width:0; border:0; background:none; outline:none;
  font:inherit; font-size:1.0625rem; color:var(--ink); padding:.9375rem 0;
}
.search input::placeholder{ color:var(--muted) }
.search input::-webkit-search-decoration,
.search input::-webkit-search-cancel-button{ -webkit-appearance:none; appearance:none }
.search__clear{
  flex:none; border:0; background:none; padding:.25rem; cursor:pointer;
  color:var(--muted); display:flex; transition:color var(--dur) var(--ease);
}
.search__clear:hover{ color:var(--ink) }
.search__clear svg{ width:18px; height:18px }
.search__count{ margin-top:.75rem; font-size:var(--fs-meta); color:var(--muted) }

/* ---- mark wall (ventures / associations / press) ------------
   Flat. Everything on one plane. No carousel — audit finding 2. */
.wall{ display:grid; gap:1px; background:var(--hair); border:var(--rule-w) solid var(--hair) }
.wall--2{ grid-template-columns:repeat(2,1fr) }
.wall--4{ grid-template-columns:repeat(4,1fr) }
.wall__cell{
  background:var(--paper); display:flex; align-items:center; justify-content:center;
  padding:2rem 1.5rem; min-height:132px;
  transition:background var(--dur) var(--ease);
}
.wall__cell:hover{ background:var(--field) }
/* Marks arrive at wildly different aspect ratios. A single height cap is the
   wrong instrument: at 34px a 2.1:1 mark (Loka Viveka) covers a third of the
   area of a 4.1:1 one (Xempla) and reads as an afterthought. pages.py measures
   each file and sets --mark-h so every mark lands at the same optical WIDTH;
   max-height is the ceiling that stops a near-square badge from towering. */
.wall__cell img{ height:var(--mark-h,40px); max-height:48px; max-width:160px;
  width:auto; object-fit:contain }
.wall__name{ font-size:1.0625rem; font-weight:var(--w-bold); letter-spacing:-.01em }

/* ---- lazy list loader --------------------------------------
   20 rows at a time. The indicator is three hairlines that fade in
   sequence — no spinner, and it uses the accent rule that mechanism 5
   already licenses rather than introducing a new shape. */
.loader{ display:none; gap:.4rem; align-items:center; justify-content:center; padding:2.5rem 0 }
.loader.is-on{ display:flex }
.loader span{
  width:26px; height:var(--rule-w-live); background:var(--accent); opacity:.25;
  animation:pulse 1.05s ease-in-out infinite;
}
.loader span:nth-child(2){ animation-delay:.14s }
.loader span:nth-child(3){ animation-delay:.28s }
@keyframes pulse{ 0%,100%{opacity:.2} 50%{opacity:1} }
@media (prefers-reduced-motion: reduce){ .loader span{ animation:none; opacity:.6 } }

/* ---- switch (Podcasts) -------------------------------------
   The underlined-text tabs read as decoration and people missed the second
   one entirely. A bordered segmented control with the inactive segment on the
   field tint makes both options visibly clickable, and the labels now say what
   each one IS rather than a one-word abstraction. */
.switch{ display:inline-flex; flex-wrap:wrap; border:var(--rule-w) solid var(--ink);
  margin-bottom:2rem }
.switch__btn{
  display:inline-flex; align-items:center; gap:.6rem;
  background:var(--field); color:var(--ink); border:0; cursor:pointer;
  font-family:inherit; font-size:var(--fs-small); font-weight:var(--w-medium);
  padding:.95rem 1.5rem;
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.switch__btn + .switch__btn{ border-left:var(--rule-w) solid var(--ink) }
.switch__btn:hover{ background:var(--paper) }
.switch__btn[aria-selected="true"]{ background:var(--ink); color:var(--paper) }
.switch__n{ font-variant-numeric:tabular-nums; opacity:.65;
  font-size:var(--fs-kicker); letter-spacing:.04em }
.switch__btn[aria-selected="true"] .switch__n{ opacity:.8 }

/* ---- tabs (Podcasts) --------------------------------------- */
.tabs{ display:flex; gap:2rem; border-bottom:var(--rule-w) solid var(--hair); margin-bottom:2.5rem }
.tabs button{
  background:none; border:0; font-family:inherit; cursor:pointer;
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); text-transform:uppercase;
  font-weight:var(--w-medium); color:var(--muted); padding:0 0 1rem;
  border-bottom:var(--rule-w-live) solid transparent; margin-bottom:calc(var(--rule-w) * -1);
  transition:color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.tabs button:hover{ color:var(--ink) }
.tabs button[aria-selected="true"]{ color:var(--accent); border-bottom-color:var(--accent) }
.tabs__count{ font-variant-numeric:tabular-nums; opacity:.6; margin-left:.4rem }

/* the homepage subject cloud is the same control without the counts */
.cloud--tags{ margin-bottom:2.5rem }

/* ---- theme cloud (Reflections) ------------------------------ */
.cloud{ display:flex; flex-wrap:wrap; gap:.5rem; margin-bottom:3rem }
.cloud button{
  background:var(--paper); border:1px solid var(--hair); border-radius:var(--r-interactive);
  font-family:inherit; font-size:var(--fs-small); color:var(--ink);
  padding:.55rem 1rem; cursor:pointer;
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease),
             border-color var(--dur) var(--ease);
}
.cloud button:hover{ border-color:var(--accent) }
.cloud button[aria-pressed="true"]{ background:var(--accent); color:var(--paper); border-color:var(--accent) }
.cloud b{ font-weight:var(--w-medium); font-variant-numeric:tabular-nums; opacity:.6; margin-left:.4rem }

/* ---- share cluster ------------------------------------------
   Deliberately louder than the old text links: these are the one place
   the site asks the reader to do something other than read. */
.share{ display:flex; flex-wrap:wrap; gap:.5rem; align-items:center }
.share__btn{
  display:inline-flex; align-items:center; gap:.5rem;
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); text-transform:uppercase;
  font-weight:var(--w-medium); font-family:inherit;
  background:var(--paper); color:var(--ink);
  border:1px solid var(--ink); border-radius:var(--r-interactive);
  padding:.7rem 1rem; cursor:pointer;
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.share__btn svg{ width:15px; height:15px; flex:none }
.share__btn:hover{ background:var(--ink); color:var(--paper) }
.share__btn--pdf{ background:var(--accent); color:var(--paper); border-color:var(--accent) }
.share__btn--pdf:hover{ background:var(--accent-deep); border-color:var(--accent-deep) }
.share__note{ font-size:var(--fs-small); color:var(--accent); margin-left:.25rem }

/* the reflection card's own share row is quieter — icon only */
.rshare{ display:flex; gap:.4rem; margin-top:1.25rem }
.rshare button, .rshare a{
  display:flex; align-items:center; justify-content:center;
  width:34px; height:34px; background:none; cursor:pointer; color:var(--muted);
  border:1px solid var(--hair); border-radius:var(--r-interactive);
  transition:background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.rshare svg{ width:15px; height:15px }
.rshare button:hover, .rshare a:hover{ background:var(--accent); color:var(--paper); border-color:var(--accent) }

/* ---- MARQUEE ------------------------------------------------
   Client-directed 2026-08-22: the associations and the press marks
   combined into one soft-scrolling band.

   This sits against audit finding 2, which rejected the current site's
   carousels for hiding three of seven ventures behind a control. The
   distinction that makes it acceptable: a click-carousel hides content
   until the visitor works for it, whereas every mark here passes the
   viewport unprompted, all of them are in the DOM at once for assistive
   tech and for search, and the strip pauses on hover so a mark can be
   read. Under prefers-reduced-motion it stops and becomes scrollable,
   so nothing is ever unreachable.

   No edge fade: a mask would be a gradient (prohibition 3), and hard
   edges are what the rest of the system does anyway. */
.marquee{ overflow:hidden; position:relative }
.marquee__track{
  display:flex; align-items:center; gap:4.5rem; width:max-content;
  animation:marquee var(--marquee-dur) linear infinite;
}
.marquee--rev .marquee__track{ animation-direction:reverse }
.marquee--slow .marquee__track{ animation-duration:calc(var(--marquee-dur) * 1.9) }
.marquee--sm .marquee__cell img{ height:30px; max-width:140px }
.marquee--sm .marquee__track{ gap:3.5rem }
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track{ animation-play-state:paused }
.marquee__cell{ flex:none; display:flex; align-items:center; justify-content:center }
.marquee__cell img{ height:38px; width:auto; max-width:170px; object-fit:contain }
.marquee__cell .wall__name{ font-size:1.125rem }
@keyframes marquee{ from{ transform:translateX(0) } to{ transform:translateX(-50%) } }

/* the strip is full-bleed: it sits OUTSIDE .shell in the markup, so it needs
   no 100vw arithmetic and cannot overflow when a scrollbar is present */
.mrow{ padding-block:1.75rem }
/* no rule between the rows — the labels already separate them, and a hairline
   here reads as a table border the rest of the system does not use */
.mrow__label{
  display:block; font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker);
  text-transform:uppercase; color:var(--muted); font-weight:var(--w-medium);
  margin-bottom:1.25rem;
}

@media (prefers-reduced-motion: reduce){
  /* stopped, and reachable by scrolling instead of by waiting */
  .marquee{ overflow-x:auto }
  .marquee__track{ animation:none }
}

/* a run of hard facts. Rows with a hairline, no bullets — the system has no
   bulleted list anywhere else and a disc list would be the only one. */
.factlist{ list-style:none; margin:2rem 0 0; padding:0; border-top:var(--rule-w) solid var(--hair) }
.factlist li{
  padding:1rem 0 1rem 1.75rem; border-bottom:var(--rule-w) solid var(--hair);
  position:relative; font-size:1.0625rem;
}
.factlist li::before{
  content:""; position:absolute; left:0; top:1.55rem;
  width:10px; height:var(--rule-w-live); background:var(--accent);
}

/* ---- VENTURES ----------------------------------------------
   INT is featured on its own row at a larger scale — it is 28 years of his
   working life and a shared logo wall flattened it to the same weight as a
   side investment. The other six sit in a 3-up grid of equal boxes. */
.vfeature{
  display:grid; grid-template-columns:minmax(0,300px) minmax(0,1fr); gap:3rem;
  align-items:center; background:var(--paper); padding:3rem;
  border:var(--rule-w) solid var(--hair);
  transition:border-color var(--dur) var(--ease);
}
.vfeature:hover{ border-color:var(--accent) }
.vfeature__mark{ display:flex; align-items:center; justify-content:flex-start }
.vfeature__mark img{ width:100%; max-width:260px; height:auto }
/* the only vector mark on the site, and the only near-square one: bound it by
   height so it sits at the weight of a wordmark rather than filling its column.
   Centred in its column rather than flush left — at this size it reads as a
   mark on display, not as a wordmark run into the body copy beside it. */
.vfeature__mark--square{ justify-content:center }
.vfeature__mark--square img{ width:auto; height:208px; max-width:100% }
.vfeature__body h2{ font-size:var(--fs-h2) }
.vfeature__body p{ color:var(--muted); max-width:56ch }

.vgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--hair); border:var(--rule-w) solid var(--hair) }
.vcard{
  display:flex; flex-direction:column; align-items:flex-start; gap:.35rem;
  background:var(--paper); padding:2.25rem 2rem;
  transition:background var(--dur) var(--ease);
}
.vcard:hover{ background:var(--field) }
.vcard__mark{ display:flex; align-items:center; height:52px; margin-bottom:1rem }
.vcard__mark img{ height:var(--mark-h,34px); max-height:48px; max-width:150px;
  width:auto; object-fit:contain }
.vcard h3{ font-size:1.1875rem }
.vcard__role{
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); text-transform:uppercase;
  color:var(--accent); font-weight:var(--w-medium);
}
.vcard p{ color:var(--muted); font-size:1rem; margin-top:.6rem; flex:1 }
.vcard .tlink{ margin-top:1.25rem }

/* ---- ventures table (About) — the only table in the system --- */
.vtable{ width:100%; border-collapse:collapse; font-size:1rem }
.vtable th{
  text-align:left; font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker);
  text-transform:uppercase; color:var(--accent); font-weight:var(--w-medium);
  padding:0 1rem 1rem 0; border-bottom:var(--rule-w) solid var(--hair);
}
.vtable td{ padding:1.15rem 1rem 1.15rem 0; border-bottom:var(--rule-w) solid var(--hair); vertical-align:middle }
.vtable td:first-child{ font-weight:var(--w-medium) }
.vtable tr:hover td{ background:var(--field) }
.vtable img{ height:26px; width:auto; object-fit:contain }

/* ---- media grid (Podcasts) — the only grid with images -------
   Third-party episode art is loud and multicoloured; it is content,
   not chrome. It is framed hard and kept to 2-up so the page's own
   voice stays sober. See strategy.html § risks. */
.mgrid{ display:grid; grid-template-columns:repeat(2,1fr); gap:var(--gutter) 2.5rem }
.mgrid--3{ grid-template-columns:repeat(3,1fr); gap:2.75rem 2rem }
.mgrid--3 .mgrid__item h3{ font-size:1.0625rem; margin-top:.9rem }
.mgrid__item{ display:block }
/* the frame backs any thumbnail that is not exactly 16:9. It is --field, not
   --ink: rejection 5 forbids a dark band anywhere, and a letterbox is a band. */
.mgrid__frame{ position:relative; background:var(--field); overflow:hidden }
.mgrid__frame img{ width:100%; aspect-ratio:16/9; object-fit:cover }
.mgrid__dur{
  position:absolute; right:0; bottom:0; background:var(--paper); color:var(--ink);
  font-size:var(--fs-kicker); letter-spacing:.06em; padding:.4rem .7rem;
  font-variant-numeric:tabular-nums;
}
.mgrid__item h3{ margin-top:1.15rem; font-size:1.1875rem; text-wrap:balance }
.mgrid__item:hover h3{ color:var(--accent) }
.mgrid__more{ display:inline-flex; align-items:center; gap:.4rem; margin-top:.7rem;
  font-size:var(--fs-small); color:var(--muted) }
.mgrid__more svg{ width:15px; height:15px }

/* reflection theme chips */
.rthemes{ display:flex; flex-wrap:wrap; gap:.5rem; margin-bottom:1rem }
.rtheme{
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); text-transform:uppercase;
  font-weight:var(--w-medium); color:var(--accent);
}
.rtheme + .rtheme::before{ content:"\00b7"; margin-right:.5rem; color:var(--hair) }

/* ---- stream (Reflections) — the only page with no media -------
   One thought per band. Typography carries it entirely. */
.stream{ border-top:var(--rule-w) solid var(--hair) }
.stream__item{ padding:2.5rem 0; border-bottom:var(--rule-w) solid var(--hair) }
/* no media on this page, so the measure can open up — 26ch made a 342-item
   list four screens taller than it needed to be */
.stream__item p{
  font-size:1.5rem; line-height:1.45; font-weight:var(--w-medium);
  letter-spacing:-.012em; max-width:44ch; text-wrap:pretty;
}
.stream__item p + p{ margin-top:.9rem; font-size:1.25rem; font-weight:var(--w-regular);
  color:var(--muted); max-width:44ch; letter-spacing:0 }
.stream__n{
  font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); color:var(--accent);
  font-weight:var(--w-medium); font-variant-numeric:tabular-nums;
}

/* ---- serial (Making of INT) — the only ordered narrative ----- */
.serial{ display:grid; grid-template-columns:5fr 7fr; gap:var(--gutter) }
.serial__step{ display:contents }
.serial__mark{
  border-top:var(--rule-w-live) solid var(--accent);
  padding-top:1rem; font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker);
  text-transform:uppercase; color:var(--accent); font-weight:var(--w-medium);
}
.serial__body{ border-top:var(--rule-w) solid var(--hair); padding:1rem 0 3.5rem }
.serial__body h3{ margin-bottom:.75rem; text-wrap:balance }
.serial__body p{ color:var(--muted); font-size:1rem }
.serial__body .tlink{ margin-top:1rem }

/* ---- long-form article -------------------------------------- */
.prose{ max-width:var(--measure) }
.prose p{ max-width:none }
.prose p + p{ margin-top:1.4em }
.prose h2{ font-size:var(--fs-h3); margin-top:2.5em; margin-bottom:.6em }
.prose blockquote{
  border-left:var(--rule-w-live) solid var(--accent);
  padding-left:1.75rem; margin:2em 0; font-size:1.375rem; line-height:1.45;
  font-weight:var(--w-medium);
}
.byline{ display:flex; align-items:center; gap:.85rem; font-size:var(--fs-small); color:var(--muted) }
.byline img{ width:44px; height:44px }
.aside{ position:sticky; top:110px; align-self:start; font-size:var(--fs-small); color:var(--muted) }
.aside dt{ font-size:var(--fs-kicker); letter-spacing:var(--ls-kicker); text-transform:uppercase;
  color:var(--accent); font-weight:var(--w-medium); margin-top:1.5rem }
.aside dt:first-child{ margin-top:0 }
.aside dd{ margin-top:.35rem; color:var(--ink) }

/* ---- pull quote --------------------------------------------- */
.pull{ max-width:26ch; font-size:1.75rem; line-height:1.35; font-weight:var(--w-medium);
  letter-spacing:-.012em; border-left:var(--rule-w-live) solid var(--accent); padding-left:1.75rem }
.pull cite{ display:block; font-size:var(--fs-small); font-style:normal; color:var(--muted);
  margin-top:1rem; letter-spacing:0; font-weight:var(--w-regular) }

/* ---- closing band ------------------------------------------
   Client-directed 2026-08-22: a full-width photographic field.
   The image is DARKENED AND DE-MAGENTA'D IN THE FILE, not with a runtime
   overlay, so prohibition 3 (zero gradients) survives a dark band. Measured
   after baking: white text is >=8.2:1 against the 99.5th percentile of every
   region of the frame, so no scrim is needed anywhere. */
.closer{ position:relative; overflow:hidden; background:var(--accent-deep); color:var(--paper) }
.closer__field{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center center;
  z-index:0; pointer-events:none; user-select:none;
}
.closer .shell{ position:relative; z-index:1 }
/* the brand accent sinks into a navy field — kicker and emphasis both take
   the light end of the ramp here, the same swap the video hero makes */
.closer .kicker{ color:var(--accent-faint) }
.closer .display{ color:var(--paper) }
.closer .display em{ color:var(--accent-faint) }
.closer p{ color:var(--paper) }
/* the accent fill sinks into a navy field — the CTA inverts here too */
.closer .btn--solid{ background:var(--paper); color:var(--ink) }
.closer .btn--solid:hover{ background:var(--accent-faint) }
.closer__credit{ font-size:var(--fs-kicker); letter-spacing:.04em; opacity:.7; margin-top:2.5rem }
.closer__credit a{ border-bottom:1px solid rgba(255,255,255,.4) }

/* ---- footer — light. There is no dark band on this site. ------ */
.foot{ background:var(--paper); padding-block:4rem 2.5rem }
.foot__top{ display:grid; grid-template-columns:7fr 5fr; gap:var(--gutter);
  padding-bottom:2.5rem; border-bottom:var(--rule-w) solid var(--hair) }
.foot__nav{ display:flex; flex-wrap:wrap; gap:1.25rem 2rem; list-style:none }
.foot__nav a{ font-size:var(--fs-small); color:var(--muted) }
.foot__nav a:hover{ color:var(--accent) }
.foot__social{ display:flex; gap:1.25rem; margin-top:1.5rem }
.foot__social a{ color:var(--muted); transition:color var(--dur) var(--ease) }
.foot__social a:hover{ color:var(--accent) }
.foot__social svg{ width:20px; height:20px }
.foot__bottom{ display:flex; flex-wrap:wrap; gap:1rem 2rem; justify-content:space-between;
  padding-top:1.5rem; font-size:var(--fs-small); color:var(--muted) }

.ico{ width:20px; height:20px; flex:none }

/* ---- utilities ---------------------------------------------- */
.vh{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap }
.mt-1{ margin-top:1rem } .mt-2{ margin-top:2rem } .mt-3{ margin-top:3rem }

/* ---- responsive ---------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  /* the clip is paused in JS as well — this only stops any residual paint */
  .vhero__media{ animation:none }
}

@media (max-width: 900px){
  /* a portrait viewport and a 16:9 clip fight each other: the only way to keep
     the type off the horizon glow is to give the band more height. 720px is
     what the contrast measurement demanded, not a stylistic choice. */
  /* Narrow viewports cannot hold a figure beside the type, so it drops to a
     band beneath it — still flush to the bottom edge. The band is taller and
     the figure shorter than instinct suggests, because the figure's TOP has to
     clear the last line of the subtext: at 38% of an 820px band the top lands
     ~50px below it. Measured, not guessed. */
  /* The band is not given a height here; it is given a FLOOR, and the type
     column reserves the figure's height plus 44px below itself. The band then
     comes out as masthead + type + figure + 44 whatever the type actually
     measures — so the clearance between the last line of subtext and the top of
     his head is 44px at 375 and at 768 alike. A fixed band height cannot do
     that: the constant that fits the five-line phone wrap leaves 138px of dead
     air once the type reflows to three lines on a tablet. */
  :root{ --hero-fig-w:clamp(260px, 78vw, 400px) }
  /* a floor only, and a low one: the content stack below now decides the band,
     which is what holds the clearance constant. Set too high, the min-height
     wins instead and the gap under the subtext drifts — it reached 202px at
     414x896 before this came down. */
  .vhero{ min-height:clamp(560px, 72vh, 760px);
    padding-block:calc(var(--bar-h) + var(--rule-w) + 1.5rem) 0; align-items:flex-start }
  .vhero__in{ grid-template-columns:1fr }
  /* the shell stretches so the figure can reach the floor; the type must not
     ride down with it, or it lands on his face */
  /* the figure is 1.011 wide-to-tall, so its height is ~0.99 of its width */
  .vhero__col{ padding-bottom:calc(var(--hero-fig-w) * 0.99 + 44px); align-self:start }
  /* width-driven, same as desktop. Centred rather than right-pinned: the
     right-pin was inherited from the desktop layout, where it aligns the
     figure under the header's last icon — a reference point that only exists
     because the header and hero share the same content column. On a single,
     centred mobile column there is no such edge to align to, so the figure
     just read as cropped against the right side of the screen. */
  .vhero__figure{ width:var(--hero-fig-w); height:auto;
    left:50%; right:auto; transform:translateX(-50%) }
  .vhero__title{ max-width:none }
  .vhero__sub{ max-width:34ch }
  .vhero__sub{ max-width:34ch }
  .vhero__sub{ font-size:1rem }

  .navtoggle{ display:block }
  .nav{
    display:none; position:absolute; left:0; right:0; top:100%;
    flex-direction:column; align-items:stretch; gap:0;
    background:var(--paper); padding:1rem var(--shell-pad) 1.75rem;
    border-top:var(--rule-w) solid var(--hair);
  }
  .nav.is-open{ display:flex }
  .nav a{ padding:.85rem 0; border-bottom:var(--rule-w) solid var(--hair) }
  .masthead__in{ position:relative; gap:1rem }
  .social{ display:none }

  .overlap,.split,.split--rail,.split--aside,.serial,.foot__top{ grid-template-columns:1fr }
  .split--rail{ gap:2.5rem }
  .split--aside{ gap:2.5rem }
  .overlap__panel,.overlap--flip .overlap__panel{ margin:0; padding:2.25rem 1.5rem; order:2 }
  .overlap__media,.overlap--flip .overlap__media{ order:1 }
  .triad{ grid-template-columns:1fr }
  .triad__item{ padding:1.5rem 0; border-left:0; border-top:var(--rule-w) solid var(--accent-faint) }
  .triad__item:first-child{ padding-top:0; border-top:0 }
  .stack__row{ grid-template-columns:1fr; gap:.75rem }
  .stack__side{ order:-1; text-align:left; display:flex; gap:1rem; align-items:baseline }
  .stack__date{ margin-top:0 }
  .mgrid,.mgrid--3{ grid-template-columns:1fr }
  .tabs{ gap:1.25rem }
  /* Podcasts pairs the switch with the search on one row (.head--split); it is
     the only page that uses .switch, so this can be tuned for that pairing
     without a second component. Kept as a row rather than the two-line stack
     column layout used to force, with the label text shrunk to fit — dropping
     to a stack would have pushed the search to its own line below, which is
     the misalignment this was written to fix. */
  .switch__btn{ font-size:.8125rem; padding:.7rem .85rem; gap:.4rem }
  .switch__n{ margin-left:.35rem }
  .cloud button{ font-size:var(--fs-kicker) }
    .wall--4,.wall--2{ grid-template-columns:repeat(2,1fr) }
  .wall__cell{ padding:1.25rem .75rem; min-height:104px }
  .wall__cell img{ max-width:100% }
  .rail,.aside{ position:static }
  .serial__step{ display:block; }
  .serial__mark{ padding-bottom:.5rem }
  .serial__body{ border-top:0 }
  .vgrid{ grid-template-columns:1fr }
  .vfeature{ grid-template-columns:1fr; gap:1.75rem; padding:2rem }
  .vfeature__mark img{ max-width:200px }
  .vfeature__mark--square img{ height:168px }
  .head--split{ align-items:stretch }
  .head--split .search{ margin-left:0; max-width:none }
  .vtable thead{ display:none }
  .vtable td{ display:block; border:0; padding:.15rem 0 }
  .vtable tr{ display:block; padding:1.15rem 0; border-bottom:var(--rule-w) solid var(--hair) }
  .stream__item p{ font-size:1.25rem; max-width:none }
  .closer__terrain{ width:110%; right:-25%; opacity:.12 }
}
