/* ==========================================================================
   db5ive — pages.css
   Per-section styles. Section IDs match docs/copy.md.
   ========================================================================== */

/* --------------------------------------------------------------------------
   [HOME-01] HERO (build-spec §7.2)
   Single column, left-aligned, CTA pair beneath.
   No hero image, no background graphic.
   -------------------------------------------------------------------------- */

/* Top padding is deliberately tight. A tall gap between a white header and
   white page reads as an ambiguous void rather than as breathing room —
   the eyebrow needs to anchor close enough that the header reads as a header. */
#home-01 {
  padding-block: var(--sp-5) var(--section-y);
}

@media (min-width: 48em) {
  #home-01 { padding-block: var(--sp-6) var(--section-y); }
}

.hero-h1 {
  font-size: var(--fs-hero);
  font-weight: 400;
  letter-spacing: var(--track-hero);
  line-height: var(--lh-display);
  text-wrap: balance;
  max-width: 17ch;
  margin-top: var(--sp-4);
}

.hero-body {
  margin-top: var(--sp-6);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  /* Wider than --measure because the type is larger: this lands the hero
     body at ~65 characters, the same measure as body prose elsewhere. */
  max-width: 40rem;
}

.hero-actions { margin-top: var(--sp-8); }

/* Portrait held small on mobile and placed last, so the H1 -> body -> CTA
   sequence above the fold is unchanged on a phone. */
.hero-portrait {
  margin: var(--sp-8) 0 0;
  max-width: 15rem;
}

.hero-portrait img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* Desktop: the portrait occupies the right four columns for the full height of
   the hero and is centred against the text block, matching the [HOME-03]
   portrait exactly (both are columns 9-12, both 352px at 1440).

   The H1 is grid-bound to columns 1-8 rather than held back by a max-width, so
   clearance from the portrait is structural: it cannot reach column 9, and the
   grid gap guarantees at least 24px of air at every width. An earlier version
   let the H1 span all twelve columns on a 17ch cap — at 1440 its widest line
   reached 806px against a column-9 edge of 752px and ran under the image.

   Cost of the narrower column: the H1 sets five lines instead of four. The
   non-breaking space before the em dash in index.html is what stops a line
   from opening on the dash. */
@media (min-width: 60em) {
  .hero-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: start;
  }

  .hero-eyebrow { grid-column: 1 / -1;      grid-row: 1; }
  .hero-h1      { grid-column: 1 / span 8;  grid-row: 2; }
  .hero-body    { grid-column: 1 / span 7;  grid-row: 3; }
  .hero-actions { grid-column: 1 / span 7;  grid-row: 4; }

  .hero-portrait {
    grid-column: 9 / -1;
    grid-row: 1 / span 4;
    align-self: center;
    max-width: 100%;
    margin: 0;
  }
}

/* --------------------------------------------------------------------------
   [HOME-03] WHERE I AM MOST USEFUL
   Four blocks, 2×2 desktop, stacked mobile.
   Hairline separation — NO cards, boxes, shadows or rounded rectangles.
   This is the section most likely to be turned into a generic feature grid.
   -------------------------------------------------------------------------- */

.useful-grid {
  margin-top: var(--sp-10);
  display: grid;
  grid-template-columns: 1fr;
  column-gap: var(--sp-8);
}

@media (min-width: 48em) {
  .useful-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--sp-10);
  }
}

/* Copy v3: [HOME-03] went from four blocks to two. Same component, same
   hairlines — only the column count and the foot link are different. The
   modifier exists so the four-block version can come back untouched on
   /approach [AP-04]. */
/* [HOME-03] is a coaching section since the revised copy v3 spec: eyebrow,
   heading, two body paragraphs, three blocks, one link. The blocks are the same
   component the four-block version used — only the column count differs, and
   the border-top on each still draws the continuous rule across the row. */
.coaching-heading {
  margin-top: 0;
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
  max-width: 26ch;
}

.coaching-body {
  margin-top: var(--sp-5);
  max-width: var(--measure);
}

.coaching-body p + p { margin-top: var(--sp-3); }

.useful-grid-3 { margin-top: var(--sp-8); }

.useful-grid-3 .useful-block { padding-block: var(--sp-4) var(--sp-5); }

.coaching-link { margin-top: var(--sp-6); }

@media (min-width: 48em) {
  .useful-grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--sp-6);
  }

  .useful-grid-3 .useful-block { padding-block: var(--sp-5) var(--sp-6); }
}

.useful-block {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-5) var(--sp-6);
}

@media (min-width: 48em) {
  .useful-block { padding-block: var(--sp-6) var(--sp-8); }
}

.useful-block h3 {
  font-size: var(--fs-h2);
  font-weight: 400;
  max-width: 20ch;
}

/* No max-width: the grid column is the measure here (~63 characters at
   desktop), which keeps the four blocks reading as one system. */
.useful-block p {
  margin-top: var(--sp-3);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   [HOME-02] THE THESIS  /  [HOME-03] WHERE I AM MOST USEFUL

   [HOME-03] is the four blocks and keeps .useful-grid unchanged.

   [HOME-02] is three beats rather than three stacked blocks of prose:

     1. a large statement — the H2 is promoted to --fs-h1 so it carries the
        section instead of labelling it
     2. the support, set small and narrow beside it, so the section never
        presents more than a few lines of body at once
     3. the pull quote below a hairline, as the conclusion

   Earlier versions stacked heading, two paragraphs and quote in one column.
   That gave two competing display blocks and read as an undifferentiated
   wall of text with no focal point.
   -------------------------------------------------------------------------- */

.thesis-heading {
  font-size: var(--fs-h1);
  max-width: 18ch;
}

.thesis-body { margin-top: var(--sp-6); }

.thesis-body p + p { margin-top: var(--sp-3); }

/* Was a dark band until the light-band change; prose now inherits --ink like
   every other light section, so no colour override is needed here. */

/* The customer-first statement. --fs-body-lg in the reading face so it reads as
   a stated principle rather than another paragraph. No heading, no box, no
   icon, no accent colour: its weight comes from position. --ink, not
   --deep-text — this section is on the light band. */
.thesis-principle {
  margin-top: var(--sp-6);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  max-width: 34ch;
}

.thesis-actions { margin-top: var(--sp-6); }

/* Decorative stacked db5 lockup filling the empty right column. Hidden below the
   desktop grid, where there is no empty column and it would just interrupt the
   stack. */
.thesis-mark { display: none; }

/* --- The quote: the section's focal point ---------------------------------
   [HOME-08]'s H2 became a blockquote here — the heading states the argument,
   the quote is the line David wanted carried.

   Quotation marks are generated rather than typed, so the markup text stays
   byte-identical to docs/copy.md. Blue appears only in the marks: typographic
   accent, the same permission the numerals and the "5" have, not a fill. The
   opening mark hangs into the margin so the first character of the sentence
   still lines up with the grid and the hairline above it.

   Type treatment is on .statement-quote below. */
.statement {
  margin: var(--sp-8) 0 0;
  border-top: 1px solid var(--rule);
  padding-top: var(--sp-6);
}

/* Set in the READING face, not the display face. The heading above it is Jost;
   putting the quote in Newsreader gives it a different voice, so it reads as
   something David said rather than as a second headline. It also stops the two
   large blocks in this section competing at the same weight, which was why the
   section felt like three loose slabs.

   No negative tracking: --track-head is a correction for the geometric sans and
   opens nothing good on a serif. Newsreader ships roman only (see the @font-face
   in global.css), so this is deliberately NOT italic — the browser would have to
   synthesise the slant and a faked serif italic looks cheap at this size. */
.statement-quote {
  margin: 0;
  font-family: var(--font-reading);
  font-size: var(--fs-quote);
  font-weight: 400;
  line-height: var(--lh-quote);
  letter-spacing: normal;
  color: var(--ink);
  /* Was 22ch, sized to clear the portrait that used to sit beside it. Copy v3
     moved that portrait to [HOME-10], so the quote has the column to itself and
     22ch left it at five cramped lines. A pull quote deliberately breaks the
     prose measure — this runs wider than body copy, not narrower. */
  max-width: 32ch;
  text-wrap: balance;
}

.statement-quote p {
  margin: 0;
  color: inherit;
  text-indent: -0.43em;   /* hangs Newsreader's opening mark into the margin */
}

/* --blue on the light band; --blue-light is for dark grounds only. */
.statement-quote p::before { content: "\201C"; color: var(--blue); }
.statement-quote p::after  { content: "\201D"; color: var(--blue); }

/* Unused since copy v3 removed the attribution from the [HOME-02] quote. Kept
   for the story pages, which carry attributed pull quotes. */
.statement-cite {
  margin-top: var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-style: normal;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}

@media (min-width: 60em) {
  .thesis-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: start;
  }

  .thesis-heading { grid-column: 1 / span 6;  grid-row: 1; }

  /* Narrow and offset — support, not a second column of equal weight */
  .thesis-body {
    grid-column: 8 / -1;
    grid-row: 1;
    margin-top: var(--sp-2);
  }

  /* Copy v3 halved this section and moved the portrait to [HOME-10], so the
     two-column arrangement is gone. Heading left, supporting paragraph offset
     right — the same relationship they had before — then the quote, the
     principle line and the button run down a single left rail.

     Nothing sits in columns 9-12 below row 1 any more. That is fine here in a
     way it was not before: the section is now short enough that the empty right
     side reads as margin rather than as a hole. */
  .thesis-heading { grid-column: 1 / span 7;  grid-row: 1; }

  .thesis-body {
    grid-column: 9 / -1;
    grid-row: 1;
    margin-top: var(--sp-2);
  }

  .statement        { grid-column: 1 / span 8;  grid-row: 2; }
  .thesis-principle { grid-column: 1 / span 7;  grid-row: 3; }
  .thesis-actions   { grid-column: 1 / span 7;  grid-row: 4; }

  /* Centred in the empty right column, both axes, rather than pinned to its top
     left corner. Top-aligned it read as something left over in the corner; the
     empty area is 352px wide and most of the section tall, so the lockup needs
     to sit in the middle of it to look placed rather than stranded. */
  .thesis-mark {
    display: flex;
    flex-direction: column;
    align-items: center;
    grid-column: 9 / -1;
    grid-row: 2 / span 3;
    align-self: center;
    justify-self: center;
    margin: 0;
    width: 15rem;
  }

  .thesis-mark img {
    display: block;
    width: 100%;
    height: auto;
    /* The mark's bowl counters are opaque WHITE — it was drawn for a white
       ground (see the note in logo-ink.svg). This band is --paper-alt, so
       without this the counters read as brighter discs inside the letterforms.
       Multiply leaves white compositing to nothing and darkens only the strokes,
       so the mark sits correctly on any light ground. Not a decorative effect:
       it is what stops the artwork showing its own background. */
    mix-blend-mode: multiply;
  }

  /* Same construction as the footer lockup: the rule is sized to the wordmark
     beneath it, not to the mark above, so it reads as part of the lockup rather
     than as a divider across the column. */
  .thesis-mark-rule {
    width: 7rem;
    height: 1px;
    background: var(--rule);
    margin-block: var(--sp-3);
  }

  .thesis-mark .lockup-word {
    font-size: var(--fs-body);
    letter-spacing: 0.22em;
    /* the tracking adds a trailing gap on the last letter; pull the block back
       so the wordmark is optically centred under the mark, not mathematically */
    text-indent: 0.22em;
  }
}

/* --------------------------------------------------------------------------
   [HOME-10] ABOUT — new in copy v3

   PORTRAIT LEFT, text right. The hero puts its portrait on the RIGHT; running
   the same figure placement twice on one page would read as a template, so
   these two deliberately mirror each other. Do not "fix" the inconsistency.

   Mobile stacks portrait above text, both full width.
   -------------------------------------------------------------------------- */

.about-portrait {
  margin: 0;
  max-width: 16rem;
}

.about-portrait img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.about-text { margin-top: var(--sp-8); }

.about-heading {
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
  max-width: 24ch;
}

.about-text p { margin-top: var(--sp-4); }

.about-text p:first-of-type { margin-top: var(--sp-6); }

.about-link { margin-top: var(--sp-6); }

@media (min-width: 60em) {
  .about-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: start;
  }

  /* Columns 1-5 for the figure, 6-12 for the prose. The text column lands at
     roughly the reading measure at container width, so no extra cap is needed. */
  .about-portrait {
    grid-column: 1 / span 5;
    max-width: none;
  }

  .about-text {
    grid-column: 7 / -1;
    margin-top: 0;
  }
}

/* --------------------------------------------------------------------------
   [HOME-04] WHERE I'VE OPERATED (build-spec §7.4)
   Logo row: single row desktop wrapping to two, centered, --ink-muted.
   No hover effects, no carousel, no marquee.
   -------------------------------------------------------------------------- */

/* Single line at desktop. This is a one-sentence standfirst, not running
   prose, so it is not held to the 36rem measure — breaking it across two
   lines makes it read as a paragraph rather than as a caption. */
.operated-body {
  margin-top: var(--sp-4);
  max-width: none;
}

/* MARQUEE. Earlier revisions of the spec banned carousels and looping motion;
   David asked for this directly and it is now documented as built in
   build-spec §7.4.

   Seamless loop: the track holds two identical lists and translates -50%, so
   at the end of the cycle the layout is pixel-identical to the start. Spacing
   uses margin-right rather than flex gap — a gap would add half a gap to the
   -50% and the loop would visibly jump.

   Safeguards: pauses on hover and on keyboard focus (so a tabbing user is not
   chasing a moving target), and prefers-reduced-motion falls back to the
   static centred row this replaced. Only transform is animated, so it stays
   on the compositor. 82s over a 1719px set is ~21px/sec — the same drift as
   before the marks were enlarged. */
.logo-marquee {
  margin-top: var(--sp-10);
  overflow: hidden;
  /* Soften the ends so marks do not hard-cut at the container edge */
  -webkit-mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.logo-track {
  display: flex;
  width: max-content;
  animation: logo-scroll 82s linear infinite;
}

.logo-marquee:hover .logo-track,
.logo-marquee:focus-within .logo-track {
  animation-play-state: paused;
}

@keyframes logo-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.logo-row {
  display: flex;
  align-items: center;
}

.logo-row li {
  flex: none;
  margin-right: var(--sp-8);
  /* The mask lives on the inner span. Nothing is nested inside a masked
     element — text in there gets painted by the mask wherever the artwork is
     opaque, which reads as letterforms running through the logo. The
     accessible name is carried by role="img" + aria-label instead. */
}

/* The band runs larger than the chapter-card marks — it is the only place the
   logos are the subject rather than metadata. Masks are stored at 176px tall
   so 1.5x still resolves above 2dpr; the one exception is CollegeEye, whose
   source is 167x42 and has no more detail to give. */
.logo-marquee .logo { --logo-scale: 1.5; }

/* Static fallback: the centred, wrapping row from before the marquee. */
@media (prefers-reduced-motion: reduce) {
  .logo-marquee {
    -webkit-mask: none;
    mask: none;
  }

  .logo-track {
    animation: none;
    width: 100%;
    justify-content: center;
  }

  .logo-track > ul + ul { display: none; }

  .logo-row {
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--sp-5);
  }

  .logo-row li { margin-right: 0; }
}

/* --------------------------------------------------------------------------
   [HOME-05] PROOF (build-spec §7.5)

   Six figures. Static — never animated counting up.
   Grid 3×2 desktop, 2×3 tablet, 1×6 mobile.

   Four of the six link to a story page. Hover lifts and highlights — a soft
   panel, a hairline, the numeral deepening, and the cue fading in — but does
   NOT scale. The chapter cards below are specified as "nothing moves"
   (build-spec §7), and a resizing tile would be the only moving element on the page.

   The two figures without a destination ($7M duplicates Crunch, $400M+ has no
   page) get none of this, so nothing implies they are clickable.
   -------------------------------------------------------------------------- */

/* Tightened: at six tiles on three columns the old --sp-6 row gap left more
   background than figures and the section read bare. */
.proof-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-4) var(--sp-3);
}

@media (min-width: 36em) {
  .proof-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 60em) {
  .proof-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.proof-item {
  display: block;
  height: 100%;
  padding: var(--sp-3);
  border: 1px solid transparent;
  border-radius: 2px;
  color: inherit;
  text-decoration: none;
  transition: background var(--dur-hover) var(--ease),
              border-color var(--dur-hover) var(--ease);
}

.proof-figure {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--track-head);
  color: var(--blue);
  transition: color var(--dur-hover) var(--ease);
}

.proof-label {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-muted);
  max-width: 32ch;
}

/* Reserved by the link only, so the static tiles carry no dead space */
.proof-cue {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--blue);
  opacity: 0;
  transition: opacity var(--dur-hover) var(--ease);
}

a.proof-item:hover,
a.proof-item:focus-visible {
  background: var(--paper-alt);
  border-color: var(--rule);
}

a.proof-item:hover .proof-figure,
a.proof-item:focus-visible .proof-figure { color: var(--blue-hover); }

a.proof-item:hover .proof-cue,
a.proof-item:focus-visible .proof-cue { opacity: 1; }

/* No hover on touch — show the cue so a tappable tile still reads as one */
@media (pointer: coarse) {
  .proof-cue { opacity: 1; }
}

/* --------------------------------------------------------------------------
   [HOME-06] / [WORK-02] CHAPTER CARDS (build-spec §7.6)
   Insight line dominates. Hairline separation, not elevated cards.
   Whole card is one click target. On hover the headline underline appears —
   nothing moves.
   -------------------------------------------------------------------------- */

/* Tighter than the default section rhythm — the title was sitting in a lot
   of air with more beneath it before the first card. */
#home-06 { padding-block: var(--sp-12); }

.chapter-list { margin-top: var(--sp-6); }

.chapter-card {
  display: block;
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-6) var(--sp-7);
  text-decoration: none;
  color: var(--ink);
}

.chapter-card:last-child { border-bottom: 1px solid var(--rule); }

.chapter-card:hover { text-decoration: none; }

@media (min-width: 60em) {
  .chapter-card {
    display: grid;
    /* Narrower meta column and a wider gap give the headline and body more
       room, so the cards fill the container instead of stopping short. */
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: var(--sp-8);
    align-items: start;
  }
}

.chapter-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  padding-top: var(--sp-1);
}

/* Slightly smaller than the [HOME-04] row so the marks read as metadata
   beside the insight line rather than competing with it. */
.chapter-logo { --logo-scale: 1; }

.chapter-headline {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--track-head);
  max-width: 34ch;
  text-wrap: balance;
  margin-top: var(--sp-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.14em;
  transition: text-decoration-color var(--dur-hover) var(--ease);
}

@media (min-width: 60em) {
  .chapter-headline { margin-top: 0; }
}

.chapter-card:hover .chapter-headline,
.chapter-card:focus-visible .chapter-headline {
  text-decoration-color: currentColor;
}

.chapter-body {
  margin-top: var(--sp-3);
  /* Widened from 46ch so the cards fill the container, but held at 57ch —
     62ch measured out at ~74 characters, past the comfortable band. */
  max-width: 57ch;
  color: var(--ink);
}

.chapter-link {
  display: inline-block;
  margin-top: var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--blue);
}

/* The --sp-16 padding here existed to give the dark band more air than a
   standard section. It is no longer a dark band and no longer needs it — the
   default section rhythm applies. */

/* --------------------------------------------------------------------------
   [HOME-09] IN THEIR WORDS — three quotes

   Built at David's request, reversing an earlier "no testimonials" rule and the
   position it specified. Sits last. Documented in build-spec §7.9.

   Hairline above each quote, quote in the reading face, attribution small and
   letterspaced beneath. No cards, no boxes, no shadows — same language as the
   rest of the page.

   Filled in copy v3. The empty-slot scaffolding that stood here from 19 Aug
   until the quotes arrived has been removed along with the .is-empty class.
   -------------------------------------------------------------------------- */

.testimonials-heading { max-width: 24ch; }

/* Was --sp-10, which opened a gap between the heading and the first quote wide
   enough that the title looked detached from the section. */
.testimonials {
  list-style: none;
  margin: var(--sp-6) 0 0;
  padding: 0;
}

.testimonial + .testimonial { margin-top: var(--sp-6); }

.testimonial-figure {
  margin: 0;
  border-top: 1px solid var(--rule);
  padding-top: var(--sp-4);
}

.testimonial-quote {
  margin: 0;
  font-family: var(--font-reading);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--ink);
}

.testimonial-quote p { margin: 0; }

/* Generated quote marks, for the same reason as .statement-quote: the copy in
   the markup stays exactly what docs/copy.md says, and a screen reader is not
   made to announce punctuation twice. The opening mark hangs into the margin so
   the text lines up with the hairline above it. */
.testimonial-quote p { text-indent: -0.42em; }
.testimonial-quote p::before { content: "\201C"; }
.testimonial-quote p::after  { content: "\201D"; }

.testimonial-cite {
  margin-top: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.testimonial-name {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
}

.testimonial-role {
  font-size: var(--fs-small);
  color: var(--ink-muted);
}

@media (min-width: 60em) {
  .testimonial-quote { max-width: var(--measure); }

  .testimonial-figure {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
  }

  .testimonial-quote { grid-column: 1 / span 8; }

  .testimonial-cite {
    grid-column: 9 / -1;
    margin-top: 0;
  }
}






/* ==========================================================================
   STORY TEMPLATE — /work/*
   Reference build: /work/withers-preserve. Everything here is shared by all six
   story pages; nothing in it is Withers-specific.

   The page is continuous prose, not a stack of blocks, so the beats run tighter
   than the home page's --section-y and share the white ground. Only the
   strategic-insight beat takes a band, because it is the visual peak.
   ========================================================================== */

/* Top padding is deliberately tight, for the same reason as the hero: a tall gap
   between a white site header and a white page reads as an ambiguous void rather
   than as breathing room. Was --sp-10 / --sp-14, which left the eyebrow floating
   well below the bar. Now matches #home-01 exactly. */
.story-header {
  padding-block: var(--sp-5) var(--sp-6);
}

/* The company mark opens every story page — the same mark, in the same place, at
   the same scale, echoing the [HOME-06] card the reader arrived from. Slightly
   larger than the card's scale 1 because it is the page's opening element rather
   than metadata beside a headline. */
.story-logo { margin-bottom: var(--sp-4); }

/* Descendant selector on purpose. css/logos.css loads AFTER pages.css and sets
   --logo-scale: 1 on .logo, so a single-class .story-logo rule loses on source
   order and the mark silently renders at scale 1. Same pattern the marquee
   already uses (.logo-marquee .logo). */
.story-header .logo { --logo-scale: 1.25; }

.story-h1 {
  margin-top: var(--sp-3);
  font-size: var(--fs-h1);
  font-weight: 400;
  letter-spacing: var(--track-head);
  line-height: var(--lh-display);
  text-wrap: balance;
  max-width: 20ch;
}

/* Beats are narrative, not sections: --sp-6 rather than --section-y, so the
   prose reads as one piece instead of six separated slabs. */
.story-beat { padding-block: var(--sp-6); }

/* /work's header has no eyebrow, so the H1 is the section's first element and
   its intro needs the space the eyebrow would otherwise have provided. */
.work-intro { margin-top: var(--sp-5); }

.story-prose { max-width: var(--measure); }

.story-prose p + p { margin-top: var(--sp-3); }

/* The peak gets its air back — the band needs room around it or it reads as a
   stripe through the middle of the prose. */
.story-peak { padding-block: var(--sp-10); }

.story-quote {
  margin-block: var(--sp-8);
  /* .pullquote already sets the display face, --fs-quote and the 28ch cap that
     deliberately breaks the prose measure. Only the rhythm is set here. */
}

.story-quote p { margin: 0; }

/* --- Project photography — /work/yb-fitness ------------------------------
   Added 20 Aug 2026 from David's own project material, revised 21 Aug after he
   found the first pass too large: at 3:2 and full container width a single
   photograph was 736px of a 900px screen, so each one was the whole view and
   the page stopped flowing between them.

   TWO RATIOS, EACH TIED TO A ROLE. A photograph standing alone is 2:1; a
   photograph in a pair is 3:2. That is what makes the change read as designed
   rather than just smaller — the shape now tells you which kind you are looking
   at. Cropping is done in tools-photos.py, per image and on a stated focal
   point, because a centred 2:1 crop of the exterior sign framed the sky.

   TWO WIDTHS, ALTERNATING. Standing photographs run full container width or
   inset to nine columns, and the page alternates between them: lead full,
   [YB-02] inset, the peak full, [YB-04] inset. Every image the same width was
   the other half of why it did not flow.

   Still container width at most, never full-bleed — everything on this site is
   bound to the 74rem container and an image breaking it would be the only
   element anywhere that does. It does not need to: the prose beside it is
   capped at --measure (36rem), so even the inset width is more than twice the
   text, and that contrast is the effect.

   NO border, NO radius, NO shadow. A photograph has its own edges. The
   CollegeEye screen renders are the exception and say why below. */
.story-figure { margin-block: var(--sp-8); }

.story-figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
}

/* Nine of twelve columns. Left-aligned, so it shares its left edge with the
   prose above it and the reading column carries straight down the page. */
.story-figure-inset { max-width: 75%; }

/* The opening photograph sits inside the header section, beneath the H1, so it
   needs its own clearance from the headline — the header's padding falls below
   it, not between. */
.story-figure-lead { margin-top: var(--sp-6); }

/* Two photographs side by side, used ONLY where the pairing is the argument:
   [YB-05] sets the YBZone empty beside the same room in use, which is precisely
   what "idle hours became productive capacity" means. Not a gallery device — a
   third column would turn it into one. These keep 3:2: at half width they were
   never too tall, and the different shape marks them as a pair rather than as
   two unrelated pictures. The gap matches the grid gutter. */
.story-figures {
  display: grid;
  gap: var(--sp-3);
  margin-block: var(--sp-8);
}

.story-figures figure { margin: 0; }

.story-figures img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* Captions. Permitted from 21 Aug 2026 — rule 1 previously forbade them as
   invented copy, and David lifted that for photographs specifically.

   Deliberately quiet: the display face at --fs-small in --ink-muted, sentence
   case, NOT the uppercase tracked treatment the eyebrows use. An eyebrow labels
   a section and wants to be found; a caption is read only if the picture raises
   a question, and should not compete with the prose. Keep them to a few words —
   they identify, they do not narrate. */
.story-figure figcaption,
.story-figures figcaption {
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  color: var(--ink-muted);
}

/* --- Screen renders — /work/collegeeye ----------------------------------
   Interface renderings, not photographs, and both are white to their edges. On
   --paper they would dissolve into the page, so these carry a hairline: the
   same 1px --rule the capability block and the chapter cards already use. That
   is the site's existing idiom for "this is an object", and it is the reason
   they are bordered where the gym photographs must not be.

   Still not cards: no radius, no shadow, no padding, no ground.

   They keep their native shapes rather than being cropped to match. The web
   render is 1:1.97 and the app render 1:1.27, so equal columns would force one
   of them to be cut; weighting the columns 5:7 gives the tall one a narrow
   measure and the wide one room. Capped at ten columns for the same reason the
   photographs were cut down — at full width the tall render ran to 870px. */
.story-renders {
  display: grid;
  gap: var(--sp-4);
  margin-block: var(--sp-8);
  align-items: start;
  max-width: 83.333%;
}

.story-renders figure { margin: 0; }

.story-renders figcaption {
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  color: var(--ink-muted);
}

.story-renders img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
}

@media (min-width: 48em) {
  .story-figures { grid-template-columns: 1fr 1fr; }

  .story-renders {
    grid-template-columns: 5fr 7fr;
    gap: var(--sp-5);
  }
}

/* Below the desktop grid there is no room to inset anything: the column IS the
   measure. Both the nine-column photographs and the ten-column render pair drop
   their caps and run the full width, or they sit needlessly narrow on a phone. */
@media (max-width: 47.99em) {
  .story-figure-inset,
  .story-renders { max-width: none; }
}

/* --- Image spacing at the edges of a beat --------------------------------
   A figure carries --sp-8 above and below so it breathes inside a run of
   prose. At the START or END of a beat that margin lands on top of the
   section's own padding and the two stack: the lead photograph was sitting
   176px clear of the first paragraph, and a beat that ended on a pair left
   192px of white before the next line of text. Both read as the page coming
   apart rather than as breathing room.

   So a figure that touches the edge of its beat drops the margin on that side
   and lets the section padding do the work it was already doing. */
.story-beat .container > .story-figure:first-child,
.story-beat .container > .story-figures:first-child,
.story-beat .container > .story-renders:first-child { margin-top: 0; }

.story-beat .container > .story-figure:last-child,
.story-beat .container > .story-figures:last-child,
.story-beat .container > .story-renders:last-child { margin-bottom: 0; }

/* And a beat that ENDS on an image needs less padding under it than a beat
   ending on prose. A photograph already has a hard bottom edge and its caption
   sits in the gap, so the full --sp-8 reads as a hole. */
.story-beat:has(> .container > .story-figure:last-child),
.story-beat:has(> .container > .story-figures:last-child),
.story-beat:has(> .container > .story-renders:last-child) {
  padding-bottom: var(--sp-3);
}

/* The lead photograph is inside the header section, so the header's bottom
   padding, the figure's own margin and the first beat's top padding were all
   stacking under it. Specificity beats the 60em rule without needing !important
   or a second media query. */
.story-figure-lead { margin-bottom: 0; }

.story-header:has(.story-figure-lead) { padding-bottom: var(--sp-2); }

/* --- Display list — [WP-05], and any story with named items ---------------
   Display face, larger than body, indented, no bullets, space around. Not a
   stat block: these are names, not figures, so they carry no numerals and no
   --blue. */
.display-list {
  list-style: none;
  margin: var(--sp-8) 0;
  padding: 0 0 0 var(--sp-4);
  border-left: 1px solid var(--rule);
  max-width: var(--measure);
}

.display-list li {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: var(--track-head);
  color: var(--ink);
}

.display-list li + li { margin-top: var(--sp-2); }

/* --- Stat block — [WH-05], [YB-05], [CF-05] ------------------------------
   The [HOME-05] proof-figure treatment at smaller scale, inline in the prose
   flow: numeral in the display face in --blue, label beneath in --ink-muted.

   STATIC. Never animated counting up (build-spec §2).

   The numerals are TYPE, not fills, so they do not count against the
   one-solid-blue-element rule — same reasoning that lets [HOME-05] carry six
   blue figures on a page whose only solid blue is the hero CTA. */
.stat-block {
  list-style: none;
  margin: var(--sp-8) 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-5);
}

.stat-figure {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--track-head);
  color: var(--blue);
}

.stat-label {
  display: block;
  margin-top: var(--sp-1);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-muted);
  max-width: 28ch;
}

@media (min-width: 48em) {
  .stat-block {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-4);
  }

  /* [CE-05] has four figures where the others have three. Two columns rather
     than four: its fourth label runs to twenty words and a quarter-width column
     would break it into a ragged stack. */
  .stat-block-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-6) var(--sp-8);
  }

  /* The grid column is the measure in the two-up arrangement, so the 28ch cap
     comes off — with it the twenty-word fourth label wrapped to five lines
     inside a 520px column while the others sat on one. */
  .stat-block-4 .stat-label { max-width: none; }
}

/* A story whose insight beat leads with the quote rather than setting it
   between paragraphs — [WH-03] does, [WP-03] does not. Without this the
   .story-quote top margin doubles up with the section padding. */
.story-quote-lead { margin-top: 0; }

/* --- Portfolio block — [WL-05] only -------------------------------------
   Three ventures, each a heading plus one paragraph, stacked and typographic.
   NO LOGOS, NO CARDS — build-spec §10 is explicit, and the portfolio companies'
   marks are deliberately not wanted. Hairline separation, like every other
   block on this site. */
.portfolio { margin-top: var(--sp-8); }

.portfolio-item {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-5);
  max-width: var(--measure);
}

.portfolio-item:last-child { border-bottom: 1px solid var(--rule); }

.portfolio-name {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
}

.portfolio-item p { margin-top: var(--sp-2); }

/* --- Client list — [CF-05] only ------------------------------------------
   Deliberately UNLIKE the capability block that closes the same page. Both are
   middot-separated runs of names; if they matched, Crunch would appear to end
   on the same element twice. This one is larger, in --ink rather than
   --ink-muted, and carries no border — these are evidence, not a summary.
   Client LOGOS are not wanted; this is a text list. */
.client-list {
  margin: var(--sp-8) 0;
  font-family: var(--font-display);
  font-size: var(--fs-body-lg);
  line-height: 1.7;
  color: var(--ink);
  max-width: 44rem;
}

/* --- Wellecta's closing statement — [WL-06] only -------------------------
   Wellecta has no capability block; this closes the page instead. Set as a
   statement rather than body prose, in the reading face so it does not read as
   another heading. */
.story-close-statement {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--ink);
  max-width: 40rem;
}

/* --- Capability block — "what this demonstrates" -------------------------
   Foot of every story page. Terms separated by middots, --fs-small,
   --ink-muted, wrapping naturally, in a BORDERED block.

   Bordered rather than inverted: build-spec §10 permits either, and the dark
   band was deliberately removed from the home page, so a dark block here would
   reintroduce exactly what was taken out. Not tags, not pills, not chips —
   one continuous line of text that happens to wrap. */
.story-capability { padding-block: var(--sp-6) var(--sp-10); }

.capability {
  border: 1px solid var(--rule);
  padding: var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  line-height: 1.7;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  max-width: 48rem;
}

/* --- Chapter navigation --------------------------------------------------
   Previous / index / next at the foot of every story page. Labels are the story
   names verbatim from docs/copy.md — the copy doc carries no navigation
   strings, and rule 1 forbids inventing any, so the arrows carry direction.

   Revised 21 Aug 2026 on two counts, both reported by David:

   1. It read as a SECOND FOOTER. 48px of padding each side made a 136px strip,
      sitting under the last beat's own 64px and immediately above the real
      footer. Taken to --sp-3 (96px), then to --sp-2 (80px) when David asked for
      it tighter again. The last beat's own bottom padding comes down with it —
      that 64px sits inside the same block of white and there is no point
      halving one without the other.

   2. The hover rule was ALWAYS THE SAME LENGTH. It lived on the <a>, and the
      previous/next links are flex: 1 1 0 at 48em — so each stretched to a third
      of the row and drew 388px under names of 219px and 258px. Stacked below
      48em the same thing happened on the other axis: align-items defaulted to
      stretch and "The Work" drew a 327px rule under eight characters.
      The rule now lives on the name and the container no longer stretches. */
/* This is a strip, not a second footer. It was padding-block: --sp-6 (48px each
   side, 136px tall) sitting under the last beat's own 64px and directly above
   the real footer, which stacked into roughly 200px of furniture and read as
   the page ending twice. --sp-3 takes the strip to 88px. */
.chapter-nav {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-2);
}

/* The beat immediately above the strip. Its --sp-8 was set for the gap between
   two beats of prose, and against a hairline rule it just deepens the same
   pocket of white the strip sits in. Only the last section on a story page is
   affected; every other beat keeps its rhythm. */
.section:has(+ .chapter-nav) { padding-bottom: var(--sp-4); }

.chapter-nav-grid {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  /* Stacked, a flex item stretches to the full column by default — which drew
     the hover rule 327px wide under "The Work". Each link must be only as wide
     as its own text, on this axis as much as on the desktop row. */
  align-items: flex-start;
}

.chapter-nav a {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  text-decoration: none;
  padding-block: var(--sp-1);
  transition: color var(--dur-hover) var(--ease);
}

.chapter-nav a:hover,
.chapter-nav a:focus-visible { color: var(--blue); }

/* THE UNDERLINE HUGS THE NAME, NOT THE LINK BOX.
   It used to sit on the <a>, and at 48em the previous/next links are
   flex: 1 1 0 so each stretches to a third of the row — the rule drew 388px
   under a 219px story name, identical on both sides whatever the names were.
   It has to live on an element that is only as wide as its text.

   The arrow stays outside it: it is a direction indicator, not part of the
   label, and including it made the rule overshoot the word by the arrow plus
   the gap. --sp-1 holds the rule off the baseline, the distance the <a>'s own
   padding used to provide. */
.chapter-nav-name,
.chapter-nav-index {
  border-bottom: 1px solid transparent;
  padding-bottom: var(--sp-1);
  transition: border-color var(--dur-hover) var(--ease);
}

.chapter-nav a:hover .chapter-nav-name,
.chapter-nav a:focus-visible .chapter-nav-name,
.chapter-nav-index:hover,
.chapter-nav-index:focus-visible { border-bottom-color: var(--blue); }

.chapter-nav-dir { color: var(--ink-muted); }

@media (min-width: 48em) {
  .chapter-nav-grid {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
  }

  /* The index link sits centred between the two, matching the footer's
     lockup / tagline / email arrangement. Wellecta has no previous story and
     Crunch has no next, so an empty spacer holds the missing side and keeps
     "The Work" in the middle rather than letting it slide to one end. */
  .chapter-nav-index { flex: none; }

  .chapter-nav-spacer { flex: 1 1 0; }

  .chapter-nav-prev,
  .chapter-nav-next { flex: 1 1 0; }

  .chapter-nav-next { justify-content: flex-end; }
}

@media (min-width: 60em) {
  .story-header { padding-block: var(--sp-6) var(--sp-8); }

  .story-beat { padding-block: var(--sp-8); }

  .story-peak { padding-block: var(--sp-12); }

  .story-capability { padding-block: var(--sp-8) var(--sp-14); }
}

/* ==========================================================================
   INTERIOR PAGES — /approach, /coaching, /about
   Longer than a story, and unlike the stories these DO render H2s: the copy doc
   marks them explicitly, so they are printed copy rather than structural names.
   ========================================================================== */

.page-standfirst {
  margin-top: var(--sp-4);
  max-width: 34ch;
}

.page-heading {
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
  max-width: 26ch;
}

.page-body { margin-top: var(--sp-5); }

.page-link { margin-top: var(--sp-5); }

.page-close { padding-block: var(--sp-10) var(--sp-12); }

.close-quote { margin-block: var(--sp-8); }

.close-quote p { margin: 0; }

/* --- Numbered steps — [AP-02] four, [CO-04] three ------------------------
   Numeral large in the display face in --blue, heading beside it, body beneath.
   Stacked full-width rows, hairline between, generous vertical space.

   NO circles around the numerals. NO icons. NO connecting line or timeline
   rail. NO cards. NO four-across grid — build-spec §10 names the four-across
   grid as precisely what makes this pattern look like a template, and it is the
   easiest thing to get wrong here.

   The numerals are TYPE, not fills, so they do not count against the
   one-solid-blue-element rule; the page's one is the [AP-10] CTA.

   aria-hidden on the numeral: it is an <ol>, so the order is already conveyed
   semantically and a screen reader would otherwise hear "01" twice. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.step {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-6);
}

.step:last-child { border-bottom: 1px solid var(--rule); }

.step-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--track-head);
  color: var(--blue);
}

.step-heading {
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
  max-width: 24ch;
}

.step-body { margin-top: var(--sp-3); }

.step-body p {
  margin-top: var(--sp-3);
  max-width: var(--measure);
}

@media (min-width: 48em) {
  /* Numeral beside the heading, not above it — but as a grid column, never as
     a four-across row of steps. The rows stay full width. */
  .step {
    display: grid;
    grid-template-columns: 6rem minmax(0, 1fr);
    gap: var(--sp-6);
    align-items: start;
    padding-block: var(--sp-8);
  }

  .step-body { margin-top: 0; }
}

/* --- Stanza — [AP-06] only -----------------------------------------------
   Four short lines set large in the display face with space between, as a
   stanza rather than a list. NO bullets, NO numerals: left as an ordinary list
   these read as a bulleted feature rundown, which is the wrong register for
   what is a personal credo. */
.stanza {
  list-style: none;
  margin: 0;
  padding: 0;
  /* NO measure cap. A stanza's lines are set by the author, not by a column —
     a 30ch cap broke three of the four across two lines each, which turned the
     credo back into the wrapped list this component exists to avoid. They wrap
     only on narrow viewports, where there is no alternative. */
}

.stanza li {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: var(--track-head);
  color: var(--ink);
}

.stanza li + li { margin-top: var(--sp-3); }

/* --- Lead testimonial — [CO-06] on /coaching ----------------------------
   Kat Byrne Frosolone's quote, the strongest evidence on the site that the
   coaching claim is real.

   SIZE: --fs-quote. Copy v3 says "set largest on the page" and it was first
   built at --fs-h1 to satisfy that, but David found it too large on 20 Aug 2026.
   At --fs-quote it MATCHES the page's pull quotes rather than outweighing them,
   so this deliberately diverges from the copy doc.

   It stays distinguishable without the size: it is attributed, with a name and
   role beneath, where a pull quote has neither, and it is the only testimonial
   on the page since Sito's was removed. */
.testimonial-lead .testimonial-quote {
  font-size: var(--fs-quote);
  line-height: var(--lh-quote);
}

.testimonial-lead .testimonial-quote p { text-indent: -0.3em; }

@media (min-width: 60em) {
  /* The lead quote takes the full grid rather than the 8-column split the
     standard testimonial uses — at --fs-h1 an 8-column measure would run to a
     dozen short lines. Its attribution sits beneath instead of beside. */
  .testimonial-lead .testimonial-figure { display: block; }

  /* No ch cap. Sixty-four words at this size: the 22ch measure a short pull
     quote wants ran it to thirteen narrow lines, which reads as a tower rather
     than a statement. The container is the measure here. */
  .testimonial-lead .testimonial-quote { max-width: none; }

  .testimonial-lead .testimonial-cite { margin-top: var(--sp-4); }
}

/* [AP-07] reuses the portfolio block for its four engagement modes. Only the
   name differs — the pattern is identical: heading, paragraph, hairline. */
.modes .portfolio-name { max-width: 30ch; }

/* ==========================================================================
   ABOUT — /about
   ========================================================================== */

/* Header: text left, the blue-shirt headshot right. Same photograph as
   [HOME-10]; a reader only ever sees one of them at a time, so reusing it
   across pages is fine where reusing it within a page would not be. */
.about-header-portrait {
  margin: var(--sp-8) 0 0;
  max-width: 16rem;
}

.about-header-portrait img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

@media (min-width: 60em) {
  .about-header-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gap);
    align-items: center;
  }

  .about-header-text { grid-column: 1 / span 7; }

  .about-header-portrait {
    grid-column: 9 / -1;
    max-width: none;
    margin: 0;
  }
}

/* [AB-04]'s closing line. Reuses Wellecta's closing-statement treatment. */
.about-name-line { margin-top: var(--sp-8); }

/* --- The record — [AB-05], and the advisory entry in [AB-06] -------------
   Company, role and dates, then a paragraph. Hairline between entries, same
   language as every other block on the site.

   CTE is the only entry with CHILDREN. Presidium, Wharton and RWO were
   engagements carried out THROUGH CTE, not separate employers, so they are
   indented behind a hairline beneath it rather than sitting as peers in the
   main sequence. That nesting is the whole reason this component exists —
   flattening it would misstate the record.

   The nested entries are h4 under CTE's h3, so the hierarchy says the same
   thing the indent does. */
.record { margin-top: var(--sp-8); }

.record-entry {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-5);
  max-width: var(--measure);
}

.record > .record-entry:last-child { border-bottom: 1px solid var(--rule); }

.record-name {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: var(--track-head);
}

.record-role {
  margin-top: var(--sp-1);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.record-entry p:not(.record-role) { margin-top: var(--sp-3); }

/* The nested engagements. Indented behind their own hairline, and a step down
   in scale so they read as belonging to CTE rather than competing with it. */
.record-nested {
  margin-top: var(--sp-5);
  padding-left: var(--sp-4);
  border-left: 1px solid var(--rule);
}

.record-nested .record-entry:first-child { border-top: 0; padding-top: 0; }

.record-nested .record-name { font-size: var(--fs-body-lg); }

@media (min-width: 48em) {
  .record-nested { padding-left: var(--sp-6); }
}

/* [AB-06]'s expertise run. Reuses the capability block's treatment — it is the
   same kind of thing, a middot-separated run of terms. */
.expertise { margin-top: var(--sp-8); }

.expertise-heading {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--sp-3);
}

/* ==========================================================================
   CONTACT — /contact
   Inputs are a hairline bottom border only: no filled boxes, no rounded
   rectangles, blue border on focus (build-spec §10). No CAPTCHA anywhere.
   ========================================================================== */

.contact-intro { margin-top: var(--sp-5); }

.contact-form {
  max-width: var(--measure);
  margin: 0;
}

.field + .field { margin-top: var(--sp-6); }

.field label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.field input,
.field textarea {
  display: block;
  width: 100%;
  margin-top: var(--sp-2);
  padding: var(--sp-1) 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  font-family: var(--font-reading);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
  transition: border-color var(--dur-hover) var(--ease);
}

.field textarea {
  resize: vertical;
  min-height: 8rem;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--blue);
  border-bottom-width: 2px;
  /* keep the baseline steady when the rule thickens */
  padding-bottom: calc(var(--sp-1) - 1px);
}

/* Invalid state is announced by .field-error; the border only reinforces it,
   so colour is never the sole carrier of the message. */
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] { border-bottom-color: var(--blue-hover); }

.field-error {
  margin-top: var(--sp-1);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  color: var(--blue-hover);
}

/* Off-screen rather than display:none — a bot reading the DOM still sees a
   fillable field, while people and screen readers do not. */
.contact-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.form-actions { margin-top: var(--sp-8); }

.form-status {
  margin-top: var(--sp-5);
  font-size: var(--fs-body);
  max-width: var(--measure);
}

.form-status-success { color: var(--ink); }

.form-status-error { color: var(--blue-hover); }

/* 404. The whole page is a heading and one link, so it gets the header
   treatment and nothing else. */
.notfound-link { margin-top: var(--sp-6); }

.direct-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.direct-list li + li { margin-top: var(--sp-3); }
