/* ==========================================================================
   gregwitz.com — "Broadsheet"
   An editorial system, not a landing-page template.

   Reference points: Adam Grant's masthead + photo mosaic, Brené Brown's
   kicker/serif/image unit, Esther Perel's full-bleed stage photography,
   Mark Manson's refusal to use default white. Explicitly NOT: card grids,
   stat boxes, countdown timers, pill CTAs, alternating gradient bands.

   Rules this system holds to:
   - Hairline rules do the dividing. Boxes and drop shadows do not exist.
   - Numerals are ornament: oversized, outlined, hanging in the margin.
   - The grid is asymmetric. Content rarely starts at column 1.
   - Warm neutrals only. No neutral grey, no pure black, no pure white.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,300..900&display=swap');

/* ---------- tokens ---------- */
:root {
  /* Warm neutrals. Every "black" is brown-shifted, every "white" is bone.
     This is the single biggest reason the page does not read as default. */
  --ink:        #14120F;
  --ink-deep:   #0B0A08;
  --ink-raise:  #1D1A16;
  --bone:       #F2EDE4;
  --bone-deep:  #E6DED1;
  --bone-pure:  #FAF7F1;

  --accent:        #6C4D9E;   /* Witz brand purple — CTA band, rules */
  --accent-ink:    #54397D;   /* on bone; 8.0:1 / 7.0:1 on bone-deep */
  --accent-bright: #9B80D0;   /* on ink; 5.7:1, and 5.7:1 for ink text on it */

  --on-dark:        #F2EDE4;
  --on-dark-muted:  rgba(242, 237, 228, 0.66);
  --on-dark-faint:  rgba(242, 237, 228, 0.56);
  --on-light:       #14120F;
  --on-light-muted: #5A5148;

  --accent-deep:   #3C2A5C;   /* plum ground; bone on it is 10.6:1 */

  /* Hairlines carry the brand. The rules are the most repeated element on the
     site — masthead, cards, index lists, dossier, footer, fields — so tinting
     them violet puts purple on every screen without putting it on any text.
     Colour on kickers and links is what got the two previous palettes killed. */
  --hair-dark:  rgba(176, 152, 220, 0.26);
  --hair-light: rgba(84, 57, 125, 0.24);

  /* The Witz Education house system, matched to the live site: Fraunces for
     headings, Helvetica Neue for everything else. There is no mono in the
     house system — small labels are Helvetica, uppercase and tracked out,
     which is exactly how witzeducation.com sets its kickers. */
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body:    'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-label:   'Helvetica Neue', Helvetica, Arial, sans-serif;

  --s1:.25rem; --s2:.5rem; --s3:.75rem; --s4:1rem; --s5:1.5rem; --s6:2rem;
  --s7:2.5rem; --s8:3rem; --s9:4rem; --s10:5rem; --s11:6rem; --s12:8rem;

  --wrap: 1320px;
  --wrap-narrow: 680px;
  --gutter: clamp(1.25rem, 4.5vw, 3.5rem);
  --section-y: clamp(4.5rem, 10vw, 9rem);

  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 220ms;
  --z-nav: 100;
}

/* ---------- reset ---------- */
*,*::before,*::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 7rem; }
body {
  font-family: var(--font-body);
  font-size: 1.0625rem; line-height: 1.68; font-weight: 400;
  color: var(--on-dark); background: var(--ink);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img,svg,video,iframe { display: block; max-width: 100%; }
img { height: auto; }
button,input,textarea,select { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* ---------- a11y ---------- */
.skip-link {
  position: absolute; left: var(--s4); top: -100%; z-index: 999;
  background: var(--accent-bright); color: #14120F;
  padding: var(--s3) var(--s5); font-weight: 600;
  transition: top var(--dur) var(--ease-out);
}
.skip-link:focus { top: var(--s4); }
:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 4px; }
::selection { background: var(--accent); color: #FFF; }
.visually-hidden {
  position:absolute; width:1px; height:1px; padding:0; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,*::before,*::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .js .reveal { opacity:1 !important; transform:none !important; }
}

/* ---------- surfaces ---------- */
/* Film grain. Kills the flat-vector "AI gradient" feel on dark sections. */
.on-ink, .on-ink-deep { position: relative; }
.on-ink::before, .on-ink-deep::before {
  content:''; position:absolute; inset:0; pointer-events:none; opacity:.20;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
.on-ink > *, .on-ink-deep > * { position: relative; z-index: 1; }

.on-ink      { background: var(--ink);      color: var(--on-dark); }
.on-ink-deep { background: var(--ink-deep); color: var(--on-dark); }
.on-paper    { background: var(--bone);      color: var(--on-light); }
.on-paper-warm { background: var(--bone-deep); color: var(--on-light); }
/* Plum. A third ground, not a second CTA band — reserved for one statement per
   page, so it stays an event rather than a stripe. --accent-bright fails AA as
   text on it, so anything on this ground is bone. */
.on-accent { background: var(--accent-deep); color: var(--on-dark); }
.on-accent .kicker,.on-accent .eyebrow { color:rgba(242,237,228,.72); }
.on-accent .kicker::before,.on-accent .eyebrow::before { background:rgba(242,237,228,.62); }
.on-accent .pullquote::before,.on-accent .pullquote cite { color:rgba(242,237,228,.62); }
.on-accent .lead,.on-accent p { color:rgba(242,237,228,.86); }
.on-accent .btn--primary { background:var(--bone); border-color:var(--bone); color:#14120F; }
.on-accent .btn--ghost { color:var(--bone); border-color:rgba(242,237,228,.45); }
.on-accent .btn--ghost:hover { border-color:var(--bone); }

/* ---------- layout ---------- */
.wrap { width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--gutter); }
.wrap--narrow { max-width: var(--wrap-narrow); }
.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }

/* asymmetric 12-col grid */
.g12 { display:grid; grid-template-columns:repeat(12,1fr); gap:var(--s6) clamp(1rem,2.5vw,2.5rem); }
@media (max-width: 860px) { .g12 { grid-template-columns:1fr; } .g12 > * { grid-column:1/-1 !important; } }

/* ---------- type ---------- */
h1,h2,h3,h4 { font-family:var(--font-display); font-weight:700; line-height:1.02; letter-spacing:-0.022em; text-wrap:balance; }
.display-xl {
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(2rem, 6.1vw, 5.75rem);
  line-height:.86; letter-spacing:-0.048em;
  font-optical-sizing:auto;   /* Fraunces opsz -> display cut at hero sizes */
}
.display-l  { font-family:var(--font-display); font-size:clamp(2.25rem, 5.6vw, 4.5rem); line-height:.98; letter-spacing:-0.028em; }
.display-m  { font-family:var(--font-display); font-size:clamp(1.75rem, 3.6vw, 2.875rem); line-height:1.05; }
.display-s  { font-family:var(--font-display); font-size:clamp(1.3rem, 2.2vw, 1.625rem); line-height:1.18; }
/* Italic Bodoni inside a headline — editorial texture, not decoration. */
.ital { font-style: italic; font-weight: inherit; }

.kicker {
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.24em; color:var(--on-dark-faint);
  display:flex; align-items:center; gap:.7rem; flex-wrap:wrap;
  margin-bottom:var(--s5);
}
/* A purple tick, not purple text. Every section on the site opens with a
   kicker, so this is the highest-frequency place the brand colour can appear —
   and it stays off the words, which is the line Greg drew. */
.kicker::before {
  content:''; flex:0 0 auto; width:1.75rem; height:2px;
  background:var(--accent-bright);
}
.on-paper .kicker, .on-paper-warm .kicker { color:var(--on-light-muted); }
.kicker--quiet { color:var(--on-dark-faint); }
.on-paper .kicker--quiet { color:var(--on-light-muted); }
.eyebrow { /* legacy alias */ composes: kicker; }
.eyebrow {
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.24em; color:var(--on-dark-faint);
  display:flex; align-items:center; gap:.7rem; flex-wrap:wrap;
  margin-bottom:var(--s5);
}
.eyebrow::before {
  content:''; flex:0 0 auto; width:1.75rem; height:2px;
  background:var(--accent-bright);
}
.on-paper .kicker::before,.on-paper-warm .kicker::before,
.on-paper .eyebrow::before,.on-paper-warm .eyebrow::before { background:var(--accent-ink); }
.center .kicker,.center .eyebrow { justify-content:center; }
.on-paper .eyebrow, .on-paper-warm .eyebrow { color:var(--on-light-muted); }

.lead { font-size:clamp(1.125rem,1.7vw,1.3125rem); line-height:1.58; color:var(--on-dark-muted); max-width:54ch; }
.on-paper .lead, .on-paper-warm .lead { color:var(--on-light-muted); }
.muted { color:var(--on-dark-muted); }
.on-paper .muted, .on-paper-warm .muted { color:var(--on-light-muted); }

.prose { max-width:64ch; }
.prose p + p { margin-top:var(--s5); }
.prose h2 { margin-top:var(--s9); margin-bottom:var(--s4); }
.prose h3 { margin-top:var(--s7); margin-bottom:var(--s3); font-size:1.375rem; }
.prose ul,.prose ol { margin-top:var(--s4); padding-left:var(--s5); }
.prose li + li { margin-top:var(--s2); }
.prose a { color:inherit; text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px; }
.on-paper .prose a { color:inherit; }

.rule { height:1px; background:var(--hair-dark); border:0; }
.on-paper .rule,.on-paper-warm .rule { background:var(--hair-light); }

/* ---------- actions: mono, squared, pressed — not SaaS pills ---------- */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s3);
  min-height:52px; padding:var(--s3) var(--s6);
  font-family:var(--font-label); font-size:.75rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.16em;
  border:1px solid transparent; border-radius:0; cursor:pointer; text-align:center;
  transition:background-color var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease-out),
             color var(--dur) var(--ease-out);
}
.btn--primary { background:var(--accent-bright); color:#14120F; border-color:var(--accent-bright); }
.btn--primary:hover { background:#AE96DC; border-color:#AE96DC; }
.on-paper .btn--primary,.on-paper-warm .btn--primary { background:var(--accent-ink); border-color:var(--accent-ink); color:#FFF; }
.on-paper .btn--primary:hover,.on-paper-warm .btn--primary:hover { background:#432E63; border-color:#432E63; }
.btn--ghost { background:transparent; color:var(--on-dark); border-color:var(--hair-dark); }
.btn--ghost:hover { border-color:var(--on-dark); }
.on-paper .btn--ghost,.on-paper-warm .btn--ghost { color:var(--on-light); border-color:var(--hair-light); }
.on-paper .btn--ghost:hover,.on-paper-warm .btn--ghost:hover { border-color:var(--on-light); }
/* Purple secondary. Same accent as .btn--primary but outlined, so a row can
   read as all-one-colour without three solid fills fighting for primacy.
   #9B80D0 on ink is 5.7:1, so the text and the border both clear AA. */
.btn--ghost-accent { background:transparent; color:var(--accent-bright); border-color:var(--accent-bright); }
.btn--ghost-accent:hover { background:var(--accent-bright); color:#14120F; }
.on-paper .btn--ghost-accent,.on-paper-warm .btn--ghost-accent { color:var(--accent-ink); border-color:var(--accent-ink); }
.on-paper .btn--ghost-accent:hover,.on-paper-warm .btn--ghost-accent:hover { background:var(--accent-ink); color:#FFF; }

.btn[disabled],.btn[aria-disabled="true"] { opacity:.45; cursor:not-allowed; }
.btn-row { display:flex; flex-wrap:wrap; gap:var(--s4); margin-top:var(--s7); }

/* the quieter, more common action: a ruled text link */
.link-arrow {
  display:inline-flex; align-items:center; gap:var(--s3); min-height:44px;
  font-family:var(--font-label); font-size:.75rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.14em;
  color:var(--on-dark); border-bottom:1px solid currentColor; align-self:flex-start;
}
.on-paper .link-arrow,.on-paper-warm .link-arrow { color:var(--on-light); }
.link-arrow svg { transition:transform var(--dur) var(--ease-out); flex:none; }
.link-arrow:hover svg { transform:translateX(4px); }

/* ==========================================================================
   MASTHEAD — two hairline rows. A newspaper masthead, not a product navbar.
   ========================================================================== */
.masthead { position:fixed; inset:0 0 auto 0; z-index:var(--z-nav); transition:background-color var(--dur) var(--ease-out); }
.masthead.is-stuck { background:rgba(11,10,8,.94); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); }

/* row 1 — utility strip */
.mast-utility { border-bottom:1px solid var(--hair-dark); }
.mast-utility .wrap {
  display:flex; align-items:center; justify-content:space-between; gap:var(--s5);
  min-height:44px;
  font-family:var(--font-label); font-size:.625rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.2em;
}
.mast-utility p { color:var(--on-dark-faint); }
.mast-utility a { color:var(--accent-bright); display:inline-flex; align-items:center; gap:var(--s2); min-height:44px; }
.mast-utility a:hover { color:#AE96DC; }

/* row 2 — masthead proper: split nav around a centred wordmark */
.mast-main { border-bottom:1px solid var(--hair-dark); }
.mast-main .wrap {
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:var(--s5);
  min-height:70px;
}
.wordmark {
  grid-column:2; justify-self:center;
  font-family:var(--font-display); font-weight:700; font-size:1.375rem;
  letter-spacing:-0.02em; color:var(--on-dark);
  display:inline-flex; align-items:center; min-height:44px; white-space:nowrap;
}
.wordmark span { color:var(--accent-bright); }
.nav-group { display:flex; align-items:center; gap:clamp(.75rem,2vw,2rem); }
.nav-group--l { grid-column:1; justify-content:flex-start; }
.nav-group--r { grid-column:3; justify-content:flex-end; }
.nav-group a {
  display:inline-flex; align-items:center; min-height:44px;
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.16em;
  color:var(--on-dark-muted); border-bottom:1px solid transparent;
  transition:color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
  white-space:nowrap;
}
.nav-group a:hover { color:var(--on-dark); }
.nav-group a[aria-current="page"] { color:var(--on-dark); border-bottom-color:var(--accent-bright); }

.nav-toggle {
  display:none; grid-column:3; justify-self:end;
  width:48px; height:48px; align-items:center; justify-content:center;
  background:transparent; border:1px solid var(--hair-dark); border-radius:0;
  cursor:pointer; color:var(--on-dark);
}

@media (max-width: 1000px) {
  .mast-main .wrap { grid-template-columns:1fr auto; }
  .wordmark { grid-column:1; justify-self:start; }
  .nav-toggle { display:inline-flex; grid-column:2; }
  .nav-group--l { display:none; }
  .nav-group--r {
    position:fixed; inset:114px 0 auto 0; grid-column:1/-1;
    flex-direction:column; align-items:stretch; gap:0;
    background:var(--ink-deep); border-bottom:1px solid var(--hair-dark);
    padding:var(--s4) var(--gutter) var(--s7);
    max-height:calc(100dvh - 114px); overflow-y:auto;
    transform:translateY(-8px); opacity:0; pointer-events:none;
    transition:opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
  }
  .nav-group--r[data-open="true"] { transform:translateY(0); opacity:1; pointer-events:auto; }
  .nav-group--r a { min-height:56px; font-size:.8125rem; border-bottom:1px solid var(--hair-dark); }
  .nav-group--r .m-only { display:inline-flex; }
  .mast-utility p { display:none; }
  .mast-utility .wrap { justify-content:flex-end; }
}
@media (min-width: 1001px) { .m-only { display:none !important; } }

/* ==========================================================================
   HERO — full-bleed photography, headline overlapping at editorial scale
   ========================================================================== */
.hero { position:relative; display:flex; align-items:flex-end; min-height:min(94dvh, 860px); padding-top:180px; padding-bottom:0; background:var(--ink-deep); overflow:hidden; }
.hero__media {
  /* -3% bleed so the drift never exposes an edge */
  position:absolute; inset:-3%; background-repeat:no-repeat;
  background-size:cover; background-position:72% 26%;
  background-image:url('../images/hero-stage.jpg');            /* fallback */
  background-image:image-set(
    url('../images/hero-stage.webp') type('image/webp'),
    url('../images/hero-stage.jpg')  type('image/jpeg'));
  transform:scale(1.02);
  animation:heroDrift 32s ease-in-out infinite alternate;
  will-change:transform;
}
/* One slow push-in. Transform only, so it never triggers layout, and it is the
   single animated element in the view. */
@keyframes heroDrift {
  from { transform:scale(1.02) translate3d(0, 0, 0); }
  to   { transform:scale(1.09) translate3d(-1.2%, -0.8%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__media { animation:none; transform:scale(1.02); }
}
/* With a cut montage the slow drift fights the edit — a hard cut should reset
   the camera, not continue a push-in across it. Drift is for the still hero.

   background-position must also go back to centre. The poster is frame 1 of
   the clip, but the still hero crops it at 72%/26% while a video with
   object-fit:cover crops at 50%/50% — so the identical image visibly JUMPS at
   the moment the video takes over. Same pixels, different crop, same pop. */
.hero--video .hero__media { animation:none; transform:none; inset:0; background-position:center; }

/* grain over the photo too, so image and page share one surface */
/* Scrim + grain on one static layer. It must NOT move with the image, or the
   headline's contrast floor would drift with the animation. */
.hero__grain {
  position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(to top, rgba(11,10,8,.86) 0%, rgba(11,10,8,.78) 38%, rgba(11,10,8,.50) 74%, rgba(11,10,8,.68) 100%),
    linear-gradient(to right, rgba(29,18,48,.88) 0%, rgba(24,16,40,.80) 34%, rgba(16,11,26,.52) 64%, rgba(11,10,8,.26) 100%);
}
.hero__grain::after {
  content:''; position:absolute; inset:0; opacity:.22;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
.hero__inner { position:relative; width:100%; z-index:2; }
/* Mobile: STACK, do not overlay. A portrait viewport cannot give a headline
   both a legible scrim and a readable photo — so the photo becomes a band and
   the type sits on solid ink underneath it. */
@media (max-width: 860px) {
  .hero { display:block; min-height:auto; padding-top:108px; padding-bottom:0; }
  .hero__media {
    position:relative; inset:auto; width:100%;
    height:min(46vh, 360px); background-position:68% 18%;
  }
  .hero__media::after {
    background:linear-gradient(to bottom,
      rgba(11,10,8,.30) 0%, rgba(11,10,8,.10) 40%, rgba(11,10,8,.92) 88%, rgba(11,10,8,1) 100%);
  }
  .hero__content { max-width:100%; padding-top:var(--s6); padding-bottom:var(--s7); }
  .hero .lead { max-width:100%; }
  .hero__cta { gap:var(--s5); }
  .hero__cta .btn { width:100%; }
}
.hero__content { max-width:min(54rem, 62%); padding-bottom:var(--s8); }
.hero .display-xl { margin-bottom:var(--s6); }
.hero .lead { max-width:34rem; }
.hero__cta { margin-top:var(--s7); display:flex; flex-wrap:wrap; gap:var(--s6); align-items:center; }

/* ---------- credit line: the logo belt as a broadsheet caption ---------- */
.credits { border-top:1px solid var(--hair-dark); padding-block:var(--s5) var(--s6); }
.credits__label {
  font-family:var(--font-label); font-size:.625rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.24em; color:var(--on-dark-faint);
  margin-bottom:var(--s4);
}
.credits__list { display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--s3) clamp(1.1rem,2.6vw,2.25rem); list-style:none; padding:0; margin:0; }
.credits__list li {
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(.9375rem,1.5vw,1.25rem); letter-spacing:.01em;
  color:var(--on-dark); opacity:.88;
}
.on-paper .credits { border-top-color:var(--hair-light); }
.on-paper .credits__label { color:var(--on-light-muted); }
.on-paper .credits__list li { color:var(--on-light); opacity:.86; }

/* Real client logos, rendered as one flat tone. Sizes come from width/height
   attributes (intrinsic/3) so each mark keeps its own optical weight instead
   of every logo being clamped to the same height. */
/* baseline alignment is right for the typographic credit line but wrong for
   images — logos should sit on a common optical centre, not a baseline. */
.credits__list--logos { gap:var(--s5) clamp(1.5rem,3vw,2.75rem); align-items:center; }
/* Forced row break. Only above the width where the belt would otherwise fit
   nine across — below that it wraps on its own and a forced break would just
   strand items. */
.credits__break { display:none; }
@media (min-width:1000px) {
  .credits__break { display:block; flex-basis:100%; height:0; margin:0; padding:0; }
}

/* Centred variant — used under the homepage hero. Centring only the logo row
   and leaving the label ranged left reads as a mistake, so the whole block
   centres together. */
.credits__also {
  margin-top:var(--s5); max-width:62ch;
  font-size:.875rem; line-height:1.7; color:var(--on-dark-muted);
}
.on-paper .credits__also { color:var(--on-light-muted); }
.credits--center .credits__also { margin-inline:auto; }
.credits--center { text-align:center; }
.credits--center .credits__list { justify-content:center; }
.credits--center .credits__list--logos img { transform-origin:center; }
.credits__list--logos li { display:flex; align-items:center; }
.credits__list--logos img {
  height:auto; max-width:100%; opacity:.72;
  transition:opacity var(--dur) var(--ease-out);
}
.credits__list--logos img:hover { opacity:1; }
@media (max-width:640px) { .credits__list--logos img { transform:scale(.86); transform-origin:left center; } }

/* ==========================================================================
   PAGE HEAD (interior)
   ========================================================================== */
/* Image variant. /speaking carries the still that the homepage gave up when
   its hero became video — same photograph, tighter framing, no motion. */
.page-head--image { border-bottom:0; }
.page-head--image .page-head__media {
  position:absolute; inset:0; z-index:0;
  background-repeat:no-repeat; background-size:cover; background-position:74% 22%;
}
.page-head--image .page-head__media::after {
  content:''; position:absolute; inset:0;
  background:
    linear-gradient(to top, rgba(11,10,8,.97) 0%, rgba(11,10,8,.80) 34%, rgba(11,10,8,.30) 72%, rgba(11,10,8,.60) 100%),
    linear-gradient(to right, rgba(29,18,48,.95) 0%, rgba(24,16,40,.86) 32%, rgba(16,11,26,.42) 60%, rgba(11,10,8,.06) 88%);
}
/* per-page hero art. --hero-img/--hero-pos are set on the section. */
.page-head--image .page-head__media { background-image:var(--hero-img); background-position:var(--hero-pos, 74% 22%); }

/* Video variant: the montage on /podcast. Brighter, busier footage than the
   stills, so it carries a heavier scrim to keep the headline legible. */
.page-head--video .page-head__media::after {
  /* ~12% lighter than the still scrim: enough footage shows through to read
     as motion, while the left column stays dark enough to hold the headline. */
  background:
    linear-gradient(to top, rgba(11,10,8,.86) 0%, rgba(11,10,8,.78) 38%, rgba(11,10,8,.50) 74%, rgba(11,10,8,.68) 100%),
    linear-gradient(to right, rgba(11,10,8,.88) 0%, rgba(11,10,8,.80) 34%, rgba(11,10,8,.52) 64%, rgba(11,10,8,.26) 100%);
  z-index:2;
}
/* Same crop guard as .hero--video: object-fit:cover is centred, so the
   backing poster must be too, whatever --hero-pos a page sets. */
.page-head--video .page-head__media { background-position:center; }
.page-head--video .page-head__media .media-video { z-index:1; }

@media (max-width:860px) {
  .page-head--image .page-head__media { background-position:72% 18%; }
  .page-head--image .page-head__media::after {
    background:linear-gradient(to bottom, rgba(11,10,8,.72) 0%, rgba(11,10,8,.86) 45%, rgba(11,10,8,.97) 100%);
  }
}
.page-head {
  /* --head-pad-top lets a page drop its text further down the hero when the
     top of the footage is worth seeing (see /podcast, where the guest grid
     sits in the upper third). */
  padding-top:var(--head-pad-top, clamp(10rem,17vw,14rem));
  padding-bottom:var(--section-y);
  background:var(--ink-deep); border-bottom:1px solid var(--hair-dark); position:relative;
}
.page-head::before {
  content:''; position:absolute; inset:0; pointer-events:none; opacity:.20;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
.page-head > * { position:relative; z-index:1; }
/* Plum light thrown from the top-left of every text hero. Gives the dark
   grounds a colour temperature instead of leaving them neutral black. */
.page-head:not(.page-head--image)::after {
  content:''; position:absolute; inset:0; pointer-events:none; z-index:0;
  background:radial-gradient(115% 85% at 10% 0%, rgba(108,77,158,.42), transparent 60%);
}

/* ==========================================================================
   PRINTED BOOK
   Lead, Follow is a book you can buy and hold, so it is drawn as an object
   with a spine and a page block rather than a flat cover image, which reads
   as an e-book. Built as CSS geometry, not a rendered mockup: the artwork
   stays the real cover file, it survives a cover swap, and it is crisp at any
   size. Loaded stays flat on purpose — it is still in manuscript, so there is
   no printed object to show yet.
   ========================================================================== */
.book3d {
  --b-depth: 1.5rem;          /* half-thickness of the block */
  /* Positive turn brings the LEFT edge forward, so the spine is the face you
     see. That is the canonical printed-book read; turning the other way shows
     the page block, which looks more like a ream than a book. */
  --b-turn: 18deg;
  width:100%; max-width:16rem; perspective:1800px;
}
.book3d__body {
  position:relative; width:100%; aspect-ratio:2/3;
  transform-style:preserve-3d; transform:rotateY(var(--b-turn));
  transition:transform 600ms var(--ease-out);
}
.book3d:hover .book3d__body { --b-turn:9deg; }
/* Front board. */
.book3d__cover {
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block;
  transform:translateZ(var(--b-depth));
  box-shadow:0 0 0 1px rgba(20,18,15,.22);
}
/* Spine, hinged off the left edge and turned to face left. */
.book3d__spine {
  position:absolute; top:0; left:0; height:100%;
  width:calc(var(--b-depth) * 2);
  transform-origin:left center;
  transform:rotateY(-90deg) translateX(calc(var(--b-depth) * -1));
  background:linear-gradient(to right, #6E747A 0%, #9BA1A7 26%, #B7BCC1 62%, #7C8288 100%);
}
/* There is no page-block face. With the spine turned forward the right side
   of the book faces away, so a fore-edge panel is never visible — and the one
   that used to be here rendered in front of the cover and hid it. Two faces,
   both of which can actually be seen. */
/* Contact shadow. Separate element so it does not inherit the rotation. */
.book3d__shadow {
  position:absolute; left:-2%; right:6%; bottom:-5%; height:7%;
  background:radial-gradient(50% 50% at 50% 50%, rgba(20,18,15,.42), transparent 72%);
  filter:blur(6px); transform:translateZ(0);
}
.on-ink .book3d__shadow,.on-ink-deep .book3d__shadow,.on-accent .book3d__shadow {
  background:radial-gradient(50% 50% at 50% 50%, rgba(0,0,0,.62), transparent 72%);
}
@media (prefers-reduced-motion: reduce) {
  .book3d__body { transition:none; }
}
/* No 3D on narrow screens: at phone width the turn eats readable cover area
   and the spine is a smudge. Straight on, with the block still showing. */
@media (max-width:600px) {
  .book3d { max-width:14rem; margin-inline:auto; }
  .book3d__body { transform:none; }
  .book3d:hover .book3d__body { transform:none; }
  .book3d__spine { display:none; }
  .book3d__cover { transform:none; box-shadow:0 1rem 2.5rem rgba(20,18,15,.3), 0 0 0 1px rgba(20,18,15,.22); }
}

/* ==========================================================================
   DOSSIER
   A colophon, not a card grid: label left, detail right, hairline between.
   Used on /advisory for the credential list, where the whole argument is that
   the rooms speak for themselves — boxing each one in a card would make them
   look like product features instead of a record.
   ========================================================================== */
.dossier { list-style:none; padding:0; margin:0; border-top:1px solid var(--hair-dark); }
.on-paper .dossier,.on-paper-warm .dossier { border-top-color:var(--hair-light); }
.dossier li {
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.7fr);
  gap:clamp(.5rem,3vw,3rem); align-items:baseline;
  padding-block:clamp(1.25rem,2.4vw,1.85rem);
  border-bottom:1px solid var(--hair-dark);
}
.on-paper .dossier li,.on-paper-warm .dossier li { border-bottom-color:var(--hair-light); }
.dossier__label {
  font-family:var(--font-label); font-weight:700; text-transform:uppercase;
  font-size:.75rem; letter-spacing:.2em; line-height:1.4;
}
.dossier__detail { color:var(--on-dark-muted); max-width:56ch; }
.on-paper .dossier__detail,.on-paper-warm .dossier__detail { color:var(--on-light-muted); }
@media (max-width:780px) {
  .dossier li { grid-template-columns:1fr; gap:.5rem; }
}

/* ==========================================================================
   BOOK COVER
   The cover is a physical object on the page, not a decorative image, so it
   gets a hairline edge and one soft shadow — no perspective tilt, no gloss,
   nothing the rest of the site would not do. The artwork is almost black, so
   on the dark grounds the hairline is the only thing separating cover from
   page; on bone it is the shadow doing that work instead.
   ========================================================================== */
.book-cover {
  display:block; width:100%; max-width:23rem; aspect-ratio:2/3;
  object-fit:cover; background:var(--ink-deep);
  border:1px solid var(--hair-dark);
  box-shadow:0 1.5rem 3.5rem rgba(0,0,0,.55);
}
.on-paper .book-cover,.on-paper-warm .book-cover {
  border-color:var(--hair-light);
  box-shadow:0 1.25rem 3rem rgba(20,18,15,.28);
}
/* Right-hand column placements sit optically low next to a display heading,
   so nudge the cover up rather than centring it on the text block. */
.book-cover--aside { margin-inline:auto; }
/* Backlist. Same object, deliberately smaller, so the new book stays loudest. */
.book-cover--sm { max-width:17rem; }
@media (min-width:781px) { .book-cover--aside { margin-inline:0 auto; } }

/* ==========================================================================
   THE SIGNATURE DEVICE — editorial index
   Oversized outlined numeral hanging in the margin, hairline rules, two
   columns of unequal width. This replaces the three-card grid everywhere.
   ========================================================================== */
.index-list { list-style:none; padding:0; margin:0; border-top:1px solid var(--hair-dark); }
.on-paper .index-list,.on-paper-warm .index-list { border-top-color:var(--hair-light); }
.index-item {
  display:grid; grid-template-columns:minmax(5.5rem,10vw) minmax(0,1fr) minmax(0,1.35fr);
  gap:clamp(1rem,3vw,3rem); align-items:start;
  padding-block:clamp(2rem,4vw,3.25rem);
  border-bottom:1px solid var(--hair-dark);
}
.on-paper .index-item,.on-paper-warm .index-item { border-bottom-color:var(--hair-light); }
.index-item__num {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2.75rem,6vw,5rem); line-height:.8; letter-spacing:-0.04em;
  color:transparent;
  -webkit-text-stroke:1px var(--accent-bright);
  transition:color var(--dur) var(--ease-out), -webkit-text-stroke-color var(--dur) var(--ease-out);
}
.on-paper .index-item__num { -webkit-text-stroke-color:var(--accent-ink); }
.index-item:hover .index-item__num,
a.index-item:hover .index-item__num { color:var(--accent-bright); -webkit-text-stroke-color:var(--accent-bright); }
.on-paper .index-item:hover .index-item__num { color:var(--accent-ink); -webkit-text-stroke-color:var(--accent-ink); }
.index-item__title { font-family:var(--font-display); font-weight:700; font-size:clamp(1.5rem,2.6vw,2.125rem); line-height:1.06; letter-spacing:-0.02em; }
.index-item__body { color:var(--on-dark-muted); max-width:52ch; }
.on-paper .index-item__body,.on-paper-warm .index-item__body { color:var(--on-light-muted); }
.index-item__body .link-arrow { margin-top:var(--s5); }
@media (max-width: 860px) {
  .index-item { grid-template-columns:1fr; gap:var(--s4); }
  .index-item__num { font-size:2.5rem; }
}

/* ==========================================================================
   POST INDEX — the Substack essays, set as a broadsheet archive.
   Same language as .index-list: hairline rules, a mono date in the margin,
   Bodoni title, excerpt in the wide right column. No cover art on purpose.
   ========================================================================== */
.post__date {
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.18em; color:var(--on-dark-faint);
  display:block;
}
.on-paper .post__date,.on-paper-warm .post__date { color:var(--on-light-muted); }
.post__excerpt { color:var(--on-dark-muted); font-size:.9875rem; max-width:56ch; }
.on-paper .post__excerpt,.on-paper-warm .post__excerpt { color:var(--on-light-muted); }

/* the latest piece, given the weight of a front-page lead */
.post-lead {
  display:block; padding-block:clamp(2rem,4vw,3rem);
  border-top:2px solid var(--on-light); border-bottom:1px solid var(--hair-light);
}
.on-ink .post-lead,.on-ink-deep .post-lead { border-top-color:var(--on-dark); border-bottom-color:var(--hair-dark); }
.post-lead__title {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.875rem,4.4vw,3.25rem); line-height:1.02; letter-spacing:-0.028em;
  margin:var(--s4) 0 var(--s4); max-width:20ch;
  transition:color var(--dur) var(--ease-out);
}
.post-lead:hover .post-lead__title { color:var(--on-light); }
.on-ink .post-lead:hover .post-lead__title { color:var(--on-dark); }
.post-lead .post__excerpt { font-size:1.0625rem; max-width:52ch; }
.post-lead .link-arrow { margin-top:var(--s5); }

/* the archive below it */
.post-index { list-style:none; padding:0; margin:0; }
.post-item {
  display:grid; grid-template-columns:minmax(7rem,11%) minmax(0,1fr) minmax(0,1.25fr);
  gap:clamp(.75rem,2.5vw,2.5rem); align-items:baseline;
  padding-block:clamp(1.25rem,2.4vw,1.75rem);
  border-bottom:1px solid var(--hair-light);
}
.on-ink .post-item,.on-ink-deep .post-item { border-bottom-color:var(--hair-dark); }
.post-item__title {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.125rem,1.8vw,1.4375rem); line-height:1.14; letter-spacing:-0.016em;
  transition:color var(--dur) var(--ease-out);
}
.post-item:hover .post-item__title { color:var(--on-light); }
.on-ink .post-item:hover .post-item__title { color:var(--on-dark); }
.post-item .post__date { padding-top:.3em; }

@media (max-width:780px) {
  .post-item { grid-template-columns:1fr; gap:var(--s2); align-items:start; }
  .post-item .post__date { padding-top:0; }
  .post-item__title { margin-top:var(--s1); }
}

/* ---------- stat line: typographic, in a hairline band ---------- */
.statline { display:flex; flex-wrap:wrap; gap:var(--s6) clamp(1.75rem,4.5vw,3.5rem); align-items:baseline; }
.statline > div { display:flex; align-items:baseline; gap:var(--s3); }
.stat__num {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.875rem,3.4vw,3rem); line-height:1; letter-spacing:-0.03em;
  color:var(--on-dark); font-variant-numeric:tabular-nums;
}
.on-paper .stat__num,.on-paper-warm .stat__num { color:var(--on-light); }
.stat__label {
  font-family:var(--font-label); font-size:.6875rem; text-transform:uppercase;
  letter-spacing:.18em; color:var(--on-dark-faint); max-width:14ch; line-height:1.5;
}
.on-paper .stat__label,.on-paper-warm .stat__label { color:var(--on-light-muted); }

/* ---------- looping background video ----------
   Same pattern as oceanclubcr.com: autoplay + loop + muted + playsinline,
   object-fit cover, poster underneath. Two differences here, both deliberate:

   1. Nothing autoplays off-screen. js/site.js only calls play() when the clip
      is actually in view, and pauses it when it leaves. Four hero-weight
      videos all decoding at once is the usual way a page like this gets slow.
   2. prefers-reduced-motion and Save-Data both suppress playback entirely --
      the poster stays, and no video bytes are fetched at all.
   ------------------------------------------------------------------ */
.media-video {
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block;
  opacity:0; transition:opacity 600ms var(--ease-out);
}
.media-video.is-ready { opacity:1; }
@media (prefers-reduced-motion: reduce) { .media-video { display:none; } }

/* hero: the video sits on the image plane and inherits its drift */
.hero__media .media-video { z-index:0; }

/* tiles: the poster image stays underneath as the fallback layer, so a tile
   video needs no poster attribute of its own — but the <img> must still be
   frame 1 of the clip or the tile flashes. tools/build-tile-loop.sh writes
   both from the same source for exactly that reason. */
.tile__media { position:relative; }
.tile__media img { position:relative; z-index:0; }
.tile__media .media-video { z-index:1; transition:opacity 600ms var(--ease-out), transform 700ms var(--ease-out); }
.tile:hover .tile__media .media-video { transform:scale(1.035); }
.tile__media .media-video { z-index:1; }

/* ---------- full-bleed media band ----------
   A video shown as content rather than as wallpaper. No scrim, no overlay,
   nothing on top of it, so faces read at full brightness. */
.media-band {
  position:relative;
  background:var(--ink-deep) var(--band-img, none) center/cover no-repeat;
  line-height:0; aspect-ratio:16/9;
}
/* A light wash so the band sits in the palette rather than reading as a raw
   video drop-in. Much lighter than a hero scrim, because nothing has to stay
   legible on top of it — the faces still read clearly. */
.media-band::after {
  content:''; position:absolute; inset:0; pointer-events:none; z-index:1;
  background:linear-gradient(to bottom, rgba(11,10,8,.34) 0%, rgba(11,10,8,.16) 35%, rgba(11,10,8,.16) 65%, rgba(11,10,8,.40) 100%);
}
.media-band__video {
  display:block; width:100%; height:auto; aspect-ratio:16/9;
  object-fit:cover; opacity:0; transition:opacity 600ms var(--ease-out);
}
.media-band__video.is-ready { opacity:1; }
/* Under reduced motion (and if JS never runs) site.js removes the <video>
   entirely, so --band-img on the section is what the reader actually sees. */

/* ---------- speaker reel ---------- */
.reel { margin:0; }
.reel__video {
  width:100%; aspect-ratio:16/9; height:auto; display:block;
  background:#000; border:1px solid var(--hair-dark);
}
.on-paper .reel__video { border-color:var(--hair-light); }
.reel__cap {
  margin-top:var(--s4);
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.18em; color:var(--on-dark-faint);
}
.on-paper .reel__cap { color:var(--on-light-muted); }
/* captions sit inside the frame, so keep them off the very bottom edge */
.reel__video::cue { font-family:var(--font-body); font-size:.9em; }

/* ---------- photo tiles (Adam Grant / Brené pattern) ---------- */
.tiles { display:grid; gap:clamp(1.25rem,2.5vw,2rem); grid-template-columns:repeat(auto-fit,minmax(min(100%,19rem),1fr)); }
.tile { display:flex; flex-direction:column; }
.tile__media { position:relative; overflow:hidden; background:var(--ink-raise); aspect-ratio:4/5; }
.tile__media img { width:100%; height:100%; object-fit:cover; transition:transform 700ms var(--ease-out); }
.tile:hover .tile__media img { transform:scale(1.035); }
.tile__kicker { font-family:var(--font-label); font-size:.625rem; text-transform:uppercase; letter-spacing:.24em; color:var(--on-dark-faint); margin-top:var(--s5); }
.on-paper .tile__kicker { color:var(--on-light-muted); }
.tile h3 { font-size:clamp(1.375rem,2.1vw,1.75rem); margin-top:var(--s3); }
.tile p { color:var(--on-dark-muted); margin-top:var(--s3); font-size:.9875rem; }
.on-paper .tile p { color:var(--on-light-muted); }

/* ---------- legacy .card, restyled: hairline block, no box ---------- */
.card {
  display:flex; flex-direction:column; padding:var(--s6) 0 var(--s7);
  background:none; border:0; border-top:1px solid var(--hair-dark); border-radius:0;
}
.on-paper .card,.on-paper-warm .card { background:none; border-top-color:var(--hair-light); }
.card { transition:border-top-color var(--dur) var(--ease-out); }
.card:hover { border-top-color:var(--accent-bright); }
.on-paper .card:hover,.on-paper-warm .card:hover { border-top-color:var(--accent-ink); }
a.card:hover h3 { color:var(--on-dark); }
.on-paper a.card:hover h3 { color:var(--on-light); }
.card h3 { font-size:1.375rem; margin-bottom:var(--s3); line-height:1.1; transition:color var(--dur) var(--ease-out); }
.card p { color:var(--on-dark-muted); font-size:.9875rem; }
.on-paper .card p,.on-paper-warm .card p { color:var(--on-light-muted); }
.card__num {
  font-family:var(--font-display); font-weight:700; font-size:2rem; line-height:1;
  color:transparent; -webkit-text-stroke:1px var(--on-dark-faint); margin-bottom:var(--s4);
}
.on-paper .card__num { -webkit-text-stroke-color:rgba(20,18,15,.34); }
.card .link-arrow { margin-top:var(--s5); }
.grid { display:grid; gap:clamp(1.25rem,3vw,2.75rem); }
/* A true 2-up. auto-fit resolved to 3 columns at 1440px, which left a 4-item
   set orphaned as 3+1 (see /advisory). */
.grid--2 { grid-template-columns:1fr; }
@media (min-width:820px) { .grid--2 { grid-template-columns:repeat(2,1fr); } }
.grid--3 { grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr)); }

.split { display:grid; gap:clamp(2rem,5vw,5rem); grid-template-columns:1fr; align-items:center; }
@media (min-width:900px) {
  .split { grid-template-columns:1fr 1fr; }
  .split--wide-text { grid-template-columns:1.3fr 1fr; }
}
.split__media img { width:100%; }

/* ---------- framework list ---------- */
.framework-list { list-style:none; padding:0; margin:0; border-top:1px solid var(--hair-dark); }
.on-paper .framework-list { border-top-color:var(--hair-light); }
.framework-list li {
  display:grid; grid-template-columns:minmax(9rem,16%) 1fr; gap:clamp(1rem,3vw,2.5rem);
  padding-block:clamp(1.5rem,3vw,2.25rem); border-bottom:1px solid var(--hair-dark);
}
.on-paper .framework-list li { border-bottom-color:var(--hair-light); }
.framework-list .fw__name { font-family:var(--font-display); font-weight:700; font-size:clamp(1.25rem,2vw,1.625rem); letter-spacing:-0.015em; line-height:1.1; }
.framework-list .fw__body { color:var(--on-dark-muted); max-width:62ch; }
.on-paper .framework-list .fw__body { color:var(--on-light-muted); }
@media (max-width:700px) { .framework-list li { grid-template-columns:1fr; gap:var(--s3); } }

/* ---------- pull quote: hangs into the margin, large italic Bodoni ---------- */
.pullquote {
  font-family:var(--font-display); font-weight:400; font-style:italic;
  font-size:clamp(1.625rem,3.4vw,2.75rem); line-height:1.22; letter-spacing:-0.02em;
  text-wrap:balance; max-width:20ch;
}
.pullquote::before { content:'“'; display:block; font-size:2.2em; line-height:.55; color:var(--on-dark-faint); margin-bottom:.06em; }
.on-paper .pullquote::before,.on-paper-warm .pullquote::before { color:var(--on-light-muted); }
.pullquote cite {
  display:block; margin-top:var(--s6); font-family:var(--font-label); font-style:normal;
  font-size:.625rem; text-transform:uppercase; letter-spacing:.2em; color:var(--on-dark-faint);
}
.on-paper .pullquote cite,.on-paper-warm .pullquote cite { color:var(--on-light-muted); }

/* ---------- case studies ----------
   A logo proves Greg was in the room. A number proves something changed there.
   .case__metric is the whole point of the component — if an entry has no
   figure in it, it is a testimonial, not a case study, and belongs in .quotes.
   ------------------------------------------------------------------ */
.cases { display:grid; gap:clamp(1.5rem,3vw,3rem); grid-template-columns:1fr;
         border-top:1px solid var(--hair-dark); }
.on-paper .cases,.on-paper-warm .cases { border-top-color:var(--hair-light); }
@media (min-width:880px) { .cases--2 { grid-template-columns:repeat(2,1fr); } }
.case { padding-top:clamp(1.5rem,3vw,2.25rem); }
.case__sector {
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.18em; color:var(--on-dark-faint);
}
.on-paper .case__sector,.on-paper-warm .case__sector { color:var(--on-light-muted); }
.case__metric {
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(2.25rem,4.4vw,3.5rem); line-height:1; letter-spacing:-0.035em;
  margin:var(--s4) 0 var(--s3); font-variant-numeric:tabular-nums;
}
.case__label {
  font-size:1.0625rem; line-height:1.5; max-width:30ch;
  color:var(--on-dark); font-weight:600;
}
.on-paper .case__label,.on-paper-warm .case__label { color:var(--on-light); }
.case__body { margin-top:var(--s4); color:var(--on-dark-muted); font-size:.9875rem; max-width:46ch; }
.on-paper .case__body,.on-paper-warm .case__body { color:var(--on-light-muted); }

/* ---------- testimonials ----------
   Attributed quotes. An unattributed quote reads as marketing; a named one
   with a role reads as evidence, which is the whole point of the section. */
.quotes { display:grid; gap:clamp(1.5rem,3vw,3rem); grid-template-columns:1fr; border-top:1px solid var(--hair-dark); }
.on-paper .quotes,.on-paper-warm .quotes { border-top-color:var(--hair-light); }
@media (min-width:880px) { .quotes--2 { grid-template-columns:repeat(2,1fr); } }
.quote { padding-top:clamp(1.5rem,3vw,2.25rem); }
.quote blockquote {
  font-family:var(--font-display); font-weight:400; font-style:italic;
  font-size:clamp(1.25rem,2.1vw,1.625rem); line-height:1.32; letter-spacing:-0.015em;
  margin:0; max-width:34ch;
}
.quote figcaption {
  margin-top:var(--s5);
  font-family:var(--font-label); font-size:.6875rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.18em; line-height:1.7;
  color:var(--on-dark-faint);
}
.on-paper .quote figcaption,.on-paper-warm .quote figcaption { color:var(--on-light-muted); }
.quote figcaption b { display:block; font-weight:700; color:var(--on-dark); }
.on-paper .quote figcaption b,.on-paper-warm .quote figcaption b { color:var(--on-light); }

/* ---------- CTA band ---------- */
.cta-band { background:#6C4D9E; color:#FFF; }
.cta-band .kicker,.cta-band .eyebrow { color:rgba(255,255,255,.8); }
/* Purple-on-purple would all but vanish; the tick goes white on this band. */
.cta-band .kicker::before,.cta-band .eyebrow::before { background:rgba(255,255,255,.66); }
.cta-band h2 { color:#FFF; }
.cta-band p,.cta-band .lead { color:rgba(255,255,255,.94); }
.cta-band .btn--primary { background:#14120F; border-color:#14120F; color:var(--bone); }
.cta-band .btn--primary:hover { background:#000; border-color:#000; }
.cta-band .btn--ghost { color:#FFF; border-color:rgba(255,255,255,.5); }
.cta-band .btn--ghost:hover { border-color:#FFF; }

/* ---------- forms ---------- */
.field { margin-bottom:var(--s5); }
/* Two-up rows inside the booking block. */
.grid-2 { display:grid; gap:0 var(--s5); grid-template-columns:1fr; }
@media (min-width:640px) { .grid-2 { grid-template-columns:1fr 1fr; } }
/* Speaking-only fields; JS also disables the inputs so a hidden group is
   never submitted and never lands in the tab order. */
.field-group[hidden] { display:none; }
.field label { display:block; margin-bottom:var(--s2); font-family:var(--font-label); font-size:.6875rem; text-transform:uppercase; letter-spacing:.14em; }
.field .req { color:var(--accent-bright); }
.on-paper .field .req { color:var(--accent-ink); }
.field__help { margin-top:var(--s2); font-size:.8125rem; color:var(--on-dark-muted); }
.on-paper .field__help { color:var(--on-light-muted); }
.field input,.field textarea,.field select {
  width:100%; min-height:52px; padding:var(--s3) var(--s4);
  background:transparent; border:0; border-bottom:1px solid var(--hair-dark);
  border-radius:0; color:var(--on-dark); font-size:1rem;
  transition:border-color var(--dur) var(--ease-out);
}
.on-paper .field input,.on-paper .field textarea,.on-paper .field select {
  border-bottom-color:rgba(20,18,15,.28); color:var(--on-light);
}
.field input:focus,.field textarea:focus,.field select:focus { border-bottom-color:var(--accent-bright); outline-offset:2px; }
.on-paper .field input:focus,.on-paper .field textarea:focus,.on-paper .field select:focus { border-bottom-color:var(--accent); }
.field textarea { min-height:140px; resize:vertical; line-height:1.6; }
.field__error { display:none; margin-top:var(--s2); font-size:.8125rem; font-weight:600; color:#F0A090; }
.on-paper .field__error { color:#8A3A1E; }
.field[data-invalid="true"] .field__error { display:block; }
.field[data-invalid="true"] input,.field[data-invalid="true"] textarea { border-bottom-color:#F0A090; }
.on-paper .field[data-invalid="true"] input,.on-paper .field[data-invalid="true"] textarea { border-bottom-color:#8A3A1E; }
.form-status { margin-top:var(--s5); font-size:.9375rem; font-weight:500; }

/* The tagline is always set in capitals — Greg's instruction. */
.tagline {
  display:block;
  font-family:var(--font-label); font-size:.75rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.2em; line-height:1.5;
  color:var(--on-dark);
}
.on-paper .tagline,.on-paper-warm .tagline { color:var(--on-light); }

/* Honeypot: off-screen rather than display:none, because some bots skip
   hidden inputs. Never focusable, never announced. */
.hp { position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* ---------- footer ---------- */
.site-footer { background:var(--ink-deep); border-top:1px solid var(--hair-dark); padding-block:var(--s10) var(--s7); position:relative; }
.footer-grid { display:grid; gap:var(--s8); grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr)); }
.footer-grid .foot-head {
  font-family:var(--font-label); font-size:.625rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.22em; color:var(--on-dark-faint);
  margin-bottom:var(--s4); line-height:1.4;
}
/* re-ranked from h4 to h2 to stop a skipped heading level on every page;
   the styling keeps them looking like the small labels they are */
.card-head { font-size:1.375rem; line-height:1.2; }
.footer-grid ul { list-style:none; padding:0; margin:0; }
.footer-grid li a { display:inline-flex; align-items:center; min-height:44px; font-size:.9375rem; color:var(--on-dark-muted); transition:color var(--dur) var(--ease-out); }
.footer-grid li a:hover { color:var(--on-dark); }
.footer-bottom {
  display:flex; flex-wrap:wrap; gap:var(--s4); align-items:center; justify-content:space-between;
  margin-top:var(--s9); padding-top:var(--s5); border-top:1px solid var(--hair-dark);
  font-family:var(--font-label); font-size:.625rem; text-transform:uppercase; letter-spacing:.14em; color:var(--on-dark-faint);
}
.footer-bottom a { color:var(--on-dark-muted); }
.footer-bottom a:hover { color:var(--on-dark); }
.social-row { display:flex; gap:var(--s2); }
.social-row a {
  display:inline-flex; align-items:center; justify-content:center; width:44px; height:44px;
  border:1px solid var(--hair-dark); color:var(--on-dark-muted);
  transition:color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.social-row a:hover { color:var(--on-dark); border-color:var(--on-dark); }
/* footer wordmark must not inherit the masthead's centring grid */
.site-footer .wordmark { grid-column:auto; justify-self:start; }

/* ---------- reveal ---------- */
.js .reveal { opacity:0; transform:translateY(16px); }
.js .reveal.is-in { opacity:1; transform:none; transition:opacity 620ms var(--ease-out), transform 620ms var(--ease-out); }

/* Above the fold, never hide. The hero and interior page heads are the LCP
   region: holding them at opacity 0 until an observer fires costs real
   perceived speed for no benefit, since nobody scrolls them into view.
   Scroll reveals are for content below the fold only. */
.js .hero .reveal,
.js .page-head .reveal { opacity:1; transform:none; }

/* ---------- utilities ---------- */
.mt-0{margin-top:0}.mt-3{margin-top:var(--s3)}.mt-4{margin-top:var(--s4)}.mt-5{margin-top:var(--s5)}
.mt-6{margin-top:var(--s6)}.mt-7{margin-top:var(--s7)}.mt-8{margin-top:var(--s8)}.mt-9{margin-top:var(--s9)}
.mb-5{margin-bottom:var(--s5)}.mb-7{margin-bottom:var(--s7)}.mb-8{margin-bottom:var(--s8)}
.center{text-align:center}
.center .lead,.center .pullquote{margin-inline:auto}
.center .pullquote{max-width:26ch}
.pullquote--statement{font-size:clamp(2rem,5vw,3.75rem);line-height:1.14;max-width:22ch}
.center .pullquote--statement{max-width:22ch}
