/* ============================================================================
   layouts/home-v2.css — Acts III, V, VI and VII.

   Proof grouped by employer, five capabilities instead of a taxonomy, the
   human layer, and the closing point-of-view band.

   The governing decision in this file: numbers are never presented bare. The
   pre-2.0 site had a KPI wall where "$1.75B" floated with a two-word caption,
   which invites the reader to assume Kyle produced the figure. Every number
   here inherits an employer heading and carries its own mechanism line, so the
   claim it makes is the claim that is actually true.
   ============================================================================ */

/* A band head carrying only its eyebrow. The label's own bottom margin exists
   to separate it from an h2; with no h2 it just adds slack. */
.band-head--bare { margin-bottom: var(--space-m); }
.band-head--bare .label { margin-bottom: 0; }


/* ---- ACT I · HERO, SIDEBAR FACTS ------------------------------------------
   2026-09-10 — identity.css collapsed .hero to a single column when the
   portrait moved out (correct: the H1 needs the full page measure, and it is
   frozen and untouched here). What that left uncorrected: hero-sub caps at
   52ch and hero-cta is two buttons, so .hero-body read as a narrow stack
   pinned to the left edge of a 1240px .page with the entire right half empty
   above the fold. Kyle, looking at the rendered page: the deck, the CTAs and
   the facts row were all sitting in a left column with dead space beside
   them.

   Fix follows the same device as the Background rebuild one band down: a
   sidebar grid rather than a wider text column. hero-sub stays at a readable
   52ch inside .hero-main; hero-meta (Based / Currently) becomes a facts rail
   in the second column, matching the vertical-rule facts pattern case studies
   already use in .cs-rail-facts. At 52ch, .hero-main happens to fill almost
   exactly the space the grid leaves it once the rail and gap are subtracted,
   so nothing here is stretched past a comfortable reading measure to hit the
   width — the two pieces just now sit side by side instead of stacked. */
@media (min-width: 860px) {
  .hero-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
    column-gap: var(--space-2xl);
    align-items: start;
  }
  .hero-meta {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-m);
    margin-top: 0;
    padding-top: 0;
    padding-left: var(--space-l);
    border-top: none;
    border-left: 1px solid var(--line-2);
  }
  .hero-meta div { min-width: 0; }
}

/* The proofline strip directly under the hero reads as part of the same
   block (only a hairline separates them), so once hero-body fills the full
   width above it, four short facts left-aligned under that started reading
   as their own dead zone on the right. Spreading them edge to edge is the
   same fix as the sidebar above: use the width that is already there rather
   than adding visual weight to make the row longer. Below 860px this stays
   the original compact, left-hugging line — there is no room to spread it
   meaningfully on tablet and phone. */
@media (min-width: 860px) {
  .proofline { justify-content: space-between; }
}


/* ---- ACT III · PROOF, GROUPED -------------------------------------------- */

.proofset { display: grid; gap: var(--space-m); }
/* Three-up from 760px, not 900. Between 760 and 899 the groups stacked into a
   single column of three 525px cards — 1.6 screens of one-column cards on an
   iPad — while the capabilities directly beneath were already two-up. */
@media (min-width: 760px) { .proofset { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 760px) and (max-width: 899px) {
  .pgroup { padding: var(--space-s); }
  .pstat-n { font-size: var(--step-1); }
}

.pgroup {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  padding: var(--space-m);
  text-decoration: none;
  color: inherit;
}

.pgroup-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2xs);
  padding-bottom: var(--space-2xs);
  margin-bottom: var(--space-s);
  border-bottom: 1px solid var(--line);
}
.pgroup-co {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
}
.pgroup-when {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pstat { padding-block: var(--space-2xs); }
.pstat + .pstat { border-top: 1px dashed var(--line); }

/* The figure. Fraunces at data settings — no wonk, so numerals stay sober. */
.pstat-n {
  display: block;
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  margin-bottom: 3px;
}
.pstat-what {
  display: block;
  font-size: var(--step--1);
  line-height: 1.45;
  color: var(--ink-2);
  text-wrap: pretty;
}

.pgroup-cue {
  margin-top: auto;
  padding-top: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.04em;
  color: var(--ink-3);
  transition: color var(--dur-fast) var(--ease-out);
}
.pgroup:hover .pgroup-cue,
.pgroup:focus-visible .pgroup-cue { color: var(--gold); }

/* A group with no case study behind it is a <div>, not an <a>, and must not
   pretend to be clickable. */
.pgroup--static { cursor: default; }
/* --ink-faint is not a text colour (2.41:1 on surface). --ink-3 is 4.6:1 and
   the cue still reads quieter than the linked groups' gold hover. */
.pgroup--static .pgroup-cue { color: var(--ink-3); }


/* ---- ACT V · CAPABILITIES ------------------------------------------------ */

.caps5 { display: grid; gap: var(--space-s); }
@media (min-width: 760px)  { .caps5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .caps5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.cap5 {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

/* The fifth card is the hinge into the operating-system band: it is the one
   capability the rest of the page has to earn the right to claim.

   It also spans two columns on the three-up grid. Five cards in a three-column
   grid otherwise resolve to 3 + 2 and leave a visible hole in the second row.
   Widening this card closes the hole AND puts the emphasis on the capability
   that the section is building toward, so the fix is compositional rather than
   a patch. On the two-up grid five resolves to 3 + 2 with the hole in the same
   place, so it spans there too. */
.cap5--ai { border-color: var(--gold-line); background: linear-gradient(var(--gold-wash), var(--gold-wash)) var(--surface); }
@media (min-width: 760px)  { .cap5--ai { grid-column: span 2; } }
@media (min-width: 1080px) { .cap5--ai { grid-column: span 2; } }

.cap5-n {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  color: var(--ink-3);
}
.cap5--ai .cap5-n { color: var(--gold); }

.cap5 h3 {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.18;
  margin: 0;
}
.cap5 p {
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
  text-wrap: pretty;
}

/* Evidence line — the specific thing that makes the capability claim checkable. */
.cap5-ev {
  margin-top: auto;
  padding-top: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.5;
  color: var(--ink-3);
  border-top: 1px dashed var(--line);
}

/* Tools are a footnote to capability, never the story. */
.toolrow {
  margin-top: var(--space-m);
  padding-top: var(--space-s);
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-s);
  align-items: baseline;
}
.toolrow-label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-3);
}
.toolrow ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-xs);
  margin: 0;
  padding: 0;
}
.toolrow li {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-2);
}
.toolrow li:not(:last-child)::after { content: " ·"; color: var(--ink-faint); }


/* ---- ACT IV LEAD-IN ------------------------------------------------------ */

.os-thesis {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 52ch;
  margin: 0 0 var(--space-l);
  text-wrap: pretty;
}

.os-figure {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m) var(--space-xl);
}

/* The legend variant. A rule underneath ties the three figures to the diagram
   below rather than letting them float as a standalone stat row, and the tight
   bottom margin keeps them inside the map's visual group. */
.os-legend {
  padding-bottom: var(--space-s);
  margin-bottom: var(--space-l);
  border-bottom: 1px solid var(--line);
}
.os-figure div { display: flex; flex-direction: column; gap: 2px; }
.os-figure b {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-3);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.os-figure span {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* LIGHT-THEME CONTRAST FIX.
   --gold (#90680C) clears AA on the page ground, on surface and on surface-2,
   which is what it was tuned against. It does NOT clear it on --bg-sunk: the
   sunken band is darker than the page, so the same gold measures 4.16:1 there
   against a 4.5 requirement. --gold-deep measures 6.13:1 on that ground and
   holds the same hue, so the band reads identically and passes.
   Same story for the 12%-gold wash behind the AI capability card: gold on that
   panel is 4.31:1, gold-deep is 6.36:1.
   Declared twice because the viewer's toggle must beat the media query. */
@media (prefers-color-scheme: light) {
  .band--sunk .os-figure b { color: var(--gold-deep); }
  .cap5--ai .cap5-n        { color: var(--gold-deep); }
}
:root[data-theme="light"] .band--sunk .os-figure b { color: var(--gold-deep); }
:root[data-theme="light"] .cap5--ai .cap5-n        { color: var(--gold-deep); }


/* ---- ACT VI · THE HUMAN LAYER -------------------------------------------- */

/* 2026-09-10, first pass — rebuilt from a two-column grid to a floated
   portrait (Kyle: "tons of blank space next to my background... put my pic
   in the top right and have the words form around it"). That fixed the
   photo's dead margin but created a new one: the whole section collapsed to
   a single 68ch column inside a 1240px .page, so the entire right half of
   the band sat empty next to every sibling section (#method, #capabilities)
   that fills the same container edge to edge. Kyle: "This should take up
   the page. not be condensed."

   Second pass — full-width sidebar layout. The portrait moves into its own
   column (matches the .os-run-side sticky pattern used lower on the page)
   and the three dimension blocks become a two-column sub-grid inside the
   remaining width, same device as .moves: an odd block count means the last
   one spans full width instead of sitting alone in a half column. This
   fills the band's actual width instead of just widening a single text
   measure past comfortable reading length. */
.human { display: block; }
@media (min-width: 860px) {
  .human {
    display: grid;
    grid-template-columns: minmax(200px, 260px) minmax(0, 1fr);
    gap: var(--space-2xl);
    align-items: start;
  }
}

.human-portrait {
  display: block;
  width: 168px;
  max-width: 40%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-l);
  border: 1px solid var(--gold-line);
  margin: 0 0 var(--space-m);
}
@media (min-width: 860px) {
  .human-portrait {
    width: 100%;
    max-width: none;
    margin: 0;
    position: sticky;
    top: calc(var(--nav-h) + var(--space-l));
  }
}

.human-dims { display: grid; gap: var(--space-l); }
@media (min-width: 640px) {
  .human-dims { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-l) var(--space-xl); }
  .human-dims .human-dim:last-child { grid-column: 1 / -1; }
}

.human-body p {
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink-2);
  margin: 0;
  max-width: var(--measure-narrow);
  text-wrap: pretty;
}

.human-foot { margin-top: var(--space-l); }

.human-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m) var(--space-xl);
  margin: var(--space-m) 0 0;
  padding-top: var(--space-s);
  border-top: 1px solid var(--line);
}
.human-facts div { display: flex; flex-direction: column; gap: 2px; }
.human-facts b {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.human-facts span {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.04em;
  color: var(--ink-3);
}


/* ---- ACT VII · POINT OF VIEW --------------------------------------------- */

.povs { display: grid; gap: var(--space-s); }
@media (min-width: 900px) { .povs { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.pov {
  border-left: 2px solid var(--gold-line);
  padding: var(--space-2xs) 0 var(--space-2xs) var(--space-s);
}
.pov p {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-1);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0;
  text-wrap: pretty;
}

.pov-out { margin-top: var(--space-l); }


/* ============================================================================
   DEAD-COLUMN FIXES — 2026-09-08

   Three separate reports of "this doesn't fill the page" turned out to be one
   cause. In 2.1 the operating-system band was wrapped in .os-band, a two-column
   grid: prose on the left, the six pipeline stages on the right. The V2.0
   rebuild dissolved that wrapper, so everything inside it fell to full width —
   a 24ch heading, a 52ch paragraph and six short pipeline rows, each hugging
   the left edge of a 1240px page with nothing opposite.
   ============================================================================ */

/* Headline and thesis as a pair, rather than two stacked left-aligned blocks
   with half the band empty beside them. */
@media (min-width: 1000px) {
  .band-head--split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-2xl);
    align-items: end;
  }
  .band-head--split h2 { max-width: none; margin: 0; }
  .band-head--split .os-thesis { margin: 0; max-width: none; }
}

/* The pipeline regains a right-hand column: the trace control and the status
   line that narrates whichever stage is currently lit. */
.os-run { display: grid; gap: var(--space-l); }
@media (min-width: 1000px) {
  .os-run { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: var(--space-2xl); align-items: start; }
  .os-run-side { position: sticky; top: calc(var(--nav-h) + var(--space-l)); }
}
.os-run-side > p { margin-top: var(--space-l); }

/* Long band headings were breaking at 24ch — "Neuroscience, process management,
   and five industries entered cold" is 62 characters, so it stacked into a
   narrow tower with the rest of the row empty. Homepage only: home-v2.css is
   not loaded by any other page, and it follows nav.css in source order. */
.band-head h2 { max-width: 34ch; }


/* ============================================================================
   POSITIONING PASS — 2026-09-09
   ============================================================================ */

/* Proof before chronology. A single quiet line under the hero so an executive
   has evidence in the first screenful without being asked to read a timeline
   first. Deliberately typographic rather than a card grid: cards here would
   compete with the Evidence band further down, which is where these figures
   are actually sourced and explained. */
.proofline-band { padding-block: 0 var(--space-l); }
.proofline {
  list-style: none;
  margin: 0;
  padding: var(--space-s) 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
  font-size: var(--step--1);
  color: var(--ink-2);
}
.proofline li { display: inline-flex; align-items: baseline; gap: 0.4em; }
.proofline b {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 700px) { .proofline { gap: var(--space-3xs) var(--space-m); } }

/* The agent count is evidence, not the achievement. Same row, less weight. */
.os-figure--quiet b { font-size: var(--step-2); color: var(--ink-2); }
.os-figure--quiet span { color: var(--ink-3); }

/* Tools as a toolkit with three named groups rather than fifteen equal items.
   The label leads, the group names carry the structure, and the products sit
   at body weight so the row reads as capability rather than a software list. */
.toolrow ul { flex-direction: column; gap: var(--space-2xs); }
.toolrow li { color: var(--ink-2); font-family: var(--font-body); }
.toolrow li::after { content: none; }
.toolrow li em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-right: var(--space-2xs);
}

/* Each principle now carries its argument. The claim stays in the display
   face; the reasoning sits under it in body type so the pair reads as a
   position rather than a pull-quote. */
.pov cite {
  display: block;
  margin-top: var(--space-2xs);
  font-style: normal;
  font-family: var(--font-body);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* Personality, held apart from the professional figures above it. */
.human-aside {
  margin: var(--space-s) 0 0;
  font-size: var(--step--1);
  color: var(--ink-3);
}


/* ============================================================================
   V3 — 2026-09-09

   Five new components, one retired. The retired one is the old .arcline career
   strip, replaced by .tl below; its rules are left in place because the case
   study pages still use .arc-* for their own timelines.

   Governing decision in this block, inherited from the file above: hierarchy
   carries meaning. In .moves that means three distinct typographic levels —
   MOVE (what he does), PRINCIPLE (why it works), EVIDENCE (where it was shown).
   Flattening them into one voice produces a wall of slogans, which is exactly
   what the band this replaces had become.
   ============================================================================ */

/* ---- Centred band heads -------------------------------------------------- */

.band-head--center { text-align: center; }
.band-head--center h2 { max-width: 24ch; margin-inline: auto; }
.band-dek {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.35;
  color: var(--ink-2);
  /* Wide enough that both current one-liners ("Six roles. Five industries.
     One operating method." and "Three environments, one method, different
     evidence.") never wrap on their own account (Kyle, 2026-09-10) — the cap
     only exists to stop a much longer future dek from running the full band
     width, not to force-wrap a 51-character sentence into two short lines.
     Still a max-width, not a fixed width, so a narrow viewport wraps exactly
     as before. */
  max-width: 46ch;
  margin: var(--space-2xs) auto 0;
  text-wrap: balance;
}
.band-head:not(.band-head--center) .band-dek { margin-inline: 0; }


/* ---- ACT II · CAREER SPINE ----------------------------------------------- */
/* 2026-09-10 — reoriented left-to-right on request. Company and dates (and,
   below 1080px, role) are ALWAYS rendered — nothing here is ever hidden from
   a reader without JavaScript or without a mouse. Only .tl-detail — the
   there-to-solve / owned / evidence / move rows — collapses into a hover/tap
   panel, and only once career.js has added .tl--js AND the row is wide enough
   to run horizontally. Below that width, or with JS unavailable, every detail
   block stays expanded in normal document flow. That is the same fail-safe
   philosophy the rest of this section already used; only the trigger changed,
   from "nearest the vertical centre of the viewport" to "hovered, focused, or
   tapped". Default DOM order is unchanged and load-bearing: Maximus first,
   KLJ Ventures last, so the horizontal row reads left-to-right exactly as the
   markup already reads top-to-bottom. Do not reorder the .tl-node children to
   "fix" the visual — fix the CSS instead. */

.tl { list-style: none; margin: 0; padding: 0; }
.tl-node {
  position: relative;
  padding: var(--space-m) 0;
  text-align: center;
}
/* The connector is drawn PER NODE, spanning only the gap above its dot, rather
   than as one line down the whole list. A full-height spine runs behind the
   detail block — which is centred on the same axis — and the 1px rule was
   visibly cutting through the body copy of whichever node was open. Confining
   it to the inter-node gap means it never crosses text, and needs no opaque
   background to mask it (the ambient field shows through these bands, so a
   masking background would have read as a floating rectangle). Horizontal
   mode replaces this per-node connector with a single spine across the row;
   see the >=1080px block below. */
.tl-node::before {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(var(--space-m) * -1);
  height: calc(var(--space-m) * 2);
  width: 1px;
  background: var(--line-2);
}
.tl-node:first-child::before { display: none; }
.tl-dot {
  display: block;
  width: 9px; height: 9px;
  margin: 0 auto var(--space-xs);
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  position: relative;
  z-index: 1;
  transition: background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.tl-node--now .tl-dot { border-color: var(--gold); }
/* Gold dot = "this one is open", on any input: mouse hover, keyboard focus,
   or the tap-toggle career.js adds. Same accent the rest of the page already
   uses for emphasis, so the affordance needs no new colour to read. */
.tl-node:hover .tl-dot,
.tl-node:focus-within .tl-dot,
.tl-node.is-open .tl-dot { background: var(--gold); border-color: var(--gold); }

.tl-when {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.tl-co {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 2px 0 1px;
  line-height: 1.15;
}
.tl-role { display: block; font-size: var(--step--1); color: var(--ink-2); }

/* .tl-head is the part that is ALWAYS visible and, once career.js runs, the
   part a reader clicks or tabs to. It gets the interactive treatment (cursor,
   focus ring) unconditionally; whether that affordance does anything is a
   layout question answered by the media queries below. */
.tl-head { border-radius: var(--radius-s); }
.tl--js .tl-head { cursor: pointer; }
.tl-head:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* The detail block reads as a document, so it is left-aligned inside a centred
   column. Centred body copy at this length is a legibility cost with no gain. */
.tl-detail {
  max-width: 62ch;
  margin: var(--space-s) auto 0;
  text-align: left;
  display: grid;
  gap: var(--space-2xs);
}
.tl-row { display: grid; gap: 2px; }
.tl-k {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.tl-row p { margin: 0; font-size: var(--step--1); line-height: 1.55; color: var(--ink-2); }
.tl-row--move p, .tl-row--start p { color: var(--ink); }
.tl-row--move .tl-k { color: var(--gold-deep); }
.tl-row--move b { font-weight: 600; }

/* ---- <1080px: vertical rail, everything expanded -------------------------
   Same ceiling as the horizontal threshold below, one pixel apart on purpose
   (see the note on that query). Nothing collapses here regardless of .tl--js:
   a stacked, always-open read is the correct phone and small-tablet treatment,
   and it means a touch user never has to discover a tap target to see the
   content — the fallback this section needs is "don't require the gesture at
   all" rather than "make the gesture reachable". */

/* ---- >=1080px: horizontal row, hover/tap to open -------------------------
   Threshold matches the one the pre-2.0 horizontal attempt on this exact
   section used and documented: six columns below ~1080px resolve too narrow
   for the company/role text to sit on a clean baseline. That reasoning still
   applies here, one layer up — it decided where the ROW breaks; this decides
   where the DETAIL POPOVER is allowed to exist at all. */
@media (min-width: 1080px) {
  .tl {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
    position: relative;
  }
  .tl-node {
    flex: 1 1 0;
    min-width: 0;
    padding: var(--space-m) var(--space-2xs) var(--space-l);
  }
  .tl-node::before { content: none; }

  /* One spine across the whole row, drawn once so it cannot develop the
     sub-pixel seams a per-cell border would. It runs through the dots, not
     the text, and stops short of both ends so the run reads as a segment of
     a longer career rather than a closed box — same intent as the vertical
     rail's spine, rotated 90 degrees. */
  .tl::before {
    content: "";
    position: absolute;
    top: calc(var(--space-m) + 4.5px);
    left: 4%;
    right: 4%;
    height: 1px;
    background: linear-gradient(90deg,
      transparent,
      var(--line-2) 10%,
      var(--line-2) 85%,
      var(--gold-line) 100%);
    z-index: 0;
  }

  /* Company + dates are the compact, at-rest row Kyle asked for. Role stays
     visible too, rather than being folded into the popover — the pre-2.0
     horizontal version already solved "does the role line fit" with a
     reserved two/three-line height, and that fix is recovered as-is below.
     Only the there-to-solve/owned/evidence/move rows — the actual paragraphs
     — move into the hover panel. */
  .tl-co { min-height: 2.24em; }
  .tl-role { min-height: 4.05em; }

  /* The popover. Anchored to its own node (position: relative, set above),
     sized independently of the ~1/6-width column so six columns of narrow
     text don't force the paragraphs into a vertical ribbon. Width is capped
     both by a fixed ch-derived value and by the viewport, so it can never
     force horizontal scroll on a laptop-width screen. */
  .tl--js .tl-detail {
    position: absolute;
    top: 100%;
    max-width: none;
    width: min(28rem, calc(100vw - 2 * var(--page-pad)));
    margin: var(--space-2xs) 0 0;
    padding: var(--space-m);
    background: var(--surface-raised);
    border: var(--hairline);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-raised);
    z-index: 10;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
    transition: max-height var(--dur-slow, .45s) ease, opacity var(--dur-slow, .45s) ease;
  }

  /* Edge anchoring. Six known, fixed children — Maximus never gains a
     seventh neighbour without this section being rebuilt anyway — so this is
     tuned to the actual row rather than solved generically. The two leftmost
     nodes open their popover flush with their own left edge so it cannot run
     off the page's left padding; the two rightmost mirror that on the right;
     the middle two centre under the node, which the row has width for. */
  .tl-node:nth-child(1) .tl-detail,
  .tl-node:nth-child(2) .tl-detail { left: 0; }
  .tl-node:nth-child(3) .tl-detail,
  .tl-node:nth-child(4) .tl-detail { left: 50%; transform: translateX(-50%); }
  .tl-node:nth-child(5) .tl-detail,
  .tl-node:nth-child(6) .tl-detail { left: auto; right: 0; }

  /* Open state: real mouse hover, keyboard focus, or the .is-open class
     career.js toggles on click/tap. Hover is scoped to devices that report
     genuine hover + a fine pointer, so a touchscreen never gets stuck in a
     sticky, one-tap-behind hover state — it relies on the click toggle
     instead, which fires identically for touch, mouse and keyboard. */
  .tl--js .tl-node.is-open .tl-detail,
  .tl--js .tl-node:focus-within .tl-detail {
    max-height: 46rem;
    opacity: 1;
    pointer-events: auto;
  }
}
@media (min-width: 1080px) and (hover: hover) and (pointer: fine) {
  .tl--js .tl-node:hover .tl-detail {
    max-height: 46rem;
    opacity: 1;
    pointer-events: auto;
  }
}

/* The popover is position:absolute, so opening it does not natively push
   anything below the career row — left alone it floats on top of the
   Selected Work cards beneath (reported 2026-09-10). :has() lets the ROW
   reserve exactly the space its own open panel needs, live, so the section
   before/after content reflows instead of the panel covering it. Sized PER
   NODE rather than to the tallest of the six, because a single worst-case
   reserve would leave a large dead gap under the row every time a shorter
   panel opened — the same "blank space" problem this pass exists to remove.
   Values are measured against each node's actual rendered detail height
   plus a buffer; six known, fixed children, same assumption the edge-
   anchoring rule above already makes — a seventh node means these get
   re-measured too. */
@media (min-width: 1080px) {
  .tl { transition: margin-bottom var(--dur-slow, .45s) ease; }
  .tl:has(.tl-node:nth-child(1).is-open),
  .tl:has(.tl-node:nth-child(1):focus-within) { margin-bottom: 19rem; }
  .tl:has(.tl-node:nth-child(2).is-open),
  .tl:has(.tl-node:nth-child(2):focus-within) { margin-bottom: 29rem; }
  .tl:has(.tl-node:nth-child(3).is-open),
  .tl:has(.tl-node:nth-child(3):focus-within) { margin-bottom: 27.5rem; }
  .tl:has(.tl-node:nth-child(4).is-open),
  .tl:has(.tl-node:nth-child(4):focus-within) { margin-bottom: 34rem; }
  .tl:has(.tl-node:nth-child(5).is-open),
  .tl:has(.tl-node:nth-child(5):focus-within) { margin-bottom: 30.5rem; }
  .tl:has(.tl-node:nth-child(6).is-open),
  .tl:has(.tl-node:nth-child(6):focus-within) { margin-bottom: 26rem; }
}
@media (min-width: 1080px) and (hover: hover) and (pointer: fine) {
  .tl:has(.tl-node:nth-child(1):hover) { margin-bottom: 19rem; }
  .tl:has(.tl-node:nth-child(2):hover) { margin-bottom: 29rem; }
  .tl:has(.tl-node:nth-child(3):hover) { margin-bottom: 27.5rem; }
  .tl:has(.tl-node:nth-child(4):hover) { margin-bottom: 34rem; }
  .tl:has(.tl-node:nth-child(5):hover) { margin-bottom: 30.5rem; }
  .tl:has(.tl-node:nth-child(6):hover) { margin-bottom: 26rem; }
}

/* ---- ACT III · SELECTED WORK, CONSISTENT METADATA ------------------------ */

.pgroup-kind {
  font-size: var(--step--1);
  color: var(--ink-2);
  margin: 0 0 var(--space-s);
  line-height: 1.4;
}
.pmeta { margin: 0; display: grid; gap: var(--space-xs); }
.pmeta > div { display: grid; gap: 2px; }
.pmeta dt {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pmeta dd {
  margin: 0;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--ink-2);
}
.pmeta dd b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }


/* ---- DECISION INFRASTRUCTURE -------------------------------------------- */
/* The origin thesis leads. Kyle's standing rule: the term never ships without
   its provenance in the same viewport, or it flattens into consultant register
   that any operator could claim. */

.method-origin {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-2);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 46ch;
  margin: var(--space-m) auto 0;
  text-align: center;
  text-wrap: pretty;
}
.method-lede {
  font-size: var(--step--1);
  color: var(--ink-3);
  max-width: 46ch;
  margin: var(--space-s) auto var(--space-xl);
  text-align: center;
}

.moves { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-m); }
@media (min-width: 900px) {
  .moves { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-l) var(--space-xl); }
  /* Five items into two columns leaves a widow. The fifth — the only test that
     counts — takes the full width rather than sitting alone in a half column. */
  .moves .move:last-child { grid-column: 1 / -1; }
}
.move { border-top: 1px solid var(--line); padding-top: var(--space-s); }
.move-name {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-data);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-2xs);
}
.move-principle {
  font-size: var(--step-0);
  line-height: 1.4;
  color: var(--gold-deep);
  margin: 0 0 var(--space-2xs);
  text-wrap: pretty;
}
.move-ev { font-size: var(--step--1); line-height: 1.55; color: var(--ink-2); margin: 0; }

.method-loop {
  margin-top: var(--space-xl);
  padding: var(--space-m);
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-l);
  background: var(--gold-wash);
  text-align: center;
}
.method-loop-line {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-2);
  font-weight: 500;
  letter-spacing: -0.015em;
  margin: var(--space-2xs) 0 var(--space-xs);
  line-height: 1.25;
}
.method-loop-ev {
  font-size: var(--step--1);
  color: var(--ink-2);
  max-width: 58ch;
  margin: 0 auto;
  line-height: 1.55;
}


/* ---- OPERATING SYSTEM · problem statement and the catch ------------------ */

.os-problem { text-align: center; margin: var(--space-m) auto 0; max-width: 52ch; }
.os-problem p {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.015em;
  margin: var(--space-2xs) 0 0;
  text-wrap: pretty;
}
/* The thesis now spans the content width beneath the centred head rather than
   sitting in a second grid column. */
.os-thesis {
  max-width: 68ch;
  margin: var(--space-m) auto var(--space-l);
  text-align: center;
  color: var(--ink-2);
}

.os-catch {
  margin: var(--space-xl) auto 0;
  max-width: 72ch;
  padding: var(--space-m);
  border: 1px solid var(--line);
  border-left: 2px solid var(--gold-line);
  border-radius: var(--radius-m);
  background: var(--surface);
}
.os-catch blockquote { margin: var(--space-2xs) 0 var(--space-s); }
.os-catch blockquote p {
  font-family: var(--font-display);
  font-variation-settings: var(--fraunces-display);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.4;
  color: var(--ink);
  margin: 0;
  text-wrap: pretty;
}
.os-catch figcaption { font-size: var(--step--1); line-height: 1.55; color: var(--ink-2); }


/* ---- CAPABILITIES, DEMOTED ---------------------------------------------- */
/* Kyle, V3: "an executive capability index, not a major narrative section."
   The cap5--ai highlight is gone from the markup; this quiets the whole band so
   it cannot compete with the method band above it. */

.capdex {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-s) var(--space-l);
  border-top: 1px solid var(--line);
  padding-top: var(--space-s);
}
/* 2026-09-10 — was 2 columns to 1039px, then 3 above it. Five items into
   three columns leaves the second row with two items and an empty third
   cell — a visible gap at the exact widths (1440px+) Kyle was reviewing on.
   Same defect .moves already solved for its own five items, so this takes
   the same fix: two columns at every width from 700px up, with the fifth
   item spanning the full row instead of sitting alone next to a gap. */
@media (min-width: 700px) {
  .capdex { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .capdex li:last-child { grid-column: 1 / -1; }
}
.capdex li { display: grid; gap: 2px; }
.capdex h3 {
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
  line-height: 1.25;
}
.capdex-ev {
  font-size: var(--step--2);
  line-height: 1.45;
  color: var(--ink-3);
}


/* ---- HUMAN LAYER, THREE DIMENSIONS -------------------------------------- */

.human-k {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: 2px;
}
.human-dim p { margin: 0; }


/* ---- CONTACT ------------------------------------------------------------- */
/* Relocated from the hero. A job-seeking signal belongs at the point of
   conversion, not in the identity statement. */

.contact-open {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  color: var(--gold-deep);
  margin: calc(var(--space-2xs) * -1) 0 var(--space-m);
}


@media (prefers-reduced-motion: reduce) {
  .tl--js .tl-detail { transition: none; }
}
