/* =============================================================
   Synvarael Innovations — synvarael.com
   One stylesheet. No build step. No framework. Edit freely.

   Sibling site: doveboard-site (doveboard.com). This inherits that
   site's type system and its two OKLCh accent ramps deliberately —
   same house, same tokens — and diverges on purpose in three places,
   each noted where it happens:

     · GOLD MEANS SHIPPED HERE. On doveboard.com --gild means
       "business" and --dove means "personal". That split belongs to
       the product. On this site there is exactly one semantic for
       the gold ramp: it marks the one division with something
       finished in the world. Teal is the company's own structure
       colour. See §1 and §10.
     · A LEDGER, NOT A CARD GRID. The sibling reaches for
       card grids; five divisions in five full-width rows read as an
       index of a company rather than a feature list. See §9.
     · A CALMER AURORA. Two fields instead of three, lower opacity,
       longer periods. The parent should feel like foundation, not
       product energy. See §2.

   Sections: 0 fonts · 1 tokens · 2 base · 3 type · 4 layout
             5 nav · 6 buttons · 7 hero · 8 statements
             9 division ledger · 10 status · 11 shipped card
             12 shape diagram · 13 company · 14 contact
             15 prose · 16 footer · 17 spine · 18 motion
             19 responsive
   ============================================================= */

/* ---------- 0. Fonts ----------
   Self-hosted, and not negotiable. This company's position is that
   your systems should not depend on someone else's server staying
   up; a front door that fetches its typefaces from a font CDN on
   every page load would be contradicting that in the first 200ms.

   One variable file per family per subset, taken from the sibling
   repo so the two sites cannot drift apart typographically.
   Bricolage ships without its optical-size axis: pinning it drops
   the latin file from 75 KB to 41 KB and renders identically at
   every size either site sets.
   -------------------------------------------------------------- */
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/bricolage-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/bricolage-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/instrument-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/instrument-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/jetbrains-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/jetbrains-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- 1. Tokens ----------
   Inherited wholesale from the sibling repo: the same near-black
   page, the same two nine-step ramps stepped in OKLCh at a fixed hue
   (dove 181.7deg, gild 85.2deg) so every step is perceptually even
   rather than eyeballed. Written as hex because an unsupported
   oklch() on a near-black page is invisible text; the source oklch()
   is in the comment beside each step and is the thing to edit from.

   WHAT CHANGED HERE IS THE MEANING, NOT THE VALUES:
     --dove  is the company's structure colour — rules, eyebrows,
             the spine, the diagram, focus rings.
     --gild  means SHIPPED. It appears on exactly one division and
             on the one product that exists. If a second thing ever
             ships, it gets gold too; nothing else ever does.
   -------------------------------------------------------------- */
:root {
  --ink:        #07090C;   /* oklch(13.9% .008 255.5) */
  --ink-2:      #0C1017;
  --ink-3:      #11161F;
  --paper:      #E9EEF5;   /* oklch(94.7% .011 256.7) — 17.1:1 on ink */
  --fog:        #8A94A4;   /* 6.51:1 on ink */
  --fog-dim:    #7A869C;   /* 5.43:1 on ink — AA on every surface here */

  --dove:       #4FD8C4;   /* structure  — oklch(80.3% .121 181.7) */
  --gild:       #E3B23C;   /* shipped    — oklch(78.8% .141  85.2) */

  /* dove ramp, hue 181.7 */
  --dove-100:   #D2FCF4;   /* oklch(96% .045 181.7) */
  --dove-200:   #9DF1E2;   /* oklch(90% .085 181.7) */
  --dove-300:   #63E0CC;   /* oklch(83% .115 181.7) */
  --dove-500:   #00B29E;   /* oklch(68% .130 181.7) */
  --dove-700:   #006B5E;   /* oklch(47% .090 181.7) */
  --dove-800:   #004840;   /* oklch(36% .068 181.7) */
  --dove-900:   #002B26;   /* oklch(26% .048 181.7) */

  /* gild ramp, hue 85.2 */
  --gild-100:   #FEF0D4;   /* oklch(96% .040 85.2) */
  --gild-200:   #F6DBA1;   /* oklch(90% .080 85.2) */
  --gild-300:   #EDC56E;   /* oklch(84% .115 85.2) */
  --gild-500:   #C79600;   /* oklch(70% .145 85.2) */
  --gild-700:   #7A5B01;   /* oklch(49% .100 85.2) */
  --gild-800:   #553F03;   /* oklch(38% .076 85.2) */
  --gild-900:   #352602;   /* oklch(28% .055 85.2) */

  --dove-deep:  #1E8F80;
  --gild-deep:  #9A741C;

  --accent:     var(--dove);

  --glass:      rgba(255,255,255,.035);
  --glass-2:    rgba(255,255,255,.055);
  --hair:       rgba(255,255,255,.09);
  --hair-soft:  rgba(255,255,255,.05);

  --font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --shell: 1180px;
  --pad: clamp(20px, 5vw, 40px);
  --band: clamp(76px, 9vw, 128px);
  --r: 14px;
  --r-lg: 20px;

  --ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Ambient aurora — TWO slow fields, fixed behind everything.

   NO filter: blur(). The sibling repo measured this and the note is
   worth carrying over verbatim: blurring two ~900px fixed layers on
   every composited frame cost 33ms of a 16.7ms budget — 20fps under a
   4x CPU throttle, 60fps with nothing changed but that one line. A
   radial-gradient with soft stops is already a blur; the filter was
   re-blurring something blurry and buying nothing. Do not put it back.

   Calmer than the sibling on purpose: two fields rather than three,
   lower opacity, longer periods (74s / 92s, no useful common
   multiple). A parent company should read as ground, not weather. */
body::before,
body::after {
  content: "";
  position: fixed;
  z-index: -2;
  border-radius: 50%;
  pointer-events: none;
}
body::before {
  width: 104vw; height: 104vw;
  top: -40vw; left: -30vw;
  background: radial-gradient(circle,
    rgba(79,216,196,.10), rgba(79,216,196,.038) 44%, transparent 70%);
  animation: drift-a 74s var(--ease) infinite alternate;
}
body::after {
  width: 92vw; height: 92vw;
  top: 48vh; right: -34vw;
  background: radial-gradient(circle,
    rgba(227,178,60,.075), rgba(227,178,60,.028) 44%, transparent 70%);
  animation: drift-b 92s var(--ease) infinite alternate;
}
@keyframes drift-a {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(7vw, 6vh, 0) scale(1.1); }
}
@keyframes drift-b {
  from { transform: translate3d(0,0,0) scale(1.05); }
  to   { transform: translate3d(-6vw, -7vh, 0) scale(1); }
}
/* site.js sets this when the tab goes to the background. */
body.is-still::before,
body.is-still::after { animation-play-state: paused; }

img, svg { max-width: 100%; display: block; }

a { color: inherit; }

::selection { background: rgba(79,216,196,.28); }

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

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--dove); color: #04211C;
  padding: 12px 18px; z-index: 100;
  font-family: var(--font-mono); font-size: 13px;
}
.skip:focus { left: 12px; top: 12px; }

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

/* ---------- 3. Type ---------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -.028em;
  margin: 0 0 .5em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 6.2vw, 4.7rem); letter-spacing: -.042em; line-height: 1; }
h2 { font-size: clamp(1.95rem, 4vw, 3.05rem); letter-spacing: -.034em; }
h3 { font-size: clamp(1.24rem, 1.9vw, 1.5rem); letter-spacing: -.02em; }
h4 { font-size: 1.04rem; letter-spacing: -.012em; }

p { margin: 0 0 1.15em; color: var(--fog); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: clamp(1.05rem, 1.7vw, 1.26rem);
  line-height: 1.6;
  color: #A6B0BF;
  max-width: 64ch;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.eyebrow::before {
  content: "";
  width: 22px; height: 1px;
  background: currentColor;
  flex: none;
}

.mono { font-family: var(--font-mono); }
strong { color: var(--paper); font-weight: 600; }
.dove-text { color: var(--dove); }
.gild-text { color: var(--gild); }

/* The one-line thesis, set apart behind a rule. Inherited shape from
   the sibling; here it carries the data-ownership position, which is
   the sentence the whole site exists to make. */
.thesis {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 400;
  line-height: 1.36;
  letter-spacing: -.02em;
  color: var(--paper);
  margin: 0;
  padding-left: 22px;
  border-left: 2px solid var(--accent);
  max-width: 54ch;
}

/* ---------- 4. Layout ---------- */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.band { position: relative; padding-block: var(--band); }
.band--tint { background: linear-gradient(180deg, transparent, rgba(12,16,23,.72) 18%, rgba(12,16,23,.72) 82%, transparent); }

.rule {
  height: 1px; border: 0; margin: 0;
  background: linear-gradient(90deg, transparent, var(--hair) 22%, var(--hair) 78%, transparent);
}

.stack > * + * { margin-top: 18px; }

.section-head { max-width: 780px; margin-bottom: clamp(38px, 5vw, 62px); }

/* ---------- 5. Nav ----------
   NO JAVASCRIPT ANYWHERE IN HERE, and that is a deliberate departure
   from the sibling. doveboard.com collapses its nav into a
   display:none list behind a button that only a script can open — so
   with scripting off, on a phone, its nav links are unreachable. This
   site has three links; they stay visible at every width and simply
   get smaller. A menu that cannot fail is better than a menu that
   degrades. */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(7,9,12,.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hair-soft);
}
.nav-inner {
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 28px);
  min-height: 66px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  margin-right: auto;
  flex: none;
}
.brand svg { width: 25px; height: 25px; flex: none; }
.brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -.012em;
}
.brand-sub {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fog-dim);
  margin-left: 2px;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.6vw, 26px);
  list-style: none;
  margin: 0; padding: 0;
}
.nav-links a {
  font-size: 14.5px;
  color: var(--fog);
  text-decoration: none;
  transition: color .18s var(--ease);
  white-space: nowrap;
}
.nav-links a:hover { color: var(--paper); }
.nav-links a[aria-current="page"] { color: var(--paper); }

/* ---------- 6. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  padding: 13px 22px;
  border-radius: 10px;
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .16s var(--ease), background .18s var(--ease), border-color .18s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--dove); color: #04211C; }   /* 9.64:1 */
.btn--primary:hover { background: var(--dove-300); }
.btn--ghost {
  background: var(--glass);
  border-color: var(--hair);
  color: var(--paper);
}
.btn--ghost:hover { background: var(--glass-2); border-color: rgba(255,255,255,.16); }
.btn--sm { padding: 10px 16px; font-size: 14px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* ---------- 7. Hero ---------- */
.hero {
  position: relative;
  padding-top: clamp(52px, 7vw, 92px);
  padding-bottom: clamp(48px, 6vw, 78px);
}
.hero-head { max-width: 960px; }
.hero h1 { margin-bottom: 24px; }
.hero .lede { margin-bottom: 34px; }
.hero .thesis { margin-bottom: 34px; }

.hero-note {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fog-dim);
  letter-spacing: .02em;
  line-height: 1.75;
  margin-top: 26px;
  max-width: 74ch;
}

/* ---------- 8. Statements ----------
   The position, three plain claims separated by hairlines. A card
   grid would make these look like product features; a ruled list
   makes them look like terms. */
.statements { border-top: 1px solid var(--hair-soft); max-width: 900px; }
.statement {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: 10px clamp(24px, 4vw, 56px);
  padding-block: clamp(26px, 3vw, 38px);
  border-bottom: 1px solid var(--hair-soft);
}
.statement h3 { margin: 0; }
.statement p { margin: 0; }

/* ---------- 9. The division ledger ----------
   Five rows, not five cards. Each row is [number] [content] [status],
   and the whole block reads as an index of a company: ordered,
   numbered, and instantly scannable for which entry is live.

   The number column is also where the spine's branches land, so its
   width is shared with §17. */
.ledger { border-top: 1px solid var(--hair); }

/* Areas rather than line numbers, because the status chip has to sit
   directly under the division's name at EVERY width. Laid out by
   column it ended up after the DoveBoard card on a phone — the one
   piece of information a visitor is scanning for, printed last. DOM
   order is name → status → description → note, which is also the
   order a screen reader should hear it in. */
.division {
  position: relative;
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr) 190px;
  grid-template-areas:
    "num name chip"
    "num body note";
  gap: 0 clamp(20px, 3.4vw, 46px);
  padding-block: clamp(40px, 4.6vw, 66px);
  border-bottom: 1px solid var(--hair-soft);
  scroll-margin-top: 84px;
}

.division-num {
  grid-area: num;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 4.4vw, 3.6rem);
  line-height: .82;
  letter-spacing: -.05em;
  color: var(--fog-dim);          /* 5.43:1 — clears AA even as small text */
  margin: 0;
  padding-top: .06em;
}
.division h3 { grid-area: name; margin: 0 0 14px; }
.division > .status { grid-area: chip; align-self: start; justify-self: start; }
.division-body { grid-area: body; }
.division > .status-note { grid-area: note; margin-top: 16px; }

.division-lead {
  color: #A6B0BF;
  font-size: clamp(1.02rem, 1.4vw, 1.14rem);
  margin: 0 0 14px;
  max-width: 60ch;
}
.division-detail { margin: 0; max-width: 68ch; }

/* The live one. Four signals, not one: a gold wash across the row, the
   number in gold, a filled status chip, and the only card on the page.
   Four because one colour cue alone fails for anyone reading this in
   greyscale or without full colour vision — the chip's WORD is what
   actually carries the meaning, and the colour only speeds it up. */
.division--live { background: linear-gradient(90deg, rgba(227,178,60,.06), transparent 56%); }
.division--live .division-num { color: var(--gild); }

/* ---------- 10. Status ---------- */
.status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .15em;
  text-transform: uppercase;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--hair);
  background: var(--glass);
  color: var(--fog);              /* 6.5:1 on ink, 6.2:1 over the glass */
  white-space: nowrap;
}
.status::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: .85;
  flex: none;
}
.status--live {
  color: var(--gild-200);         /* 13.6:1 on ink */
  border-color: rgba(227,178,60,.42);
  background: rgba(227,178,60,.11);
}
.status-note {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.65;
  color: var(--fog-dim);
  margin: 0;
  letter-spacing: .01em;
}

/* ---------- 11. The shipped card ----------
   DoveBoard gets exactly one of these on the whole site. It states
   what the product is, what is honestly true of it today, and links
   out. It is not a pitch: anyone who wants the pitch follows the
   link, and the pitch lives at doveboard.com where it belongs. */
.shipped {
  margin-top: 26px;
  border: 1px solid rgba(227,178,60,.24);
  border-radius: var(--r);
  background: linear-gradient(160deg, rgba(227,178,60,.075), rgba(255,255,255,.02) 62%);
  padding: clamp(20px, 2.4vw, 28px);
  max-width: 62ch;
}
.shipped-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.shipped-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -.02em;
}
.shipped p { margin: 0 0 12px; }
/* --fog, not --fog-dim. This note sits on two stacked gold washes —
   the row's and the card's — and --fog-dim measures 4.25:1 against
   the lightest point of that stack, which is a fail. Against the bare
   page it measures 5.43:1, which is why looking at the token instead
   of the composited pixel would have passed it. */
.shipped-note {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fog);
  line-height: 1.65;
  margin: 0 0 18px;
}
.out {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 15px;
  color: var(--gild);
  text-decoration: none;
  border-bottom: 1px solid rgba(227,178,60,.4);
  padding-bottom: 2px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.out:hover { color: var(--gild-200); border-color: var(--gild-200); }
.out svg { width: 13px; height: 13px; }

/* ---------- 12. The shape diagram ----------
   Four pillars standing on one bar. The three in the chain are linked
   by arrows; the trade stands on the same ground with a gap and a
   dashed edge, because it is not in the chain and should not look
   like it is.

   Built from HTML boxes rather than one big SVG on purpose: the text
   is real text, so it reflows, scales with the reader's font size,
   and its contrast can be measured. Only the arrows are SVG, at a
   fixed size, so nothing in here can be stretched out of shape. */
.shape-map { margin-top: clamp(36px, 4.4vw, 58px); }

.map-row { display: flex; align-items: stretch; }

.map-node {
  flex: 1 1 0;
  min-width: 0;
  border: 1px solid var(--hair);
  border-bottom: 0;
  border-radius: var(--r) var(--r) 0 0;
  background: var(--glass);
  padding: 18px 18px 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.map-n {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  color: var(--fog-dim);
}
.map-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(.95rem, 1.35vw, 1.1rem);
  letter-spacing: -.018em;
  line-height: 1.2;
  color: var(--paper);
}
.map-role {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .05em;
  color: var(--dove);
  margin-top: auto;
  padding-top: 8px;
}

.map-node--live {
  border-color: rgba(227,178,60,.34);
  background: linear-gradient(180deg, rgba(227,178,60,.10), rgba(227,178,60,.03));
}
.map-node--live .map-n { color: var(--gild); }
.map-node--live .map-role { color: var(--gild-200); }

/* Dashed, and set apart by a real gap: this one is not in the chain. */
.map-node--apart { border-style: dashed; }
.map-node--apart .map-role { color: var(--fog); }

.map-arrow {
  flex: 0 0 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 0;
}
.map-arrow svg { width: 26px; height: 12px; color: var(--dove); opacity: .8; }
/* Wider than the arrow slots, and deliberately so — this gap is the
   only thing saying the trade is not the fourth link in the chain. */
.map-gap { flex: 0 0 clamp(20px, 3.2vw, 48px); }

.map-base {
  border: 1px solid rgba(79,216,196,.3);
  border-radius: 0 0 var(--r) var(--r);
  background: linear-gradient(180deg, rgba(79,216,196,.12), rgba(79,216,196,.035));
  padding: 16px clamp(16px, 2vw, 22px);
  display: flex;
  align-items: baseline;
  gap: 8px 16px;
  flex-wrap: wrap;
}
.map-base b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  letter-spacing: -.02em;
  color: var(--paper);
}
.map-base .map-n { color: var(--dove); }
.map-base span:last-child {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--fog);
  letter-spacing: .02em;
}

/* ---------- 13. Company ---------- */
.company-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 72px);
  align-items: start;
}
.company-facts {
  border-top: 1px solid var(--hair-soft);
  margin: 0;
}
.company-facts div {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding-block: 15px;
  border-bottom: 1px solid var(--hair-soft);
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .02em;
}
.company-facts dt { color: var(--fog-dim); }
.company-facts dd { margin: 0; color: var(--paper); text-align: right; }

/* ---------- 14. Contact ---------- */
.contact-card {
  border: 1px solid var(--hair);
  border-radius: var(--r-lg);
  background: var(--glass);
  padding: clamp(26px, 3.4vw, 44px);
  max-width: 760px;
}
.mail {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: clamp(1rem, 2.6vw, 1.35rem);
  color: var(--dove);
  text-decoration: none;
  border-bottom: 1px solid rgba(79,216,196,.4);
  padding-bottom: 3px;
  margin-bottom: 20px;
  word-break: break-word;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.mail:hover { color: var(--dove-200); border-color: var(--dove-200); }

/* ---------- 15. Prose (about page) ---------- */
.prose { max-width: 72ch; }
.prose h2 { font-size: clamp(1.4rem, 2.4vw, 1.8rem); margin-top: 52px; }
.prose h2:first-of-type { margin-top: 0; }
.prose h3 { font-size: 1.14rem; margin-top: 34px; }
.prose ul { color: var(--fog); padding-left: 20px; margin: 0 0 1.15em; }
.prose li { margin-bottom: 10px; }
.prose a { color: var(--dove); }
.prose .sign {
  font-family: var(--font-mono);
  color: var(--fog-dim);
  font-size: 13px;
  letter-spacing: .05em;
  margin-top: 30px;
}

.principles { border-top: 1px solid var(--hair-soft); }
.principle {
  padding-block: clamp(22px, 2.6vw, 32px);
  border-bottom: 1px solid var(--hair-soft);
}
.principle h3 { margin: 0 0 10px; }
.principle p { margin: 0; max-width: 68ch; }

/* Three utilities, and the reason they exist: with these, the site has
   no style attribute anywhere, so the Content-Security-Policy can say
   style-src 'self' with no 'unsafe-inline' at all. The sibling site
   keeps 'unsafe-inline' for exactly this handful of cases. */
.mt { margin-top: 26px; }
.link { color: var(--dove); }
.foot-base--bare { border-top: 0; padding-top: 0; }

/* ---------- 16. Footer ---------- */
.foot {
  border-top: 1px solid var(--hair-soft);
  padding-block: 54px 40px;
  background: rgba(9,12,17,.6);
  position: relative;
  z-index: 1;
}
.foot-top {
  display: grid;
  grid-template-columns: 1.8fr 1fr 1fr 1fr;
  gap: 36px;
  margin-bottom: 44px;
}
/* Not headings. These label the three footer nav regions, and as <h4>
   after the page's <h2>s they would put a two-level jump in the
   outline of every page on the site. */
.foot-h {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--fog-dim);
  margin: 0 0 16px;
}
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.foot ul a {
  font-size: 14.5px;
  color: var(--fog);
  text-decoration: none;
  transition: color .18s var(--ease);
}
.foot ul a:hover { color: var(--paper); }
.foot-blurb { font-size: 14.5px; max-width: 42ch; margin-top: 16px; }
.foot-base {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 26px;
  align-items: center;
  padding-top: 26px;
  border-top: 1px solid var(--hair-soft);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--fog-dim);
  letter-spacing: .03em;
}
.foot-base .spacer { margin-left: auto; }
.foot-base a { color: inherit; text-decoration: none; }
.foot-base a:hover { color: var(--fog); }

/* ---------- 17. The spine ----------
   The sibling's spine is a scroll journey: one path weaving side to
   side down the whole page with sections hanging off it. Here it does
   a different job. It is a trunk down the left of the division ledger
   with a branch and a node into each division — structure, and which
   things hang off it, rather than a route through a story.

   THE DEFAULT IS THE FULLY DRAWN TRUNK. Everything below only ever
   takes drawing away, from a browser with a scroll timeline or one
   running site.js. So the failure direction is "already drawn" rather
   than "invisible for ever", and reduced-motion and no-JS both land
   on the same picture, finished.

   GEOMETRY NOTE. The trunk SVG is stretched with
   preserveAspectRatio="none" and contains a vertical line and
   nothing else, because a vertical line is the one shape that
   stretching vertically cannot distort. Everything with a curve in
   it — the nodes — lives in the per-row branch SVGs, which are a
   fixed size and are never stretched at all. */
.spine-host { position: relative; }
.spine-host > *:not(.spine) { position: relative; z-index: 1; }

.spine {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: var(--lane);
  z-index: 0;
  pointer-events: none;
  contain: layout paint;
}
.spine svg { width: 100%; height: 100%; display: block; }
.spine-line {
  fill: none;
  stroke: url(#spine-grad);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* The ledger reserves a lane down its left for the trunk. */
.ledger { --lane: 46px; padding-left: var(--lane); }

/* The node has to sit on the optical centre of the number it points at,
   and both the row's padding and the number's size are fluid, so a fixed
   offset only lines up at one width — it was 9px low at 820px. This
   derives the offset from the same two clamps the layout uses:
   padding-top, plus the number's .06em padding and half its .82
   line-height, minus half this box's own height. */
.branch {
  position: absolute;
  left: calc(var(--lane) * -1);
  top: calc(clamp(40px, 4.6vw, 66px) + 0.47 * clamp(2.4rem, 4.4vw, 3.6rem) - 24px);
  width: var(--lane);
  height: 48px;
  pointer-events: none;
}
.branch-line {
  fill: none;
  stroke: var(--dove);
  stroke-width: 1.2;
  opacity: .5;
  vector-effect: non-scaling-stroke;
}
.branch-node {
  fill: var(--ink);
  stroke: var(--dove);
  stroke-width: 1.6;
  vector-effect: non-scaling-stroke;
}
.division--live .branch-node { stroke: var(--gild); fill: var(--gild-900); }
.division--live .branch-line { stroke: var(--gild); opacity: .7; }

/* The trunk's terminator: the ledger ends in something, rather than
   the line simply stopping. */
.spine-cap {
  position: absolute;
  left: calc(var(--lane) / 2 - 3px);
  bottom: -3px;
  width: 6px; height: 6px;
  border-radius: 1px;
  background: var(--dove);
  opacity: .55;
}

@keyframes spine-draw {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

@media (prefers-reduced-motion: no-preference) {
  /* 1. In CSS alone, where the browser has scroll timelines. The range
        stops at 70% rather than the sibling's 92%: this element is
        ~2600px tall, and over a `cover` range the drawn front edge
        runs behind the reader on a block that long — row 05 would
        still be undrawn while you were reading it. Ending the draw
        early keeps the trunk ahead of the eye the whole way down. */
  @supports (animation-timeline: view()) {
    .spine {
      view-timeline-name: --spine;
      view-timeline-axis: block;
      animation: spine-draw linear both;
      animation-timeline: --spine;
      animation-range: cover 0% cover 70%;
    }
  }
  /* 2. Otherwise, and only when site.js is running, from --draw. */
  @supports not (animation-timeline: view()) {
    .js .spine { clip-path: inset(0 0 calc((1 - var(--draw, 1)) * 100%) 0); }
  }
}

/* Registered so the initial value is a real typed 1 — fully drawn —
   rather than only the fallback inside each var(). */
@property --draw {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}

/* ---------- 18. Reveal + motion ----------
   THE HIDDEN STATE IS GATED ON .no-js HAVING GONE. A bare
   `.reveal { opacity: 0 }` means a visitor with scripting off gets a
   blank page below the hero, because the class that would reveal it
   is added by the script that is not running. `no-js` ships in the
   HTML and site.js removes it, so the default — no JS, a failed
   script load, a blocked file — is the whole page, visible.

   site.js also marks everything already on screen as `is-in` BEFORE
   it removes that class, so nothing a visitor can already see is
   taken away from them for the length of an animation frame. */
html:not(.no-js) .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
  transition-delay: var(--rd, 0ms);
}
html:not(.no-js) .reveal.is-in { opacity: 1; transform: none; }

/* The foundation bar draws itself in from the left as the diagram
   arrives — the one gesture on the page that reads as assembly
   rather than arrival. Same gate: with no JS it is simply drawn. */
html:not(.no-js) .grow {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .62s var(--ease);
  transition-delay: var(--rd, 0ms);
}
html:not(.no-js) .grow.is-in { transform: none; }

/* The pillars only fade — they must not rise. Their bottom edge is
   the top edge of the foundation bar, so a 12px lift opens a visible
   seam between them mid-animation and the diagram looks broken for
   half a second. And they wait for the ground: the bar draws, then
   the things standing on it arrive. */
html:not(.no-js) .map-node.reveal,
html:not(.no-js) .map-arrow.reveal { transform: none; }
html:not(.no-js) .map-row .reveal { transition-delay: calc(var(--rd, 0ms) + 190ms); }

/* Staggered, and deliberately fast. A reader should never be waiting
   on an animation to be allowed to read. */
.stagger > *:nth-child(1) { --rd: 0ms; }
.stagger > *:nth-child(2) { --rd: 55ms; }
.stagger > *:nth-child(3) { --rd: 110ms; }
.stagger > *:nth-child(4) { --rd: 165ms; }
.stagger > *:nth-child(5) { --rd: 220ms; }
.stagger > *:nth-child(6) { --rd: 275ms; }
.stagger > *:nth-child(n+7) { --rd: 320ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  html:not(.no-js) .reveal { opacity: 1; transform: none; }
  html:not(.no-js) .grow   { transform: none; }
  body::before, body::after { animation: none; }
  /* Say it twice. The blanket rule above kills the animation, but an
     animation with `both` fill can still hold its from-state, and the
     from-state here is an undrawn spine. */
  .spine { animation: none !important; clip-path: none !important; }
}

/* ---------- 19. Responsive ---------- */
@media (max-width: 1000px) {
  .division {
    grid-template-columns: 84px minmax(0, 1fr);
    grid-template-areas: "num name" "num chip" "num body" "num note";
  }
  .division h3 { margin-bottom: 12px; }
  .division > .status { margin-bottom: 20px; }
  .company-grid { grid-template-columns: 1fr; }
  .foot-top { grid-template-columns: 1.5fr 1fr 1fr; }
}

/* Four pillars side by side stop fitting well before the page does.
   Below this the diagram becomes a column, and the arrows turn a
   quarter turn to keep pointing along the chain. */
@media (max-width: 880px) {
  .map-row { flex-direction: column; }
  .map-node {
    flex: 0 0 auto;
    border-bottom: 1px solid var(--hair);
    border-radius: var(--r);
  }
  .map-node--live { border-color: rgba(227,178,60,.34); }
  .map-arrow { flex: 0 0 30px; }
  .map-arrow svg { transform: rotate(90deg); }
  .map-gap { flex: 0 0 14px; }
  .map-base { border-radius: var(--r); margin-top: 14px; }
  .map-role { margin-top: 0; padding-top: 2px; }
}

@media (max-width: 760px) {
  /* The branches go the way the sibling's spine nodes go at narrow
     widths: the lane is too tight for them to land anywhere sensible,
     and the trunk on its own still says "these hang off one thing". */
  .ledger { --lane: 24px; }
  .branch { display: none; }

  .statement { grid-template-columns: 1fr; gap: 8px; }
  .division {
    grid-template-columns: 1fr;
    grid-template-areas: "num" "name" "chip" "body" "note";
    padding-block: 36px;
  }
  .division-num { font-size: 2rem; margin-bottom: 8px; }
  .foot-top { grid-template-columns: 1fr 1fr; }
  .foot-top > :first-child { grid-column: 1 / -1; }
  .foot-blurb { max-width: none; }
  .brand-sub { display: none; }
}

@media (max-width: 480px) {
  body { font-size: 16px; }
  .thesis { padding-left: 16px; }
  .nav-links { gap: 13px; }
  .nav-links a { font-size: 13.5px; }
  .company-facts div { flex-direction: column; gap: 2px; }
  .company-facts dd { text-align: left; }
}
