/* ---------------------------------------------------------------------------
   Talk for Impact — the appearance layer.

   DIRECTION A2, "THE SEAM", chosen 2026-08-25 from four rendered directions.

   THE IDEA, and it decides most of what follows: the gold rule is not
   decoration, it is the subject. The page splits — what you say on one side,
   what your organisation does on the other — and the gold line between them is
   the interpretation sitting there. In the hero the same seam separates the
   person from everything downstream. Every other gold element on the page is a
   restatement of that one line, at a smaller size.

   Consequence: gold is never added for warmth or emphasis. If a gold mark is
   not standing for a gap or a boundary, it does not belong.

   Derived from three working artefacts rather than re-read from the tokens:
     A. infographics/two-models-interpretation-gap-scroll.html   proportion, rules
     B. articles/2026-08-20-false-alignment.html                 article register
     C. tfi-online-tools/landing/template.html                   responsive, chrome

   tokens.css holds the values. This file holds the decisions.

   THREE DESIGN_SYSTEM RULES ARE DELIBERATELY OVERRIDDEN FOR THE WEB, all on
   Leonardo's call, all print-derived, all flagged in build-plan.md as ONE open
   decision about how to restate them in canon:
     rule 7  never letterspaces      -> tracking follows the landing pages, so
                                        the two halves of the estate agree
     rule 8  never centres a column  -> the reading column centres; the TEXT
                                        inside stays left-aligned, ragged right
     signature element               -> the 16px bar is on TOP, not the left
                                        edge. The small gold rules are KEPT.
--------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background: var(--ground-light);
  color: var(--ink-on-light);
  font-family: var(--font-sans);
  font-weight: var(--w-regular);
  font-size: var(--size-body);
  line-height: var(--lh-text);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }

/* ---------------------------------------------------------------------------
   1. SHELL
   The page fills the viewport so every ground bleeds edge to edge; the WRAP is
   the only thing that centres. A centred page container leaves the body ground
   showing beside every dark section, which is the defect this replaced.
--------------------------------------------------------------------------- */

.page {
  border-top: var(--edge-bar) solid var(--gold);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.page > main { flex: 1 0 auto; }

.wrap { max-width: 1220px; margin: 0 auto; padding: 0 var(--space-48); }
.measure       { max-width: var(--measure-max); }
.measure--read { max-width: 720px; }

/* ---------------------------------------------------------------------------
   2. GROUNDS. Surfaces invert, never tint.
   There is no light-ground secondary ink and there must not be. Slate on cream
   is 2.95:1, gold on cream is 1.78:1. The landing template runs both; neither
   travels here. On a light ground secondary is weight and size. Rule 9.
--------------------------------------------------------------------------- */

.ground-light { background: var(--ground-light);     color: var(--ink-on-light); }
.ground-deep  { background: var(--surface-on-light); color: var(--ink-on-light); }
.ground-dark  { background: var(--ground-dark);      color: var(--ink-on-dark); }

.ground-dark h1, .ground-dark h2, .ground-dark h3 { color: var(--ink-on-dark); }
.ground-dark .eyebrow { color: var(--accent); }
.ground-dark .muted   { color: var(--ink-secondary-on-dark); }

/* ---------------------------------------------------------------------------
   3. TYPE — the site register. Lato. The corpus register (serif) is section 11.
--------------------------------------------------------------------------- */

.eyebrow {
  font-size: var(--size-label); line-height: 1.2; font-weight: var(--w-bold);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-on-light-strong); margin: 0 0 var(--space-32);
}
.label {
  font-size: var(--size-table); line-height: 1.2; font-weight: var(--w-bold);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-on-light-strong); margin: 0 0 var(--space-24);
}

h1 {
  font-family: var(--font-sans); font-weight: 900;
  font-size: clamp(32px, 4.4vw, 56px); line-height: 1.08;
  letter-spacing: -0.015em; color: var(--ink-on-light-strong);
}
h1 em { font-style: normal; color: var(--gold); }

h2 {
  font-family: var(--font-serif); font-weight: var(--w-bold);
  font-size: clamp(24px, 2.9vw, 36px); line-height: 1.22;
  letter-spacing: -0.4px; color: var(--ink-on-light-strong);
}
h3 {
  font-family: var(--font-sans); font-weight: var(--w-bold);
  font-size: var(--size-body-lg); line-height: var(--lh-headline);
  color: var(--ink-on-light-strong);
}

p { margin: 0 0 var(--space-24); }
p:last-child { margin-bottom: 0; }
strong { font-weight: var(--w-bold); }

.lead  { font-size: var(--size-lead); line-height: var(--lh-text); }
.micro { font-size: var(--size-micro); line-height: var(--lh-micro); }

/* ---------------------------------------------------------------------------
   4. LINKS AND BUTTONS
--------------------------------------------------------------------------- */

a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--gold); }
a:hover { border-bottom-width: 2px; }

.btn {
  display: inline-block; background: var(--gold); color: var(--navy);
  font-size: var(--size-table); font-weight: var(--w-bold);
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: var(--space-16) var(--space-32);
  border: none; border-radius: var(--radius); box-shadow: var(--shadow);
  cursor: pointer; transition: opacity .15s;
}
.btn:hover { opacity: .88; border: none; }

/* ---------------------------------------------------------------------------
   5. CHROME
--------------------------------------------------------------------------- */

.site-header { background: var(--ground-dark); padding: var(--space-16) 0; }
/* align-items was baseline while the wordmark was type. An image has no
   useful baseline, so it centres against the nav instead. 2026-09-03.

   ⚠ The header does NOT use the standard .wrap geometry, deliberately. .wrap
   is 1220px with 48px both sides; the hero below is a 1440px grid whose type
   column is inset 48px and whose photograph runs flush to the container's
   right edge. Above 1220px viewport those two diverge, and at 1440px the logo
   sat 110px right of the hero text under it. So the header takes the hero's
   container: 1440px rather than 1220px, inset 48px on the left to meet the
   hero type. Leonardo, 2026-09-03.

   ⚠ THE RIGHT SIDE IS NO LONGER FLUSH. It was 0, to meet the photograph's
   edge, on his instruction the same day. He reversed it on 2026-09-04 having
   seen it: the nav read as jammed against the window with no air, and the
   symmetry with the logo matters more than meeting an edge the eye does not
   trace anyway. Both narrower breakpoints below were ALREADY symmetric, so
   this rule was the only asymmetric one and the fault showed on wide screens
   only. The 1440px container stays: that is what aligns the logo with the
   hero type, and it is a separate decision from the padding. */
.site-header .wrap {
  display: flex; align-items: center; gap: var(--space-24);
  max-width: 1440px; padding: 0 var(--space-48);
}
/* ⚠ flex: none on BOTH, and it is not belt and braces. The wrap is a flex row
   and the logo is a flex item, so between 601 and 900px — where the nav is at
   its widest but has not yet stacked — the anchor was shrinking to fit. The
   anchor is itself display:flex, so the img inside it is a flex item too and
   shrank with it. Because the img is height-pinned at 28px with width:auto,
   shrinking did not scale it, it SQUASHED it: measured at 700px viewport the
   rendered aspect was 3.72 against a true 5.36, a 30% horizontal crush.
   Leonardo, 2026-09-04. A logo is never a flexible box. */
.site-logo { border: none; display: flex; flex: none; }
.site-logo img { height: 28px; width: auto; display: block; flex: none; }
.site-nav { margin-left: auto; display: flex; gap: var(--space-24); flex-wrap: wrap; }
.site-nav a {
  color: var(--ink-on-dark); font-size: var(--size-table);
  letter-spacing: .08em; text-transform: uppercase; opacity: .78;
  padding-bottom: 3px; border-bottom: 1px solid transparent;
}
.site-nav a:hover, .site-nav a[aria-current="page"] { opacity: 1; border-bottom-color: var(--gold); }

.site-footer {
  background: var(--ground-dark); color: var(--ink-secondary-on-dark);
  border-top: 1px solid rgba(253,251,246,.12);
  padding: var(--space-32) 0 var(--space-48);
}
.site-footer .wrap { display: flex; gap: var(--space-24); flex-wrap: wrap; align-items: baseline; }
.site-footer a {
  color: var(--ink-on-dark); font-size: var(--size-table);
  letter-spacing: .08em; text-transform: uppercase; opacity: .72;
  border-bottom: 1px solid transparent;
}
.site-footer a:hover { opacity: 1; border-bottom-color: var(--gold); }
.site-footer .micro { margin-left: auto; color: var(--ink-secondary-on-dark); }

/* ---------------------------------------------------------------------------
   6. THE HERO — type | seam | photograph
   The dark ground is structural, not a mood. Gold on cream is 1.78:1 against a
   3:1 large-text threshold, so the gold em, the gold eyebrow and a legible
   photograph all require navy. A cream hero cannot carry any of the three.
--------------------------------------------------------------------------- */

.hero { background: var(--ground-dark); color: var(--ink-on-dark); }

/* THE HERO TRACKS THE VIEWPORT. Leonardo, 2026-09-03: not a fixed height.
   It fills the screen minus the chrome above it, minus a deliberate peek of
   the evidence strip below. That peek is the scroll cue: a strip half in view
   pulls the reader down, where a hero that exactly fills the screen reads as
   the whole page.
     --hero-chrome  the gold band (16) plus the header (60)
     --hero-peek    how much of the evidence strip stays visible
   Clamped at both ends: never shorter than the photograph's own minimum,
   never so tall on a large monitor that the hero becomes a field of navy.
   svh rather than vh so mobile browser chrome collapsing does not resize it. */
/* THE FOLD. The hero and the evidence strip together occupy exactly one
   viewport, so the strip always lands on the fold WHOLE, at any screen height,
   and keeps doing so if its contents change. The hero takes what is left.

   This replaces a hand-measured --hero-peek, which had two faults: it had to
   be re-measured every time the strip changed (adding the heading grew it from
   130px to 209px and moved the cut through the heading), and it broke on tall
   screens, where the hero hit its 900px ceiling and the leftover space became
   the peek regardless of the value set.

   --hero-chrome is the one number still measured by hand: the gold band (16)
   plus the header (60). The header sits outside this wrapper, in baseof. */
:root { --hero-chrome: 76px; }

.fold {
  min-height: calc(100vh  - var(--hero-chrome));
  min-height: calc(100svh - var(--hero-chrome));
  display: flex; flex-direction: column;
}
.fold .hero  { flex: 1 1 auto; display: flex; }
.fold .proof { flex: 0 0 auto; }
.hero-grid {
  max-width: 1440px; margin: 0 auto; width: 100%; display: grid;
  grid-template-columns: 1fr var(--rule) .78fr; align-items: stretch;
}
/* Padding and headline both scale, so the block fits a short laptop without
   overflowing and opens up on a tall monitor. Leonardo authorised reducing the
   headline height, 2026-09-03: at 820px the fold leaves the hero 535px, and at
   the old 80px padding and 56px headline the content needed 661px. */
.hero-type {
  padding: clamp(28px, 4.4vh, 80px) var(--space-48);
  display: flex; flex-direction: column; justify-content: center;
}
.hero-seam { background: var(--gold); }
/* No min-height: the image is out of flow, and a floor here would stop the
   hero shrinking to fit the fold. The grid row is set by the type column. */
.hero-photo { position: relative; overflow: hidden; }
/* ⚠ The image is absolutely positioned so it CANNOT drive the hero's height.
   Measured 2026-09-03 at 1440x820: the type column needs 661px, but the photo
   was rendering at its natural aspect (height:100% resolves to auto in a grid
   row with no definite height) and stretching the row to 944px, 124px taller
   than the whole viewport. The hero was pushing itself past the fold and
   taking the evidence strip with it. Out of flow, the photo now fills whatever
   height the text sets. */
.hero-photo img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: 52% 22%;
}
.hero-photo::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(21,32,47,.55) 0%, rgba(21,32,47,.10) 42%, rgba(21,32,47,0) 100%);
}
.hero .eyebrow { color: var(--gold); margin-bottom: var(--space-32); }
/* Measure widened 2026-09-03 on Leonardo's call: h1 15ch → 22ch, lead
   48ch → 56ch. Both still sit inside the type column at 1440px, so the
   grid ratio is untouched. */
.hero h1 { color: var(--ink-on-dark); max-width: 22ch;
           font-size: clamp(28px, 3.4vw, 46px); }
.hero .lead {
  font-weight: var(--w-light); font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.55; color: rgba(253,251,246,.80); max-width: 56ch;
  margin-top: clamp(12px, 2vh, 24px);
}
.hero .btn { margin-top: clamp(16px, 2.6vh, 32px); align-self: flex-start; }

/* ---------------------------------------------------------------------------
   7. THE EVIDENCE STRIP. Numbers, not adjectives.
--------------------------------------------------------------------------- */

.proof { background: var(--ground-dark); border-top: 1px solid rgba(253,251,246,.12); }
/* The wrap is a block now: a heading, then the row. Added 2026-09-03 with the
   "Interpretation Gap" heading, which is what stops the research tile reading
   as Leonardo's own. The heading takes no gold: the A2 rule is that gold marks
   a gap or a boundary, and a section label is neither, however it is worded. */
.proof .wrap { display: block; }
.proof-head {
  font-size: var(--size-table); font-weight: var(--w-bold);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-on-dark); margin: 0;
  padding: var(--space-24) 0 var(--space-16);
}
.proof .stats { display: flex; }
.proof .stat { flex: 1; padding: var(--space-24) 0 var(--space-32);
               border-right: 1px solid rgba(253,251,246,.12); }
.proof .stat:last-child { border-right: none; }
.proof .n { font-family: var(--font-serif); font-weight: var(--w-bold);
            font-size: var(--size-headline); line-height: 1; color: var(--gold); }
.proof .t { font-size: var(--size-micro); letter-spacing: .14em; text-transform: uppercase;
            color: rgba(253,251,246,.62); margin-top: var(--space-8); line-height: 1.4; }

/* ---------------------------------------------------------------------------
   8. THE SEAM SECTION. The idea, stated once, plainly.
--------------------------------------------------------------------------- */

.seamsec { padding: var(--space-72) 0; }
.seamsec .wrap { display: grid; grid-template-columns: 1fr 168px 1fr; align-items: center; }
/* :not(.label) — the label is Lato micro-caps and must not inherit the serif.
   Without it, .seamsec .pane p out-specifies .label and the label renders as a
   28px serif heading. */
.seamsec .pane p:not(.label) {
  font-family: var(--font-serif); font-size: clamp(20px, 2.1vw, 27px);
  line-height: 1.35; color: var(--ink-on-light-strong);
}
.seamsec .pane--right { text-align: right; }
.seamsec .pane--right .label,
.seamsec .pane--right p:not(.label) { color: var(--ink-on-light); }

.seam { position: relative; height: 250px; display: flex; align-items: center; justify-content: center; }
.seam .line { position: absolute; top: 0; bottom: 0; left: 50%; width: var(--rule);
              margin-left: calc(var(--rule) / -2); background: var(--gold); }
.seam .word {
  position: relative; background: var(--ground-light); padding: var(--space-16) 0;
  font-size: var(--size-micro); letter-spacing: .2em; text-transform: uppercase;
  font-weight: var(--w-bold); color: var(--ink-on-light-strong); writing-mode: vertical-rl;
}

/* ---------------------------------------------------------------------------
   9. THE BAND. Air, and one line over it.
--------------------------------------------------------------------------- */

.band { position: relative; background: var(--ground-dark); }
.band img { width: 100%; height: clamp(320px, 44vh, 520px); object-fit: cover;
            object-position: 50% 42%; opacity: .55; }
.band .over {
  position: absolute; inset: 0; display: flex; align-items: center;
  background: linear-gradient(90deg, rgba(21,32,47,.90) 0%, rgba(21,32,47,.62) 46%, rgba(21,32,47,.25) 100%);
}
.band .over .wrap { width: 100%; }
.band blockquote {
  border-left: var(--rule) solid var(--gold); padding-left: var(--space-24);
  max-width: 24ch; font-family: var(--font-serif); font-style: italic;
  color: var(--ink-on-dark); font-size: clamp(22px, 2.8vw, 36px); line-height: 1.3;
}

/* ---------------------------------------------------------------------------
   10. SECTIONS
--------------------------------------------------------------------------- */

.section { padding: var(--space-80) 0; }
.section--tight { padding: var(--space-64) 0; }
.rule-mark { width: 56px; height: var(--rule); background: var(--gold); margin-bottom: var(--space-24); }

.philo .wrap { max-width: 900px; }
.philo h2 { margin-bottom: var(--space-24); }
.philo p { max-width: 62ch; font-size: var(--size-body-sm); line-height: 1.62; }
/* The ladder NEVER travels without the paragraph above it. Extracted, an arrow
   chain reads as steps in a process, which is the item reading the 2026-08-19
   rule forbids. It also goes in no machine field — see schema.html. */
.philo p.ladder {
  margin-top: var(--space-32); font-family: var(--font-sans); font-weight: 900;
  font-size: clamp(20px, 2.2vw, 27px); color: var(--ink-on-light-strong);
  letter-spacing: -0.01em;
}
.philo p.ladder span { color: var(--gold); }

.chal h2 { max-width: 24ch; margin-bottom: var(--space-48); }
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--hairline); }
.card {
  background: var(--ground-light); padding: var(--space-32) var(--space-32) var(--space-48);
  border-left: var(--rule) solid var(--gold);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.card .label { margin-bottom: var(--space-16); }
.card p { font-size: var(--size-body-sm); line-height: 1.62; }

.about .wrap { display: grid; grid-template-columns: .62fr 1fr; gap: var(--space-48); align-items: center; }
.about .shot { border-left: var(--rule) solid var(--gold); }
.about .shot img { width: 100%; height: clamp(380px, 48vh, 520px); object-fit: cover; object-position: 50% 36%; }
.about p { font-size: var(--size-body-sm); line-height: 1.62; max-width: 52ch; }
.about .emph { font-family: var(--font-serif); color: var(--ink-on-light-strong);
               font-size: var(--size-body-lg); line-height: 1.4; }

.index-head {
  font-family: var(--font-sans); font-size: var(--size-table); letter-spacing: .2em;
  text-transform: uppercase; font-weight: var(--w-bold);
  color: var(--ink-on-light-strong); padding-bottom: var(--space-16);
  border-bottom: 1px solid var(--ink-on-light-strong); margin: 0;
}
.index { list-style: none; margin: 0; }
.index li {
  display: grid; grid-template-columns: 112px 1fr 200px; gap: var(--space-24);
  padding: var(--space-16) 0; border-bottom: 1px solid var(--hairline); align-items: baseline;
}
.index .d { font-size: var(--size-micro); letter-spacing: .1em; text-transform: uppercase; }
.index .t { font-family: var(--font-serif); font-size: var(--size-body); line-height: 1.3;
            color: var(--ink-on-light-strong); }
.index .t a { border-bottom-color: transparent; }
.index li:hover .t a { border-bottom-color: var(--gold); }
.index .k { font-size: var(--size-micro); letter-spacing: .11em; text-transform: uppercase; text-align: right; }
.index-more { margin-top: var(--space-24); font-size: var(--size-table);
              letter-spacing: .1em; text-transform: uppercase; font-weight: var(--w-bold); }
.index-more a { border-bottom: 2px solid var(--gold); }

.final .wrap { max-width: 880px; }
.final h2 { color: var(--ink-on-dark); margin-bottom: var(--space-24); }
.final p { max-width: 62ch; font-size: var(--size-body-sm); line-height: 1.62; font-weight: var(--w-light); }
.final .btn { margin-top: var(--space-32); }
.clients { margin-top: var(--space-48); padding-top: var(--space-24);
           border-top: 1px solid rgba(253,251,246,.14);
           display: flex; gap: var(--space-32); flex-wrap: wrap; align-items: center; }
.clients b, .clients span {
  font-size: var(--size-table); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-secondary-on-dark); font-weight: var(--w-bold);
}
.clients b { font-size: var(--size-micro); }

/* ---------------------------------------------------------------------------
   11. THE CORPUS REGISTER — face map row "Report, article".
   Serif title and headings, Lato body, 720px measure, column centred.
   Applied by .is-article on /writing/, /reports/, /books/ only.
--------------------------------------------------------------------------- */

.is-article { max-width: 720px; margin-left: auto; margin-right: auto; }
.is-article h1 {
  font-family: var(--font-serif); font-weight: var(--w-bold);
  font-size: clamp(34px, 5vw, 46px); line-height: 1.18; letter-spacing: -0.4px;
}
.is-article h2 {
  font-size: clamp(23px, 2.6vw, 26px); line-height: var(--lh-headline);
  margin: var(--space-48) 0 var(--space-24);
}
.is-article h2::before {
  content: ''; display: block; width: 52px; height: 3px;
  background: var(--gold); margin-bottom: 18px;
}
.is-article h3 { font-family: var(--font-serif); font-weight: var(--w-bold); font-size: var(--size-body-lg); }
/* Product and service names are ALWAYS Lato, matched by x-height, never nominal. */
.is-article .name { font-family: var(--font-sans); font-size: 0.956em; }
.is-article .sub {
  font-family: var(--font-sans); font-weight: var(--w-light);
  font-size: clamp(20px, 2.2vw, 23px); line-height: 1.42; margin-top: var(--space-24);
}
.is-article .meta {
  font-size: var(--size-table); margin-top: var(--space-32);
  padding-top: 18px; border-top: 1px solid var(--hairline);
}
.is-article .body { line-height: 1.45; }
.is-article .body p { margin: 0 0 22px; }
.is-article .body > p:first-of-type { font-size: var(--size-body-lg); }
.is-article .body blockquote {
  border-left: var(--rule) solid var(--gold); padding-left: var(--space-24);
  font-style: italic; font-weight: var(--w-light); margin: var(--space-32) 0;
}
.is-article .body img { margin: var(--space-32) 0; }

/* ---------------------------------------------------------------------------
   12. RESPONSIVE — source C. Two breakpoints plus clamp() fluid type.
   The top band does not change.
--------------------------------------------------------------------------- */

/* ⚠ THE HEADER STACKS WHERE IT STOPS FITTING, not at a round number.
   Leonardo, 2026-09-04: the breakpoint should be where the room for the logo
   is exactly the logo width. Measured on the live page that day: logo 150px
   at its true aspect, nav 672.5px on one line, 48px padding each side, 24px
   gap. They need 943px. The stack was at 600px, so from 601 to 943 the nav
   wrapped onto two lines beside the logo, which is the band he saw. 960 takes
   the measured figure and leaves a little headroom for font-rendering
   differences between machines.
   ⚠ ADD OR RENAME A NAV ITEM AND THIS NUMBER MOVES. Remeasure: it is
   padding + logo + gap + the nav's single-line width. */
@media (max-width: 960px) {
  .site-header .wrap { flex-wrap: wrap; gap: var(--space-8); }
  .site-nav { margin-left: 0; width: 100%; gap: var(--space-16); }
}

@media (max-width: 900px) {
  /* Single column from here down. The fold is released too: stacked, hero
     plus strip cannot fit one viewport and should simply scroll. */
  .hero-grid { grid-template-columns: 1fr; min-height: 0; }
  .fold { min-height: 0; display: block; }
  /* 320px put the mobile hero at 884px against an 812px viewport, so the phone
   showed the photograph and half a headline. 200px brings it to ~760px, which
   fits the headline, subtitle and button on one screen. The min-height is
   load-bearing here: the image is absolutely positioned, so without it the
   column collapses to nothing. Leonardo, 2026-09-03. */
  .hero-photo { order: 0; min-height: 200px; }
  .hero-seam  { order: 1; height: var(--rule); }
  .hero-type  { order: 2; padding: var(--space-48) var(--space-24); }
  .hero-photo::after { background: linear-gradient(180deg, rgba(21,32,47,0) 40%, rgba(21,32,47,.85) 100%); }
  .proof .stats { flex-wrap: wrap; }
  .proof .stat { flex: 1 0 50%; border-right: none; }
  .seamsec .wrap { grid-template-columns: 1fr; }
  .seam { height: 110px; }
  .seam .line { left: 0; margin-left: 0; }
  .seam .word { writing-mode: horizontal-tb; background: transparent; padding-left: var(--space-24); }
  .seamsec .pane--right { text-align: left; }
  .cards { grid-template-columns: 1fr; }
  .about .wrap { grid-template-columns: 1fr; gap: var(--space-32); }
  .index li { grid-template-columns: 1fr; gap: var(--space-8); }
  .index .k { text-align: left; }
}

@media (max-width: 600px) {
  body { font-size: var(--size-body-sm); }
  .wrap { padding: 0 var(--space-24); }
  .section { padding: var(--space-48) 0; }
  .seamsec { padding: var(--space-48) 0; }
  .is-article .body > p:first-of-type { font-size: var(--size-body); }
  .site-header .wrap { padding: 0 var(--space-24); }
  .site-footer .micro { margin-left: 0; width: 100%; }
}

@media print {
  .site-header, .site-nav, .hero-photo, .band { display: none; }
  .page { min-height: 0; }
  a { border-bottom: none; }
}

/* ---------------------------------------------------------------------------
   13. ARTICLE FIGURES. Added with the Substack migration, 2026-08-25.
   No rounding, no shadow. A caption is secondary by weight and size, never by
   a grey — there is no light-ground secondary ink (rule 9).
--------------------------------------------------------------------------- */

.figure { margin: var(--space-32) 0; }
.figure img { width: 100%; height: auto; border-radius: var(--radius); box-shadow: var(--shadow); }
.figure figcaption {
  margin-top: var(--space-8);
  font-size: var(--size-micro);
  line-height: var(--lh-micro);
  font-weight: var(--w-light);
}

/* ---------------------------------------------------------------------------
   14. THE ABOUT PAGE. Person entity page, Lato register.
--------------------------------------------------------------------------- */

.about-page .about-grid {
  display: grid; grid-template-columns: .58fr 1fr;
  gap: var(--space-48); align-items: start; margin-top: var(--space-48);
}
.about-page .shot { border-left: var(--rule) solid var(--gold); }
.about-page .shot img { width: 100%; height: auto; }
.about-page .about-text p { max-width: 58ch; font-size: var(--size-body-sm); line-height: 1.62; }
.about-page .emph-block {
  margin-top: var(--space-32);
  border-left: var(--rule) solid var(--gold);
  padding-left: var(--space-24);
}
.about-page .emph {
  font-family: var(--font-serif);
  color: var(--ink-on-light-strong);
  font-size: var(--size-body-lg);
  line-height: 1.4;
  margin-bottom: var(--space-8);
}
.about-page .about-cta { margin-top: var(--space-48); }

@media (max-width: 900px) {
  .about-page .about-grid { grid-template-columns: 1fr; gap: var(--space-32); }
}

/* ---------------------------------------------------------------------------
   THE ARTICLE LIST. Added 2026-09-03 (Leonardo): every entry carries the
   article's own first image and its front-matter description, with a first-40-
   words fallback where a description is missing.

   No gold anywhere in here. The rule from direction A2 holds: gold stands for
   a gap or a boundary and nothing else, so a list of articles gets none.
--------------------------------------------------------------------------- */
.entries { list-style: none; margin: var(--space-48) 0 0; padding: 0; }
.entry {
  display: grid; grid-template-columns: 280px 1fr; gap: var(--space-32);
  padding: var(--space-32) 0;
  border-top: 1px solid rgba(21,32,47,.12);
  align-items: start;
}
.entry:last-child { border-bottom: 1px solid rgba(21,32,47,.12); }
.entry-thumb { display: block; border: none; overflow: hidden; }
.entry-thumb img {
  width: 100%; height: 175px; object-fit: cover; display: block;
  transition: transform .4s ease;
}
.entry:hover .entry-thumb img { transform: scale(1.03); }
.entry-meta {
  font-size: var(--size-table); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-secondary); margin: 0 0 var(--space-8);
  display: flex; gap: var(--space-16);
}
.entry-title { margin: 0 0 var(--space-8); font-size: var(--size-h3); line-height: 1.25; }
.entry-title a { border-bottom: none; color: var(--ink); }
.entry-title a:hover { border-bottom: 1px solid var(--ink); }
.entry-sum { margin: 0 0 var(--space-16); max-width: 62ch; color: var(--ink); }
.entry-more { margin: 0; }
.entry-more a {
  font-size: var(--size-table); letter-spacing: .08em; text-transform: uppercase;
  border-bottom: 1px solid transparent;
}
.entry-more a:hover { border-bottom-color: var(--ink); }

@media (max-width: 900px) {
  .entry { grid-template-columns: 200px 1fr; gap: var(--space-24); }
  .entry-thumb img { height: 130px; }
}
@media (max-width: 600px) {
  .entry { grid-template-columns: 1fr; gap: var(--space-16); }
  .entry-thumb img { height: 200px; }
}

/* ---------------------------------------------------------------------------
   CONTACT ROUTES. Added 2026-09-03. Each route is a real destination, not a
   form: a static site cannot accept a POST, and /try/* stays on the app.
   The gold left rule is the established card treatment and it stands for the
   boundary between the page and what is on the other side of it.
--------------------------------------------------------------------------- */
.routes { list-style: none; margin: var(--space-48) 0 0; padding: 0;
          display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-32); }
.route { border-left: var(--rule) solid var(--gold); padding-left: var(--space-24); }
.route-do { margin: var(--space-16) 0 0; }
.route-do a { font-size: var(--size-table); letter-spacing: .08em;
              text-transform: uppercase; word-break: break-word; }

@media (max-width: 900px) { .routes { grid-template-columns: 1fr; gap: var(--space-24); } }

/* ---------------------------------------------------------------------------
   THE LIBRARY. Added 2026-09-03. The corpus front door: every format, grouped
   by year, so the body of work reads as one. Self-filling, so no gold rules
   marking sections that may not exist yet.
--------------------------------------------------------------------------- */
.lib-block { margin-top: var(--space-48); }
.lib-n { font-weight: var(--w-regular); opacity: .55; letter-spacing: 0; }
.lib-year { display: grid; grid-template-columns: 88px 1fr; gap: var(--space-24);
            padding: var(--space-16) 0; border-top: 1px solid rgba(21,32,47,.12); }
.lib-yr { font-size: var(--size-table); letter-spacing: .1em; color: var(--ink-secondary);
          margin: 0; padding-top: 3px; }
.lib-list { list-style: none; margin: 0; padding: 0; }
.lib-list li { margin-bottom: var(--space-8); }
.lib-list li:last-child { margin-bottom: 0; }
.lib-list a { border-bottom: none; }
.lib-list a:hover { border-bottom: 1px solid var(--ink); }

@media (max-width: 600px) {
  .lib-year { grid-template-columns: 1fr; gap: var(--space-8); }
}

/* ---------------------------------------------------------------------------
   CRAFT 91, /work/. Added 2026-09-03.
   The page reads as a journey: Problem is point A, Payoff is point Z, the
   spine runs between them and the always-on band runs underneath. Layout
   follows assets/core-product/product-on-a-page-build-spec.md.
   ⛔ No prices here or anywhere on this site. Standing rule, Leonardo.
--------------------------------------------------------------------------- */
.prob-pay { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-72); }

/* Scenes, not bullets: separated by space, never markers. The outer two and
   the middle three are never separated by weight, or the middle three become
   subordinate and those are the lines that make him feel seen. */
.scene { margin-bottom: var(--space-32); }
.scene p { margin: 0; }
.scene-q { font-style: italic; opacity: .68; margin-top: var(--space-8) !important; }

/* Three sizes, unlike the Problem column: payoff 1 carries the Prize. */
.payoffs { list-style: none; margin: 0; padding: 0; }
.payoffs li { margin-bottom: var(--space-24); }
.payoffs .payoff-1 { font-size: var(--size-body-lg); font-weight: var(--w-bold); }
.payoffs li:last-child { font-size: var(--size-body-sm); opacity: .82; }

.spine-eh { font-weight: var(--w-bold); margin-bottom: var(--space-8); }
.spine { list-style: none; margin: var(--space-48) 0 0; padding: 0;
         display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-16); }
.node { border-top: var(--rule) solid var(--gold); padding-top: var(--space-16); }
.node p { margin: 0; font-size: var(--size-body-sm); }
.node-n { font-weight: var(--w-bold); margin-bottom: var(--space-8) !important; }
.node-d { font-weight: var(--w-regular); opacity: .6; }

.around-intro { margin: 0 0 var(--space-32); }
.around { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-48); }
.ar-block--key { border-left: var(--rule) solid var(--gold); padding-left: var(--space-24); }

/* Unbroken, edge to edge, so it reads as continuous rather than as another
   item in a list. Without it the page reads as five meetings. */
.band-on { margin-top: var(--space-48); padding: var(--space-32) var(--space-32);
           background: var(--surface-on-light); }
.band-on p:last-child { margin: 0; }
.keep { margin-top: var(--space-48); }

.craft { margin: var(--space-48) 0 0; }
.craft-row { display: grid; grid-template-columns: 200px 1fr; gap: var(--space-24);
             padding: var(--space-16) 0; border-top: 1px solid rgba(21,32,47,.12); }
.craft dt { font-weight: var(--w-bold); }
.craft dd { margin: 0; }

@media (max-width: 900px) {
  .prob-pay, .around { grid-template-columns: 1fr; gap: var(--space-48); }
  .spine { grid-template-columns: 1fr 1fr; }
  .craft-row { grid-template-columns: 1fr; gap: var(--space-8); }
}
@media (max-width: 600px) { .spine { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   ANSWERS. Added 2026-09-03, closing audit item 24 (FAQ and definition blocks,
   0/100 and 14% of the weight between them).
   The answer sits immediately after its heading with nothing between them:
   that adjacency is what lets an answer engine lift the passage cleanly, and
   it is also just how someone scanning for their own question reads.
--------------------------------------------------------------------------- */
.qa-block { margin-top: var(--space-48); max-width: 820px; }
.qa { padding: var(--space-32) 0; border-top: 1px solid rgba(21,32,47,.12); }
.qa:first-child { border-top: none; padding-top: var(--space-16); }
.qa-q { font-family: var(--font-sans); font-weight: var(--w-bold);
        font-size: var(--size-body-lg); line-height: var(--lh-headline);
        margin: 0 0 var(--space-16); }
.qa-a { margin: 0; }

/* ---------------------------------------------------------------------------
   PROBLEM AND PAYOFF, PAIRED. Added 2026-09-03 (Leonardo: they must match
   visually left to right). Each payoff is the specific negation of its own
   problem, which is the argument rather than an ornament, so the pairs have to
   be visibly on the same line. One grid, two columns, each pair one row.
--------------------------------------------------------------------------- */
.pp { display: grid; grid-template-columns: 1fr 34px 1fr; gap: 0 var(--space-24);
      align-items: stretch; }
.pp .label { margin-bottom: var(--space-32); }
.pp-cell { padding: var(--space-24) 0; border-top: 1px solid rgba(21,32,47,.10); }
.pp-cell p { margin: 0; }
.pp-pay { font-weight: var(--w-bold); }
/* Payoff 1 carries the Prize; the last is long, so it steps down. Three sizes,
   unlike the Problem column, whose job is uniform recognition. */
.pp-pay.payoff-1 { font-size: var(--size-body-lg); }
/* The last payoff is the longest, so it steps down in SIZE only. It stays
   bold like the other four: Leonardo, 2026-09-03. Weight is what marks these
   as payoffs, and dropping it on one made that one read as a footnote. */
.pp-pay.payoff-last { font-size: var(--size-body-sm); }

/* The arrow marks the crossing from a problem to its own payoff. Gold is
   legal here because it is standing for that seam, which is the A2 rule, not
   an exception to it. Hidden from assistive tech: it carries no information a
   screen reader does not already get from the reading order. */
.pp-mid { display: flex; align-items: center; justify-content: center; }
/* Short on purpose. Leonardo, 2026-09-03: the arrow marks the crossing, it
   does not need to span the gutter to do it. Stem plus head, 18px total. */
.pp-arrow { display: block; width: 18px; height: var(--rule);
            background: var(--gold); position: relative; }
.pp-arrow::after {
  content: ''; position: absolute; right: -1px; top: 50%;
  width: 7px; height: 7px; border-top: var(--rule) solid var(--gold);
  border-right: var(--rule) solid var(--gold);
  transform: translateY(-50%) rotate(45deg);
}

.offers { list-style: none; margin: var(--space-48) 0 0; padding: 0;
          display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-48); }
.offer { border-top: var(--rule) solid var(--gold); padding-top: var(--space-24); }
.offer-t { margin: 0 0 var(--space-16); }
.offer-t a { border-bottom: none; }
.offer-t a:hover { border-bottom: 1px solid var(--ink); }

@media (max-width: 900px) {
  /* Stacked, there is no left-to-right crossing for the arrow to mark. */
  .pp { grid-template-columns: 1fr; gap: 0; }
  .pp .pp-mid { display: none; }
  .pp .label:nth-of-type(3) { margin-top: var(--space-48); }
  .offers { grid-template-columns: 1fr; gap: var(--space-32); }
}

/* Report source line: it is somebody else's research and should read as a
   citation, not as body copy. */
.case-src { margin-top: var(--space-24); color: var(--ink-secondary); }
.after-btn { margin-top: var(--space-24); font-size: var(--size-table);
             letter-spacing: .08em; text-transform: uppercase; }

/* Book editions. An edition with no recorded store link says so rather than
   carrying a constructed URL. */
.editions { list-style: none; margin: var(--space-48) 0 0; padding: 0;
            display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-32); }
.editions > li { border-top: var(--rule) solid var(--gold); padding-top: var(--space-16); }
.ed-t { font-weight: var(--w-bold); margin-bottom: var(--space-8); }
.ed-none { color: var(--ink-secondary); margin: 0; }
@media (max-width: 600px) { .editions { grid-template-columns: 1fr; } }

/* Diagrams. These are dark-ground artwork with their own gold edge bar, so
   they sit on a deep ground and take no frame of their own. */
.qa-fig, .page-fig { margin: var(--space-32) 0 0; }
.qa-fig img, .page-fig img { width: 100%; height: auto; }
.qa-fig figcaption, .page-fig figcaption { margin-top: var(--space-16); color: var(--ink-secondary); }
.section--tight.ground-deep .page-fig { margin: 0; }

/* ---------------------------------------------------------------------------
   THE SHELF. Books lead with the cover: it is the object being sold, and the
   covers are already navy and gold, so they sit in the page without a frame.
--------------------------------------------------------------------------- */
.shelf { list-style: none; margin: var(--space-48) 0 0; padding: 0;
         display: grid; gap: var(--space-48); }
.book { display: grid; grid-template-columns: 200px 1fr; gap: var(--space-32);
        align-items: start; }
.book-cover { display: block; border: none; }
.book-cover img { width: 100%; height: auto; box-shadow: 0 2px 24px rgba(21,32,47,.18); }
.book-body .offer-t { margin-top: 0; }
.book-lead { display: grid; grid-template-columns: 260px 1fr; gap: var(--space-48);
             align-items: start; }
.book-cover--lead img { width: 100%; }
.editions .ed-cover img { width: 96px; height: auto; margin-bottom: var(--space-16);
                          box-shadow: 0 2px 16px rgba(21,32,47,.16); }

@media (max-width: 900px) {
  .book { grid-template-columns: 140px 1fr; gap: var(--space-24); }
  .book-lead { grid-template-columns: 1fr; gap: var(--space-32); }
  .book-cover--lead { max-width: 240px; }
}

/* Editions listed inline on the shelf, so /books/ is the whole story. */
.ed-inline { list-style: none; margin: var(--space-24) 0 0; padding: 0; }
.ed-inline li { display: flex; flex-wrap: wrap; gap: var(--space-16);
                align-items: baseline; padding: var(--space-8) 0;
                border-top: 1px solid rgba(21,32,47,.10); }
.ed-lang { font-size: var(--size-table); letter-spacing: .1em;
           text-transform: uppercase; color: var(--ink-secondary); min-width: 68px; }
.ed-name { font-weight: var(--w-bold); }
.ed-buy { margin-left: auto; font-size: var(--size-table); letter-spacing: .08em;
          text-transform: uppercase; white-space: nowrap; }
.ed-inline .ed-none { margin-left: auto; font-size: var(--size-table);
                      letter-spacing: .08em; text-transform: uppercase;
                      color: var(--ink-secondary); white-space: nowrap; }
@media (max-width: 600px) {
  .ed-buy, .ed-inline .ed-none { margin-left: 0; width: 100%; }
}

/* The research behind it. Other people's work, so it is set quieter than the
   corpus above it: no gold, no cards, a plain reference list. */
.research { margin-top: var(--space-80); }
.papers { margin: var(--space-32) 0 0; }
.paper { display: grid; grid-template-columns: 260px 1fr; gap: var(--space-24);
         padding: var(--space-16) 0; border-top: 1px solid rgba(21,32,47,.12); }
.paper dt { font-weight: var(--w-bold); }
.paper-yr { font-weight: var(--w-regular); color: var(--ink-secondary); }
.paper dd { margin: 0; }
@media (max-width: 900px) { .paper { grid-template-columns: 1fr; gap: var(--space-8); } }
.lib-links { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .lib-links { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   THE CARD SHELF. The promotional cards carried over from Carrd, one per
   edition, QR code and all. Leonardo's call 2026-09-03.
   ⚠ The card art is on a WHITE ground, not the site's cream. It is given a
   hairline border so its edge is deliberate rather than looking like a bleed,
   and it sits full width of its column so the QR stays scannable.
--------------------------------------------------------------------------- */
.cards-shelf { list-style: none; margin: var(--space-48) 0 0; padding: 0;
               display: grid; gap: var(--space-72); }
.bookcard { display: grid; gap: var(--space-24); }
.bookcard-img { display: block; border: none; }
.bookcard-img img { width: 100%; height: auto; border: 1px solid rgba(21,32,47,.14); }
.bookcard-body { max-width: 72ch; }
.bookcard-body .offer-t { margin: var(--space-8) 0 var(--space-16); }

/* ---------------------------------------------------------------------------
   DECK ARTWORK. Added 2026-09-03. The images carry their own grounds, sampled
   to match the tokens exactly (navy #15202F, cream-deep #ECE9E4), so they are
   given no frame, no border and no radius: any of those would draw an edge
   where the point is that there isn't one. Each must stay on its matching
   ground section or the seam appears.
--------------------------------------------------------------------------- */
.prod-hero { max-width: 1600px; margin: var(--space-48) auto 0; }
.prod-hero img { width: 100%; height: auto; display: block; }
.prod-fig { margin: var(--space-48) 0 0; }
.prod-fig img { width: 100%; height: auto; display: block; }

/* ---------------------------------------------------------------------------
   THE PRODUCT SLIDE HERO. Added 2026-09-03: the deck's own opening slide, the
   illustration full bleed with the text centred over it. Replaces a version
   that put the image below the type at full width, which read as a band rather
   than a hero and was far too tall.
   The artwork's ground is the site navy exactly, so it needs no scrim beyond
   the light wash that keeps the type legible over the figure.
--------------------------------------------------------------------------- */
.prod-slide { position: relative; background: var(--ground-dark); overflow: hidden;
              min-height: clamp(420px, 62vh, 620px);
              display: flex; align-items: center; justify-content: center; }
.prod-slide > img { position: absolute; inset: 0; width: 100%; height: 100%;
                    object-fit: cover; object-position: 60% 40%; }
.prod-slide::after { content: ''; position: absolute; inset: 0;
                     background: linear-gradient(90deg, rgba(21,32,47,.72) 0%, rgba(21,32,47,.52) 55%, rgba(21,32,47,.20) 100%); }
.prod-slide-type { position: relative; z-index: 1; text-align: center;
                   padding: var(--space-72) var(--space-48); max-width: 900px; }
/* ⚠ The kicker and the title were set in the display SERIF at up to 24px and
   84px, while the Landing Scan's hero, which takes the plain navy branch in
   product.html, uses the site's own h1: sans, and forty per cent smaller.
   Three product pages, two typographic systems. Leonardo, 2026-09-04: the
   Landing Scan's is the lighter one and the one to keep.
   The kicker stays a SENTENCE rather than becoming an uppercase eyebrow,
   because on CRAFT 91 it is two clauses long and would not survive that.
   Weight is left to inherit, which is what .lead does on the Landing Scan, so
   the two really are the same line. ⚠ Deliberately not --w-light: 300 sits
   over a photograph here, where .lead sits over flat navy. */
.ps-kick { font-family: var(--font-sans); font-size: var(--size-lead);
           line-height: 1.4; color: var(--ink-on-dark); margin: 0 0 var(--space-32); }
/* Identical to h1, so the three product heroes now share one title. */
.ps-title { font-family: var(--font-sans); font-weight: 900;
            font-size: clamp(32px, 4.4vw, 56px); line-height: 1.08; letter-spacing: -0.015em;
            color: var(--gold); margin: 0 0 var(--space-32); }
.ps-sub, .ps-line { font-size: clamp(15px, 1.5vw, 19px); line-height: 1.5;
                    color: var(--ink-on-dark); margin: 0 0 var(--space-16); }
.ps-sub em, .ps-line em { font-style: normal; font-weight: var(--w-bold); color: var(--gold); display: block; }
.ps-foot { font-size: var(--size-micro); font-style: italic; line-height: 1.5;
           color: rgba(253,251,246,.72); margin: var(--space-32) 0 0; }
@media (max-width: 600px) { .prod-slide-type { padding: var(--space-48) var(--space-24); } }

/* Start here. The act leads and the name follows, so the name is set quieter
   than the sentence above it, not as a heading. Vocabulary_Dictionary.md. */
.entry--tool { grid-template-columns: 1fr; }
.tool-lead { font-size: var(--size-body-lg); font-weight: var(--w-bold);
             line-height: var(--lh-headline); margin: 0 0 var(--space-16);
             font-family: var(--font-sans); }
.tool-name { font-size: var(--size-table); letter-spacing: .08em;
             text-transform: uppercase; color: var(--ink-secondary);
             margin: 0 0 var(--space-16); }
.work-before { margin-top: var(--space-48); padding-left: var(--space-24);
               border-left: var(--rule) solid var(--gold); max-width: 62ch; }

/* ---------------------------------------------------------------------------
   THE SHARED CARD. Two columns, used by /books/, /reports/, /tools/ and
   /work/. Leonardo, 2026-09-03: the book cards were far too big and every
   section was inventing its own shape.
   Images are cropped to a common 16:9 because their native ratios disagree
   badly (banners 1.91, report cover 0.71). object-position: top is what keeps
   the report cover's navy title band in frame.
--------------------------------------------------------------------------- */
.cardgrid { list-style: none; margin: var(--space-48) 0 0; padding: 0;
            display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-48); }
.card2 { display: flex; flex-direction: column; }
/* ⚠ 1200/627, the promotional cards' own ratio, NOT 16/9. At 16/9 the banners
   were cropped at both sides and lost the QR. The report cover is portrait and
   still crops, but from the top, which is what keeps its navy title band. */
.card2-img { display: block; position: relative; border: none; overflow: hidden;
             aspect-ratio: 1200 / 627; background: var(--ground-dark); }
.card2-img img { width: 100%; height: 100%; object-fit: cover; object-position: top;
                 display: block; transition: transform .4s ease; }
.card2:hover .card2-img img { transform: scale(1.03); }
/* Title over the image, for cards whose artwork does not carry it. */
.card2-over { position: absolute; inset: auto 0 0 0; padding: var(--space-24);
              background: linear-gradient(180deg, rgba(21,32,47,0) 0%, rgba(21,32,47,.86) 62%);
              color: var(--ink-on-dark); }
.card2-img--blank .card2-over { background: none; inset: 0;
                                display: flex; flex-direction: column; justify-content: flex-end; }
.card2-eyebrow { display: block; font-size: var(--size-table); letter-spacing: .14em;
                 text-transform: uppercase; color: var(--accent); margin-bottom: var(--space-8); }
.card2-title { display: block; font-family: var(--font-serif); font-weight: var(--w-bold);
               font-size: var(--size-body-lg); line-height: 1.2; }
.card2-sub { margin: var(--space-16) 0 var(--space-16); flex: 1 0 auto; }
.card2 .index-more { margin: 0; }

@media (max-width: 700px) { .cardgrid { grid-template-columns: 1fr; gap: var(--space-32); } }

/* A photographic hero needs its own scrim. The CRAFT 91 illustration is navy
   throughout, so a left-to-right wash is enough; the driving photograph has a
   bright sky over dark tarmac (130/255 mean), and that wash would leave the top
   of the frame unreadable. This one darkens evenly and weights the centre,
   where the text sits. */
.prod-slide--photo::after {
  background: linear-gradient(180deg, rgba(21,32,47,.78) 0%, rgba(21,32,47,.58) 45%, rgba(21,32,47,.80) 100%);
}
.prod-slide--photo > img { object-position: center; }

/* A slide title that splits its colour: the plain half is cream, the <em> is
   gold. CRAFT 91's title is gold end to end and is unaffected, because it
   carries no <em>. Leonardo, 2026-09-04. */
.ps-title:has(em) { color: var(--ink-on-dark); }
.ps-title em { font-style: normal; color: var(--gold); }

/* A split title on a card behaves like one in a heading: the em is gold, not
   italic. Without this the browser default applies and "Scan" came out
   italicised instead of coloured. Leonardo, 2026-09-04. */
.card2-title em { font-style: normal; color: var(--gold); }

/* The card section's own label, so the grid does not arrive unannounced. It
   sits above the grid's top margin, which the grid then closes up. */
.cards-label { margin-top: var(--space-72); margin-bottom: 0; }
.cards-label + .cardgrid { margin-top: var(--space-24); }
