/* ============================================================
   Self-hosted type. These were previously loaded from
   fonts.googleapis.com, which is a render-blocking third party request
   on the critical path, and a privacy exposure for EU visitors. Each
   family is one variable woff2 covering the weights used, Latin subset.
   Playfair Display is SIL Open Font License 1.1, Roboto and Roboto Mono
   are Apache License 2.0. Both permit self-hosting and redistribution.
   Licences are in fonts/.
   ============================================================ */
@font-face {
  font-family: 'Playfair Display'; font-style: normal; font-weight: 500;
  font-display: swap; src: url("../fonts/playfair.woff2") format("woff2");
}
@font-face {
  font-family: 'Playfair Display'; font-style: normal; font-weight: 600;
  font-display: swap; src: url("../fonts/playfair.woff2") format("woff2");
}
@font-face {
  font-family: 'Roboto'; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonts/roboto.woff2") format("woff2");
}
@font-face {
  font-family: 'Roboto'; font-style: normal; font-weight: 500;
  font-display: swap; src: url("../fonts/roboto.woff2") format("woff2");
}
@font-face {
  font-family: 'Roboto Mono'; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonts/roboto-mono.woff2") format("woff2");
}
@font-face {
  font-family: 'Roboto Mono'; font-style: normal; font-weight: 500;
  font-display: swap; src: url("../fonts/roboto-mono.woff2") format("woff2");
}

/* jordanmurphy.co — "Scrim Sweep" editorial system
   Translated faithfully from the approved mockup:
   artifacts/mockup-sandbox/.../JordanMurphyScrimSweep.tsx + .css
   Palette: Paper #FAF8F5, Ink #1A1A1A, Tide #1F5C63, Tide deep #0C2A2E, Gold #C5A059 */

:root {
  color-scheme: light;
  --ink: #1A1A1A;
  --ink-70: rgba(26, 26, 26, 0.72);
  --ink-50: rgba(26, 26, 26, 0.66);
  --slate: #4A4A4A;
  --paper: #FAF8F5;
  --paper-70: rgba(250, 248, 245, 0.78);
  --paper-50: rgba(250, 248, 245, 0.55);
  --paper-line: rgba(250, 248, 245, 0.16);
  --line: rgba(26, 26, 26, 0.12);
  --mist: #ECECEC;
  --tide: #1F5C63;
  --tide-deep: #0C2A2E;
  --tide-lift: #6FB6BE;
  --gold: #C5A059;
  --gold-ink: #8A6A22;   /* same hue, darkened to clear AA on light surfaces */
  --gold-soft: rgba(197, 160, 89, 0.5);
  --serif: 'Playfair Display', Georgia, serif;
  --sans: 'Roboto', -apple-system, sans-serif;
  --mono: 'Roboto Mono', monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 90px; }
#letter, #book, #inquiry, #kit, #apply, #main { scroll-margin-top: 90px; }

body {
  background-color: var(--paper);
  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='0.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.1 0 0 0 0 0.09 0 0 0 0.03 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  color: var(--ink);
  font-family: var(--sans);
  font-size: 19px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  min-height: 100dvh;
}

a { color: var(--tide); text-decoration: none; transition: color 0.15s ease; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* keyboard path. Gold is only 2.32:1 on paper, so light surfaces take the
   darkened token and dark surfaces take paper. */
:focus-visible { outline: 3px solid var(--gold-ink); outline-offset: 3px; }
.band :focus-visible, .page-hero :focus-visible, .hero-content :focus-visible,
.nav--over-hero :focus-visible, .subscribe.band :focus-visible { outline-color: var(--paper); }

/* C4 skip link */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--tide-deep); color: var(--paper);
  font-family: var(--mono); font-size: 14px; letter-spacing: 0.08em;
  padding: 12px 20px; border: 2px solid var(--gold);
}
.skip-link:focus { left: 8px; top: 8px; text-decoration: none; }

/* L2: one canonical visually-hidden utility */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.15; letter-spacing: -0.01em; color: var(--ink); }
h1 { font-size: clamp(40px, 6.4vw, 72px); font-weight: 600; }
h2 { font-size: clamp(28px, 4vw, 40px); margin-bottom: 24px; }
h3 { font-size: 24px; }
/* headings promoted for document outline keep the h3 visual size */
.pillar h2, .card h2, .essay-index h2, .h-sub { font-size: 24px; margin-bottom: 8px; }

.label { font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-50); }
.label--tide { color: var(--tide); }
.label--gold { color: var(--gold-ink); }
.band .label--gold, .glass-dark .label--gold, .page-hero .label--gold, .hero-content .label--gold { color: var(--gold); }

.gold { color: var(--gold); }

.rule-gold { border: none; border-top: 1px solid var(--gold); width: 56px; margin: 0; }
.section-rule { border: none; border-top: 1px solid var(--line); }

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
.wrap-wide { max-width: 1240px; margin: 0 auto; padding: 0 32px; }
.reading { max-width: 680px; }

/* ============================================================
   Fleuron ornament — section punctuation
   ============================================================ */
.fleuron {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin: 0 auto 8px; color: var(--gold);
}
.fleuron::before, .fleuron::after {
  content: ""; height: 1px; width: 60px;
  background: linear-gradient(to var(--dir, right), transparent, var(--gold-soft));
}
.fleuron::before { --dir: left; }
.fleuron svg { display: block; width: 30px; height: 30px; flex: none; }
.fleuron--start { justify-content: flex-start; margin-left: 0; }
.fleuron--start::before { display: none; }
.fleuron--start::after { width: 88px; }
.band .fleuron, .glass-dark .fleuron { color: var(--gold); }

/* ============================================================
   Nav — sticky, glass; transparent variant over dark heroes
   ============================================================ */
.nav {
  position: sticky; top: 0; z-index: 60;
  background: rgba(250, 248, 245, 0.86);
  backdrop-filter: blur(10px) saturate(1.2); -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border-bottom: 1px solid var(--line);
  transition: background 0.3s ease, border-color 0.3s ease;
}
.nav-inner {
  max-width: 1240px; margin: 0 auto; padding: 18px 32px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.nav-name { font-family: var(--serif); font-size: 21px; font-weight: 600; color: var(--ink); }
.nav-name:hover { text-decoration: none; color: var(--tide); }
.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links > a, .nav-item > a { font-size: 15px; font-weight: 500; color: var(--slate); }
.nav-links a.active { color: var(--ink); }
.nav-links a:hover { color: var(--tide); text-decoration: none; }
.nav-links a.btn, .nav-links a.btn:hover { color: #fff; }

/* nav dropdown ("More") */
.nav-item { position: relative; }
.nav-item > button {
  font-family: var(--sans); font-size: 15px; font-weight: 500; color: var(--slate);
  background: none; border: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  padding: 0;
}
.nav-item > button:hover { color: var(--tide); }
.nav-item > button svg { width: 10px; height: 10px; transition: transform 0.2s ease; }
.nav-item[data-open="true"] > button svg { transform: rotate(180deg); }
.nav-menu {
  position: absolute; top: calc(100% + 14px); right: 0; min-width: 210px;
  background: rgba(250, 248, 245, 0.98);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--line); border-top: 2px solid var(--gold);
  padding: 10px; display: none; flex-direction: column; gap: 2px;
  box-shadow: 0 20px 50px rgba(12, 42, 46, 0.16);
}
.nav-item[data-open="true"] .nav-menu { display: flex; }
.nav-menu a { font-size: 15px; color: var(--slate); padding: 9px 12px; border-radius: 2px; }
.nav-menu a:hover { color: var(--tide); background: rgba(31, 92, 99, 0.06); text-decoration: none; }

/* transparent nav over dark hero pages */
.nav--over-hero {
  position: fixed; top: 0; left: 0; right: 0;
  background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
  border-bottom: 1px solid rgba(250, 248, 245, 0.18);
}
.nav--over-hero .nav-name { color: var(--paper); }
.nav--over-hero .nav-name:hover { color: #fff; }
.nav--over-hero .nav-links > a,
.nav--over-hero .nav-item > button { color: rgba(250, 248, 245, 0.85); }
.nav--over-hero .nav-links > a:hover,
.nav--over-hero .nav-item > button:hover { color: #fff; }
.nav--over-hero .nav-links a.active { color: #fff; }
.nav--over-hero .nav .btn,
.nav--over-hero .nav-links a.btn { background: rgba(250, 248, 245, 0.14); border: 1px solid rgba(250, 248, 245, 0.4); }
.nav--over-hero .nav-links a.btn:hover { background: rgba(250, 248, 245, 0.26); }
.nav--over-hero.nav--stuck {
  position: fixed; background: rgba(12, 42, 46, 0.82);
  backdrop-filter: blur(12px) saturate(1.2); -webkit-backdrop-filter: blur(12px) saturate(1.2);
  border-bottom: 1px solid rgba(197, 160, 89, 0.28);
}
.nav-toggle { display: none; background: none; border: none; cursor: pointer; padding: 6px; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--ink); margin: 5px 0; transition: background 0.2s; }
.nav--over-hero .nav-toggle span { background: var(--paper); }

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-block; background: var(--tide); color: #fff;
  font-family: var(--sans); font-size: 15px; font-weight: 500;
  padding: 11px 24px; border: none; cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}
.btn:hover { background: #2a707a; text-decoration: none; color: #fff; transform: translateY(-1px); }
.btn--big { font-size: 17px; padding: 15px 34px; }
.btn--gold { background: var(--gold); color: #0F0F0F; border: 1px solid #9A7A32; }
.band .btn--gold, .page-hero .btn--gold, .hero-actions .btn--gold { border-color: transparent; }
.btn--gold:hover { background: #d4b273; color: #0F0F0F; }
.btn--ghost { background: transparent; border: 1px solid var(--tide); color: var(--tide); }
.btn--ghost:hover { background: var(--tide); color: #fff; }
.link-quiet { color: var(--slate); font-size: 15px; }

/* ============================================================
   Sections
   ============================================================ */
.section { padding: 96px 0; }
.section--tight { padding: 64px 0; }
.offset-left { margin-left: 0; max-width: 720px; }
.offset-right { margin-left: auto; max-width: 720px; }

/* pull quote */
.pull {
  font-family: var(--serif); font-size: clamp(24px, 3.4vw, 34px); font-weight: 500; line-height: 1.4;
  border-left: 2px solid var(--gold); padding-left: 32px; max-width: 820px; color: var(--ink);
}

/* ============================================================
   FULL-BLEED HERO — deep Tide duotone scrim + scrim sweep
   ============================================================ */
.hero-bleed {
  position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: flex-end;
  overflow: hidden; isolation: isolate; background: var(--tide-deep);
}
.hero-bleed .hero-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  object-position: 38% 30%; z-index: -3; filter: saturate(0.6) contrast(1.04);
  transform-origin: 38% 30%;
}
.hero-scrim {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: -2; background:
    radial-gradient(ellipse 80% 60% at 24% 78%, rgba(62,138,147,0.28) 0%, rgba(62,138,147,0) 62%),
    linear-gradient(to top, rgba(8,26,29,0.97) 0%, rgba(12,42,46,0.62) 42%, rgba(19,66,72,0.28) 70%, rgba(12,42,46,0.46) 100%),
    linear-gradient(to right, rgba(10,36,40,0.72) 0%, rgba(12,42,46,0.3) 55%, rgba(31,92,99,0.08) 100%);
}
.hero-scrim::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0;
  background: linear-gradient(160deg, rgba(31,92,99,0.34) 0%, rgba(12,42,46,0.18) 48%, rgba(8,26,29,0.34) 100%);
  mix-blend-mode: color;
}
.hero-veil {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(to right, rgba(5,17,19,0.99) 0%, rgba(6,21,23,0.96) 45%, rgba(8,26,29,0.9) 100%);
  /* rests CLEAR. The .js rule below opaques it so the sweep has something to
     lift. If js is ever absent the portrait shows rather than being blacked out. */
  opacity: 0;
}
.hero-content {
  position: relative; width: 100%; max-width: 1240px; margin: 0 auto; padding: 168px 32px 84px;
}
.hero-content .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold); margin-bottom: 20px; }
.hero-content h1 { max-width: 16ch; margin: 18px 0 24px; color: var(--paper); text-shadow: 0 1px 24px rgba(4,18,20,0.55); }
.hero-content h1 .gold { color: var(--gold); }
.hero-sub { font-size: 20px; color: rgba(250,248,245,0.86); max-width: 540px; margin-bottom: 36px; }
.hero-actions { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.hero-actions .quiet-link { color: rgba(250,248,245,0.82); font-size: 15px; }
.hero-actions .quiet-link:hover { color: #fff; }
.cred-bar {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.06em; color: rgba(250,248,245,0.7);
  margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--gold-soft); line-height: 2; max-width: 660px;
}
.scroll-cue {
  position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%); z-index: 2;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: rgba(250,248,245,0.6); display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.scroll-cue span { display: block; width: 1px; height: 34px; background: linear-gradient(to bottom, var(--gold), transparent); }

/* compact page hero (interior pages) */
.page-hero { position: relative; padding: 148px 0 72px; overflow: hidden; isolation: isolate; background: var(--tide-deep); }
.page-hero .hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 26%; z-index: -3; filter: saturate(0.55) contrast(1.04); }
.page-hero::before {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: -2;
  background:
    linear-gradient(to top, rgba(8,26,29,0.96) 0%, rgba(12,42,46,0.72) 60%, rgba(12,42,46,0.6) 100%),
    linear-gradient(120deg, rgba(10,36,40,0.7) 0%, rgba(31,92,99,0.1) 100%);
}
.page-hero h1 { color: var(--paper); margin: 18px 0 0; text-shadow: 0 1px 20px rgba(4,18,20,0.5); }
.page-hero .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold); }
.page-hero .page-hero-sub { font-size: 21px; color: rgba(250,248,245,0.86); max-width: 640px; margin-top: 20px; }
.page-hero .rule-gold { margin-top: 20px; }

/* ============================================================
   Duotone parallax bands (dark glass)
   ============================================================ */
.band {
  position: relative; isolation: isolate;
  background-color: var(--tide-deep); background-size: cover; background-position: center;
  background-repeat: no-repeat; background-attachment: scroll; background-blend-mode: luminosity;
  color: var(--paper-70);
  border-top: 1px solid rgba(197,160,89,0.35); border-bottom: 1px solid rgba(197,160,89,0.35);
}
.band--tide-rocks { background-image: url("../img/bands/tide-rocks.jpg"); }
.band--city { background-image: url("../img/bands/city.jpg"); }
.band--horizon { background-image: url("../img/bands/horizon.jpg"); }
/* A fixed background repaints on every scrolled frame, and here each repaint
   also runs the luminosity blend under the backdrop-filtered cards. Scroll is
   the default now; fixed is opt-in only where it is cheap enough to be worth it. */
@media (min-width: 861px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .band { background-attachment: fixed; }
}
.band > .band-scrim {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: -1; background:
    radial-gradient(ellipse 70% 90% at 85% 0%, rgba(62,138,147,0.18) 0%, rgba(62,138,147,0) 60%),
    linear-gradient(to bottom, rgba(8,26,29,0.94) 0%, rgba(12,42,46,0.90) 50%, rgba(8,26,29,0.94) 100%);
}
.band .wrap, .band .wrap-wide { position: relative; }
.band h1, .band h2, .band h3 { color: var(--paper); }
.band a { color: var(--tide-lift); }
.band a:hover { color: var(--paper); }
/* .band a is (0,1,1) and .btn--gold is (0,1,0), so buttons inside a band were
   taking the tide-lift link colour instead of their own label colour. On gold
   that measured 1.07:1, which is invisible. These win on specificity and put
   each button's real label colour back. */
.band .btn, .band .btn:hover { color: #fff; }
.band .btn--gold, .band .btn--gold:hover { color: #0F0F0F; }
.band .btn--ghost { color: var(--paper); border-color: var(--paper); }
.band .btn--ghost:hover { color: var(--tide-deep); background: var(--paper); }
.band .label { color: var(--paper-70); }
.band .label--gold { color: var(--gold); }
.band .pull { color: var(--paper); }

/* ============================================================
   Glass panels — dark glass + light glass mode
   ============================================================ */
.glass-dark {
  background: rgba(8, 26, 29, 0.58); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  border: 1px solid var(--paper-line);
}
.glass-light {
  background: rgba(255, 255, 255, 0.66); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 18px 44px rgba(12, 42, 46, 0.08);
}
/* light-glass section band (paper mode, distinct from dark bands) */
.section--glass {
  position: relative; isolation: isolate;
  background:
    radial-gradient(ellipse 60% 80% at 90% 0%, rgba(31,92,99,0.06) 0%, rgba(31,92,99,0) 60%),
    linear-gradient(180deg, rgba(236,236,236,0.4) 0%, rgba(250,248,245,0) 100%);
  border-top: 1px solid var(--gold-soft);
}

/* ============================================================
   Pillars / cards / lists
   ============================================================ */
.pillars { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 24px; }
.pillar { background: var(--paper); padding: 36px 32px; }
.pillar h3 { margin: 10px 0 8px; }
.pillar h3 a { color: inherit; }
.pillar h3 a:hover { color: var(--tide); text-decoration: none; }
.pillar p { font-size: 16px; color: var(--slate); }
.band .pillars { background: var(--paper-line); border-color: var(--paper-line); }
.band .pillar { background: rgba(8,26,29,0.58); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.band .pillar h3 a { color: var(--paper); }
.band .pillar h3 a:hover { color: var(--gold); }
.band .pillar p { color: var(--paper-70); }

.proof-list { list-style: none; margin-top: 24px; }
.proof-list li { display: flex; gap: 24px; align-items: baseline; padding: 18px 0; border-bottom: 1px solid var(--line); font-size: 17px; color: var(--ink-70); }
.proof-list .num { font-family: var(--serif); font-size: 30px; font-weight: 600; color: var(--tide); min-width: 190px; }
.band .proof-list li { border-color: var(--paper-line); color: var(--paper-70); }
.band .proof-list .num { color: var(--gold); }

.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 24px; }
/* four up on desktop, but as a class so the breakpoints below can win.
   An inline grid-template-columns cannot be overridden by a media query. */
.cards--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1100px) { .cards--4 { grid-template-columns: repeat(2, 1fr); } }
/* middle tier: one 860px cliff gave four newspaper gutters on one side and
   140 character lines on the other */
@media (max-width: 980px) {
  .cards, .trail, .wall, .statline, .who-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  .cards, .cards--4, .trail, .wall, .pillars, .statline, .who-grid { grid-template-columns: 1fr; }
}
.card { border: 1px solid var(--line); background: #fff; padding: 32px 28px; display: flex; flex-direction: column; gap: 12px; }
.card h3 { font-size: 22px; }
.card p { font-size: 16px; color: var(--slate); flex: 1; }
.card .label { font-size: 11px; color: var(--tide); }
.band .cards .card { border-color: var(--paper-line); background: rgba(8,26,29,0.58); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.band .cards .card p { color: var(--paper-70); }
.band .cards .card .label { color: var(--gold); }
.band .cards .card a { color: var(--tide-lift); }
.band .cards .card a:hover { color: var(--paper); }

.essay-index { list-style: none; margin-top: 12px; max-width: 720px; }
.essay-index li { padding: 26px 0; border-bottom: 1px solid var(--line); }
.essay-index .meta { font-family: var(--mono); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--slate); margin-bottom: 6px; display: flex; gap: 16px; }
.essay-index .meta .tag { color: var(--tide); }
.essay-index h3 a { color: var(--ink); }
.essay-index h3 a:hover { color: var(--tide); }
.essay-index p { font-size: 16px; color: var(--ink-70); margin-top: 6px; }

/* ============================================================
   Testimonials
   ============================================================ */
.avatar {
  width: 52px; height: 52px; border-radius: 50%; object-fit: cover; flex: none;
  background: var(--mist); border: 1px solid var(--line);
}
.avatar--initials {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 19px; font-weight: 600; color: #fff;
  background: linear-gradient(140deg, var(--tide) 0%, var(--tide-deep) 100%);
  border: 1px solid var(--gold-soft);
}
.stars { display: inline-flex; gap: 3px; color: var(--gold-ink); }
.band .stars, .glass-dark .stars, .page-hero .stars { color: var(--gold); }
.stars svg { width: 15px; height: 15px; display: block; }

/* single featured quote block */
.quote-feature { max-width: 860px; }
.quote-feature blockquote { font-family: var(--serif); font-size: clamp(22px, 3vw, 30px); font-weight: 500; line-height: 1.45; color: var(--ink); }
.band .quote-feature blockquote { color: var(--paper); }
.quote-feature .qmark { font-family: var(--serif); font-size: 64px; line-height: 0.5; color: var(--gold); display: block; height: 32px; }
.quote-attrib { display: flex; align-items: center; gap: 14px; margin-top: 28px; }
.quote-attrib .who { display: flex; flex-direction: column; gap: 2px; }
.quote-attrib .who .name { font-weight: 500; color: var(--ink); font-size: 16px; }
.quote-attrib .who .role { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--slate); text-transform: uppercase; }
.band .quote-attrib .who .name { color: var(--paper); }
.band .quote-attrib .who .role { color: var(--paper-70); }
.quote-attrib .stars { margin-left: auto; }

/* compact testimonial card (rails / grids) */
.tcard { border: 1px solid var(--line); background: rgba(255,255,255,0.72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); padding: 26px 24px; display: flex; flex-direction: column; gap: 16px; -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid; }
.tcard .stars { color: var(--gold-ink); }
.band .tcard .stars { color: var(--gold); }
/* some quotes were captured with line breaks in them. pre-line honours those
   rather than collapsing them into a run-on line, and changes no wording. */
.tcard p.tquote { font-size: 15.5px; line-height: 1.6; color: var(--ink-70); white-space: pre-line; }
.tcard .tperson { display: flex; align-items: center; gap: 12px; margin-top: auto; }
.tcard .avatar { width: 44px; height: 44px; }
.tcard .avatar--initials { font-size: 16px; }
.tcard .tname { font-size: 15px; font-weight: 500; color: var(--ink); }
.tcard .trole { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--slate); margin-top: 2px; line-height: 1.35; }

/* the wall — masonry via CSS columns */
/* grid, not columns: multicol fills column by column, so a reader hits the
   bottom of column one and assumes the wall has ended. */
.wall { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 22px; margin-top: 8px; }
.wall > .tcard { margin: 0; }
.wall > li { break-inside: avoid; }
.tcard figure { margin: 0; display: flex; flex-direction: column; gap: 16px; flex: 1; }
.tcard blockquote.tquote { margin: 0; }
/* 47 cards means 47 backdrop readbacks. Bump the fill instead. */
.wall > .tcard { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(255,255,255,0.86); }
.wall-toolbar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 24px 0 36px; }
.wall-toolbar .count { font-family: var(--mono); font-size: 13px; letter-spacing: 0.08em; color: var(--slate); }
.wall-toolbar .count strong { font-family: var(--serif); font-size: 22px; color: var(--tide); font-weight: 600; }

/* testimonial rail (home / interior) */
.trail { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 24px; }

/* ============================================================
   Subscribe
   ============================================================ */
.subscribe { padding: 112px 0; }
.subscribe.band h2 { text-shadow: 0 1px 20px rgba(4,18,20,0.55); }
.subscribe h2 { margin-bottom: 8px; }
.subscribe .sub { color: var(--paper-70); margin-bottom: 12px; max-width: 560px; }
.subscribe .promise { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 26px; margin: 0 0 24px; }
.subscribe .promise li { font-size: 15px; color: var(--paper-70); display: flex; align-items: center; gap: 8px; }
.subscribe .promise li::before { content: ""; width: 6px; height: 6px; background: var(--gold); border-radius: 50%; flex: none; }
.sub-form { display: flex; gap: 12px; max-width: 480px; flex-wrap: wrap; }
.sub-form input[type=email] { flex: 1; min-width: 220px; font-family: var(--sans); font-size: 16px; padding: 13px 16px; border: 1px solid rgba(250, 248, 245, 0.45); background: rgba(8,26,29,0.55); color: var(--paper); }
.sub-form input::placeholder { color: var(--paper-50); }
.sub-form input:focus { outline: 2px solid var(--gold); outline-offset: 1px; border-color: var(--gold); }
.subscribe .fine { font-size: 13px; color: var(--paper-70); margin-top: 12px; }
.subscribe .socialproof { display: flex; align-items: center; gap: 14px; margin-top: 28px; }
.subscribe .socialproof .faces { display: flex; }
.subscribe .socialproof .faces .avatar { width: 36px; height: 36px; margin-left: -10px; border: 2px solid var(--tide-deep); }
.subscribe .socialproof .faces .avatar:first-child { margin-left: 0; }
.subscribe .socialproof .pf { font-size: 14px; color: var(--paper-70); }
.subscribe .socialproof .pf strong { color: var(--paper); }

/* light subscribe (paper mode) */
.subscribe--light { background: #fff; border-top: 1px solid var(--gold); border-bottom: 1px solid var(--line); }
.subscribe--light h2 { text-shadow: none; }
.subscribe--light .sub { color: var(--slate); }
.subscribe--light .promise li { color: var(--slate); }
.subscribe--light .sub-form input[type=email] { border: 1px solid var(--line); background: var(--paper); color: var(--ink); }
.subscribe--light .sub-form input::placeholder { color: var(--ink-50); }
.subscribe--light .sub-form input:focus { outline: 2px solid var(--tide); border-color: var(--tide); }
.subscribe--light .fine { color: var(--slate); }
.subscribe--light .socialproof .pf { color: var(--slate); }
.subscribe--light .socialproof .pf strong { color: var(--ink); }
.subscribe--light .socialproof .faces .avatar { border-color: #fff; }

/* ============================================================
   Ethos / beliefs
   ============================================================ */
.belief { min-height: 62vh; min-height: 62svh; display: flex; align-items: center; padding: 48px 0; border-bottom: 1px solid var(--line); }
.belief p { font-family: var(--serif); font-weight: 500; font-size: clamp(28px, 4.4vw, 44px); line-height: 1.3; max-width: 900px; }
.belief--staircase { min-height: 92vh; min-height: 92svh; border-bottom: none; position: relative; }
@media (max-height: 640px) and (orientation: landscape) { .belief, .belief--staircase { min-height: 0; } }
.belief--staircase p { font-size: clamp(30px, 4.8vw, 50px); font-weight: 600; }
.spiral-mark { margin-bottom: 40px; }

/* ============================================================
   Facts / forms / todo
   ============================================================ */
.facts { border-top: 1px solid var(--gold); }
.facts > div { display: grid; grid-template-columns: 220px 1fr; gap: 8px 32px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.facts dt { font-family: var(--mono); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--slate); padding-top: 5px; }
.facts dd { font-size: 17px; }

.form { display: flex; flex-direction: column; gap: 20px; max-width: 560px; }
.form label { display: block; font-family: var(--mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--slate); margin-bottom: 6px; }
.form input, .form select, .form textarea { width: 100%; font-family: var(--sans); font-size: 16px; padding: 12px 14px; border: 1px solid #8E8E8E; background: #fff; color: var(--ink); }
.form input:focus, .form select:focus, .form textarea:focus { outline: 2px solid var(--tide); outline-offset: 1px; }
.form textarea { min-height: 140px; resize: vertical; }
.form input::placeholder, .form textarea::placeholder { color: var(--ink-50); }

/* forms sitting on a dark band need their own contrast treatment */
.band .form label { color: var(--paper); font-size: 12px; }
.band .form { max-width: 720px; }
.band .form input, .band .form select, .band .form textarea {
  background: var(--mist); color: var(--ink); border: 1px solid var(--gold-soft);
}
.band .form input:focus, .band .form select:focus, .band .form textarea:focus {
  outline: 2px solid var(--gold); outline-offset: 2px; background: #fff;
}

.form-confirm { font-family: var(--mono); font-size: 14px; letter-spacing: 0.06em; margin-top: 10px; color: var(--gold-ink); }
.band .form-confirm { color: var(--gold); }

.todo { font-family: var(--mono); font-size: 13px; color: var(--slate); background: rgba(236,236,236,0.6); padding: 16px 20px; border-left: 2px solid var(--gold); }

/* ============================================================
   Booking embed (Work With Me)
   ============================================================ */
/* ONE source of truth for the height: the widget div below. Previously three
   things set it, the container, the iframe and Calendly's own inline style,
   and the tallest won. That left roughly 170px of empty white under the
   calendar on desktop and far more on a phone, because the iframe was pinned
   to 940px while Calendly's content needed about 700.

   The height lives here rather than in the inline style Calendly ships,
   because an inline style cannot be overridden by a media query and the
   compact view needs a different height on a phone.

   TUNE HERE: --booking-h is the only number to change. The day and time steps
   fit inside it; Calendly scrolls its own confirm step internally if that one
   runs taller. */
.booking-embed {
  --booking-h: 660px;
  border: 1px solid var(--line); background: #fff; overflow: hidden;
}
.booking-embed .calendly-inline-widget {
  min-width: 320px; height: var(--booking-h); width: 100%;
}
.booking-embed iframe { display: block; width: 100%; height: 100%; border: 0; }
.booking-fallback { font-size: 16px; color: var(--slate); padding: 32px 24px; max-width: 44ch; margin: 0 auto; text-align: center; }
@media (max-width: 640px) {
  /* Measured, not assumed: with event details hidden the compact view needs
     roughly the same height on a phone as on desktop, so there is no height
     override here. What it does need is width. The reading column leaves it
     346px at 390px wide, which pushes Saturday to the clipped edge, so the
     embed is allowed to eat most of the page gutter. */
  .booking-embed { margin-left: -14px; margin-right: -14px; }
}

/* ============================================================
   Footer
   ============================================================ */
.footer { border-top: 1px solid var(--line); padding: 56px 0 40px; margin-top: 0; }
.footer-grid { display: flex; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.footer a { color: var(--ink-70); font-size: 15px; }
.footer a:hover { color: var(--tide); }
.footer .col { display: flex; flex-direction: column; gap: 10px; }
.footer .col ul { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.footer .col h2.label { font-size: 12px; margin-bottom: 4px; font-family: var(--mono); font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-50); }
.footer .col .label { margin-bottom: 4px; }
.footer-bottom { margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.footer-bottom span { font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; color: var(--ink-50); }

/* ============================================================
   MOTION
   ============================================================ */
/* scroll reveal */
/* No will-change here on purpose: it would hold a compositor layer per reveal
   for the whole session, and browsers already promote an element for the life
   of an opacity or transform transition. */
.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.7s cubic-bezier(0.22,0.61,0.36,1), transform 0.7s cubic-bezier(0.22,0.61,0.36,1); }
.js .reveal.is-revealed { opacity: 1; transform: translateY(0); }
/* legacy .rise alias (kept so any residual markup still animates) */
.js .rise { opacity: 0; transform: translateY(18px); transition: opacity 0.6s cubic-bezier(0.22,0.61,0.36,1), transform 0.6s cubic-bezier(0.22,0.61,0.36,1); }
.js .rise.in, .js .rise.is-revealed { opacity: 1; transform: none; }

/* hero entrance (staggered fade + rise) */
@keyframes jm-rise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: translateY(0); } }
.js .hero-anim { opacity: 0; animation: jm-rise 0.85s cubic-bezier(0.22,0.61,0.36,1) forwards; animation-delay: var(--hero-delay, 0ms); will-change: opacity, transform; }

/* nav drops in last */
@keyframes jm-drop { from { opacity: 0; transform: translateY(-18px); } to { opacity: 1; transform: translateY(0); } }
.js .nav-anim { opacity: 0; animation: jm-drop 0.8s cubic-bezier(0.22,0.61,0.36,1) forwards; animation-delay: var(--hero-delay, 0ms); will-change: opacity, transform; }

/* Ken Burns entrance, synced with the scrim sweep (2.3s).
   The motion itself lives in js/site.js, not here. A CSS keyframe cannot carry
   the scroll offset, so a keyframe entrance plus an inline parallax means two
   systems own one property and the swap between them is visible. This rule is
   only the start state; JS takes the transform over on its first frame and
   never gives it back. If js/site.js fails to load, the inline onerror handler
   in every page removes the .js class and this rule stops applying, so the
   hero simply sits unscaled. */
.js .hero-bleed .hero-img { transform: scale(1.20) translate3d(-1.5%, -1%, 0); will-change: transform; }
/* scrim sweep — veil lifts dark to light */
@keyframes jm-lift { 0% { opacity: 1; } 25% { opacity: 0.92; } 60% { opacity: 0.5; } 100% { opacity: 0; } }
/* linear on purpose: a timing function applies between every PAIR of keyframes,
   so a bezier here stalls the fade at 25% and again at 60%. The opacity stops
   already carry the shape of the curve. */
.js .hero-veil { opacity: 1; animation: jm-lift 2.3s linear forwards; will-change: opacity; }

/* count-up numbers hold a min-width so layout does not jump */
.countup { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .rise { opacity: 1 !important; transform: none !important; transition: none !important; }
  .hero-anim, .nav-anim { opacity: 1 !important; animation: none !important; }
  /* cancels the .js start state, since the JS entrance never runs under reduce */
  .hero-bleed .hero-img { transform: none !important; }
  .hero-veil { animation: none !important; opacity: 0 !important; }
  /* the parallax handler is skipped under reduce, but a mid-session toggle
     would otherwise strand the hero copy shifted and half faded */
  .hero-content { transform: none !important; opacity: 1 !important; }
  .btn:hover { transform: none; }
  .reveal, .rise, .hero-anim, .nav-anim, .hero-veil, .hero-bleed .hero-img { will-change: auto !important; }
  .scroll-cue { display: none; }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 860px) {
  body { font-size: 17px; }
  .section { padding: 64px 0; }
  .section--tight { padding: 48px 0; }
  .subscribe { padding: 72px 0; }
  .nav-inner { padding: 16px 22px; }
  .hero-content { padding: 128px 22px 64px; }
  /* The subject sits at 61% across a 1672x941 landscape frame. In a tall phone
     box object-fit:cover crops by width, and at 45% the window landed entirely
     on the empty side of the photograph, so the hero rendered as a flat dark
     field with no face in it at 390x844 and 414x896. Measured against the real
     asset: 68% puts him in frame and roughly centred at every phone size, and
     he lands in the upper third, above the bottom-aligned copy. */
  .hero-bleed .hero-img {
    object-position: 68% 26%;
    /* the phone crop shows far less of the frame, so it carries less light */
    filter: saturate(0.66) contrast(1.05) brightness(1.06);
  }
  /* On a phone the portrait and the headline occupy the same vertical band,
     because the copy spans the full width instead of sitting beside him. So
     the scrim stays dark from the bottom up through the whole copy block, and
     only opens up at the very top where his face is and no text sits. The
     headline then carries its own contrast with a heavier shadow rather than
     needing a dark plate over his face. */
  .hero-scrim {
    background:
      radial-gradient(ellipse 95% 40% at 48% 18%, rgba(62,138,147,0.14) 0%, rgba(62,138,147,0) 64%),
      linear-gradient(to top, rgba(8,26,29,0.97) 0%, rgba(9,30,34,0.94) 40%, rgba(10,34,39,0.80) 66%, rgba(12,42,46,0.46) 88%, rgba(12,42,46,0.34) 100%),
      linear-gradient(to right, rgba(10,36,40,0.44) 0%, rgba(12,42,46,0.18) 55%, rgba(31,92,99,0.05) 100%);
  }
  .hero-content h1 { text-shadow: 0 2px 20px rgba(4,18,20,0.92), 0 1px 3px rgba(4,18,20,0.75); }
  .hero-sub { text-shadow: 0 1px 12px rgba(4,18,20,0.85); }
  .hero-sub { font-size: 18px; }
  .page-hero { padding: 120px 0 56px; }
  .pillars { grid-template-columns: 1fr; }
  .cards, .cards--4 { grid-template-columns: 1fr; }
  .trail { grid-template-columns: 1fr; }
  .facts > div { grid-template-columns: 1fr; gap: 2px; }
  .proof-list .num { min-width: 130px; font-size: 24px; }
}
/* =========================================================================
   Phone hero. Scoped to 600px, not the 860px breakpoint above.

   A tablet at 768x1024 is wide enough that the copy column sits beside him
   and never collides, and its aspect ratio is close enough to the source
   that the plain cover crop shows his whole head. Applying the phone lift
   there magnifies the image to 165 percent and crops the top of his head
   off. So the tablet keeps the treatment above untouched.
   ========================================================================= */
@media (max-width: 600px) {
  /* ---------- Mobile hero: the copy sits on his jacket, not his face ----------
     On desktop he is on the right and the copy is on the left, so they never
     touch. On a phone the copy spans the full width, so it lands in the same
     band as his face and both lose.

     The fix is to lift him. The image box is taller than the hero and pulled
     up, which moves his face into the top third and puts his jacket, which is
     near black and even, behind the headline. Measured against the real asset
     at 390x844: the face lands 13 percent down and 48 percent across.

     top and height work together here. The image is position:absolute with
     inset:0, so bottom must be released or height is ignored. */
  .hero-bleed .hero-img {
    top: -30%; bottom: auto; height: 152%;
    object-position: 64% 0%;
    filter: saturate(0.66) contrast(1.05) brightness(1.04);
  }
  /* dark through the copy, open at the top where his face is */
  .hero-scrim {
    background:
      linear-gradient(to top, rgba(8,26,29,0.96) 0%, rgba(9,30,34,0.93) 44%, rgba(10,34,39,0.58) 70%, rgba(12,42,46,0.18) 100%),
      linear-gradient(to right, rgba(10,36,40,0.28) 0%, rgba(12,42,46,0.10) 60%, rgba(31,92,99,0.03) 100%);
  }
  .hero-content { padding: 44px 22px 46px; }
  .hero-content h1 { font-size: 34px; max-width: none; text-shadow: 0 2px 16px rgba(4,18,20,0.85); }
  .hero-sub { font-size: 16px; margin-bottom: 26px; text-shadow: 0 1px 12px rgba(4,18,20,0.8); }
  /* the credential line returns in the Proof section immediately below, and
     keeping it here would push the copy back up into his face */
  .cred-bar { display: none; }

  /* The scroll cue is a desktop affordance. There, the copy sits in the left
     column and the cue has the bottom centre to itself. On a phone the copy
     spans the full width and its button row ends up in exactly that band, so
     the cue lands on top of "Or find your constraint".

     Bottom-anchored at 26px it also fights the iOS Safari toolbar, which
     floats over the same strip. Nothing signals a scroll on a phone anyway,
     the image running off the bottom edge already does that. */
  .scroll-cue { display: none; }
}

@media (max-width: 600px) and (max-height: 779px) {
  .hero-bleed .hero-img { top: -6%; height: 112%; }
  .hero-content { padding: 30px 20px 32px; }
  /* the credential line survives in the About copy further down the page,
     so dropping it here costs no information and buys 68px */
  .hero-content .kicker { display: none; }
  .hero-content .rule-gold { margin: 0 0 18px; }
  .hero-content h1 { font-size: 27px; line-height: 1.14; }
  .hero-sub { font-size: 14.5px; line-height: 1.5; margin-bottom: 18px; }
}

@media (max-width: 600px) and (max-height: 620px) {
  /* 71% not 61%: object-position is applied before the rest-scale transform
     the hero script leaves on the image, so the arithmetic centre lands right
     of the optical one. This value is read off the render, not computed. */
  .hero-bleed .hero-img { top: 0; height: 100%; object-position: 71% 10%; }
  .hero-content h1 { font-size: 24px; }
  .hero-sub { font-size: 14px; margin-bottom: 16px; }
  .hero-scrim {
    background:
      linear-gradient(to top, rgba(8,26,29,0.97) 0%, rgba(9,30,34,0.94) 52%, rgba(10,34,39,0.72) 78%, rgba(12,42,46,0.34) 100%),
      linear-gradient(to right, rgba(10,36,40,0.34) 0%, rgba(12,42,46,0.12) 60%, rgba(31,92,99,0.03) 100%);
  }
}


/* ---------- Mobile hero, short-viewport tier ----------
   The block above assumes a modern tall phone. Measured, the copy column is
   515px on a 390x844 and 587px on a 375x667, because narrower text wraps to
   more lines exactly where there is less height to spend. On anything under
   about 780px tall that leaves nothing above the copy, and the portrait ends
   up behind the type again.

   So on short viewports the copy gets smaller and the lift gets shallower.
   Less lift means a smaller scale factor, which means his face renders
   smaller and sits lower, which is what buys the clearance back. */

@media (max-width: 640px) {
  /* a 130px number column left 118px of text at 320px, three words a line */
  .proof-list li { display: block; }
  .proof-list .num { display: block; min-width: 0; margin-bottom: 4px; }
  .logo-wall { grid-template-columns: 1fr; }
  .logo-wall li { min-height: 88px; }
  .wall { grid-template-columns: 1fr; }

  /* no-JS: the hamburger is hidden, so the row must be allowed to wrap */
  .nav-links { flex-wrap: wrap; row-gap: 12px; }
  .js .nav-links { flex-wrap: nowrap; }
  /* tap targets: primary nav links were 26px, the hamburger 34x38, and every
     footer link an 18px inline box */
  .wrap, .wrap-wide { padding: 0 22px; }
  .nav-toggle { padding: 6px 11px; min-height: 44px; }
  .js .nav-links > a { display: block; width: 100%; padding: 9px 0; }
  .js .nav-links .nav-item > button { padding: 13px 0; }
  .footer .col ul { gap: 0; }
  .footer .col ul li a { display: block; padding: 13px 0; }
  .btn { padding: 13px 24px; }
  .tcard .trole { font-size: 11.5px; }
  .form label, .chips legend, .quote-attrib .who .role, .card .label { font-size: 12px; }
  .js .nav-toggle { display: block; }
  .js .nav-links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: rgba(250,248,245,0.98); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
    flex-direction: column; align-items: flex-start; padding: 22px 24px; gap: 18px;
    max-height: calc(100vh - 100%); max-height: calc(100dvh - 100%); overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
  .js .nav--over-hero .nav-links, .nav--over-hero .nav-links.open { background: rgba(12,42,46,0.96); }
  .nav-links.open { display: flex; }
  .nav-item { width: 100%; }
  .nav-menu { position: static; display: flex; border: none; border-top: none; box-shadow: none; background: transparent; padding: 8px 0 0 12px; min-width: 0; }
  .nav-item[data-open="true"] .nav-menu { display: flex; } .nav-item[data-open="false"] .nav-menu { display: none; }
  .nav--over-hero .nav-menu a { color: rgba(250,248,245,0.8); }
}


/* ============================================================
   The letter: excerpt teaser, magnet card, quiet bar, exit prompt
   All four are inert until there is a real offer behind them.
   ============================================================ */

/* ---------- excerpt teaser: one whole section of a real letter ---------- */
/* No fade-out and no truncation on purpose. A masked "subscribe to read the
   rest" is the most recognisable cheap-site tell there is. The reader gets a
   finished thought, which is what makes it read as a gift. */
.letter-teaser {
  max-width: 680px; background: #fff;
  border: 1px solid var(--line); border-top: 2px solid var(--gold);
  padding: 38px 38px 32px;
  box-shadow: 0 18px 44px rgba(12, 42, 46, 0.07);
}
.letter-teaser .meta {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--slate);
  display: flex; flex-wrap: wrap; gap: 6px 18px;
}
.letter-teaser .subject {
  font-family: var(--serif); font-size: clamp(23px, 2.8vw, 29px); font-weight: 500;
  line-height: 1.25; color: var(--ink); margin: 14px 0 22px;
}
.letter-teaser .excerpt { border: none; padding: 0; margin: 0; }
.letter-teaser .excerpt p { font-size: 17px; line-height: 1.72; color: var(--ink-70); }
.letter-teaser .excerpt p + p { margin-top: 17px; }
.letter-teaser .sign { font-family: var(--serif); font-size: 19px; color: var(--ink); margin-top: 24px; }
.letter-teaser .note {
  font-size: 15px; color: var(--slate);
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line);
}
.band .letter-teaser {
  background: rgba(8, 26, 29, 0.58);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  border-color: var(--paper-line); border-top-color: var(--gold); box-shadow: none;
}
.band .letter-teaser .meta { color: var(--paper-50); }
.band .letter-teaser .subject, .band .letter-teaser .sign { color: var(--paper); }
.band .letter-teaser .excerpt p, .band .letter-teaser .note { color: var(--paper-70); }
.band .letter-teaser .note { border-top-color: var(--paper-line); }

/* ---------- the magnet card ---------- */
.magnet {
  max-width: 720px;
  border: 1px solid var(--line); border-left: 2px solid var(--gold);
  background: rgba(255, 255, 255, 0.74);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 34px 34px 30px;
}
.magnet .label { color: var(--gold-ink); margin-bottom: 12px; }
.magnet h3, .magnet h2 { font-size: clamp(23px, 2.8vw, 29px); margin-bottom: 12px; }
.magnet .what { font-size: 17px; color: var(--ink-70); max-width: 54ch; }
.magnet .inside { list-style: none; margin: 22px 0 26px; display: grid; gap: 11px; }
.magnet .inside li { display: flex; gap: 13px; align-items: baseline; font-size: 16px; color: var(--slate); }
.magnet .inside li::before {
  content: ""; width: 6px; height: 6px; flex: none; border-radius: 50%;
  background: var(--gold); transform: translateY(-2px);
}
.magnet .fine { font-size: 13px; color: var(--slate); margin-top: 14px; max-width: 48ch; }
.band .magnet { background: rgba(8, 26, 29, 0.58); border-color: var(--paper-line); border-left-color: var(--gold); }
.band .magnet .label { color: var(--gold); }
.band .magnet .what, .band .magnet .inside li, .band .magnet .fine { color: var(--paper-70); }

/* ---------- subscribe form on a light ground ---------- */
.sub-form--light input[type=email] { border: 1px solid #8E8E8E; background: #fff; color: var(--ink); }
.sub-form--light input::placeholder { color: var(--ink-50); }
.sub-form--light input:focus { outline: 2px solid var(--tide); outline-offset: 1px; border-color: var(--tide); }
.sub-form .form-confirm { flex-basis: 100%; }

/* ---------- shared dismiss control ---------- */
.letter-dismiss {
  background: none; border: none; cursor: pointer; padding: 7px; line-height: 0;
  color: var(--ink-50); flex: none; min-width: 44px; min-height: 44px;
}
.letter-dismiss:hover { color: var(--ink); }
.letter-dismiss svg { width: 15px; height: 15px; display: block; }

/* ---------- the quiet bar ---------- */
.letter-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  display: flex;
  background: rgba(250, 248, 245, 0.97);
  backdrop-filter: blur(12px) saturate(1.2); -webkit-backdrop-filter: blur(12px) saturate(1.2);
  border-top: 2px solid var(--gold);
  box-shadow: 0 -14px 40px rgba(12, 42, 46, 0.13);
}
/* display:flex outranks the hidden attribute, so this is required for the bar
   to stay invisible with JS off and before the depth gate opens */
.letter-bar[hidden] { display: none; }
.letter-bar .inner {
  position: relative; width: 100%; max-width: 1240px; margin: 0 auto;
  padding: 15px 32px; display: flex; align-items: center; gap: 22px;
}
.letter-bar .pitch { font-size: 15px; line-height: 1.5; color: var(--ink-70); flex: 1; min-width: 220px; }
.letter-bar .pitch strong { color: var(--ink); font-weight: 500; }
.letter-bar .sub-form { max-width: 420px; }
.letter-bar .sub-form input[type=email] { font-size: 16px; padding: 10px 14px; min-width: 170px; }
.letter-bar .sub-form .btn { padding: 10px 20px; }
body.has-letter-bar { padding-bottom: 96px; }

/* ---------- the exit prompt (native dialog) ---------- */
.exit-prompt {
  padding: 0; border: none; background: transparent; color: var(--ink);
  width: calc(100% - 32px); max-width: 560px; margin: auto;
  max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px); overflow: auto;
}
.exit-prompt:not([open]) { display: none; }
.exit-prompt::backdrop { background: rgba(8, 26, 29, 0.64); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
/* zero padding on the dialog is deliberate: a click landing on the dialog
   element itself is a backdrop click, which is what closes it */
.exit-prompt .inner {
  position: relative; background: var(--paper);
  border: 1px solid var(--line); border-top: 2px solid var(--gold);
  padding: 42px 42px 34px;
  box-shadow: 0 30px 80px rgba(12, 42, 46, 0.34);
}
.exit-prompt .label { color: var(--gold-ink); }
.exit-prompt .title { font-size: clamp(26px, 3.4vw, 33px); margin: 12px 0 14px; }
.exit-prompt .what { font-size: 17px; color: var(--ink-70); margin-bottom: 24px; }
.exit-prompt .fine { font-size: 13px; color: var(--slate); margin-top: 14px; }
.exit-prompt .later {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--sans); font-size: 15px; color: var(--slate); text-decoration: underline;
  text-underline-offset: 3px; margin-top: 18px;
}
.exit-prompt .later:hover { color: var(--ink); }
.exit-prompt .letter-dismiss { position: absolute; top: 14px; right: 14px; }

@keyframes jm-bar-in { from { opacity: 0; transform: translateY(100%); } to { opacity: 1; transform: translateY(0); } }
@keyframes jm-prompt-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
.js .letter-bar { animation: jm-bar-in 0.45s var(--ease, cubic-bezier(0.22,0.61,0.36,1)) both; }
.js .exit-prompt[open] .inner { animation: jm-prompt-in 0.35s cubic-bezier(0.22,0.61,0.36,1) both; }
@media (prefers-reduced-motion: reduce) {
  .letter-bar, .exit-prompt[open] .inner { animation: none !important; }
}

@media (max-width: 860px) {
  .letter-teaser { padding: 28px 22px 26px; }
  .letter-teaser .excerpt p { font-size: 16px; }
  .magnet { padding: 26px 22px 24px; }
  .exit-prompt .inner { padding: 34px 24px 28px; }
  .letter-bar .inner { padding: 16px 20px 18px; flex-wrap: wrap; gap: 13px; align-items: flex-start; }
  .letter-bar .pitch { flex-basis: 100%; font-size: 14px; padding-right: 30px; }
  .letter-bar .sub-form { max-width: none; width: 100%; }
  .letter-bar .sub-form input[type=email] { flex: 1 1 100%; }
  .letter-bar .sub-form .btn { width: 100%; }
  .letter-bar .letter-dismiss { position: absolute; top: 8px; right: 12px; }
  body.has-letter-bar { padding-bottom: 210px; }
}


/* ============================================================
   Progressive profile: step two of the subscribe flow
   The email is already recorded before any of this renders, so every
   field here is genuinely optional and the copy says so.
   ============================================================ */
.profile-step {
  border: 1px solid var(--line); border-left: 2px solid var(--gold);
  background: rgba(255, 255, 255, 0.74);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 34px 34px 30px; max-width: 720px;
}
.profile-step h2 { font-size: clamp(23px, 2.8vw, 29px); margin-bottom: 10px; }
.profile-step .what { font-size: 17px; color: var(--ink-70); max-width: 54ch; margin-bottom: 26px; }
.profile-step .form { gap: 18px; max-width: none; }

/* the "already done" marker, so step two reads as a bonus not a toll */
.step-meta {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--slate);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px;
}
.step-meta strong { color: var(--gold-ink); font-weight: 500; }
.step-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); flex: none; }
.step-dot.is-done { background: var(--gold); box-shadow: 0 0 0 3px rgba(197,160,89,0.22); }
.step-sep { width: 22px; height: 1px; background: var(--line); flex: none; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

/* topics as chips: one tap each, no dropdown, no multi-select nonsense */
.chips { border: none; padding: 0; margin: 4px 0 0; }
.chips legend {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--slate); padding: 0; margin-bottom: 12px;
}
.chip { display: inline-flex; margin: 0 8px 8px 0; }
.chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chip span {
  display: inline-flex; align-items: center; cursor: pointer; user-select: none;
  font-size: 15px; line-height: 1.3; padding: 9px 15px;
  border: 1px solid var(--line); background: #fff; color: var(--slate);
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.chip span:hover { border-color: var(--gold-soft); color: var(--ink); }
/* the checked state needs a shape, not just a tint: the band override used to
   outrank :checked and the two states rendered identically */
.chip span::before {
  content: ""; display: inline-block; width: 14px; height: 14px;
  margin-right: 9px; flex: none;
  border: 1px solid #6B6B6B; background: #fff;
}
.chip input:checked + span::before {
  border-color: #1A1A1A; background: #1A1A1A no-repeat center/12px 12px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 7.4l3 3 5-6' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E");
}
.chip input:checked + span,
.band .profile-step .chip input:checked + span {
  border-color: var(--gold-ink); background: rgba(197,160,89,0.20); color: var(--ink);
}
.chip input:focus + span { outline: 3px solid var(--gold-ink); outline-offset: 3px; }
.chip input:focus:not(:focus-visible) + span { outline: none; }
.chip input:focus-visible + span { outline: 3px solid var(--gold-ink); outline-offset: 3px; }
.band .chip input:focus-visible + span { outline-color: var(--paper); }

.step-actions { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-top: 8px; }
.step-skip {
  font-family: var(--sans); font-size: 15px; color: var(--slate);
  background: none; border: none; padding: 9px 0; display: inline-block; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.step-skip:hover { color: var(--ink); }

/* inline variant, injected in place of the email field after step one */
.subscribe .profile-step, .band .profile-step {
  background: rgba(8, 26, 29, 0.58); border-color: var(--paper-line); border-left-color: var(--gold);
  margin-top: 22px;
}
.band .profile-step h2 { color: var(--paper); }
.band .profile-step .what, .band .step-meta, .band .step-skip { color: var(--paper-70); }
.band .profile-step .chip span { background: var(--mist); border-color: var(--gold-soft); color: var(--ink); }
.band .profile-step .chips legend { color: var(--paper); }
.band .step-dot { background: var(--paper-line); }
.band .step-dot.is-done { background: var(--gold); }

@media (max-width: 860px) {
  .profile-step { padding: 26px 22px 24px; }
  .field-row { grid-template-columns: 1fr; }
}


/* ============================================================
   Brand partnerships: media kit components
   ============================================================ */
.statline {
  list-style: none; display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.statline li { background: var(--paper); padding: 28px 24px; display: flex; flex-direction: column; gap: 8px; }
.stat-num { font-family: var(--serif); font-size: clamp(30px, 3.6vw, 42px); font-weight: 600; color: var(--tide); line-height: 1; }
.stat-cap { font-size: 15px; color: var(--slate); line-height: 1.45; }
.band .statline { background: var(--paper-line); border-color: var(--paper-line); }
.band .statline li { background: rgba(8,26,29,0.58); }
.band .stat-num { color: var(--gold); }
.band .stat-cap { color: var(--paper-70); }

/* every number on this page is dated and sourced, on purpose */
.source-note { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; color: var(--slate); margin-top: 18px; }
.band .source-note { color: var(--paper-50); }





.steps { list-style: none; display: grid; gap: 26px; max-width: 720px; }
.steps li { display: grid; grid-template-columns: 44px 1fr; gap: 18px; align-items: start; }
.step-n {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.08em; color: var(--gold-ink);
  width: 44px; height: 44px; border: 1px solid var(--gold-soft);
  display: flex; align-items: center; justify-content: center;
}
.steps h3 { margin-bottom: 4px; }
.steps p { font-size: 16px; color: var(--slate); }

/* the outlier disclaimer is load bearing, so it is styled to be read */
.disclaimer {
  font-size: 14px; line-height: 1.6; color: var(--paper-70); max-width: 720px;
  margin-top: 28px; padding: 18px 22px;
  border-left: 2px solid var(--gold-soft); background: rgba(8,26,29,0.45);
}

@media (max-width: 980px) {
  .statline { grid-template-columns: repeat(2, 1fr); }
  }
@media (max-width: 860px) {
  .statline { grid-template-columns: 1fr; }
  }


/* ---------- partnerships: logo wall, audience read, outliers ---------- */
.lede { font-size: 19px; color: var(--paper-70); max-width: 60ch; margin-bottom: 4px; }
.section--glass .lede, .section .lede { color: var(--ink-70); }
.band .lede { color: var(--paper-70); }

.logo-wall {
  list-style: none; display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--paper-line);
  border: 1px solid var(--paper-line); margin-top: 30px;
}
.logo-wall li {
  background: rgba(8, 26, 29, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 34px 26px; min-height: 128px;
}
.logo-wall img {
  max-width: 100%; max-height: 42px; width: auto; height: auto;
  opacity: 0.86; transition: opacity 0.25s ease, transform 0.25s ease;
}
.logo-wall li:hover img { opacity: 1; transform: translateY(-2px); }
/* the wall is a selection, and this says so without shrinking it */
.wall-more {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--gold);
  text-align: right; margin-top: 14px;
}
@media (prefers-reduced-motion: reduce) { .logo-wall li:hover img { transform: none; } }

.who-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 26px; }
.who-grid > div { background: var(--paper); padding: 34px 30px; }
.who-num { font-family: var(--serif); font-size: clamp(30px, 3.4vw, 40px); font-weight: 600; color: var(--tide); line-height: 1; }
.who-lab { font-family: var(--mono); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-ink); margin: 12px 0 10px; }
.who-sub { font-size: 16px; color: var(--slate); line-height: 1.6; }

.outliers { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 26px; max-width: 860px; }
.outlier { border: 1px solid var(--paper-line); border-left: 2px solid var(--gold); background: rgba(8,26,29,0.55); padding: 30px 28px; }
.o-num { font-family: var(--serif); font-size: clamp(32px, 4vw, 46px); font-weight: 600; color: var(--gold); line-height: 1; }
.o-cap { font-size: 15px; color: var(--paper-70); margin-top: 10px; }

@media (max-width: 980px) {
  .logo-wall { grid-template-columns: repeat(3, 1fr); }
  .who-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .logo-wall { grid-template-columns: repeat(2, 1fr); }
  .logo-wall li { padding: 26px 18px; min-height: 104px; }
  .outliers { grid-template-columns: 1fr; }
}


/* ============================================================
   Print. Dark bands lose their background in print output, so any
   near-white text on them would come out invisible on paper. press.html is
   the page most likely to be printed or saved to PDF.
   ============================================================ */
@media print {
  .reveal, .rise, .hero-anim, .nav-anim { opacity: 1 !important; transform: none !important; animation: none !important; }
  .band, .page-hero, .hero-content, .glass-dark, .subscribe,
  .band h1, .band h2, .band h3, .page-hero h1,
  .band .lede, .band p, .page-hero .page-hero-sub, .hero-sub, .cred-bar {
    background: none !important; color: #1A1A1A !important; text-shadow: none !important;
  }
  .band .label, .band .label--gold, .page-hero .kicker, .label--gold { color: #5A4718 !important; }
  .hero-scrim, .hero-veil, .band-scrim, .page-hero::before, .scroll-cue,
  .nav, .nav-toggle, .letter-bar, .exit-prompt, .skip-link, .booking-embed { display: none !important; }
  .hero-bleed, .page-hero { min-height: 0 !important; padding: 24px 0 !important; margin-top: 0 !important; }
  .hero-bleed .hero-img, .page-hero .hero-img { display: none !important; }
  .section, .section--tight, .subscribe { padding: 18px 0 !important; }
  .wall { grid-template-columns: 1fr 1fr !important; }
  .tcard, .card, .pillar, .letter-teaser, .facts > div, .outlier { break-inside: avoid; page-break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
  /* a printed press kit that loses the URLs is one the journalist has to come back for */
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10pt; color: #4A4A4A; }
  a[href^="mailto"]::after, a[href^="#"]::after { content: ""; }
  body { background: none !important; font-size: 11pt; }
}


/* short viewports: the open nav panel clipped its last items, and the hero
   pushed its CTA two screens down on a landscape phone */
@media (max-width: 860px) and (max-height: 620px) {
  .js .nav-links { padding: 14px 22px; gap: 10px; }
  .nav-menu a { padding: 7px 12px; }
}
@media (max-width: 860px) and (max-height: 480px) {
  .hero-content { padding: 92px 22px 40px; }
  .hero-content h1 { font-size: 32px; }
  .cred-bar { display: none; }
}
