/* --------------------------------------------------------------------- type
   Self-hosted, so every reader sees the same thing. The old stack was a
   fallback chain — Iowan on Mac, Palatino on Windows, Georgia on Android —
   which is three different brands and no control over which one a buyer gets.
   Both families are SIL Open Font License: free, self-hostable, no third-party
   request, which also keeps the site's zero-external-dependency posture.
   ------------------------------------------------------------------------- */
@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/EBGaramond-normal-400.woff2') format('woff2');}
@font-face{font-family:'EB Garamond';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/EBGaramond-normal-600.woff2') format('woff2');}
@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url('/assets/fonts/EBGaramond-italic-400.woff2') format('woff2');}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/Inter-normal-400.woff2') format('woff2');}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/Inter-normal-500.woff2') format('woff2');}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/Inter-normal-600.woff2') format('woff2');}

/* ============================================================================
   BROOD SYSTEMS — design system
   ----------------------------------------------------------------------------
   One rule governs everything here: kintsugi.

   The vessel is humble and dark. The gold is SCARCE — it appears only where
   something broke and was repaired: seams, the active tab, one accent word per
   headline, the single call to action. If gold is everywhere it is decoration.
   If gold is rare it is meaning.

   Type: a Renaissance serif for anything that makes a claim; a neutral sans
   for anything that labels, navigates, or instructs.
   ========================================================================= */

:root {
  --black:      #050403;
  --ink:        #0b0908;   /* raised surface — a fired-clay black, not a void */
  --ink-2:      #12100d;
  --gold:       #e8b64c;
  --gold-hot:   #f6d488;
  --gold-deep:  #8a5f1e;
  --ivory:      #efe9dd;
  --ash:        #9b948a;
  --ash-dim:    #6d6862;
  --line:       rgba(232, 182, 76, 0.18);
  --line-soft:  rgba(239, 233, 221, 0.10);
  --warn:       #e58f6e;

  --serif: "EB Garamond", "Iowan Old Style", "Palatino Linotype", Palatino,
           Georgia, "Times New Roman", serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
           "Segoe UI", system-ui, sans-serif;
  /* NOTE: Garamond is an old-style face with a small x-height — it sets ~7%
     smaller than Palatino at the same px. Every serif size below is already
     compensated. If the family is ever swapped back, wind them down again. */
  --mono:  ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;

  --measure: 34rem;        /* prose */
  --wide:    72rem;        /* page */

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  color-scheme: dark;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--black); scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--black);
  color: var(--ivory);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Fired-clay grain. Keeps the black from reading as an empty <div>. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

::selection { background: var(--gold); color: var(--black); }

a { color: var(--gold); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 0.22em; }
:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ------------------------------------------------------------------ layout */
.wrap  { width: min(var(--wide), 100% - 3rem); margin-inline: auto; }
.center { margin-inline: auto; }

section { padding-block: clamp(2.8rem, 5.5vw, 4.5rem); }
section:first-of-type { padding-top: clamp(2.5rem, 5vw, 3.75rem); }

/* -------------------------------------------------------------- typography */
h1, h2, h3, .display {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.18;
  text-wrap: balance;
  letter-spacing: -0.005em;
}
h1 { font-size: clamp(2.25rem, 5.7vw, 3.75rem); line-height: 1.1; }
h2 { font-size: clamp(1.72rem, 3.6vw, 2.5rem); }
h3 { font-size: clamp(1.22rem, 2.1vw, 1.5rem); line-height: 1.28; }
em, .gold { font-style: italic; color: var(--gold); }
h1 em, h2 em, h3 em { font-style: italic; color: var(--gold); }

p { margin-block: 1.05em; }
.lede {
  font-family: var(--serif);
  font-size: clamp(1.18rem, 2.25vw, 1.42rem);
  line-height: 1.5;
  color: var(--ivory);
  text-wrap: pretty;
}
.body p, p.body { color: #dcd5c8; font-size: 1.02rem; line-height: 1.72; }
.dim { color: var(--ash); }

.eyebrow {
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.36em;
  text-indent: 0.36em;
  text-transform: uppercase;
  color: var(--ash);
}


/* Display-size gold aside. Parked on 2026-08-11 when "The vessel is already
   yours" was deleted, and restored the same day for the /what-we-do tagline —
   which is what the rule was designed for. max-width is in CH on purpose: this
   is a line to be read in one glance, and a wide viewport should not stretch it
   into two clauses. */
.pull {
  font-family: var(--serif);
  font-style: italic;
  color: var(--gold);
  font-size: clamp(1.34rem, 3vw, 1.82rem);
  line-height: 1.42;
  text-wrap: balance;
  max-width: 26ch;
  margin-block: 2.2rem;
}

/* --------------------------------------------------------------- page head */
/* Headline left, standfirst right — the layout every broadsheet uses, and the
   reason is that a single narrow column stranded on a wide screen reads as an
   unfinished page rather than a considered one. */
.pagehead {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  gap: clamp(1.4rem, 5vw, 4.5rem);
  align-items: end;
}
.pagehead > * > :first-child { margin-top: 0; }
.pagehead h1 { margin: 0.4rem 0 0; }
.pagehead .lede { margin-top: 0; }
@media (max-width: 54rem) {
  .pagehead { grid-template-columns: 1fr; align-items: start; gap: 1.2rem; }
}
/* A headline and the sentence that finishes its thought. The default gap is
   sized for a head and an unrelated standfirst; here the two are one sentence
   split across a column break, so they need to read as a pair rather than as
   two things that happen to be level with each other. */
.pagehead--tight {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(1rem, 2.2vw, 1.9rem);
}
/* This has to repeat the stacking rule. `.pagehead--tight` is declared AFTER the
   max-width:54rem block above, and a media query adds no specificity — so at
   equal specificity the later rule won and the two columns survived onto a
   390px phone, where the standfirst was a 20-character-wide ravine. */
@media (max-width: 54rem) {
  .pagehead--tight { grid-template-columns: 1fr; gap: 1.2rem; }
}

/* -------------------------------------------------------------------- seam */
/* The signature element. A hairline that fractures rather than ruling. */
.seam {
  display: block;
  width: 100%;
  max-width: 30rem;
  height: 20px;
  overflow: visible;
  opacity: 0.9;
  filter: drop-shadow(0 0 5px rgba(232, 182, 76, 0.45));
}
.seam path, .seam polyline { stroke: var(--gold); fill: none; stroke-linejoin: round; }
/* Sections already carry their own padding — the rule adds none of its own,
   or every seam on the page opens into a chasm. */
hr.rule {
  border: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 12%, var(--line) 88%, transparent);
  margin-block: 0;
}

/* A quiet gold-ruled pill, off to the right of the hero. Deliberately not a
   button and deliberately not centred: it is a third action on a screen that
   already has two, so it sits off the centre line and reads as an aside rather
   than competing with "Bring us a problem". No arrow — the arrow is this site's
   mark for "keep reading in this direction", and this is a detour. */
.whatis-row { width: 100%; text-align: right; margin: 1rem 0 0; }
.whatis {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--gold);
  background: rgba(11, 9, 7, 0.78);
  border: 1px solid var(--line);
  border-radius: 999px;            /* an oval, not a chip */
  padding: 0.46rem 1.05rem;
}
.whatis:hover { border-color: var(--gold); text-decoration: none; }
@media (max-width: 46rem) { .whatis-row { text-align: center; } }


/* ------------------------------------------------------------------- band */
/* One plate behind the hero AND the practice cards. This exists because the
   two were separate sections with the video owned by the hero: the graph
   stopped dead at the hero's bottom edge, so pulling the cards up just pulled
   black up with them. The band is the shared ground; both children sit on it.

   No parallax. The plate is fixed relative to the band — it was tried against
   a 90px drag and the drag adds motion to a hero that is already a moving
   graph. */
.band {
  position: relative;
  overflow: hidden;
  background: var(--black) center/cover no-repeat;
}
.band__bg {
  position: absolute;
  left: -2%;
  /* Taller than the band and pulled UP, so the dense middle of the film sits
     behind the wordmark instead of below the cards. `object-position` cannot do
     this: the film is 16:9 and the band is nearly square, so `cover` already
     shows the full frame height and crops horizontally — there is no vertical
     slack for object-position to move. Oversizing the element is what creates
     the slack. */
  top: -26%;
  z-index: 0;
  width: 104%;
  height: 134%;
  object-fit: cover;
  opacity: 0.78;
}
/* Darkest at the foot so the band resolves into ordinary ground before the
   rule below it, rather than ending on a cut edge. */
.band::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(5,4,3,0.30) 0%, rgba(5,4,3,0.44) 42%,
                              rgba(5,4,3,0.72) 78%, var(--black) 100%);
}
/* `.band > *` here would ALSO match .band__bg and, being declared later at equal
   specificity, reset it from absolute to relative — the plate then takes layout
   space and pushes the hero down the page. This is the identical trap that
   `.hero > *` set earlier in this build; name the children instead. */
.band > section { position: relative; z-index: 2; }
/* The cards follow the hero inside one band, so the hero's bottom padding and
   the section's own top padding stack into a gap that costs ~70px of fold for
   nothing. The band is the boundary, not the two sections inside it. */
.band > section:nth-of-type(2) { padding-top: 0; padding-bottom: clamp(0.8rem, 1.6vw, 1.2rem); }
/* The cards sit ON the plate now, so they need their own ground — but only
   just enough. Fully opaque and the graph stops behind them, which is the
   thing this change was for. */
.band .card { background: rgba(11, 9, 7, 0.74); backdrop-filter: blur(2px); }
/* The four blurbs are the tallest thing on the fold. A notch smaller here buys
   more of the page back than anything left in the hero, and at 0.86rem they are
   still a comfortable read — these are teasers, not body copy. */
/* Matched to .vert__name / .vert__blurb on /what-we-do so the same four
   practices are set identically wherever they appear. The homepage cards had
   drifted smaller while I was buying back fold space; consistency between the
   two pages is worth more than those few pixels. */
.band .card h2 { font-family: var(--serif); font-weight: 400;
                 font-size: clamp(1.55rem, 2.15vw, 2rem); line-height: 1.08; }
.band .card p  { color: #c8c1b5; font-size: 0.89rem; line-height: 1.62;
                 margin-top: 0.8rem; }
/* The practice name goes gold on hover, the same as .vert__name does on
   /what-we-do. The whole card is the link, so the name is the thing that should
   answer the cursor — the border already moves, and a colour change on the one
   word you are pointing at is what makes the card feel clickable. */
.band .card h2 { transition: color 0.2s var(--ease); }
.band .card:hover h2, .band .card:focus-within h2 { color: var(--gold); }
/* The card IS an <a>, so the global `a:hover { text-decoration: underline }`
   was underlining the whole card — heading, blurb and all. The gold name is the
   hover signal; the rule is off here the same way it is on a.vert. */
a.card:hover, a.card:focus-within { text-decoration: none; }

/* Save-Data, 2g and reduced-motion all land on the still instead of the film. */
.band--still .band__bg { display: none; }
.band--still { background-image: url("/media/helix-bg-poster.jpg"); }
@media (prefers-reduced-motion: reduce), (max-width: 46rem) {
  .band__bg { display: none; }
  .band { background-image: url("/media/helix-bg-poster.jpg"); }
}

/* --------------------------------------------------------------------- nav */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(5, 4, 3, 0.82);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border-bottom: 1px solid rgba(232, 182, 76, 0.13);
}
.nav__in {
  width: min(var(--wide), 100% - 3rem);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 4.1rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ivory);
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  white-space: nowrap;
}
.brand:hover { text-decoration: none; color: var(--gold-hot); }
.brand svg { flex: none; }

.nav__links { display: flex; align-items: center; gap: 0.3rem; margin-left: auto; }
.nav__links a {
  position: relative;
  /* --ash is the colour for captions and standfirsts; these are the site's
     primary navigation and were reading as secondary text against it. A step
     up in both colour and weight, still short of ivory so the active tab and
     the CTA keep their contrast. */
  color: #c3bcb0;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.55rem 0.7rem;
  border-radius: 3px;
  transition: color 0.2s var(--ease);
}
.nav__links a:hover { color: var(--ivory); text-decoration: none; }
.nav__links a[aria-current="page"] { color: var(--ivory); }
/* the active tab is repaired with gold, not underlined */
.nav__links a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0.55rem; right: 0.55rem; bottom: 0.16rem;
  height: 6px;
  background:
    linear-gradient(90deg, transparent, var(--gold) 18%, var(--gold-hot) 46%,
                    var(--gold) 74%, transparent) center/100% 1px no-repeat;
  filter: drop-shadow(0 0 4px rgba(232, 182, 76, 0.6));
}
/* the CTA already carries a border; the repair seam on top of it reads as noise */
.nav__links a.cta[aria-current="page"]::after { display: none; }
.nav__links .cta {
  margin-left: 0.5rem;
  color: var(--gold);
  border: 1px solid rgba(232, 182, 76, 0.45);
  padding: 0.5rem 0.9rem;
}
.nav__links .cta:hover {
  color: var(--black);
  background: var(--gold);
  box-shadow: 0 0 20px rgba(232, 182, 76, 0.28);
}
.nav__toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--ivory);
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.45rem 0.7rem;
  cursor: pointer;
}
@media (max-width: 62rem) {
  .nav__toggle { display: block; }
  .nav__links {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: rgba(5, 4, 3, 0.97);
    border-bottom: 1px solid var(--line);
    padding: 0.5rem 1.5rem 1.25rem;
  }
  .nav__links.open { display: flex; }
  .nav__links a { padding: 0.8rem 0.2rem; font-size: 0.95rem; }
  .nav__links a[aria-current="page"]::after { left: 0.2rem; right: auto; width: 2.2rem; }
  .nav__links .cta { margin: 0.7rem 0 0; text-align: center; }
}

/* ------------------------------------------------------------------ button */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  /* opaque, not transparent — over the hero video a see-through button reads as
     a floating outline and the label competes with whatever is moving behind it */
  background: #0b0908;
  border: 1px solid var(--gold);
  border-radius: 3px;
  padding: 0.95rem 1.5rem;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease),
              box-shadow 0.25s var(--ease);
}
.btn:hover {
  background: var(--gold);
  color: var(--black);
  text-decoration: none;
  box-shadow: 0 0 26px rgba(232, 182, 76, 0.3);
}
.btn--quiet {
  color: var(--ash);
  border-color: rgba(239, 233, 221, 0.22);
  letter-spacing: 0.16em;
}
.btn--quiet:hover { background: #14110e; color: var(--ivory); border-color: var(--line); box-shadow: none; }
.btn:disabled { opacity: 0.5; cursor: wait; }

/* ------------------------------------------------------------------- cards */
/* No boxes. A card is a plane of ink with a gold seam down its broken edge. */
.card {
  position: relative;
  background: linear-gradient(180deg, var(--ink) 0%, rgba(11, 9, 8, 0.35) 100%);
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  padding: 1.1rem 1.25rem 1.05rem;
  overflow: hidden;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--gold), transparent);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.45s var(--ease);
}
.card:hover, .card:focus-within {
  border-color: rgba(232, 182, 76, 0.28);
  transform: translateY(-2px);
}
.card:hover::before, .card:focus-within::before { transform: scaleY(1); }
.card h3 { margin-bottom: 0.35rem; }
.card p { color: #cdc6ba; font-size: 0.95rem; margin-block: 0.5rem; max-width: 74ch; }

/* Explicit column counts, not auto-fit: a four-item set must break 4 -> 2 -> 1,
   never 3 + 1 orphan. */
.grid { display: grid; gap: 1.1rem; }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 64rem) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 46rem) {
  .grid--2, .grid--4 { grid-template-columns: 1fr; }
}

/* -------------------------------------------------------------------- tags */
/* ------------------------------------------------------------------ figure */
.fig { margin-block: 2rem; }
.fig picture { display: block; }
.fig video, .fig img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  border: 1px solid var(--line-soft);
  background: var(--black);
}
.fig figcaption {
  margin-top: 0.9rem;
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--ash);
  max-width: 62ch;
}
.fig figcaption b { color: var(--ivory); font-weight: 600; }
.fig figcaption .gold { font-style: normal; }
/* ------------------------------------------------------------------- forms */
.field { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 1.15rem; }
label {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}
input[type="email"], input[type="text"], textarea, select {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--ivory);
  font: inherit;
  font-size: 1rem;
  padding: 0.8rem 0.9rem;
  width: 100%;
}
textarea { min-height: 8.5rem; resize: vertical; line-height: 1.6; }
::placeholder { color: rgba(155, 148, 138, 0.6); }
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold), 0 0 16px rgba(232, 182, 76, 0.2);
}
.trap { position: absolute; left: -6000px; opacity: 0; pointer-events: none; }
.err { color: var(--warn); font-size: 0.9rem; display: none; margin-bottom: 0.8rem; }

/* ------------------------------------------------------------------ footer */
.foot {
  border-top: 1px solid var(--line-soft);
  padding-block: 2.6rem 3.2rem;
  font-size: 0.85rem;
  color: var(--ash);
}
.foot__in {
  width: min(var(--wide), 100% - 3rem);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  align-items: flex-start;
  justify-content: space-between;
}
.foot a { color: var(--ash); }
.foot a:hover { color: var(--gold); }
.foot nav { display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; }
.foot .mark { color: var(--ivory); font-family: var(--serif); font-size: 1.05rem; }
/* provenance line: quieter than the nav, and the copyright quieter still */
/* This block carries the only third-party credibility on the page — MassChallenge
   and Starburst — and it was set in --ash-dim at 0.8rem, which is the same
   treatment as the copyright line. It is not the same kind of information.
   Lifted to --ash at 0.86rem, with the incubator names in ivory so they read
   first; the copyright keeps the quiet treatment it deserves. */
.foot__meta { font-size: 0.86rem; line-height: 1.6; color: var(--ash); text-align: right; }
.foot__meta b { color: var(--ivory); font-weight: 500; }
.foot__meta span { color: var(--ash-dim); font-size: 0.8rem; opacity: 0.8; }
@media (max-width: 54rem) { .foot__meta { text-align: left; } }

/* --------------------------------------------------------------- scroll UI */
/* A gold seam fills down the page edge as you read. Progressive enhancement:
   browsers without scroll-driven animations just get the faint static line. */
.progress {
  position: fixed;
  left: 0; top: 0;
  width: 2px;
  height: 100vh;
  background: rgba(232, 182, 76, 0.08);
  z-index: 90;
  pointer-events: none;
}
.progress i {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: 50% 0;
  transform: scaleY(0);
  background: linear-gradient(180deg, var(--gold-hot), var(--gold), var(--gold-deep));
  box-shadow: 0 0 10px rgba(232, 182, 76, 0.5);
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .progress i { animation: fillseam linear both; animation-timeline: scroll(root); }
    @keyframes fillseam { from { transform: scaleY(0); } to { transform: scaleY(1); } }
  }
}

/* ----------------------------------------------------------------- reveals */
/* Gated on .js (set by a one-line inline script in every <head>) so that a
   failed or blocked brood.js leaves the page fully readable instead of
   leaving every section at opacity 0 forever. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal { opacity: 0; transform: translateY(14px); }
  .js .reveal.in {
    opacity: 1;
    transform: none;
    transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  }
}

/* ------------------------------------------------------------------- hero */
/* The helix as the headline. Two treatments, deliberately separate renders:
   `helix-bg.mp4` is unlabelled and seamless and lives BEHIND the copy;
   `helix-c.mp4` carries the labels and is shown large as the figure itself.
   Never put the labelled cut behind text — two sets of words fight. */
.hero {
  /* NO `isolation: isolate` and NO z-index here. Either one makes .hero a
     stacking context, which traps the fixed "what is this graph?" dialog and its
     backdrop inside it — and since .hero sits at z-index auto in the root
     context, every section AFTER it in the DOM then paints straight over the
     dialog no matter how high its z-index is. That is why the practices cards
     showed through the panel on scroll. Nothing inside the hero uses a negative
     z-index any more, so no stacking context is needed to contain it. */
  position: relative;
  overflow: hidden;
  /* The hero lost three paragraphs, so a near-full-height centred box left a
     dead band above the wordmark. Sized to the content it actually has now. */
  min-height: min(26svh, 13rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding-block: clamp(0.4rem, 0.9vw, 0.8rem);
}
/* The scrim is what makes text on video legible. Radial keeps the centre
   readable; the linear pass darkens top and bottom into the nav and the page. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Radial ONLY, and it fades to fully transparent inside the hero's own box.
     The linear half of this used to end in `var(--black)` at the hero's bottom
     edge — which drew a hard horizontal line across the band the moment the
     hero stopped owning the whole plate. A scrim that reaches an edge IS an
     edge. The band's own veil now carries the vertical gradient, across the
     full height, so there is nothing to butt against. */
  background:
    radial-gradient(ellipse 66% 60% at 50% 44%, rgba(5,4,3,0.72),
                    rgba(5,4,3,0.34) 54%, rgba(5,4,3,0.10) 76%, transparent 92%);
}
/* Target the copy explicitly. A blanket `.hero > *` outranks `.hero__bg` and
   `.whatsthis` on specificity and, coming later, resets both to
   position:relative — which drops the video into flow (pushing the headline
   below the fold) and un-pins the info panel. */
.hero > .wrap { position: relative; z-index: 2; }

/* The wordmark leads, the refrain follows. The refrain is set smaller than a
   normal h1 but given a much wider measure, so it spans the screen in two lines
   instead of stacking into three narrow ones — the line is long, and letting it
   run is what makes it read as a statement rather than a headline. */
/* The wordmark leads, the plain claim explains, the refrain gives it a voice.
   That order matters: a visitor who cannot tell what you sell in three seconds
   leaves, and "pour the gold into the cracks" needs the manifesto to decode.
   Demoting the refrain rather than deleting it keeps the one line on this site
   that no competitor could have written — and it now sits directly above the
   link to the essay it comes from. */
.wordmark {
  font-family: var(--sans);
  font-size: clamp(2.4rem, 7vw, 5rem);
  font-weight: 600;
  letter-spacing: 0.26em;
  text-indent: 0.26em;      /* balances the trailing tracking so it centres true */
  text-transform: uppercase;
  line-height: 1;
  color: var(--gold);
  /* A hard black offset plus a soft one under it. The hard shadow is what makes
     gold type readable over a moving plate — a blur alone goes to mush the
     moment a bright cluster drifts under a letter, because both are soft. The
     second shadow only seats the word on the ground.
     NOTE: this is the one place gold is not scarce. It is the wordmark, so it
     is the exception the rule is measured against — every other gold element on
     the page (seams, active tab, one accent word, the CTA) still is. */
  text-shadow: 0 3px 0 #050403, 0 6px 18px rgba(5, 4, 3, 0.85);
  /* MUST be zero. .wordmark is a <p>, so it inherits `p { margin-block: 1.05em }`
     — and at font-size 5rem that is 84px of margin above the wordmark. This was
     the "too much black space" at the top of the hero; it was never min-height. */
  margin: 0;
}
.hero__line {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.75rem, 4vw, 3rem);
  line-height: 1.14;
  max-width: min(24ch, 100%);
  margin: 0.85rem auto 0;
  text-wrap: balance;
  color: var(--ivory);
  /* Same hard-then-soft shadow as the wordmark. Over a moving plate a blur
     alone goes to mush the moment a bright cluster drifts under a letter,
     because both are soft; the hard offset is what holds the edge. */
  text-shadow: 0 2px 0 #050403, 0 4px 14px rgba(5, 4, 3, 0.85);
}
/* The sentence under the headline does the explaining, so it is set in the sans
   at reading size — a second serif line here competes with the headline above
   and the refrain below, and three display faces in a row is a masthead, not a
   hero. */
.hero__tag {
  font-family: var(--sans);
  font-size: clamp(1rem, 1.6vw, 1.14rem);
  line-height: 1.55;
  color: #d5cec1;
  max-width: 52ch;
  margin: 0.75rem auto 0;
  text-wrap: pretty;
  text-shadow: 0 1px 0 #050403, 0 3px 12px rgba(5, 4, 3, 0.9);
}@media (min-width: 60rem) {
  .hero__line { max-width: min(40ch, 92vw); }
  /* `nowrap` per sentence forces any break to fall at the full stop rather
     than mid-clause ("...do not cast a / gold vase"). */}

/* The still is painted ONLY where the video is hidden.
   It must never sit behind a playing `.hero__bg`: that layer is 78% opaque, and
   the poster is the LAST frame of the build, so the compositing works out to
   `video*0.78 + poster*0.22` — the finished network stays visible through every
   dark part of the frame and the build is invisible. When the video is present
   but simply cannot play, its own `poster` attribute covers the same case. */

/* ------------------------------------------------------------------- misc */
.stack > * + * { margin-top: var(--gap, 1rem); }
.hstack { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
.hero-img {
  width: 100%;
  height: auto;
  display: block;
  /* The source photograph's background is a slightly lighter black than the
     page, which reads as a visible rectangle. Screen blending dissolves it
     into the page; the mask then feathers what is left of the corners. */
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(ellipse 70% 66% at 50% 50%, #000 30%, transparent 86%);
  mask-image: radial-gradient(ellipse 70% 66% at 50% 50%, #000 30%, transparent 86%);
}
.skip {
  position: absolute;
  left: -9999px;
  background: var(--gold);
  color: var(--black);
  padding: 0.7rem 1rem;
  z-index: 999;
}
.skip:focus { left: 1rem; top: 0.6rem; }

/* ------------------------------------------------- what we do: the verticals */
/* The index is four doors, not four accordions. Each one has to stand on its
   own — a reader who lands here should be able to tell in one paragraph whether
   this is their field, without opening anything. */
.vert-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
}
/* four items, so 4 -> 2 -> 1 all divide evenly and never strand a lone card. */
@media (max-width: 72rem) { .vert-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 44rem) { .vert-grid { grid-template-columns: 1fr; } }

.vert {
  position: relative;
  display: block;
  color: inherit;
  background: linear-gradient(180deg, var(--ink) 0%, rgba(11, 9, 8, 0.35) 100%);
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  padding: 1.5rem 1.3rem 1.4rem;
  overflow: hidden;
  /* flex column so the "read the practice" line pins to the bottom of every
     card — with four unequal paragraphs side by side, ragged calls to action
     are the thing that makes a row of columns look unmade. */
  display: flex;
  flex-direction: column;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.vert::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--gold), transparent);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.45s var(--ease);
}
.vert:hover, .vert:focus-within {
  border-color: rgba(232, 182, 76, 0.28);
  transform: translateY(-2px);
}
.vert:hover::before, .vert:focus-within::before { transform: scaleY(1); }
.vert__num {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  color: var(--ash-dim);
}
.vert__name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.55rem, 2.15vw, 2rem);
  line-height: 1.08;
  color: var(--ivory);
  margin-top: 0.5rem;
  transition: color 0.3s var(--ease);
}
.vert__blurb { color: #c8c1b5; font-size: 0.89rem; line-height: 1.62; margin-top: 0.8rem; }
.vert:hover .vert__name { color: var(--gold); }
/* .vert is an <a> now. The visible "See the case study" line was deleted,
   and that line was ALSO the stretched click target, so the card element
   took over the href. Suppress the global link underline and colour the
   same way a.card does on the homepage. */
a.vert, a.vert:hover { text-decoration: none; color: inherit; }


/* --------------------------------------------------------- kintsugi block */
/* The refrain now sits BELOW the call to action, labelled, so it reads as the
   firm's stated philosophy rather than as a subhead nobody can decode. Most
   readers do not know what kintsugi is, so the line is glossed rather than left
   to carry the whole idea on its own. */
.kintsugi { margin-top: 0;
  max-width: 46ch;
  margin: 0 auto;
  text-align: center;
}
.kintsugi__label {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  color: var(--ash);
  margin: 0;
}
.kintsugi__line {
  font-family: var(--serif);
  font-style: italic;
  color: var(--gold);
  font-size: clamp(1.1rem, 2.05vw, 1.45rem);
  line-height: 1.38;
  margin: 0.7rem 0 0;
  text-wrap: balance;
}
.kintsugi__gloss {
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ash);
  margin: 0.7rem auto 0;
  max-width: 44ch;
  text-wrap: pretty;
}

/* the Signal handle is the whole contact route on the intelligence page */
.signal {
  font-family: var(--mono);
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  color: var(--gold);
  margin-top: 0.6rem;
  letter-spacing: 0.02em;
}
.signal b { color: var(--gold-hot); font-weight: 600; }
