/* /info - what Dennis did on the six campaigns, told in his own person. The page
   is a duplicate of influenceradvisory.com/info, which is the agency telling the
   same six stories as "we". Everything below the double rule is that page's own
   stylesheet (studio-feature-preview/src/app/info/csx.css) taken from the
   COMMITTED version, which is what production serves. Do not take it from the
   working tree: three radii there read var(--house-radius-photo), a token that
   only exists once public/house-tokens.css loads, and that file is not live.

   The first block is the site chrome, rebuilt here exactly as /overview does it.
   This page deliberately does NOT load /styles.css, which styles headings, links
   and body type globally and would leak into .csp and change the layout. */

:root {
  --header-h: 72px;
  --black: #030a16;
  --font-display: 'Source Serif 4', Georgia, serif;
  --font-body: 'Source Sans 3', Arial, sans-serif;
  --font-mono: 'Source Code Pro', 'Courier New', monospace;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: #f2f2f2; font-family: var(--font-body); }

/* ---- site chrome ---- */
.mono-label {
  font-family: var(--font-mono); font-weight: 700; font-size: 14px;
  letter-spacing: .16em; text-transform: uppercase; line-height: 1.5;
  display: inline-block; text-decoration: none; color: inherit;
  transition: opacity .25s ease;
}
.mono-label:hover { opacity: .55; }
/* difference keeps one bar readable over the paper page and the dark footer both,
   the same trick the rest of the site uses. */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 900;
  display: flex; justify-content: space-between; align-items: center;
  padding: 20px 32px; color: #fff; mix-blend-mode: difference;
}
.site-header .brand {
  font-family: var(--font-display); font-weight: 600;
  font-size: 30px; line-height: .9; letter-spacing: .01em;
  text-decoration: none; color: inherit;
}
.header-right { display: flex; gap: 26px; align-items: center; }
@media (max-width: 720px) {
  .site-header { padding: 16px 20px; }
  .site-header .brand { font-size: 24px; }
  .header-right { gap: 16px; }
  .header-right .hide-sm { display: none; }
}

footer.site-footer {
  background: var(--black); color: #fff; padding: 64px 40px 40px;
  border-top: 1px solid rgba(255, 255, 255, .1);
}
@media (max-width: 720px) { footer.site-footer { padding: 48px 22px 32px; } }
.foot-grid {
  max-width: 1140px; margin: 0 auto;
  display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 44px;
}
@media (max-width: 800px) { .foot-grid { grid-template-columns: 1fr; gap: 32px; } }
.foot-brand { font-family: var(--font-display); font-weight: 600; font-size: 30px; line-height: 1; margin: 0 0 14px; }
.foot-tag { font-size: 15.5px; line-height: 1.65; color: rgba(255, 255, 255, .6); max-width: 44ch; margin: 0; }
.foot-col h4 {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: rgba(255, 255, 255, .45); margin: 0 0 16px;
}
.foot-col a { display: block; padding: 6px 0; font-size: 15.5px; color: rgba(255, 255, 255, .78); text-decoration: none; transition: color .25s ease; }
.foot-col a:hover { color: #fff; }
.colophon {
  max-width: 1140px; margin: 52px auto 0; padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, .1);
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .45);
}

/* ══════════════════════════════════════════════════════════════════════════
   Everything below is csx.css, the agency page's own stylesheet, verbatim.
   ══════════════════════════════════════════════════════════════════════════ */

/* /case-study-page - light asset palette + homepage typography (rule 76,
   apply-homepage-style skill). Everything is scoped under .csp so it never
   leaks into the rest of the site.

   Layout: each campaign is a nameplate plus four full-width bands that alternate
   tint and white - the problem, what we proposed, what we did, what happened. The
   bands are identical for all six brands on purpose, so the page's own promise
   that every section reads the same way is visible before you read a word. */

.csp {
  --bg: #f2f2f2;
  --surface: #ffffff;
  --ink: #111111;
  --body-c: #3d4249;
  --head: #0a0a0a;
  /* Darkened 2026-08-13. At #6a7078 the captions measured 4.11:1 on the tinted
     band, under the 4.5 floor. This is 5.39:1. Every caption on the page uses it. */
  --mut: #585e66;
  --accent: #153a80;
  --accent-hi: #2f5fd0;
  --hairline: rgba(10, 10, 10, .14);
  --tint: rgba(21, 58, 128, .05);
  --warn: #7a4a12;
  --warn-bg: rgba(122, 74, 18, .07);
  --serif: 'Source Serif 4', Georgia, serif;
  --sans: 'Source Sans 3', Arial, sans-serif;
  --mono: 'Source Code Pro', 'Courier New', monospace;

  background: var(--bg);
  color: var(--body-c);
  font-family: var(--sans);
  font-size: 20px;
  line-height: 1.7;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
.csp * { box-sizing: border-box; }

/* Two measures. Prose stays narrow enough to read, media and tables get the
   wider one so pictures have room (rule 100). */
.csp .wrap { max-width: 1140px; margin: 0 auto; padding: 0 34px; }
.csp .measure { max-width: 800px; }

.csp .eyebrow {
  font-family: var(--mono); font-size: 0.92rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--accent); margin: 0 0 16px;
}
.csp h1 {
  font-family: var(--serif); font-weight: 500; font-size: 4.1rem; line-height: 1.04;
  letter-spacing: -.02em; color: var(--head); margin: 0;
}
.csp h2 {
  font-family: var(--serif); font-weight: 500; font-size: 2.7rem; line-height: 1.14;
  letter-spacing: -.015em; color: var(--head); margin: 0 0 20px;
}
.csp h3 {
  font-family: var(--serif); font-weight: 600; font-size: 1.7rem; line-height: 1.2;
  letter-spacing: -.01em; color: var(--head); margin: 0 0 12px;
}
.csp p { margin: 0 0 18px; }

/* ---- cover ---- */
.csp .top { padding: calc(var(--header-h, 72px) + 56px) 0 54px; }
/* /team has no cover, it opens on the team band itself, so it needs the same
   clearance under the fixed site header that .top gives /info. Written as
   .band.teamtop, not .teamtop: .band sets padding with the shorthand further
   down this file, which resets padding-top on anything of equal specificity. */
.csp .band.teamtop { padding-top: calc(var(--header-h, 72px) + 46px); }
.csp .sub { font-size: 1.42rem; color: var(--body-c); margin: 22px 0 0; max-width: 760px; }
/* The four outcomes finish the headline's sentence, so they are set at the old
   standfirst's size and hung off a short rule rather than a bullet dot, which
   keeps the left edge of the text lined up with everything below it. */
.csp .outcomes { list-style: none; padding: 0; margin: 24px 0 0; max-width: 780px; }
.csp .outcomes li {
  font-size: 1.42rem; line-height: 1.45; color: var(--body-c);
  position: relative; padding-left: 28px; margin: 0 0 12px;
}
.csp .outcomes li:last-child { margin-bottom: 0; }
.csp .outcomes li::before {
  content: ""; position: absolute; left: 0; top: .66em;
  width: 14px; height: 2px; background: var(--accent);
}
/* Darkened + a step up 2026-08-16, same legibility pass as .plate .one. */
.csp .whofor {
  font-family: var(--mono); font-size: 0.98rem; letter-spacing: .06em; color: var(--body-c);
  border-left: 3px solid var(--accent); padding: 4px 0 4px 15px; margin: 26px 0 0; max-width: 700px;
}
.csp .jump {
  display: flex; flex-wrap: wrap; gap: 0; margin: 34px 0 0;
  border-top: 1px solid var(--head); border-bottom: 1px solid var(--hairline);
}
.csp .jump a {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); text-decoration: none;
  padding: 15px 20px 14px 0; margin-right: 20px; border-right: 1px solid var(--hairline);
}
.csp .jump a:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.csp .jump a:hover { color: var(--accent-hi); text-decoration: underline; }

/* ---- the band system ---- */
/* scroll-margin keeps a jumped-to chapter clear of the sticky site header,
   otherwise the nameplate lands underneath it. */
.csp .chapter { border-top: 2px solid var(--head); scroll-margin-top: calc(var(--header-h, 72px) + 12px); }
/* #campaigns is a bare wrapper div, so it needs the same header clearance the
   chapters get, otherwise that one anchor lands under the header. */
.csp #campaigns { scroll-margin-top: calc(var(--header-h, 72px) + 12px); }
.csp .plate { background: var(--surface); padding: 56px 0 50px; }
.csp .plate .num {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .18em;
  color: var(--accent); margin: 0 0 12px;
}
.csp .plate .bname {
  font-family: var(--serif); font-weight: 500; font-size: 3.5rem; line-height: 1.04;
  letter-spacing: -.02em; color: var(--head); margin: 0;
}
/* Inline, not a flex item. Flex made the mark and the name two flex items in a
   wrapping row, so the name took its own line and the mark sat alone above it,
   which is a logo lockup and not what was asked for. Inline-block keeps it in
   the text flow, so it sits directly in front of the first word.

   width and height come off the file as attributes and both are released here,
   the cap is --lgn, the file's own pixel height, so a mark is never drawn past
   its own resolution (rule 97). Radius because five of the six are square tiles
   with their own background colour, and a hard corner against the serif name
   reads as a favicon that leaked onto the page. */
.csp .blogo {
  display: inline-block; vertical-align: middle; position: relative; top: -.05em;
  margin-right: 15px;
  width: auto; height: auto; border-radius: 9px;
  max-height: min(calc(var(--lgn, 44) * 1px), 44px);
}
/* Darkened + a step up 2026-08-16 ("some parts are a little bit hard to see"):
   the one-liner is the only line that says what the brand is, so it reads at
   body ink rather than caption gray. */
.csp .plate .one {
  font-family: var(--mono); font-size: 0.98rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--body-c); margin: 14px 0 0;
}

.csp .band { padding: 56px 0 58px; border-top: 1px solid var(--hairline); }
.csp .band.tint { background: var(--tint); }
.csp .band.plain { background: var(--surface); }
.csp .blabel {
  font-family: var(--mono); font-size: 0.92rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 22px;
  display: flex; align-items: center; gap: 12px;
}
.csp .blabel::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--hairline); }

/* The proposal band is the turn in the story, so it reads a size up. */
.csp .band.turn .measure { font-size: 1.24rem; line-height: 1.5; color: var(--head); }

/* ---- numbered steps ---- */
.csp .step { display: grid; grid-template-columns: 62px 1fr; gap: 4px 20px; padding: 26px 0 0; }
.csp .step + .step { border-top: 1px solid var(--hairline); margin-top: 26px; }
.csp .step .sn {
  font-family: var(--mono); font-size: 1.5rem; font-weight: 700; color: var(--accent);
  line-height: 1.5; padding-top: 2px;
}
.csp .step .sbody { min-width: 0; }
.csp .stepmedia { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 20px; align-items: flex-start; }
.csp .stepmedia > * { flex: 1 1 380px; min-width: 0; }

/* A read runs one per row at the full step width. Two side by side put each
   one at about 485px, too small to see what the creator was actually doing
   with the product, which is the only reason the clip is on the page. */
.csp .stepmedia > .figvid { flex: 1 1 100%; }

/* A picture is capped by its own shape, not by the column. Left alone, the 723x820
   crew-call screenshot ran the full 940px and stood 1066px tall, which buries the
   step it belongs to. Portrait gets the tightest cap, letterboxed gets none. */
.csp .mslot.port { max-width: 460px; }
.csp .mslot.mid { max-width: 780px; }

/* ---- stat row ---- */
.csp .factline {
  display: flex; flex-wrap: wrap;
  border-top: 1px solid var(--head); border-bottom: 1px solid var(--hairline);
  margin: 0 0 34px;
}
.csp .factline > div {
  flex: 1 1 0; min-width: 150px;
  padding: 17px 24px 16px 0; margin-right: 24px;
  border-right: 1px solid var(--hairline);
}
.csp .factline > div:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.csp .factline .n {
  font-family: var(--serif); font-weight: 600; font-size: 2.55rem; line-height: 1;
  color: var(--head); letter-spacing: -.015em;
}
.csp .factline .n.ph { color: var(--accent); opacity: .34; letter-spacing: .04em; }
.csp .factline .l {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mut); margin-top: 9px; line-height: 1.5;
}

/* ---- results table ---- */
.csp .rtbl { width: 100%; border-collapse: collapse; margin: 0 0 8px; font-size: 1.1rem; }
.csp .rtbl th {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--head); text-align: left;
  background: rgba(21, 58, 128, .09);
  padding: 12px 14px; border: 1px solid var(--hairline);
}
.csp .rtbl td {
  padding: 12px 14px; border: 1px solid var(--hairline); color: var(--body-c);
  background: var(--surface);
}
.csp .band.tint .rtbl td { background: rgba(255, 255, 255, .6); }
.csp .tblwrap { overflow-x: auto; }

/* ---- the proof block ---- */
.csp .proof {
  display: grid; grid-template-columns: 1fr 380px; gap: 32px; align-items: start;
  border-left: 3px solid var(--accent); padding: 0 0 0 26px; margin-top: 8px;
}
.csp .proof.solo { grid-template-columns: 1fr; }
.csp .proof .who {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); margin-top: 16px; line-height: 1.7;
}

/* ---- the chapter opener, brand first ---- */
.csp .platerow { display: grid; grid-template-columns: 340px 1fr; gap: 40px; align-items: center; }
.csp .plateid .num { display: flex; align-items: center; gap: 12px; }
.csp .welltag {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: #0d3b2e; background: rgba(13, 59, 46, .1);
  border: 1px solid rgba(13, 59, 46, .25); border-radius: 3px; padding: 3px 9px;
}
.csp .brandshots { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.csp .brandshots[data-n="1"] { grid-template-columns: minmax(0, 1fr); }
.csp .brandshots[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.csp .brandshots[data-n="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Even tiles. The brand photos arrive at every shape going, so the opener
   crops them to one 4:3 height instead of stair-stepping. height stays auto
   (not 100%) since 2026-08-16, because the tiles carry their captions now and
   a stretched image would push its own caption out of the cell. */
.csp .brandshots .fig { max-width: none !important; }
.csp .brandshots .fig img {
  aspect-ratio: 4/3 !important; object-fit: cover; width: 100%; height: auto;
  background: var(--surface);
}
.csp .brandshots figcaption { font-size: 0.92rem; line-height: 1.5; }
/* A wide image (marked in data) takes the whole row at its own shape rather
   than losing most of itself to the 4:3 crop. */
.csp .brandshots .bswide { grid-column: 1 / -1; }
.csp .brandshots .bswide .fig img { aspect-ratio: auto !important; object-fit: unset; }

/* The one picture that runs the whole opener. It sits below the nameplate row
   and it is NOT part of .brandshots, so the 4:3 crop above never touches it. */
.csp .leadshot { margin-top: 34px; }
.csp .leadshot .fig { max-width: none !important; margin: 0; }
.csp .leadshot .fig img { width: 100%; height: auto; border-radius: 10px; }

/* ---- two columns, the problem against the answer ---- */
.csp .twocol { display: grid; grid-template-columns: 1fr 1fr; gap: 52px; align-items: start; }
.csp .twocol > div > p:last-child { margin-bottom: 0; }
.csp .turncol {
  background: var(--surface); border-left: 3px solid var(--accent);
  padding: 26px 30px 28px; margin-top: -4px;
}
.csp .turntext { font-size: 1.38rem; line-height: 1.5; color: var(--head); margin: 0; }

/* ---- testimonials, up front ---- */
.csp .testrow { display: grid; grid-template-columns: 1.15fr 1fr; gap: 40px; align-items: start; }
.csp .testquotes blockquote:last-child { margin-bottom: 0; }
/* The quote column runs about three times the height of the clip now that the
   Shippo quote is his full spoken answer, which left ~590px of empty column
   beside it. Same fix the bio rows use: the clip rides along instead of sitting
   in a pool of dead space. Static on a phone, where there is only one column. */
.csp .testvid { position: sticky; top: calc(var(--header-h, 72px) + 22px); }
@media (max-width: 900px) { .csp .testvid { position: static; } }

/* ---- team, alternating picture and words ---- */
/* Nothing in this section is cropped. The old cards forced a 4:3 box over
   sources running 16:9 to 9:16 and cut the people out of their own photos, so
   every picture now keeps its real shape and the column adapts instead. */
/* Was one sentence at 1.24rem. It is four paragraphs now, so it drops to a size
   that can carry that length and gets real space between paragraphs. */
.csp .teamlede { margin: 0 0 8px; }
.csp .teamlede p { font-size: 1.12rem; line-height: 1.62; color: var(--head); margin: 0 0 17px; }
.csp .teamlede p:last-child { margin-bottom: 0; }

.csp .altrow {
  display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 46px;
  align-items: start; padding: 38px 0; border-top: 1px solid var(--hairline);
}
.csp .altrow:first-of-type { border-top: 0; }
/* A tall photo beside a paragraph needs less width than a wide one, or the row
   turns into a column of picture with a caption bolted to it. */
.csp .altrow[data-shape="port"] { grid-template-columns: 0.72fr 1.28fr; }
/* order:2 moves the picture into the SECOND column, so the widths have to swap
   with it. Without this pair the flipped rows hand the wide column to the photo
   and squeeze the words into the narrow one. */
.csp .altrow.flip { grid-template-columns: 1.1fr 0.9fr; }
.csp .altrow.flip[data-shape="port"] { grid-template-columns: 1.28fr 0.72fr; }
.csp .altrow.flip .altmedia { order: 2; }

/* A bio runs several times the height of its portrait, so the picture rides
   along beside it rather than floating in the middle of a column of air. */
/* A claim is one sentence. Left at the top of a 650px tall photo it sits in a
   pool of empty column, so the claim rows centre instead and the bio rows,
   which run several screens, stay top aligned. */
.csp .altrow[data-kind="claim"] { align-items: center; }
/* And the three claim photos were escalating, 290 then 523 then 688 tall, which
   left 623px of dead column beside two lines of text on the last one. Capping
   the height keeps the three rows a set. The cap is on the picture, not a crop:
   the width follows the height so the shape is untouched. */
.csp .altrow[data-kind="claim"] .altmedia img { max-height: 420px; width: auto; max-width: 100%; }

/* The story rows centre like the claims, but the photo is the point of the row
   rather than proof bolted to a sentence, so it gets a much taller cap. 420px
   was sized for a claim photo standing next to two lines of text; these carry
   one short line, and at 420 they read as thumbnails (rules 97 and 100). */
.csp .altrow[data-kind="story"] { align-items: center; }
.csp .altrow[data-kind="story"] .altmedia { position: static; }
/* The row carries one short line, so the default 0.9/1.1 split was handing the
   wide column to three words and squeezing the photo to 411px. The picture takes
   the larger share here and the line sits beside it. Written out for all four
   shape and flip combinations because the plain port and flip rules above are
   more specific than a bare kind selector and would otherwise win. */
.csp .altrow[data-kind="story"],
.csp .altrow[data-kind="story"][data-shape="port"] { grid-template-columns: 1.32fr 0.68fr; }
.csp .altrow[data-kind="story"].flip,
.csp .altrow[data-kind="story"].flip[data-shape="port"] { grid-template-columns: 0.68fr 1.32fr; }
.csp .altrow[data-kind="story"] .altmedia img { max-height: 580px; width: auto; max-width: 100%; }
/* One short line beside a 580px picture, so it is set well above claim size or
   it reads as a caption that fell off the photo. */
.csp .tstory { font-size: 1.62rem; line-height: 1.45; color: var(--head); margin: 0; }

/* Clear of the fixed site header, which is 73px tall and covers anything that
   parks at top: 0. Only the bio rows need to ride along, a claim row is shorter
   than the viewport. */
.csp .altmedia { margin: 0; position: sticky; top: calc(var(--header-h, 72px) + 22px); }
.csp .altrow[data-kind="claim"] .altmedia { position: static; }
.csp .altmedia picture { display: block; }
/* height:auto is not optional. The img carries width/height attributes for
   layout stability, and without this the height attribute beats aspect-ratio
   and stretches the picture. */
.csp .altmedia img {
  width: 100%; height: auto; display: block;
  border-radius: 10px; background: #dfe3e9;
}
.csp .altcap { font-size: 1rem; line-height: 1.45; color: var(--mut); margin: 10px 0 0; }

.csp .altbody > p:last-child { margin-bottom: 0; }
.csp .fname { font-family: var(--serif); font-size: 2.05rem; line-height: 1.15; color: var(--head); margin: 0 0 4px; }
.csp .frole {
  font-family: var(--mono); font-size: 0.86rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 20px;
}
.csp .fquote {
  font-family: var(--serif); font-size: 1.42rem; line-height: 1.45; color: var(--head);
  border-left: 3px solid var(--accent); padding-left: 20px; margin: 0 0 22px;
}
.csp .fpara { font-size: 1.02rem; line-height: 1.62; }
.csp .ffacts {
  margin: 26px 0 22px; padding: 22px 24px; background: var(--surface);
  border: 1px solid var(--hairline); border-radius: 8px;
}
.csp .ffacts > div { display: grid; grid-template-columns: 108px 1fr; gap: 18px; padding: 9px 0; }
.csp .ffacts > div + div { border-top: 1px solid var(--hairline); }
.csp .ffacts dt {
  font-family: var(--mono); font-size: 1.12rem; font-weight: 700;
  color: var(--accent); line-height: 1.35;
}
.csp .ffacts dd { margin: 0; font-size: 0.98rem; line-height: 1.5; color: var(--body-c); }
.csp .flink { font-size: 0.98rem; margin: 0; }
.csp .tclaim { font-size: 1.32rem; line-height: 1.55; color: var(--head); margin: 0; }

/* ---- the deck you can page through ---- */
.csp .deck { margin-top: 22px; border: 1px solid var(--hairline); background: var(--surface); }
.csp .deckbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 16px; border-bottom: 1px solid var(--hairline); background: rgba(21, 58, 128, .05);
}
.csp .deckbar .dlabel {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); line-height: 1.5;
}
.csp .deckbar .dnav { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.csp .deckbar .dnav b { font-family: var(--mono); font-size: 0.9rem; color: var(--head); min-width: 44px; text-align: center; }
.csp .deckbar .dnav button {
  width: 30px; height: 30px; border: 1px solid var(--hairline); background: var(--surface);
  color: var(--accent); font-size: 1.15rem; line-height: 1; cursor: pointer; border-radius: 3px;
}
.csp .deckbar .dnav button:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.csp .deckstage { background: #0a0a0a; display: block; }
.csp .deckstage img { width: 100%; height: 100%; object-fit: contain; display: block; }
.csp .deckdots {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 12px 16px; border-top: 1px solid var(--hairline);
}
.csp .deckdots button {
  width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(21, 58, 128, .4); background: transparent;
}
.csp .deckdots button.on { background: var(--accent); border-color: var(--accent); }
.csp .deckdots a {
  margin-left: auto; font-family: var(--mono); font-size: 0.9rem; letter-spacing: .05em;
  color: var(--accent); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid rgba(21, 58, 128, .35);
}

/* ---- figures, the real thing ---- */
.csp .fig { margin: 0; min-width: 0; }
.csp .fig img { width: 100%; height: auto; display: block; border: 1px solid var(--hairline); background: var(--surface); }
.csp .fig a { display: block; }
.csp figcaption {
  font-size: 1.09rem; line-height: 1.55; color: var(--mut); margin-top: 10px;
}
.csp figcaption.playcap {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .05em;
  display: flex; align-items: flex-start; gap: 9px; color: var(--accent);
}
.csp figcaption.playcap .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; margin-top: 8px; }
.csp .fig.port { max-width: 460px; }
.csp .fig.mid { max-width: 780px; }

.csp .stext { margin: 0; }
.csp .snote {
  font-size: 1.1rem; color: var(--body-c); background: rgba(21, 58, 128, .05);
  border-left: 3px solid var(--accent); padding: 13px 18px; margin: 20px 0 0;
}
.csp .lnks { margin: 16px 0 0; display: flex; flex-direction: column; gap: 7px; }
.csp .lnks a {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .04em;
  color: var(--accent); font-weight: 600; text-decoration: none; width: fit-content;
  max-width: 100%; overflow-wrap: anywhere;
  border-bottom: 1px solid rgba(21, 58, 128, .35); padding-bottom: 2px;
}
/* A URL sitting inside one of his own sentences becomes the link, rather than
   being repeated underneath it as a second copy of the same address. */
.csp .snote a { color: var(--accent); font-weight: 600; overflow-wrap: anywhere; }
.csp .lnks a:hover { color: var(--accent-hi); border-bottom-color: var(--accent-hi); }

.csp blockquote { margin: 0 0 22px; border-left: 3px solid var(--accent); padding-left: 22px; }
.csp blockquote .q {
  font-family: var(--serif); font-size: 1.5rem; font-weight: 500; font-style: italic;
  color: var(--head); line-height: 1.45; margin: 0;
}
.csp blockquote .who {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--mut); margin: 13px 0 0;
}

/* A size up 2026-08-16, "the what happened section is a little bit
   underdramatic". The result line is the payoff, so it reads like one. */
.csp .headline {
  font-family: var(--serif); font-size: 2.5rem; font-weight: 600; color: var(--head);
  line-height: 1.25; letter-spacing: -.015em; margin: 0 0 28px; max-width: 900px;
}
/* A value now sits in an alternating row beside its photo, so it is the whole
   body of that row and the old stacking margin would push it off the picture's
   optical centre. */
.csp .valblock { margin-bottom: 0; }
.csp .valblock p:last-child { margin-bottom: 0; }
.csp #values .altrow:first-of-type { border-top: 1px solid var(--hairline); }
.csp .wallnote { font-size: 1.1rem; color: var(--body-c); margin: 30px 0 0; }
.csp .needed {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .04em; line-height: 1.7;
  color: var(--warn); background: var(--warn-bg);
  border-left: 3px solid var(--warn); padding: 12px 17px; margin: 18px 0 0;
}
.csp .caveat {
  font-size: 1.09rem; line-height: 1.65; color: var(--body-c);
  background: var(--surface); border-left: 3px solid var(--mut);
  padding: 15px 20px; margin: 30px 0 0; max-width: 860px;
}
.csp .disclosure { font-size: 1.06rem; color: var(--mut); margin-top: 22px; }
.csp .rtbl td.em { font-weight: 700; color: var(--head); }

/* The agency's mark in front of its name. The box is a fixed size whether or not
   a logo landed in it, so every agency name starts on the same left edge and the
   one agency with no logo does not pull its row out of line. */
.csp .agmark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 22px; margin-right: 11px; vertical-align: -5px;
}
.csp .agmark img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }
.csp .rtbl td.agc { white-space: nowrap; }

.csp .proofwrap { margin-top: 48px; border-top: 1px solid var(--hairline); padding-top: 34px; }
.csp .proofmedia { margin-top: 26px; max-width: 760px; }
.csp .wideshot { margin-top: 30px; }

/* ---- placeholder slots (only the one asset that does not exist yet) ---- */
.csp .slot {
  border: 1.5px dashed rgba(21, 58, 128, .42); background: rgba(21, 58, 128, .045);
  border-radius: 8px; padding: 15px 17px;
}
.csp .slot .k {
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent);
}
.csp .slot .d { font-size: 1.01rem; color: var(--mut); line-height: 1.5; margin-top: 5px; }

/* text slot: grey rules at real line length, so an empty block still takes up the
   room its copy will take up and nothing collapses to nothing */
.csp .tslot { padding: 14px 16px; }
.csp .tslot .lines { margin-top: 11px; display: flex; flex-direction: column; gap: 9px; }
.csp .tslot .lines i { display: block; height: 9px; border-radius: 2px; background: rgba(21, 58, 128, .13); }
.csp .tslot .lines i:last-child { width: 62%; }

/* media slot: solid grey box at the real aspect ratio so the page's rhythm is honest */
.csp .mslot {
  border: 1px solid rgba(10, 10, 10, .24); background: #e2e5ea; border-radius: 6px;
  border-style: solid; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; gap: 7px; padding: 18px; position: relative;
}
.csp .mslot .k { color: var(--head); }
.csp .mslot .file {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .04em; color: #fff;
  background: rgba(10, 10, 10, .62); border-radius: 99px; padding: 3px 11px;
}
.csp .mslot .kindtag {
  position: absolute; top: 10px; left: 10px;
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: #fff; background: var(--accent);
  border-radius: 3px; padding: 3px 8px;
}
.csp .mslot.miss { background: var(--warn-bg); border-color: rgba(122, 74, 18, .45); }
.csp .mslot.miss .kindtag { background: var(--warn); }
.csp .mslot.miss .k { color: var(--warn); }
/* A link has no shape to hold, so the tag sits in the row instead of floating
   over it - absolutely positioned, it landed on top of its own label. */
.csp .mslot.linkonly {
  aspect-ratio: auto !important; padding: 14px 16px; flex-direction: row;
  gap: 13px; justify-content: flex-start; align-items: center; text-align: left;
}
.csp .mslot.linkonly .kindtag { position: static; flex: 0 0 auto; }

/* a warning strip that belongs to the page, not to the design */
.csp .warn {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .04em; line-height: 1.7;
  color: var(--warn); background: var(--warn-bg);
  border-left: 3px solid var(--warn); padding: 13px 17px; margin-top: 24px;
}

/* ---- team mosaic ----
   Four of the six photos are portrait and one is a 9:16 vertical, so a uniform
   grid either crops faces or stretches one photo to 1188px tall. Columns let each
   photo keep its own shape and flow into the shortest column. */
.csp .mosaic { columns: 3; column-gap: 22px; margin-top: 34px; }
.csp .mosaic > * { break-inside: avoid; margin: 0 0 22px; width: 100%; max-width: none !important; }
.csp .mosaic figcaption { font-size: 0.92rem; line-height: 1.5; }

.csp .claims { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; margin-top: 30px; }

/* ---- logo wall ---- */
/* minmax(0,1fr), not 1fr - a grid item will not shrink below its min-content by
   default, so plain 1fr tracks blew the wall out to 366px a column and pushed
   four of the seven off the side. */
.csp .logowall {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 14px; margin: 30px 0 0;
}
.csp .logowall .lg {
  aspect-ratio: 3/2; min-width: 0; background: var(--surface); border: 1px solid var(--hairline);
  display: flex; align-items: center; justify-content: center; padding: 10px;
}
.csp .logowall .lg img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.csp .logowall .lg.hi { border-color: var(--accent); box-shadow: inset 0 0 0 2px rgba(21, 58, 128, .16); }
.csp .walknote {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .06em; color: var(--mut); margin-top: 14px;
}

/* ---- analysis cards ---- */
.csp .cards { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin-top: 30px; }
.csp .card { background: var(--surface); border: 1px solid var(--hairline); }
.csp .card .cbody { padding: 20px 22px 24px; }
.csp .card h3 { margin-bottom: 14px; }

.csp .shots { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 30px; }

/* ---- the player, unchanged, it already works ---- */
.csp .player {
  display: block; width: 100%; padding: 0; border: 1px solid var(--hairline);
  background: #000; position: relative; cursor: pointer; overflow: hidden;
}
.csp .player .box { position: relative; width: 100%; aspect-ratio: 16/9; }
.csp .player img,
.csp .player video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.csp .player img { transition: opacity .25s; }
.csp .player.on img { opacity: 0; pointer-events: none; }
.csp .player .play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.csp .player .play i {
  width: 74px; height: 74px; border-radius: 50%; background: rgba(255, 255, 255, .93);
  color: var(--accent); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 26px rgba(0, 0, 0, .38); transition: background .2s, color .2s;
}
.csp .player:hover .play i { background: var(--accent); color: #fff; }
.csp .clipcap {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .08em; color: var(--mut);
  margin: 11px 0 0; display: flex; align-items: center; gap: 9px;
}
.csp .clipcap .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; }

/* ---- close ---- */
.csp .closing { background: var(--surface); border-top: 2px solid var(--head); padding: 56px 0 62px; }
.csp .cta {
  display: inline-block; margin-top: 14px; background: var(--accent); color: #fff;
  font-family: var(--sans); font-size: 1.05rem; font-weight: 700;
  padding: 17px 34px; text-decoration: none;
}
.csp .cta:hover { background: var(--accent-hi); }
.csp .srcnote {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .05em; color: var(--mut);
  margin: 0; padding: 26px 0 74px; line-height: 1.8;
}

@media (max-width: 900px) {
  .csp { font-size: 17px; }
  .csp h1 { font-size: 2.7rem; }
  .csp h2 { font-size: 2.05rem; }
  .csp .plate .bname { font-size: 2.5rem; }
  .csp .blogo { max-height: min(calc(var(--lgn, 34) * 1px), 34px); margin-right: 12px; }
  .csp .band.turn .measure { font-size: 1.12rem; }
  .csp .proof { grid-template-columns: 1fr; }
  .csp .claims, .csp .cards, .csp .shots { grid-template-columns: 1fr; }
  .csp .platerow { grid-template-columns: 1fr; gap: 26px; }
  .csp .twocol { grid-template-columns: 1fr; gap: 30px; }
  .csp .testrow { grid-template-columns: 1fr; gap: 28px; }
  /* Rows stack with the picture on top, whichever side it was on, and the
     picture stops riding along because there is no column to ride in. */
  .csp .altrow,
  .csp .altrow[data-shape="port"],
  .csp .altrow.flip,
  .csp .altrow.flip[data-shape="port"] { grid-template-columns: 1fr; gap: 22px; padding: 28px 0; }
  .csp .altmedia { position: static; }
  .csp .altrow.flip .altmedia { order: 0; }
  /* Every photo runs the full column on a phone. Capping only the portrait ones
     stepped their left and right edges in and out against the landscape row and
     the wall tiles. */
  .csp .altrow[data-kind="claim"] .altmedia img { max-height: none; width: 100%; }
  /* The story ratios above are written with enough specificity to beat the plain
     port and flip rules, which means they also beat the single-column rule at the
     top of this block. Without repeating them here the strip stays two columns on
     a phone and the pictures come out 135px wide. */
  .csp .altrow[data-kind="story"],
  .csp .altrow[data-kind="story"][data-shape="port"],
  .csp .altrow[data-kind="story"].flip,
  .csp .altrow[data-kind="story"].flip[data-shape="port"] {
    grid-template-columns: 1fr; gap: 22px; padding: 28px 0;
  }
  .csp .altrow[data-kind="story"] .altmedia img { max-height: none; width: 100%; }
  .csp .tstory { font-size: 1.3rem; }
  .csp .fname { font-size: 1.75rem; }
  .csp .fquote { font-size: 1.2rem; }
  .csp .tclaim { font-size: 1.14rem; }
  .csp .ffacts { padding: 18px; }
  .csp .ffacts > div { grid-template-columns: 84px 1fr; gap: 14px; }
  .csp .brandshots[data-n="3"], .csp .brandshots[data-n="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .csp .turntext { font-size: 1.08rem; }
  .csp .deckbar { flex-wrap: wrap; }
  .csp .mosaic { columns: 2; }
  .csp .logowall { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .csp .fig.port, .csp .fig.mid { max-width: 100%; }
  .csp .headline { font-size: 1.55rem; }
  .csp .step { grid-template-columns: 38px 1fr; gap: 4px 12px; }
  .csp .stepmedia > * { flex: 1 1 100%; }
  .csp .factline > div {
    flex: 1 1 45%; border-right: 0; padding-right: 0; margin-right: 0;
    border-top: 1px solid var(--hairline);
  }
}


/* ---- bigger and friendlier ---- */
.csp .fig img,
.csp .deck,
.csp .card,
.csp .turncol,
.csp .snote,
.csp .caveat { border-radius: 10px; }
.csp .brandshots .fig img { border-radius: 10px; }
.csp .tblwrap { border-radius: 10px; overflow: hidden; border: 1px solid var(--hairline); }
.csp .rtbl th, .csp .rtbl td { border: 0; border-bottom: 1px solid var(--hairline); border-right: 1px solid var(--hairline); }
.csp .rtbl th:last-child, .csp .rtbl td:last-child { border-right: 0; }
.csp .rtbl tr:last-child td { border-bottom: 0; }

/* a link in a results table is a creator you can go and watch */
.csp .rtbl td a { color: var(--accent); font-weight: 700; text-decoration: none; border-bottom: 1px solid rgba(21,58,128,.3); }
.csp .rtbl td a:hover { color: var(--accent-hi); border-bottom-color: var(--accent-hi); }

/* the brand's own site, straight off the nameplate */
.csp .sitelink {
  display: inline-block; margin-top: 16px;
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .08em;
  color: var(--accent); text-decoration: none;
  border: 1px solid rgba(21,58,128,.3); border-radius: 99px; padding: 8px 16px;
}
.csp .sitelink:hover { background: var(--accent); color: #fff; border-color: var(--accent); }

/* the analysis cards are one big link now */
.csp a.card { display: block; text-decoration: none; color: inherit; transition: transform .18s, box-shadow .18s; }
.csp a.card:hover { transform: translateY(-3px); box-shadow: 0 10px 30px rgba(10,10,10,.12); }
.csp a.card img { width: 100%; height: auto; display: block; border-radius: 10px 10px 0 0; }
.csp .cgo {
  display: inline-block; margin-top: 14px;
  font-family: var(--mono); font-size: 0.9rem; font-weight: 700; letter-spacing: .08em;
  color: var(--accent);
}
.csp a.card:hover .cgo { color: var(--accent-hi); }

/* pictures lift a little when you point at them, so it is obvious they open */
.csp .fig a { display: block; transition: transform .18s; }
.csp .fig a:hover { transform: translateY(-2px); }
.csp .player .play i { width: 88px; height: 88px; }


/* A deck slide is 185px tall on a phone, which is unreadable, so the slide is
   a link to the full-size image and says so (rule 97, nothing small ever). */
.csp .deckstage a { display: block; width: 100%; height: 100%; }
.csp .deckhint {
  font-family: var(--mono); font-size: 0.9rem; letter-spacing: .05em; color: var(--mut);
}
@media (max-width: 900px) {
  .csp .factline .n { font-size: 2rem; }
  .csp .sub { font-size: 1.18rem; }
  .csp .outcomes li { font-size: 1.18rem; padding-left: 22px; }
  .csp .outcomes li::before { width: 11px; }
  .csp .step .sn { font-size: 1.25rem; }
}


/* ---- the credibility wall ---- */
/* Same two people, as many different rooms as we can show: podcasts, meetings,
   stages, events.

   It used to be a grid with every tile cut to 4:3, which suited the seven
   landscape frames and ruined the five portrait ones. w11 showed 18 per cent of
   itself and cut his head off. Columns instead of a grid, so each tile keeps its
   own height and no picture is cropped at all. */
/* Three columns, not four. At four the landscape tiles came out 144px tall,
   which is too small to read a room off (rule 97). */
.csp .wall { columns: 3; column-gap: 18px; margin-top: 34px; }
.csp .wtile { break-inside: avoid; margin: 0 0 20px; }
.csp .wtile picture { display: block; }
/* height:auto or the height attribute on the img wins and it stretches. */
.csp .wtile img {
  width: 100%; height: auto; display: block;
  border-radius: 8px; background: #dfe3e9;
}
.csp .wtile figcaption {
  font-size: 1rem; line-height: 1.5; color: var(--mut); margin-top: 9px;
}
/* Body size, not caption size. At 0.92rem and muted it read as one more tile
   caption stranded in the short column rather than as the line that closes the
   section. */
.csp .wallcap { font-size: 1.06rem; line-height: 1.55; color: var(--body-c); margin-top: 18px; max-width: 800px; }
@media (max-width: 900px) { .csp .wall { columns: 2; } }
@media (max-width: 560px) { .csp .wall { columns: 1; } }


/* ---- one colour per campaign ---- */
/* Scrolling should tell you which campaign you are in without re-reading the
   name. Every chapter sets --ch and --ch-wash, and the bands, labels, numbers
   and rules pick them up. Falls back to the house accent outside a chapter. */
.csp { --ch: var(--accent); --ch-wash: var(--tint); }
.csp .chapter { border-top: 0; }
.csp .plate { border-top: 5px solid var(--ch); }
.csp .plate .num,
.csp .blabel,
.csp .step .sn,
.csp .cgo { color: var(--ch); }
.csp .band.tint { background: var(--ch-wash); }
.csp .turncol { border-left-color: var(--ch); }
.csp .proofwrap { border-top-color: var(--ch); }
.csp .sitelink { color: var(--ch); border-color: var(--ch); }
.csp .sitelink:hover { background: var(--ch); color: #fff; }
.csp .rtbl th { background: var(--ch-wash); }
.csp .snote { border-left-color: var(--ch); background: var(--ch-wash); }
.csp blockquote { border-left-color: var(--ch); }
.csp .factline { border-top-color: var(--ch); }

/* corners actually clip now, instead of the child squaring off the parent */
.csp .deck, .csp a.card { overflow: hidden; }
.csp .deckstage { border-radius: 0; }


/* ---- 2026-08-16 pass 2: the payoff band, section CTAs, partner wall ---- */

/* The [ What happened ] label renders as a filled chip in the campaign's own
   ink, so the payoff band is unmistakable while every other label stays quiet. */
.csp .blabel.big {
  display: inline-flex; font-size: 1rem; letter-spacing: .2em;
  color: #fff; background: var(--ch, var(--accent));
  padding: 9px 18px 8px; border-radius: 6px; margin-bottom: 28px;
}
.csp .blabel.big::after { display: none; }

/* Chapters that end in prose rather than a stat row get the same drama: the
   first outcome line reads at headline weight. */
.csp .measure.outcome p:first-child {
  font-family: var(--serif); font-size: 1.5rem; font-weight: 600;
  line-height: 1.4; color: var(--head); letter-spacing: -.01em;
}

/* One line and one button after each major section. */
.csp .ctarow { background: var(--surface); border-top: 1px solid var(--hairline); padding: 42px 0 48px; }
.csp .ctarow .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px 40px; flex-wrap: wrap;
}
.csp .ctaline {
  font-family: var(--serif); font-size: 1.75rem; font-weight: 500; color: var(--head);
  line-height: 1.3; letter-spacing: -.012em; margin: 0;
}
.csp .ctarow .cta { margin-top: 0; }

/* The partner wall: four marks with their names underneath. */
.csp .logowall.partners { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }
.csp .logowall.partners .lg { flex-direction: column; gap: 12px; aspect-ratio: auto; padding: 26px 14px 18px; }
.csp .lgname {
  font-family: var(--mono); font-size: 0.92rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--body-c); margin: 0; text-align: center;
}
@media (max-width: 900px) {
  .csp .logowall.partners { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .csp .ctaline { font-size: 1.3rem; }
  .csp .headline { font-size: 1.8rem; }
  .csp .measure.outcome p:first-child { font-size: 1.24rem; }
}

/* ---- 2026-08-16 pass: homepage-style accents + the showcase ---- */

/* **word** in the copy renders as this: the homepage's own emphasis pattern,
   key words set off in the accent ink. Inside a chapter it takes the
   campaign's own colour, on the cover it takes the house accent. */
.csp .acc { font-weight: 700; color: var(--ch, var(--accent)); }
.csp h1 .acc { font-weight: 600; }

/* The finished reads, straight under the nameplate, before the story. */
.csp .showcase { margin-top: 34px; }
.csp .showcase .blabel { margin-bottom: 16px; }
.csp .scrow { display: grid; gap: 20px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.csp .scrow[data-n="1"] { grid-template-columns: minmax(0, 1fr); }
.csp .scrow[data-n="1"] .fig { max-width: 820px !important; }
.csp .scrow .fig { max-width: none; }
@media (max-width: 900px) {
  .csp .scrow { grid-template-columns: minmax(0, 1fr); }
}

/* ══════════════════════════════════════════════════════════════════════════
   Local fixes. Everything above this line is a verbatim copy, so anything that
   has to change lives down here where a future re-sync will not lose it.
   ══════════════════════════════════════════════════════════════════════════ */

/* csx.css sets `.tblwrap { overflow-x: auto }` at line 291 and then
   `overflow: hidden` at line 761, and the later rule wins, so the results table
   is CLIPPED on a phone rather than scrollable: at a 400px viewport the table
   measures 523px and the last column is simply gone. `auto` still clips to the
   border radius, so this keeps the rounded corners and gives the columns back.
   The agency's own /info has the same bug, it is not something this port
   introduced. */
.csp .tblwrap { overflow: auto; }

/* ── creator icons and real sponsor reads ─────────────────────────────────────
   Dennis, 2026-08-21: "instead of the photos, actual influencer icons, and the
   same goes with Doola." A chapter about creators opens on the creators.

   The avatar is a fixed 92px circle rather than a fraction of the column, so a
   row of five and a row of eight read at the same size and nothing shrinks to
   the point where you cannot tell who it is (rule 97). The row wraps instead of
   scrolling sideways, because a horizontal scroller hides whoever is off the
   right edge and the whole point is how many there are. */
.csp .people { margin-top: 34px; }
.csp .people .blabel { margin-bottom: 12px; }
.csp .peopleintro { margin: 0 0 18px; max-width: 62ch; color: var(--mut); font-size: 15px; line-height: 1.6; }
.csp .prow { display: flex; flex-wrap: wrap; gap: 26px 30px; }
.csp .pcard {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  width: 118px; text-decoration: none; color: inherit;
}
.csp .pav {
  width: 92px; height: 92px; border-radius: 50%; object-fit: cover; display: block;
  border: 1px solid var(--hairline); background: var(--surface);
}
.csp a.pcard:hover .pav { border-color: var(--ch, var(--accent)); }
.csp .pname {
  margin-top: 10px; font-family: var(--sans); font-size: 13px; font-weight: 600;
  line-height: 1.3; color: var(--head);
}
.csp a.pcard:hover .pname { color: var(--ch, var(--accent)); }
.csp .psub {
  margin-top: 3px; font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--mut); line-height: 1.35;
}

/* The real reads. Same grid as .scrow so the row lines up with the video rows
   in the other chapters, and the creator's name sits above the title because
   who said it is the thing a prospect is scanning for. */
.csp .promos { margin-top: 34px; }
.csp .promos .blabel { margin-bottom: 12px; }
.csp .promorow { display: grid; gap: 22px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.csp .promo { display: block; text-decoration: none; color: inherit; }
.csp .promo img {
  width: 100%; height: auto; display: block; aspect-ratio: 16/9; object-fit: cover;
  border: 1px solid var(--hairline); background: var(--surface);
}
.csp .promo:hover img { border-color: var(--ch, var(--accent)); }
.csp .pwho {
  display: block; margin-top: 10px; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ch, var(--accent));
}
.csp .ptitle {
  display: block; margin-top: 4px; font-family: var(--sans); font-size: 14px;
  line-height: 1.45; color: var(--head);
}
.csp .promo:hover .ptitle { text-decoration: underline; }
@media (max-width: 900px) {
  .csp .promorow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .csp .prow { gap: 20px 18px; }
  .csp .pcard { width: 96px; }
  .csp .pav { width: 78px; height: 78px; }
}
@media (max-width: 560px) {
  .csp .promorow { grid-template-columns: minmax(0, 1fr); }
}
