/* ============================================================================
   CXD Consulting · site.css
   Slate navy ink on warm ivory, light only. Every section fills the measure,
   and neighbouring sections never share a shape: the hero, with the stage
   chart's strands running off the window's edge; a claim across the page with two columns
   under it; a split with the ledger on the same two columns; a navy band;
   one centred column; the contact block.
   ========================================================================== */
:root, :root[data-theme="light"], :root[data-theme="dark"] {
  color-scheme: light;
  --navy: #1E2D40;  --navy-90: #243D54;  --navy-10: #EEF2F7;
  --ivory: #F7F4EF; --paper: #FFFFFF;    --subtle: #F0EDE6;
  --hair: #D6D2CA;  --hair-soft: #E8E4DC; --muted: #5E636B;
  /* One job each, nowhere else:
     oxblood marks the single thing that is wrong, brass carries sequence
     numerals and the one locating figure on a chart. */
  --oxblood: #7B2433;
  /* the maintenance tail: same hue as a swell, carried down in value.
     Hard-coded in the SVG. */
  --tail: #748CAA;
  /* brass at display size; the darker step is the same hue at 4.60:1 and is
     what small brass type on ivory has to use to clear AA */
  --brass: #A8863F; --brass-text: #866B32;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans:  "Inter", "Helvetica Neue", Arial, sans-serif;
  --maxw: 78rem;
  --gutter: clamp(1.25rem, 4.5vw, 5.5rem);
  --track: 0.2em;
  --navh: 4.25rem;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 5.5rem; }
body {
  margin: 0; background: var(--ivory); color: var(--navy);
  font-family: var(--sans); font-size: 1.0625rem; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
/* Cormorant's figures are old-style by default, which drops the 3 in
   "risk3sixty" below the line. Headings set lining figures. */
h1, h2, h3 {
  margin: 0; font-family: var(--serif); font-weight: 500; color: var(--navy);
  text-wrap: balance; font-variant-numeric: lining-nums;
}
p { margin: 0; text-wrap: pretty; max-width: 64ch; }
ol, ul { margin: 0; padding: 0; list-style: none; }
img, svg { max-width: 100%; }
a { color: var(--navy); text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:hover { text-decoration-thickness: 2px; }
::selection { background: var(--navy); color: var(--ivory); }
:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; }
/* on the navy bands the outline turns ivory, or it would vanish */
.sec--navy :focus-visible { outline-color: var(--ivory); }

.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.nowrap { white-space: nowrap; }
.label {
  font-family: var(--sans); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--navy); margin: 0;
}
.small { margin-top: 0.9rem; font-size: 0.875rem; line-height: 1.55; }
.cap { margin-top: 1.25rem; font-size: 0.75rem; line-height: 1.5; color: var(--muted); }
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 30; background: var(--navy); color: var(--ivory);
  padding: 0.7rem 1.1rem; font-size: 0.8125rem; font-weight: 600;
}
.skip:focus { left: 0; }

/* ------------------------------------------------------------------- nav */
.nav { position: sticky; top: 0; z-index: 20; background: var(--ivory); border-bottom: 1px solid var(--hair); }
.nav__in { display: flex; align-items: center; justify-content: space-between; height: var(--navh); }
.mark { display: inline-flex; align-items: center; text-decoration: none; }
.mark__logo { display: block; width: auto; height: clamp(1.15rem, 0.9rem + 0.8vw, 1.5rem); object-fit: contain; object-position: 0 50%; }
.nav__links { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2.25rem); }
.nav__links a {
  font-size: 0.8125rem; font-weight: 500; color: var(--navy); text-decoration: none; white-space: nowrap;
  padding-block: 0.4rem; border-bottom: 1px solid transparent; transition: border-color 180ms ease;
}
.nav__links a:not(.btn):hover, .nav__links a[aria-current="page"] { border-bottom-color: var(--navy); }

/* --------------------------------------------------------------- buttons */
.btn, .nav__links a.btn {
  display: inline-block; background: var(--navy); color: var(--ivory);
  font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.02em;
  padding: 0.7rem 1.25rem; text-decoration: none; border: 1px solid var(--navy);
  transition: background 180ms ease, color 180ms ease;
}
.btn:hover, .nav__links a.btn:hover { background: transparent; color: var(--navy); }
.btn--lg { padding: 0.95rem 1.6rem; font-size: 0.875rem; }
/* a text link that leads somewhere: underlined, with an arrow */
.more {
  font-size: 0.875rem; font-weight: 600; letter-spacing: 0.01em; text-decoration: none;
  border-bottom: 1px solid currentColor; padding-bottom: 0.15rem;
}
.more:hover { border-bottom-width: 2px; padding-bottom: calc(0.15rem - 1px); }
.more::after { content: "\00a0\2192"; }
/* Small links get a fingertip-sized tap area (about 44px) from an invisible
   box around them, so nothing on the page moves. */
.mark, .nav__links a, .more, .article__back, .line__list a:not(.btn) { position: relative; }
.mark::before, .nav__links a::before, .more::before, .article__back::after,
.line__list a:not(.btn)::before { content: ""; position: absolute; }
.mark::before { inset: -1rem -0.25rem; }
.nav__links a::before { inset: -0.35rem -0.3rem; }
.more::before { inset: -0.625rem -0.25rem; }
.article__back::after { inset: -0.875rem -0.5rem; }
.line__list a:not(.btn)::before { inset: -0.625rem -0.25rem; }

/* ------------------------------------------------------------------ hero
   Text in the left columns; an engraved plate fills the space from where the
   text column ends to the window's right edge, sized to the hero's height.
   On load it inks in from the centre outward. */
.hero { position: relative; overflow: hidden; }
.hero__grid {
  display: grid; grid-template-columns: minmax(0, 1fr); align-items: center;
  min-height: min(48rem, calc(100svh - var(--navh))); padding-block: clamp(3rem, 6vw, 5.5rem);
}
.hero__text { position: relative; z-index: 1; max-width: 34rem; }
.hero__text > :first-child { margin-top: 0; }
.hero__eyebrow {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--track);
  text-transform: uppercase; color: var(--navy);
}
.hero__h {
  margin-top: 1.4rem; font-size: clamp(2.9rem, 1.1rem + 5.2vw, 6.25rem); line-height: 0.98;
  letter-spacing: -0.022em; max-width: 11ch;
}
.hero__sub {
  margin-top: 1.6rem; font-family: var(--serif); font-style: italic;
  font-size: clamp(1.3rem, 1rem + 1.1vw, 2.05rem); line-height: 1.26; max-width: 26ch; text-wrap: balance;
}
.hero__sub--long { font-size: clamp(1.15rem, 1rem + 0.55vw, 1.5rem); line-height: 1.38; max-width: 32ch; }
.hero__cta { margin-top: 2.25rem; display: flex; align-items: center; gap: 1rem 2rem; flex-wrap: wrap; }
.hero__meta {
  margin-top: 2.5rem; font-size: 0.6875rem; font-weight: 600;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--muted);
}
/* No z-index or transform here: either would isolate the plate and stop the
   multiply blend from reaching the page, leaving a white square. */
.hero__plate {
  position: absolute; margin: 0; pointer-events: none;
  top: 0; bottom: 0; right: 0; padding-block: 1.5rem;
  left: calc(max(0px, (100vw - var(--maxw)) / 2) + var(--gutter) + 36rem);
  display: flex; align-items: center; justify-content: center;
}
.hero__plate img {
  display: block; height: min(44rem, 100%); width: auto; max-width: 100%; object-fit: contain;
  mix-blend-mode: multiply;
  -webkit-mask-image: radial-gradient(circle closest-side, #000 calc(var(--ink) - 18%), transparent var(--ink));
  mask-image: radial-gradient(circle closest-side, #000 calc(var(--ink) - 18%), transparent var(--ink));
  animation: ink-in 1900ms cubic-bezier(.22,.61,.36,1) 120ms both;
}
/* The rosette (rosette.js) draws itself in: every line runs from its start at
   twelve o'clock to whole, centre first, neighbouring lines in opposite directions. */
.rosette { display: block; height: min(44rem, 100%); width: auto; aspect-ratio: 1; max-width: 100%; }
.rosette path { fill: none; stroke: var(--navy); stroke-linejoin: round; stroke-dasharray: 1; }
@media (prefers-reduced-motion: no-preference) {
  .rosette path { animation: rosette-draw 1s cubic-bezier(.45,.05,.2,1) both; }
}
@keyframes rosette-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
/* The moving rosette (data-rosette="moving"): two images, the alternate copies of
   every band in each, turning against each other at 1.25 degrees a second apiece, so
   the weave shimmers where they pass. The back one is steel and breathes a
   little, which reads as depth. Only opacity, rotate and scale animate, so the
   browser moves pixels it has already drawn. It settles in rather than drawing,
   and a visitor who prefers reduced motion gets it held still. The layer rules
   name both classes to outrank the hero's own image rules above. */
.rosette--moving { position: relative; }
.rosette--moving .rosette__layer {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%; max-width: none;
  mix-blend-mode: normal; -webkit-mask-image: none; mask-image: none; animation: none;
}
@media (prefers-reduced-motion: no-preference) {
  .rosette--moving { animation: rosette-settle 1.8s cubic-bezier(.22,.61,.36,1) 100ms both; }
  .rosette--moving .rosette__layer { will-change: transform; animation: rosette-turn 288s linear infinite; }
  .rosette--moving .rosette__layer--back {
    animation: rosette-turn-back 288s linear infinite, rosette-breathe 5.6s ease-in-out infinite alternate;
  }
}
@keyframes rosette-settle { from { opacity: 0; scale: 0.94; } }
@keyframes rosette-turn { to { rotate: 1turn; } }
@keyframes rosette-turn-back { to { rotate: -1turn; } }
@keyframes rosette-breathe { to { scale: 1.03; } }
/* On home the rosette fills the hero and the text sits over it. It is sized from
   the hero's own height, so it keeps its proportion on any screen, and it runs off
   the right edge. Behind the text, one feathered patch of paper lets the lines
   fade out before they reach the words, so the text reads cleanly on top. */
.hero__plate--rosette { left: 0; padding-block: 0; display: block; }
.hero__plate--rosette .rosette {
  position: absolute; top: 50%; left: 62%; transform: translate(-50%, -50%);
  width: calc(1.55 * min(48rem, 100svh - var(--navh))); height: auto; max-width: none;
  opacity: 0.88;
}
.hero--rosette .hero__text::before {
  content: ""; position: absolute; z-index: -1; inset: -3rem -4rem -3rem -6rem;
  background: var(--ivory); border-radius: 3rem; opacity: 0.94; filter: blur(2rem);
}
.hero__sub--offer { font-size: clamp(1.2rem, 1rem + 0.7vw, 1.65rem); line-height: 1.34; max-width: 30ch; }
@property --ink { syntax: '<percentage>'; inherits: false; initial-value: 160%; }
@keyframes ink-in { from { --ink: 0%; opacity: 0.4; } to { --ink: 160%; opacity: 1; } }

/* -------------------------------------------------------------- sections */
.sec { padding-block: clamp(4rem, 8vw, 7.5rem); }
.sec--rule { border-top: 1px solid var(--hair); }
.sec--tint { background: var(--subtle); }
.sec--navy { background: var(--navy); color: var(--ivory); }
.sec--navy h2, .sec--navy a { color: var(--ivory); }
.sec--line { border-top: 1px solid var(--navy); }
.h2 {
  margin-top: 1.1rem; font-size: clamp(1.75rem, 1rem + 2.1vw, 2.9rem);
  line-height: 1.1; letter-spacing: -0.01em; max-width: 27ch;
}
.display {
  font-weight: 400; font-size: clamp(2rem, 1rem + 3vw, 3.75rem);
  line-height: 1.08; letter-spacing: -0.012em;
}
.sec__foot {
  margin-top: clamp(2rem, 3.5vw, 2.75rem); display: flex; justify-content: space-between;
  align-items: baseline; gap: 1.25rem 3rem; flex-wrap: wrap;
}
.sec__foot p { font-size: 1.0625rem; max-width: 52ch; }

/* A claim across the measure with two columns under it (and, on the home
   page, the chart after them). */
.claim .display { max-width: 30ch; }
.cols {
  margin-top: clamp(2rem, 4vw, 3rem); display: grid; grid-template-columns: 1fr 1fr;
  column-gap: clamp(2rem, 6vw, 7rem); row-gap: 1.1rem;
}
.cols p { font-size: 1.0625rem; line-height: 1.65; max-width: 44ch; }
.cols p + p { margin-top: 0; }
.claim .gfx { margin-top: clamp(3rem, 6vw, 5rem); }

/* Heading in the left seven columns, its text in the right five, bottoms
   aligned. The ledger below sits on the same two columns. */
.split {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: clamp(2rem, 6vw, 7rem); align-items: end;
}
.split__body p { font-size: 1.0625rem; line-height: 1.65; max-width: 40ch; }
.split__body p + p { margin-top: 1.1rem; }

/* The navy band: one claim in two lines across, the two worlds under it. */
.career .display { max-width: 36ch; }
.career__lede { margin-top: 1.4rem; font-size: 1.0625rem; color: rgba(247, 244, 239, 0.86); }
.career__cols {
  margin-top: clamp(2.5rem, 5vw, 4rem); padding-top: 1.75rem; border-top: 1px solid rgba(247, 244, 239, 0.22);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) auto;
  column-gap: clamp(2rem, 5vw, 5rem); row-gap: 1.75rem; align-items: start;
}
.career__cols--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.career__cols p { font-size: 1rem; line-height: 1.6; max-width: 44ch; color: rgba(247, 244, 239, 0.86); }
.career__cols .label { margin-bottom: 0.7rem; font-size: 0.6875rem; line-height: 1.4; color: rgba(247, 244, 239, 0.66); }
.career__cols p + .more { display: inline-block; margin-top: 1rem; }
.career__more { align-self: end; }

/* The one centred section: a single column. */
.statement { text-align: center; }
.statement__in { max-width: 46rem; margin-inline: auto; }
.statement .display { font-size: clamp(1.9rem, 1rem + 2.5vw, 3.2rem); }
.statement p { max-width: 36rem; margin: 1.3rem auto 0; font-size: 1.0625rem; line-height: 1.7; }
.statement .display + p { margin-top: clamp(1.75rem, 3vw, 2.5rem); }

/* ------------------------------------------------------- the stages chart
   Two drawings of one argument, swapped at 750px. The wide one runs time left
   to right across three stages. Below 750px it used to sit in a horizontal
   scroller, which a cold reader called the page's worst failure: panning is
   not reading, and the buyer met the central claim as a cropped fragment with
   words cut mid-letter. The narrow drawing turns the work into five vertical
   lanes with time running down, so nothing pans and nothing is cut. */
.gfx { margin: 0; }
.gfx .plate { display: block; width: 100%; height: auto; }
.gfx--phone { display: none; }
@media (max-width: 750px) {
  .gfx--stream { display: none; }
  .gfx--phone { display: block; }
  /* Capped so the lanes do not stretch on a tablet. Smallest type is 10px at a
     350px plate and crosses 9px at 315px, which is a 355px viewport. */
  .gfx--phone .plate { max-width: 30rem; margin-inline: auto; }
}

/* ------------------------------------------------------ the engagement arc
   One sequence, not three options. Numbered because the order is information:
   phase two is not available without phase one. The question sits left and
   what you end up holding sits right, on the section's own two columns. */
.phases { margin-top: clamp(3rem, 6vw, 5rem); }
.phase {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: clamp(2rem, 6vw, 7rem); row-gap: 0.9rem;
  padding-block: clamp(1.5rem, 2.4vw, 2.25rem); border-top: 1px solid var(--hair);
}
.phase:last-of-type { border-bottom: 1px solid var(--hair); }
.phase__n {
  grid-column: 1; display: flex; align-items: baseline; gap: 0.7rem;
  font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--track);
  text-transform: uppercase; color: var(--navy);
}
.phase__n .num {
  font-family: var(--serif); font-size: 1.5rem; font-weight: 500; line-height: 1;
  letter-spacing: 0; color: var(--brass-text);
  font-variant-numeric: lining-nums; font-feature-settings: "lnum" 1, "onum" 0;
}
.phase__q {
  grid-column: 1; font-family: var(--serif);
  font-size: clamp(1.2rem, 0.9rem + 1.05vw, 1.75rem); line-height: 1.24; color: var(--navy);
}
/* what phase one ends in: the result, so it reads at body size in navy */
.phase__t {
  grid-column: 1; font-family: var(--serif); font-style: italic;
  font-size: clamp(1.05rem, 0.95rem + 0.35vw, 1.25rem); line-height: 1.35; color: var(--navy); max-width: 36ch;
}
.phase__hold { grid-column: 2; grid-row: 1 / span 3; align-self: start; padding-top: 0.7rem; }
.phase__hold .small { margin-top: 0.6rem; }
.hold__list { margin: 0.5rem 0 0; padding: 0; list-style: none; }
.hold__list li {
  font-size: 0.875rem; line-height: 1.55; color: var(--navy);
  padding-block: 0.4rem; border-top: 1px solid var(--hair-soft);
}
.hold__list li:first-child { border-top: 0; padding-top: 0; }

/* ----------------------------------------------------------- the contact
   A person, not a form: his photo, then the heading, the ways to reach him
   and two plain lines. The photo has no background, so he stands on the page
   rather than in a box, his head level with the heading, and he fades out at
   the waist instead of ending at a hard edge. */
.line__in {
  display: grid; grid-template-columns: minmax(12rem, 28%) minmax(0, 1fr);
  column-gap: clamp(2rem, 6vw, 7rem); align-items: start;
}
.line__portrait { margin: 0; }
.line__portrait img {
  display: block; width: 100%; height: auto;
  -webkit-mask-image: linear-gradient(to bottom, #000 66%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 66%, transparent 96%);
}
.line__list { margin-top: clamp(1.5rem, 2.5vw, 2rem); }
.line__h { font-size: clamp(1.9rem, 1rem + 2.4vw, 3rem); line-height: 1.16; max-width: 20ch; }
.line__body .small { margin-top: clamp(1.25rem, 2vw, 1.75rem); }
.line__list li {
  display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); align-items: baseline;
  column-gap: 1rem; padding-block: 0.7rem; border-top: 1px solid var(--hair-soft);
  font-size: 0.9375rem;
}
.line__list .btn { justify-self: start; padding: 0.55rem 1.05rem; }
.line__k {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--track);
  text-transform: uppercase; color: var(--muted);
}

/* ------------------------------------------------------------ page heroes
   Insights and Contact open like the home page, text left and an engraving
   right, at a lower height. */
.page-hero { padding-block: clamp(3rem, 6vw, 5rem) clamp(2.5rem, 5vw, 4rem); }
.hero__h--page { margin-top: 1.2rem; font-size: clamp(2.6rem, 1.1rem + 4.2vw, 5.2rem); max-width: 14ch; }

/* ------------------------------------------------------------- engravings
   The engravings are navy ink on paper whose tone has been taken to pure
   white, so multiplying them into the page drops the paper and leaves the
   ink on whatever ground the section has. */
.art { margin: 0; }
.art img { display: block; width: 100%; height: auto; mix-blend-mode: multiply; }

/* Text beside an engraving, on the page's seven and five columns. */
.duo {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: clamp(2rem, 6vw, 7rem); align-items: center;
}
.duo--flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.duo--flip > .art { order: -1; }
.prose p { font-size: 1.0625rem; line-height: 1.65; max-width: 46ch; }
.prose p + p { margin-top: 1.1rem; }
.lead-h { margin-top: 1.1rem; max-width: 22ch; }
.lead-h--wide { max-width: 28ch; }
.lead-h--full { max-width: 34ch; }
.lead-h + .prose { margin-top: 1.6rem; }
.solve { margin-top: clamp(1.75rem, 3vw, 2.5rem); padding-top: 1.5rem; border-top: 1px solid var(--navy); }
.solve__lead {
  margin-top: 0.8rem; font-family: var(--serif); font-size: clamp(1.3rem, 1rem + 0.9vw, 1.75rem);
  line-height: 1.3; max-width: 32ch;
}
.solve .more { display: inline-block; margin-top: 1.25rem; }

/* The problem: what it is, four situations a reader will recognise, why it
   happens, then the answer. Behind it, a faint underprint of woven waves, like
   the background of a banknote (tools/underprint.py), fading out behind the
   header and strongest toward the lower right. */
.sec--problem { position: relative; isolation: isolate; overflow: hidden; }
.sec--problem::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url("assets/img/underprint.svg") 0 0 / 40rem auto repeat;
  -webkit-mask-image: linear-gradient(118deg, transparent 18%, #000 88%);
  mask-image: linear-gradient(118deg, transparent 18%, #000 88%);
}
/* each sentence starts its own line; on phones the second one wraps */
.problem__h { max-width: none; }
.problem__h span { display: block; }
.problem__grid {
  margin-top: clamp(2.5rem, 5vw, 4rem); display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: clamp(2rem, 6vw, 7rem); row-gap: 2.5rem; align-items: start;
}
.problem__list > .label { margin-bottom: 0.6rem; }
.problem__list .problem__signs li {
  font-family: var(--serif); font-size: clamp(1.25rem, 1rem + 0.7vw, 1.55rem); line-height: 1.3; padding-block: 1.1rem;
}
.problem__why { font-size: 1.0625rem; line-height: 1.65; max-width: 40ch; }

/* Why CXD: the claim across the measure, then two lists. */
/* It sits on navy, set apart from the light sections either side, with a faint
   ivory copy of the rosette held still in its top right corner. */
.sec--why { position: relative; isolation: isolate; overflow: hidden; }
.why__mark {
  position: absolute; z-index: -1; margin: 0; pointer-events: none;
  top: 0; right: 0; width: min(52rem, 80vw); transform: translate(30%, -28%); opacity: 0.1;
}
.why__mark .rosette { width: 100%; height: auto; max-width: none; }
.why__mark .rosette path { stroke: var(--ivory); }
.rosette.rosette--still path { animation: none; }
.sec--why .label { color: color-mix(in srgb, var(--ivory) 66%, transparent); }
.sec--why .rows li, .sec--why .rows li:last-child { border-color: color-mix(in srgb, var(--ivory) 20%, transparent); }
.pair {
  margin-top: clamp(2.5rem, 5vw, 4rem); display: grid; grid-template-columns: 1fr 1fr;
  column-gap: clamp(2rem, 6vw, 7rem); row-gap: 2.5rem;
}
.pair .label { margin-bottom: 1rem; }
.rows li { font-size: 1.0625rem; line-height: 1.55; padding-block: 0.95rem; border-top: 1px solid var(--hair); }
.rows li:last-child { border-bottom: 1px solid var(--hair); }

/* The approach: sub-blocks under one claim. */
/* The approach in three steps, in the order the work runs. */
.steps {
  margin: clamp(2rem, 4vw, 3rem) 0 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 4vw, 3.5rem); row-gap: 1.75rem;
}
.step { padding-top: 1.1rem; border-top: 1px solid var(--navy); }
.step__t { font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--track); text-transform: uppercase; }
.step__t + p { margin-top: 0.75rem; font-size: 1.0625rem; line-height: 1.6; max-width: 34ch; }
.sub { margin-top: clamp(3.5rem, 7vw, 6rem); }
.h3 { font-size: clamp(1.4rem, 1rem + 1.1vw, 2rem); line-height: 1.18; }
.sub__text > p, .sub > p { margin-top: 1rem; font-size: 1.0625rem; line-height: 1.65; max-width: 62ch; }
.sub > .gfx { margin-top: clamp(2rem, 4vw, 3rem); }
.sub__text .h3 + p { margin-top: 1rem; }
.sub__text .h3:not(:first-child) { margin-top: clamp(2rem, 4vw, 2.75rem); }
.pillars { margin: 1.4rem 0 0; }
.pillars > div {
  display: grid; grid-template-columns: minmax(9rem, 36%) minmax(0, 1fr); column-gap: 1.5rem;
  padding-block: 1rem; border-top: 1px solid var(--hair);
}
.pillars > div:last-child { border-bottom: 1px solid var(--hair); }
.pillars dt { font-family: var(--serif); font-size: 1.3rem; line-height: 1.22; font-weight: 500; }
.pillars dd { margin: 0; font-size: 0.9375rem; line-height: 1.55; }
/* In the approach the pillars stand side by side, each marked by a navy upright,
   under a heading and line that run the full width. */
.sub--wide > p { max-width: none; }
.sub--wide > p span { display: block; }
.pillars--row {
  margin-top: clamp(1.75rem, 3vw, 2.5rem); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 4vw, 3.5rem); row-gap: 1.5rem;
}
.pillars--row > div, .pillars--row > div:last-child {
  display: block; padding: 0.2rem 0 0.4rem 1.25rem; border: 0; border-left: 1px solid var(--navy);
}
.pillars--row dt { font-size: 1.45rem; }
.pillars--row dd { margin-top: 0.55rem; font-size: 1rem; max-width: 30ch; }
.cta-row { display: flex; align-items: center; gap: 1rem 2rem; flex-wrap: wrap; }

/* ---------------------------------------------------------------- insights */
.sec--posts { padding-top: clamp(0.5rem, 1.5vw, 1.25rem); }
.posts { margin: 0; }
.post-card {
  display: grid; grid-template-columns: minmax(8rem, 22%) minmax(0, 1fr); column-gap: clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(1.75rem, 3vw, 2.5rem); border-top: 1px solid var(--hair);
}
.post-card:last-child { border-bottom: 1px solid var(--hair); }
.post-card__meta { font-size: 0.8125rem; color: var(--muted); padding-top: 0.45rem; }
.post-card__title { font-size: clamp(1.5rem, 1rem + 1.5vw, 2.3rem); line-height: 1.12; max-width: 28ch; }
.post-card__title a { text-decoration: none; }
.post-card__title a:hover { text-decoration: underline; text-decoration-thickness: 1px; }
.post-card__dek { margin-top: 0.8rem; font-size: 1rem; line-height: 1.6; max-width: 60ch; }
.post-card .more { display: inline-block; margin-top: 1.1rem; }

/* An article: one reading column, the engraving above it. */
.article__head { padding-block: clamp(3rem, 6vw, 5rem) clamp(2rem, 4vw, 3rem); }
.article__head .wrap, .article__body { max-width: 50rem; }
.article__back { font-size: 0.8125rem; font-weight: 600; text-decoration: none; }
.article__back::before { content: "\2190\00a0"; }
.article__h { margin-top: 1.4rem; font-size: clamp(2.2rem, 1rem + 3.6vw, 4.2rem); line-height: 1.04; letter-spacing: -0.015em; }
.article__dek {
  margin-top: 1.4rem; font-family: var(--serif); font-style: italic;
  font-size: clamp(1.2rem, 1rem + 0.7vw, 1.6rem); line-height: 1.35; max-width: 40ch;
}
.article__meta { margin-top: 1.6rem; font-size: 0.8125rem; color: var(--muted); }
.article__art { max-width: 50rem; margin: 0 auto clamp(2rem, 4vw, 3rem); padding-inline: var(--gutter); }
.article__art img { aspect-ratio: 16 / 9; object-fit: cover; }
.article__body { margin-inline: auto; padding: 0 var(--gutter) clamp(4rem, 8vw, 6rem); }
.article__body > * + * { margin-top: 1.15rem; }
.article__body p, .article__body li { font-size: 1.125rem; line-height: 1.7; max-width: 66ch; }
.article__body h2 { margin-top: clamp(2.5rem, 5vw, 3.5rem); font-size: clamp(1.6rem, 1rem + 1.6vw, 2.3rem); line-height: 1.15; }
.article__body h3 { margin-top: 2rem; font-size: clamp(1.25rem, 1rem + 0.8vw, 1.6rem); line-height: 1.25; }
.article__body ul, .article__body ol { padding-left: 1.2rem; }
.article__body ul { list-style: disc; } .article__body ol { list-style: decimal; }
.article__body li + li { margin-top: 0.4rem; }
.article__body blockquote {
  margin: 2rem 0; padding: 1.25rem 1.5rem; border-left: 2px solid var(--brass); background: var(--subtle);
}
.article__body blockquote p { font-size: 1.0625rem; }
.article__body .table { overflow-x: auto; margin-block: 2rem; }
.article__body table { border-collapse: collapse; min-width: 40rem; font-size: 0.9375rem; line-height: 1.5; }
.article__body th, .article__body td { text-align: left; vertical-align: top; padding: 0.7rem 0.9rem 0.7rem 0; border-top: 1px solid var(--hair); }
.article__body th { font-family: var(--serif); font-size: 1.05rem; font-weight: 500; }
/* On phones the essay's comparison table stacks: one block per row, each cell
   carrying its column's name (data-label, written by tools/insights.py), so
   nothing hides past the edge of the screen. */
@media (max-width: 600px) {
  /* the callout keeps a readable line length on a narrow phone */
  .article__body blockquote { padding-inline: 1rem; }
  .article__body .table { overflow: visible; }
  .article__body table { min-width: 0; }
  .article__body thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .article__body table, .article__body tbody, .article__body tr, .article__body th, .article__body td { display: block; }
  .article__body tbody tr { padding-block: 0.5rem 0.9rem; border-top: 1px solid var(--hair); }
  .article__body tbody th, .article__body td { border-top: 0; padding: 0.35rem 0; }
  .article__body td::before {
    content: attr(data-label); display: block; margin-bottom: 0.1rem;
    font-family: var(--sans); font-size: 0.6875rem; font-weight: 600;
    letter-spacing: var(--track); text-transform: uppercase; color: var(--muted);
  }
}
.article__body tbody th { font-family: var(--sans); font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--track); text-transform: uppercase; }
.article__end { margin-top: clamp(3rem, 6vw, 4rem); padding-top: 1.75rem; border-top: 1px solid var(--navy); }
.article__end .cta-row { margin-top: 1.5rem; }

/* ---------------------------------------------------------------- footer */
.foot { border-top: 1px solid var(--hair); padding-block: clamp(2rem, 3.5vw, 3rem); }
.foot__in { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.foot__tag { font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--navy); }
.foot__legal { font-size: 0.75rem; color: var(--muted); }

/* ---------------------------------------------------------------- motion
   Default state is the finished state. motion.js opts in to the pre-state, so
   the page reads complete with JS off. Reduced motion opts straight back out. */
html.js [data-rise] { opacity: 0; transform: translateY(10px); }
html.js [data-rise].is-in {
  opacity: 1; transform: none;
  transition: opacity 480ms cubic-bezier(.22,.61,.36,1), transform 520ms cubic-bezier(.22,.61,.36,1);
}
html.js [data-move] .band { clip-path: inset(0 100% 0 0); }
html.js [data-move].is-in .band { clip-path: inset(0 0 0 0); transition: clip-path 900ms cubic-bezier(.22,.61,.36,1) 120ms; }
@media (prefers-reduced-motion: reduce) {
  html.js [data-rise], html.js [data-rise].is-in { opacity: 1; transform: none; transition: none; }
  html.js [data-move] .band, html.js [data-move].is-in .band { clip-path: none; transition: none; }
  .hero__plate img { animation: none; -webkit-mask-image: none; mask-image: none; }
}

/* ----------------------------------------------------------------- phone */
@media (max-width: 860px) {
  .split, .cols, .career__cols, .career__cols--3, .phase, .line__in,
  .duo, .duo--flip, .pair, .post-card, .problem__grid, .steps, .pillars--row { grid-template-columns: minmax(0, 1fr); }
  .duo, .duo--flip { row-gap: 2.25rem; }
  .duo--flip > .art { order: 0; }
  .art { max-width: 30rem; }
  .duo > .art { max-width: 19rem; }
  .pillars > div { grid-template-columns: minmax(0, 1fr); row-gap: 0.35rem; }
  .post-card { row-gap: 0.5rem; }
  .post-card__meta { padding-top: 0; }
  .split { align-items: start; row-gap: 1.5rem; }
  .career__cols { row-gap: 1.5rem; }
  .line__in { row-gap: 0.75rem; }  /* the fade already leaves air under the photo */
  .phase__n, .phase__q, .phase__t, .phase__hold { grid-column: 1; }
  .phase__hold { grid-row: auto; padding-top: 0; }
  .h2, .display, .claim .display, .career .display, .lead-h, .lead-h--wide, .lead-h--full { max-width: none; }
  .statement, .statement p { text-align: left; }
  .statement p { margin-inline: 0; }
  .hero__grid { min-height: 0; padding-bottom: 2rem; }
  .hero__text { max-width: none; }
  /* the plate follows the text */
  .hero__plate { position: relative; top: auto; bottom: auto; left: auto; right: auto; padding-block: 0; margin: 0 auto 2.5rem; padding-inline: var(--gutter); max-width: 34rem; }
  .hero__plate img, .rosette { height: auto; width: 100%; }
  /* the rosette rises above the text, cut by the top and right edges, and the
     text overlaps its lower edge */
  .hero--rosette .hero__grid { padding-top: 58vw; }
  .hero__plate--rosette { position: absolute; inset: 0; margin: 0; padding: 0; max-width: none; }
  .hero__plate--rosette .rosette { width: 150vw; left: 70%; top: 15vw; }
  .hero--rosette .hero__text::before { inset: -2rem -1rem -2rem -2rem; }
  .line__portrait { max-width: 14rem; }
  /* name and town on two lines, so no line starts with a dot */
  .hero__meta .sep { display: none; }
  .hero__meta .nowrap { display: block; }
  .hero__meta .nowrap + .nowrap { margin-top: 0.35rem; }
  .line__list .btn { justify-self: stretch; text-align: center; padding-block: 0.8rem; }
}
/* A phone on its side: text on the left and the rosette on the right, as on a
   wide screen, so the headline is not pushed below the fold. */
@media (max-width: 860px) and (orientation: landscape) {
  .hero--rosette .hero__grid { padding-top: 2rem; }
  .hero--rosette .hero__text { max-width: 56%; }
  .hero__plate--rosette .rosette { width: 100vw; left: 84%; top: 50%; }
}
@media (max-width: 720px) {
  /* one row: logo, The work, About, Contact */
  :root, :root[data-theme="light"], :root[data-theme="dark"] { --navh: 4rem; }
  .nav__links { gap: 0.9rem; }
  .nav__links .nav__wide { display: none; }
  .nav__links a:not(.btn) { font-size: 0.75rem; }
  .nav__links a.btn { padding: 0.5rem 0.8rem; font-size: 0.75rem; }
  .mark__logo { height: 1rem; }
  /* the pillars intro reads as one paragraph once its lines wrap */
  .sub--wide > p span { display: inline; }
}
@media (max-width: 380px) {
  .mark__logo { height: 0.875rem; }
  .nav__links { gap: 0.7rem; }
  /* the email address needs the full width here, so each label sits above its value */
  .line__list li { grid-template-columns: minmax(0, 1fr); row-gap: 0.3rem; }
}
/* 320px: the smallest phones, and any iPhone with Display Zoom on. The logo
   and links only fit on one row with a slightly smaller logo and button. */
@media (max-width: 340px) {
  .mark__logo { height: 0.7rem; }
  .nav__links { gap: 0.6rem; }
  .nav__links a.btn { padding-inline: 0.6rem; }
}
