/* site.css — sailboss.ai marketing site.
   Standalone (does not load the app's tokens.css) but deliberately mirrors the
   app's HACKER theme: #28FE14 phosphor green on near-black, IBM Plex Mono for
   everything functional. Values lifted from src/sailgpt/assets/tokens.css so
   the site and the product read as one system. Unlike the app, the lime is an
   accent here, not the body colour — see the hierarchy note below. */

:root {
  --bg: #000000;
  --surface: #060B06;
  --sunken: #0A120A;
  --line: #123610;
  --line-2: #1A4716;
  --line-3: #266326;
  --ink: #28FE14;
  --ink-bright: #6BFF55;
  --muted: #8DA38F;
  --faint: #5F7361;
  --loss: #F36B5C;
  --warn: #E8C547;
  --on-accent: #001400;
  --cyan: #55CFF5;      /* secondary — pipeline stages, feature markers */
  --amber: #E8C547;     /* tertiary  — reserved for emphasis            */
  /* The marketing site keeps the app's technical character without copying
     every app token literally. Tighter corners and a sans display face give
     the narrative surfaces a distinct, more editorial hierarchy. */
  --r: 4px;
  --page-max: 1320px;
  --font: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-display: "IBM Plex Sans", system-ui, -apple-system, Segoe UI, sans-serif;
}

/* Colour hierarchy, deliberately narrow:
     --paper  reading text (headlines, body) — carries almost all the words
     --ink    lime, reserved for the product name, the active nav item, the
              highlighter and the primary CTA. Accent, never a body colour.
     --muted  secondary prose, inactive nav, labels — green-grey, so the page
              stays in family without competing with the lime
     --cyan   data/secondary accent   --loss  tertiary accent (losses, alerts)
   Both cyan and coral already occur inside the replay render, so the wider
   palette still reads as the product rather than as decoration. */
:root {
  --paper: #F0F1E9;   /* headings                                   18.5:1 */
  --body:  #C5C6C0;   /* reading text                               12.2:1 */
  --lead:  #DCDDD6;   /* the one paragraph that must be read        15.4:1 */
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--paper);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.wrap { max-width: var(--page-max); margin: 0 auto; padding: 0 24px; }

/* ── Site chrome ─────────────────────────────────────────────────────────── */

.nav {
  position: sticky; top: 0; z-index: 20;
  background: rgba(0, 0, 0, 0.92);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(6px);
}

.nav-inner {
  max-width: var(--page-max); margin: 0 auto;
  padding: 0 24px; min-height: 56px;
  display: flex; align-items: center; gap: 26px;
}

.brand {
  display: inline-flex; align-items: baseline;
  font-weight: 700; font-size: 20px; letter-spacing: -0.02em;
  text-decoration: none; color: var(--ink); margin-right: auto;
  white-space: nowrap;
}
.brand .b-sail { color: var(--ink); }
.brand:hover .b-sail { color: var(--ink-bright); }

/* Nav links. Also covers <button class="navlink"> (Contact us), which opens
   the dialog but must read exactly like the Regattas tab. */
.nav .navlink {
  font: inherit; font-size: 13px; text-decoration: none; color: var(--muted);
  padding: 4px 0; border: 0; border-bottom: 1px solid transparent;
  background: none; cursor: pointer;
}
.nav .navlink:hover { color: var(--ink); }
.nav .navlink[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); }

.nav-inner { gap: 28px; }

.foot {
  border-top: 1px solid var(--line);
  margin-top: 80px; padding: 34px 0 56px;
  color: var(--faint); font-size: 13px;
}
.foot .wrap { display: flex; gap: 20px; flex-wrap: wrap; align-items: baseline; }
.foot .sp { margin-left: auto; }

/* ── Hero ────────────────────────────────────────────────────────────────── */

.hero {
  position: relative; overflow: hidden;
  border-bottom: 1px solid var(--line);
  /* The field the render sits in, not a backdrop. Its core is the water tone
     sampled out of the replay hero (~#3B3C3D) and it decays to page black at the
     hero's own edges. Blending the image into black meant fighting it at every
     boundary; blending it into its own grey means the boundary has nothing to
     announce. The grey creeps out into the black, rather than the black
     creeping into the picture. */
  background:
    radial-gradient(ellipse 50% 62% at 67% 49%,
      #3C3D3E 0%, #383A3B 46%, #313334 66%,
      #202323 80%, #101312 91%, #050806 100%);
}
/* Sized to the image itself — height plus the source aspect ratio — so the
   mask percentages below are the image's own edges at any viewport width, not
   a guess at where it sits inside a wider box. */
.hero::after {
  content: ""; position: absolute; z-index: 0;
  top: 8%; right: 0; height: 84%;
  aspect-ratio: 2242 / 1292;             /* natural size of img/hero-replay.jpg */
  background: url("img/hero-replay.jpg") center / cover no-repeat;
  /* Eased ramps, not linear — a straight alpha ramp shows a kink where it
     starts and stops, and that kink is what reads as an edge. Short is enough
     now: grey dissolving into matching grey needs far less runway than grey
     dissolving into black. No ramp on the right, where the image ends flush
     with the page. */
  -webkit-mask-image:
    linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.04) 6%,
      rgba(0,0,0,.18) 12%, rgba(0,0,0,.45) 18%, rgba(0,0,0,.75) 24%,
      #000 32%, #000 100%),
    linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.05) 4%,
      rgba(0,0,0,.20) 8%, rgba(0,0,0,.50) 12%, rgba(0,0,0,.80) 16%,
      #000 22%, #000 78%, rgba(0,0,0,.80) 84%, rgba(0,0,0,.50) 88%,
      rgba(0,0,0,.20) 92%, rgba(0,0,0,.05) 96%, rgba(0,0,0,0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.04) 6%,
      rgba(0,0,0,.18) 12%, rgba(0,0,0,.45) 18%, rgba(0,0,0,.75) 24%,
      #000 32%, #000 100%),
    linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.05) 4%,
      rgba(0,0,0,.20) 8%, rgba(0,0,0,.50) 12%, rgba(0,0,0,.80) 16%,
      #000 22%, #000 78%, rgba(0,0,0,.80) 84%, rgba(0,0,0,.50) 88%,
      rgba(0,0,0,.20) 92%, rgba(0,0,0,.05) 96%, rgba(0,0,0,0) 100%);
  mask-composite: intersect;
}
/* Legibility only: hold the left of the frame down to black so the headline
   has a field to sit on. The edges are the grey field's job now. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, #050806 0%, rgba(5,8,6,.94) 24%,
                                     rgba(5,8,6,.58) 46%, rgba(5,8,6,.18) 66%,
                                     rgba(5,8,6,0) 80%);
}
.hero .wrap { position: relative; z-index: 2; padding-top: 74px; padding-bottom: 66px; }

h1 {
  margin: 0 0 24px; max-width: 990px;
  font-family: var(--font-display);
  font-size: clamp(28px, 3.9vw, 46px);
  font-weight: 700; line-height: 1.14; letter-spacing: -0.02em;
  color: var(--paper);
  text-shadow: 0 2px 18px rgba(0,0,0,.85);
}

/* The product name always sets in the interface mono, even inside a heading
   that is otherwise display sans — one treatment for the word everywhere it
   appears. In the hero it is also the only lime in the headline. */
.sb { font-family: var(--font); letter-spacing: -0.03em; }
/* Keep the product name as one lime unit inside the hero. */
h1 .brandmark { color: var(--ink); }
h1 .brandmark .b-sail { color: var(--ink); }

/* A slightly imperfect technical marker stroke: enough human texture to make
   the differentiator feel emphasized, without leaving the hacker vocabulary. */
h1 .hl {
  position: relative; z-index: 0;
  color: #06090A; white-space: nowrap;
  margin-left: .10em; padding: 0 1px;
}
h1 .hl::before {
  content: ""; position: absolute; z-index: -1;
  inset: 0.12em -0.16em 0.055em -0.13em;
  background: var(--ink);
  transform: rotate(-1deg);
  clip-path: polygon(
    2.6% 0%, 97.6% 0%,
    100% 16%, 97.2% 33%, 99.6% 51%, 97.4% 70%, 100% 87%, 98.2% 100%,
    2.2% 100%,
    0% 84%, 2.9% 66%, 0.4% 48%, 2.7% 30%, 0% 13%);
}

.lede {
  margin: 0; max-width: 54ch;
  font-size: clamp(15px, 1.55vw, 17px);
  color: var(--paper); opacity: .9;
  text-shadow: 0 1px 12px rgba(0,0,0,.9);
}

/* Supporting line — smaller and quieter so the reconstruction claim lands
   first and this reads as the consequence of it. */
.lede-2 {
  margin-top: 16px;
  max-width: 46ch;
  font-size: clamp(13.5px, 1.2vw, 15px);
  color: var(--muted); opacity: 1;
}

/* Narrow viewports put the copy over the whole frame, so the left-to-right
   clearing has nowhere to go — fall back to an even wash and pull the crop
   back toward the boats. */
@media (max-width: 860px) {
  .hero::before {
    background: linear-gradient(180deg, rgba(5,8,6,.90), rgba(5,8,6,.80) 55%, rgba(5,8,6,.92));
  }
  /* Too narrow to fit the render by height and still leave a column for the
     copy — go back to filling the frame, no mask, and let the wash carry
     legibility. */
  .hero::after {
    inset: 0; height: auto; aspect-ratio: auto;
    background-size: cover; background-position: 55% 42%;
    -webkit-mask-image: none; mask-image: none;
  }
  .nav-inner, .wrap { padding-left: 18px; padding-right: 18px; }
  .hero .wrap { padding-top: 64px; padding-bottom: 64px; }
}

/* Nav buttons: "Sign up for free" (filled) and "Contact us" (outline). */
.nav-mail, .nav-btn {
  font-size: 12.5px; padding: 6px 12px;
  border-color: var(--line-2); color: var(--muted);
  white-space: nowrap;
}
.nav-mail:hover, .nav-btn:hover { background: var(--ink); color: var(--on-accent); border-color: var(--ink); }

/* "Get started" is the one filled element in the nav, so the way into the
   product is always one glance away. */
a.nav-app {
  text-decoration: none;
  background: var(--ink); color: var(--on-accent); border-color: var(--ink);
  font-weight: 600;
}
a.nav-app:hover { background: var(--ink-bright); border-color: var(--ink-bright); color: var(--on-accent); }

.kicker {
  margin: 0 0 16px;
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--cyan);
}

.cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin: 30px 0 0; }

/* Proof bar — sits directly under the hero, so the first scroll is evidence
   rather than more prose. */
.proofbar {
  border-bottom: 1px solid var(--line);
  background: var(--sunken);
  font-size: 13px;
}
.proofbar .wrap {
  display: flex; flex-wrap: wrap; gap: 10px 34px;
  padding-top: 15px; padding-bottom: 15px;
  color: var(--muted);
}
.proofbar span { white-space: nowrap; }

/* Figure in accent, label in green-grey. Three different accents rather than
   three limes: the numbers are distinguishable at a glance and the bar stops
   competing with the headline for the same colour. */
.proofbar .pf b { font-weight: 700; font-size: 15px; margin-right: 3px; }
.proofbar .p1 b { color: var(--ink); }
.proofbar .p2 b { color: var(--cyan); }
.proofbar .p3 b { color: var(--loss); }

/* Signals the figures are a growing catalog rather than a fixed claim. The
   pulsing dot is decorative only — the date and wording carry the meaning, so
   it degrades fine under prefers-reduced-motion or with CSS animation off. */
.proofbar .grow {
  margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
  color: var(--faint);
}
.proofbar .grow::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink); flex: 0 0 auto;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: .35; transform: scale(.85); }
  50%      { opacity: 1;   transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .proofbar .grow::before { animation: none; opacity: .8; }
}
@media (max-width: 720px) {
  .proofbar .grow { margin-left: 0; white-space: normal; }
}

/* ── Contents column ─────────────────────────────────────────────────────── */
/* A table of contents beside the argument rather than above it. Entries are
   the section headings verbatim — a contents list that paraphrases is a second
   thing to read. It sticks while you scroll, so it doubles as a position
   indicator: the highlighted entry is the section you are in. */

.reading {
  display: grid; grid-template-columns: 268px minmax(0, 1fr); gap: 0 44px;
  align-items: start;
}
.reading-body { min-width: 0; }

.toc {
  position: sticky; top: 84px;
  padding-top: 64px;              /* aligns with the first section's heading */
  display: flex; flex-direction: column; gap: 2px;
}
.toc-h {
  margin: 0 0 10px;
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--faint);
}
.tocp {
  font-size: 13px; line-height: 1.4; text-decoration: none;
  color: var(--muted);
  padding: 7px 0 7px 13px;
  border-left: 2px solid var(--line);
}
.tocp:hover { color: var(--paper); border-left-color: var(--line-3); }
.tocp.on { color: var(--ink); border-left-color: var(--ink); }

/* Clear the sticky nav plus a little air. */
section[id] { scroll-margin-top: 92px; }

@media (max-width: 980px) {
  /* No room for a column beside the text. The contents move above it and stop
     sticking; the list form stays, because the entries are whole headings and
     were too long to sit in pills. */
  .reading { grid-template-columns: 1fr; }
  .toc { position: static; padding-top: 36px; padding-bottom: 8px; }
  .tocp { font-size: 12.5px; padding: 5px 0 5px 12px; }
}

/* ── Sections ────────────────────────────────────────────────────────────── */

section { padding: 64px 0 8px; }

/* Display type is the sans; everything functional — nav, labels, stats,
   buttons, race data — stays mono. Splitting them keeps the instrument-panel
   character where it belongs without making the argument itself look like
   terminal output. */
h2 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: clamp(21px, 2.5vw, 27px);
  font-weight: 700; letter-spacing: -0.015em;
  color: var(--paper);
}

h3 { margin: 0 0 8px; font-size: 16px; font-weight: 700; }

.section-note { margin: 0 0 30px; color: var(--muted); max-width: 68ch; }

p { max-width: 72ch; }

/* Skim tiers. Running prose sits a step below full white, so the two things
   above it register at a glance: bolded phrases in paper white, and the one
   line per section worth remembering in cyan. Lime stays out of prose
   entirely — it means "this is the product" or "this is a button". */
section p  { color: var(--body); }
section li { color: var(--body); }
strong     { color: var(--paper); font-weight: 700; }

/* Two tiers only: prose is grey, and the phrases worth landing on are white
   and bold. `.lead` marks the opening paragraph of a section for structure but
   no longer changes its colour — brightness is bold's job alone now. */

/* ── Pipeline diagram ────────────────────────────────────────────────────── */
/* Three panels: what goes in, what SailBoss does with it, who uses the result.
   The middle one is the only thing wearing the accent — the outer two are
   context, so they stay in the neutral card treatment the rest of the site
   uses. Icons are cyan throughout: decoration that labels, never the argument. */

.ico { width: 20px; height: 20px; flex: 0 0 auto; }

.flow { margin: 4px 0 0; }
.flow-row {
  display: grid; align-items: center; gap: 14px;
  /* The side cards size to their own text and nothing more; the middle panel
     takes everything left over. Stretching them to the core's height made three
     equal boxes, which read as three equal ideas — they are not. */
  grid-template-columns: auto auto minmax(0, 1fr) auto auto;
}

.side {
  display: flex; flex-direction: column; justify-content: center; gap: 7px;
  width: 214px; min-height: 152px;   /* equal to each other, sized to the
                                        longer of the two blocks of text */
  border: 1px solid var(--line-2); border-radius: 10px;
  background: var(--surface); padding: 15px 16px;
}
.side-ico { color: var(--cyan); display: block; }
.side-h { font-size: 14px; font-weight: 700; color: var(--paper); }
.side-sub { font-size: 12.5px; line-height: 1.5; color: var(--muted); }

.arrow { display: flex; align-items: center; color: var(--cyan); opacity: .85; }
.arrow-svg { width: 34px; height: 12px; }

.core {
  border: 1px solid var(--ink); border-radius: 10px;
  padding: 18px 20px 20px;
  background:
    radial-gradient(ellipse 80% 60% at 50% 118%, rgba(40,254,20,.16), transparent 70%),
    var(--sunken);
  box-shadow: 0 0 0 1px rgba(40,254,20,.12), 0 0 34px rgba(40,254,20,.10);
}
.core-label {
  display: block; margin-bottom: 14px; text-align: center;
  font-size: 23px; font-weight: 700;
  letter-spacing: -0.02em; color: var(--ink);
}

.stages { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.stages li {
  display: flex; align-items: center; gap: 13px;
  border: 1px solid var(--line-2); border-radius: 7px;
  background: rgba(0,0,0,.34); padding: 9px 12px;
  font-size: 14px; color: var(--paper);
}
.st-n {
  flex: 0 0 auto; width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 1px solid var(--line-3); border-radius: 5px;
  font-size: 13px; font-weight: 700; color: var(--ink);
}
.st-t { flex: 1 1 auto; min-width: 0; }
.stages .ico { color: var(--cyan); }

/* ── Capabilities ────────────────────────────────────────────────────────── */

.cap-h {
  margin: 34px 0 14px; padding-left: 11px;
  border-left: 3px solid var(--ink);
  font-size: 12px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink);
}

.features {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.features li {
  display: flex; align-items: center; gap: 11px;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); padding: 13px 14px;
  font-size: 13.5px; line-height: 1.35; color: var(--paper);
}
.features .ico { color: var(--cyan); }
.features .more { color: var(--muted); }

.ip {
  display: flex; align-items: center; gap: 10px;
  margin: 22px 0 0; padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted); max-width: none;
}
.ip .ico { color: var(--ink); }

@media (max-width: 760px) {
  /* Stack the process vertically. The arrows remain because sequence is the
     point of the diagram; rotate the existing horizontal mark instead of
     inventing a second mobile-only visual language. */
  .flow-row { grid-template-columns: 1fr; }
  .arrow { display: flex; height: 28px; justify-content: center; }
  .arrow-svg { transform: rotate(90deg); }
  /* Full width once stacked — the fixed width only exists to equalise them
     when they sit side by side. */
  .side { width: 100%; min-height: 0; padding: 14px 16px; }
}

/* ── Cards ───────────────────────────────────────────────────────────────── */

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.card {
  border: 1px solid var(--line-2);
  background: var(--surface);
  border-radius: var(--r);
  padding: 20px;
}
.card .tag {
  display: inline-block; margin-bottom: 12px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--on-accent); background: var(--ink);
  padding: 3px 7px; border-radius: 3px;
}
.card p { margin: 0 0 10px; color: var(--muted); font-size: 14px; }
.card .pay { color: var(--faint); font-size: 12.5px; margin-bottom: 16px; }
.card .btn { font-size: 12.5px; padding: 7px 13px; text-decoration: none; display: inline-block; }

/* Lists of questions / patterns — the em-dash bullet keeps the terminal feel
   without a glyph the mono face has to fake. */
ul.qs { list-style: none; margin: 0 0 18px; padding: 0; max-width: 72ch; }
ul.qs li { position: relative; padding-left: 22px; margin-bottom: 6px; color: var(--muted); }
ul.qs li::before { content: "\25B8"; position: absolute; left: 0; color: var(--cyan);
                    font-size: 11px; top: 1px; }

/* The line in each section worth remembering. Emphasis, not a quotation — no
   rule, no indent, just full white at bold weight so it reads as part of the
   argument rather than as something lifted out of it. */
p.pull { margin: 20px 0 0; font-weight: 700; }
section p.pull { color: var(--paper); }

.subtitle { margin: 0 0 16px; color: rgba(240, 241, 233, .84); font-size: 14px; }
.fineprint { margin-top: 14px; color: var(--faint); font-size: 13px; max-width: none; }
.na { color: var(--faint); font-size: 12px; }
.score.none { color: var(--faint); font-weight: 400; font-size: 12px; }

/* Primary calls to action — larger and filled, distinct from the quieter
   .btn used inside cards and the coach chips. */
.btn.cta { font-size: 14px; padding: 11px 20px; text-decoration: none; display: inline-block; }
.btn.cta:not(.ghost) { background: var(--ink); color: var(--on-accent); font-weight: 600; }
.btn.cta:not(.ghost):hover { background: var(--ink-bright); border-color: var(--ink-bright); }

/* Equal-height hero actions, with type—not mismatched geometry—carrying the
   primary action's extra emphasis. */
.hero .cta-row .btn.cta {
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
}
.btn.cta.cta-free { padding: 11px 28px; font-size: 15px; font-weight: 700; }
.cta-note { margin: 12px 0 0; color: var(--faint); font-size: 13.5px; }

/* Wind column: measured (coach-boat weather station) vs GPS-derived. */
.wind-m { font-weight: 700; color: var(--cyan); white-space: nowrap; }
.wind-d { color: var(--faint); font-size: 12px; white-space: nowrap; }

/* ── Program segments (native <details> accordion) ─────────────────────── */
/* Collapsed rows are identical in height regardless of how much copy each
   segment carries, which the equal-width card grid could never manage. Native
   details/summary keeps keyboard and screen-reader behavior for free. */

.progs { border: 1px solid var(--line-2); border-radius: var(--r); overflow: hidden; }

.prog + .prog { border-top: 1px solid var(--line-2); }

.prog > summary {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 16px 20px; cursor: pointer;
  background: var(--surface); list-style: none;
}
.prog > summary::-webkit-details-marker { display: none; }
.prog > summary:hover { background: var(--sunken); }
.prog > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

.prog .prog-h { font-weight: 400; font-size: 15px; }

/* A bare + was too quiet — people could not tell the rows opened. The control
   now says what it does, in the secondary accent, and reads as a button. */
.prog > summary::after {
  content: "Expand +"; margin-left: auto;
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--cyan);
  border: 1px solid var(--line-3); border-radius: 999px;
  padding: 4px 11px; white-space: nowrap;
}
.prog > summary:hover::after { background: rgba(85,207,245,.10); border-color: var(--cyan); }
.prog[open] > summary::after { content: "Close −"; color: var(--muted); border-color: var(--line-2); }
.prog[open] > summary { background: var(--sunken); }

/* The row title carries the weight of a control, not of body copy. */
.prog > summary .tag { font-size: 14.5px; font-weight: 700; color: var(--paper); }
.prog > summary { border-left: 2px solid transparent; }
.prog > summary:hover { border-left-color: var(--cyan); }
.prog[open] > summary { border-left-color: var(--cyan); }

.prog-body { padding: 4px 20px 20px; background: var(--sunken); }
.prog-body p { margin: 0 0 10px; color: rgba(240, 241, 233, .84); font-size: 14px; max-width: 72ch; }
.prog-body .pay { color: var(--cyan); font-size: 12.5px; margin-bottom: 16px; }
.prog-body .btn { font-size: 12.5px; padding: 7px 13px; text-decoration: none; display: inline-block; }

/* First section on an inner page: pull the content up so a table below the
   heading is visible without scrolling. */
section.tight { padding-top: 34px; }
section.tight h2 { margin-bottom: 18px; }

/* Stat tiles */
.stat { border: 1px solid var(--line-2); background: var(--sunken); border-radius: var(--r); padding: 16px 18px; }
.stat .n { font-size: 30px; font-weight: 700; line-height: 1.1; color: var(--cyan); }
.stat .l { font-size: 12px; color: var(--muted); letter-spacing: .04em; }

/* ── Tables ──────────────────────────────────────────────────────────────── */

.table-scroll { overflow-x: auto; border: 1px solid var(--line-2); border-radius: var(--r); }

table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 760px; }

thead th {
  text-align: left; padding: 11px 14px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: var(--sunken);
  border-bottom: 1px solid var(--line-2); white-space: nowrap;
}
tbody td { padding: 11px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--sunken); }

.ev { font-weight: 600; color: var(--paper); }
.ev small { display: block; font-weight: 400; color: var(--faint); font-size: 12px; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num { color: var(--cyan); }

/* Upcoming rows share the table with built regattas but must be legible as a
   different kind of thing: an accent rail on the left, a badge, and dimmed
   metric cells where there is nothing to report yet. */
tbody tr.upcoming td { background: rgba(40, 254, 20, .045); }
tbody tr.upcoming td:first-child { box-shadow: inset 3px 0 0 var(--ink); }
tbody tr.upcoming:hover td { background: rgba(40, 254, 20, .085); }

.badge {
  display: inline-block; margin-right: 7px;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--on-accent); background: var(--ink);
  padding: 2px 6px; border-radius: 3px; vertical-align: 1px;
}

/* ── Fleet filter ────────────────────────────────────────────────────────── */

/* Two filter rows — audience, then class. The labels are what stop this
   reading as one undifferentiated wall of chips. */
.filter-group { display: flex; align-items: baseline; gap: 12px; margin: 0 0 9px; }
.filter-label {
  flex: 0 0 62px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); padding-top: 5px;
}

.filters { display: flex; flex-wrap: wrap; gap: 7px; margin: 0; }

.chip {
  font: inherit; font-size: 12.5px;
  color: var(--muted); background: transparent;
  border: 1px solid var(--line-2); border-radius: 3px;
  padding: 4px 11px; cursor: pointer;
}
.chip:hover { color: var(--ink); border-color: var(--line-3); }
.chip.on { color: var(--on-accent); background: var(--ink); border-color: var(--ink); font-weight: 600; }
.chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.filter-count { margin: 0 0 14px; min-height: 1.4em; font-size: 12.5px; color: var(--faint); }

/* Only shown where the table actually overflows. Silent on desktop, where
   every column is already visible and the line would just be noise. */
.scroll-hint { display: none; }
@media (max-width: 860px) {
  .scroll-hint {
    display: block; margin: 0 0 10px;
    font-size: 12px; color: var(--faint);
  }
}
.empty { margin: 16px 0 0; color: var(--muted); font-size: 14px; }

/* Data-quality score. Color encodes the band, and the number is always shown
   next to it — color alone would fail for anyone who cannot distinguish it. */
.score { font-variant-numeric: tabular-nums; font-weight: 700; }
.score.good { color: var(--ink); }
.score.mod  { color: var(--warn); }
.score.poor { color: var(--loss); }
.score .band { display: block; font-weight: 400; font-size: 11px; color: var(--faint); }
.score.none { color: var(--faint); font-weight: 400; }

/* ── Coach chip: reveals an address instead of opening a mail client ─────── */

.coach {
  font: inherit; font-size: 12.5px;
  color: var(--ink); background: transparent;
  border: 1px solid var(--line-3); border-radius: 3px;
  padding: 3px 9px; cursor: pointer; white-space: nowrap;
}
.coach:hover, .coach:focus-visible { background: var(--ink); color: var(--on-accent); outline: none; }

dialog.mailer {
  border: 1px solid var(--line-3); border-radius: var(--r);
  background: var(--surface); color: var(--paper);
  padding: 26px; max-width: 440px; font-family: var(--font);
}
dialog.mailer::backdrop { background: rgba(0, 0, 0, .78); }
dialog.mailer h3 { margin: 0 0 10px; }
dialog.mailer p { margin: 0 0 16px; color: var(--muted); font-size: 14px; }
.addr {
  display: block; padding: 12px 14px; margin-bottom: 16px;
  border: 1px dashed var(--line-3); border-radius: 3px;
  background: var(--sunken); font-size: 15px; word-break: break-all;
}
.mailer-actions { display: flex; gap: 10px; }
.btn {
  font: inherit; font-size: 13px;
  border: 1px solid var(--ink); border-radius: 3px;
  background: transparent; color: var(--ink);
  padding: 8px 16px; cursor: pointer;
}
.btn:hover, .btn:focus-visible { background: var(--ink); color: var(--on-accent); outline: none; }
.btn.ghost { border-color: var(--line-3); color: var(--muted); }
.btn.ghost:hover { background: var(--sunken); color: var(--ink); }

/* ── Coach profile ───────────────────────────────────────────────────────── */

.coach-hero { display: grid; grid-template-columns: 240px 1fr; gap: 32px; align-items: start; }
.coach-hero img {
  width: 100%; border-radius: var(--r);
  border: 1px solid var(--line-2); display: block;
  filter: grayscale(1) contrast(1.08);
}
.role { margin: 0 0 14px; font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--cyan); }

.pill-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 0; padding: 0; list-style: none; }
.pill {
  border: 1px solid rgba(85, 207, 245, .32); border-radius: 3px;
  padding: 3px 9px; font-size: 12px; color: var(--cyan);
}

/* ── Video wall ──────────────────────────────────────────────────────────── */

.videos { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.video { border: 1px solid var(--line-2); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.video .frame { position: relative; aspect-ratio: 16 / 9; background: #000; }
.video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video .meta { padding: 13px 15px; }
.video .meta h3 { margin: 0 0 3px; font-size: 14px; line-height: 1.35; }
.video .meta .sub { color: var(--cyan); opacity: .85; font-size: 12.5px; margin-bottom: 9px; }
.video .meta p { margin: 0 0 14px; color: rgba(240, 241, 233, .84); font-size: 13px; }
.video .meta .btn { font-size: 12.5px; padding: 7px 13px; text-decoration: none; display: inline-block; }

/* ── Callout ─────────────────────────────────────────────────────────────── */

.callout {
  border: 1px solid var(--line-3); border-left: 3px solid var(--cyan);
  background: var(--sunken); border-radius: var(--r);
  padding: 20px 22px; margin-top: 26px;
}
.callout p { margin: 0; color: var(--paper); opacity: .92; }

/* Seven nav items plus the email button need room to wrap rather than
   overflow once the viewport narrows. */
@media (max-width: 1080px) {
  .nav-inner { flex-wrap: wrap; gap: 8px 18px; padding-top: 10px; padding-bottom: 10px; }
  .brand { margin-right: 12px; }
  .nav-mail, .nav-btn { margin-left: auto; }
}

@media (max-width: 560px) {
  /* The title takes the full width here, so `margin-left: auto` stranded the
     control on its own line, hard right. Sit it under the title instead. */
  .prog > summary { padding: 14px 16px; gap: 8px; }
  .prog > summary::after { margin-left: 0; }
}

@media (max-width: 640px) {
  /* Stack the filter label above its chips rather than squeezing the row. */
  .filter-group { flex-direction: column; gap: 5px; margin-bottom: 12px; }
  /* flex-basis is the main axis, so the 62px that sets the label's width in a
     row became its HEIGHT once the group stacked — hence the empty band under
     each label. */
  .filter-label { flex: none; padding-top: 0; }
}

@media (max-width: 720px) {
  .coach-hero { grid-template-columns: 1fr; }
  .coach-hero img { max-width: 220px; }
  /* On a phone, Sign in shares its destination with Get started, so it is
     the one duplicate we drop. Regattas, Contact and Get started all fit on
     one thumb-sized row at 360px and up. */
  .nav-inner {
    min-height: 56px; flex-wrap: nowrap; gap: 10px; padding: 0 14px;
  }
  .nav-inner .brand { margin-right: auto; font-size: 18px; }
  .nav .navlink[href="https://app.sailboss.ai"] { display: none; }
  .nav .navlink {
    min-height: 40px; display: inline-flex; align-items: center;
    font-size: 11px; white-space: nowrap;
  }
  /* "Available regattas" is too long for a 360px row; the shorter label
     keeps all three actions visible. */
  .nav .navlink[href="regattas.html"] { font-size: 0; }
  .nav .navlink[href="regattas.html"]::after { content: "Regattas"; font-size: 11px; }
  .nav-mail, .nav-btn {
    min-height: 40px; margin-left: 0; padding: 0 10px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 11px; white-space: nowrap;
  }
  .cta-row .btn { min-height: 48px; display: inline-flex; align-items: center; justify-content: center; }
}

/* ── Audience pages ──────────────────────────────────────────────────────── */
/* Components the audience-first navigation needs. Everything above is shared
   with the regatta and analysis pages. */

/* ── Audience router ─────────────────────────────────────────────────────── */
/* Replaces the thesis contents column on the home page. Three doors, sized
   equally, because none of the three is the default reader. */

.aud-sec { padding-top: 56px; }

.aud {
  display: grid; gap: 14px; margin-top: 22px;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}

.aud-card {
  display: flex; flex-direction: column; gap: 9px;
  border: 1px solid var(--line-2); border-radius: 10px;
  background: var(--surface); padding: 20px 20px 18px;
  text-decoration: none;
}
.aud-card:hover { border-color: var(--line-3); background: var(--sunken); }

.aud-h {
  font-family: var(--font-display);
  font-size: 17px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--paper);
}
.aud-p { font-size: 13.5px; line-height: 1.55; color: var(--body); }
.aud-go { margin-top: auto; padding-top: 6px; font-size: 12.5px; color: var(--cyan); }
.aud-go::after { content: " \2192"; }
.aud-card:hover .aud-go { color: var(--ink); }

/* ── Standfirst ──────────────────────────────────────────────────────────── */
/* The one paragraph that has to land before anything else on an audience page.
   Set larger than the prose under it, but the same colour: on these pages the
   headings carry the contrast and everything else reads as one voice. */

p.stand {
  margin: 0 0 20px; max-width: 64ch;
  font-size: clamp(15px, 1.5vw, 17px); line-height: 1.6;
  color: var(--lead);
}
section p.stand { color: var(--lead); }
section p.stand strong { color: inherit; font-weight: 700; }

/* A note that must not wrap; the 68ch cap on .section-note is meant for
   paragraphs, not for a single line under a heading. */
.section-note.wide { max-width: none; }

/* Three across when there are three of them. */
.ways.three { grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); }

/* ── Regattas page ───────────────────────────────────────────────────────── */
/* The contents column already sets the measure here, so the per-paragraph cap
   would narrow the column a second time. */

.reading-body p:not(.stand), .reading-body ul.qs { max-width: none; }
.reading-body .fineprint { max-width: none; }

/* ── Audience page heroes ────────────────────────────────────────────────── */
/* Smaller renders than the home hero, and feathered on the left edge only:
   enough to hand off to the headline, nothing on the other three sides. That
   means the field behind them has to be near-black rather than the home hero's
   water grey, or the image would end on a visible rectangle. */

.hero-club, .hero-olympic, .hero-junior, .hero-pro, .hero-hiw {
  background:
    radial-gradient(ellipse 58% 68% at 72% 50%,
      #0D1211 0%, #0A0E0D 52%, #070A09 78%, #050806 100%);
}

.hero-club::after, .hero-olympic::after, .hero-junior::after, .hero-pro::after,
.hero-hiw::after {
  /* Flush with the band and no feather at all: the render is a plain rectangle
     against the field, its own left edge the boundary. */
  top: 0; height: 100%;
  -webkit-mask-image: none;
  mask-image: none;
}

.hero-club::after {
  background-image: url("img/club-hero.jpg");
  aspect-ratio: 1900 / 975;   /* club-hero.jpg */
}
.hero-olympic::after {
  background-image: url("img/olympic-hero.jpg");
  aspect-ratio: 1800 / 1273;   /* olympic-hero.jpg */
}
.hero-junior::after {
  background-image: url("img/junior-hero.jpg");
  aspect-ratio: 1800 / 1026;   /* junior-hero.jpg */
}

.hero-pro::after {
  background-image: url("img/pro-hero.jpg");
  aspect-ratio: 1800 / 1250;   /* pro-hero.jpg */
}

.hero-club h1, .hero-olympic h1, .hero-junior h1, .hero-pro h1, .hero-hiw h1 {
  max-width: 700px; font-size: clamp(28px, 3.4vw, 40px);
}
.hero-club .lede, .hero-olympic .lede, .hero-junior .lede, .hero-pro .lede { max-width: 46ch; }
.hero-club .wrap, .hero-olympic .wrap, .hero-junior .wrap, .hero-pro .wrap,
.hero-hiw .wrap {
  padding-top: 104px; padding-bottom: 98px;
}
.hero-hiw .wrap { padding-top: 53px; padding-bottom: 70px; }

@media (max-width: 860px) {
  .hero-club::after, .hero-olympic::after, .hero-junior::after, .hero-pro::after,
  .hero-hiw::after {
    top: 0; height: auto; aspect-ratio: auto;
  }
  .hero-club .wrap, .hero-olympic .wrap, .hero-junior .wrap, .hero-pro .wrap,
  .hero-hiw .wrap {
    padding-top: 64px; padding-bottom: 60px;
  }
  .hiw-frame { position: static; height: auto; aspect-ratio: auto; }
  .hiw-frame .swap-tabs { position: static; margin: 0 0 8px; }
}

/* ── Colormap toggle ─────────────────────────────────────────────────────── */
/* The How it works hero carries the render, and the toggle swaps which colormap
   it shows. Mode lives on the hero as a data attribute so CSS picks the image
   and the speed frame still renders with JS off. Tabs borrow the app's own
   2D/3D control, so the gesture is already familiar. */

/* Square, so at full band height it stands much taller than the wide renders
   on the other tabs. Held to 70% and centred, with the toggle sitting directly
   under it rather than under the copy. */
.hero-hiw::after {
  background-image: url("img/tracks-speed.jpg");
  aspect-ratio: 1 / 1;
  top: 12%; height: 70%;
  /* Pulled well in off the viewport edge: past the content column's right
     margin and further again, so it sits beside the copy rather than out at
     the edge of the page. */
  right: calc(max(24px, (100vw - var(--page-max)) / 2 + 24px) + 11vw);
}
.hero-hiw[data-mode="wind"]::after { background-image: url("img/tracks-wind.jpg"); }

.swap-tabs {
  display: inline-flex; gap: 2px;
  border: 1px solid var(--line-2); border-radius: 999px; padding: 3px;
  background: rgba(0, 0, 0, .55);
}
/* An invisible box with the render's exact geometry, so the control can hang
   off the image's own left edge rather than off the viewport. Aligning to the
   right edge put it a long way from the copy once the render shrank. */
.hiw-frame {
  position: absolute; z-index: 3;
  top: 12%; height: 70%;
  right: calc(max(24px, (100vw - var(--page-max)) / 2 + 24px) + 11vw);
  aspect-ratio: 1 / 1;
  pointer-events: none;
}
.hiw-frame .swap-tabs {
  position: absolute; bottom: 10px;
  left: 50%; transform: translateX(-50%);
  pointer-events: auto;
}
.swb {
  font: inherit; font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: transparent;
  border: 0; border-radius: 999px; padding: 5px 15px; cursor: pointer;
}
.swb:hover { color: var(--paper); }
.swb.on { background: var(--ink); color: var(--on-accent); font-weight: 700; }
.swb:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

@media (max-width: 860px) {
  /* On a phone the copy and render cannot share a layer. Give the explanation
     its own block, then present the selected product frame at full contrast
     underneath it with the toggle attached to the image it controls. */
  .hero-hiw::after { display: none; }
  .hero-hiw .wrap { padding-top: 48px; padding-bottom: 24px; }
  .hero-hiw::before {
    background: linear-gradient(180deg, rgba(5,8,6,.94), rgba(5,8,6,.86));
  }
  .hiw-frame {
    position: relative; z-index: 3; inset: auto;
    width: calc(100% - 36px); height: auto; aspect-ratio: 1 / 1;
    margin: 0 18px 24px; overflow: hidden;
    border: 1px solid var(--line-2); border-radius: var(--r);
    background: url("img/tracks-speed.jpg") center / cover no-repeat;
    box-shadow: 0 14px 34px rgba(0,0,0,.28);
    pointer-events: auto;
  }
  .hero-hiw[data-mode="wind"] .hiw-frame {
    background-image: url("img/tracks-wind.jpg");
  }
  .hiw-frame .swap-tabs {
    position: absolute; left: 50%; bottom: 12px;
    margin: 0; transform: translateX(-50%);
    background: rgba(3,7,5,.88); backdrop-filter: blur(8px);
  }
}

/* ── Audience page panels ─/* ── Audience page panels ─/* ── Audience page panels ────────────────────────────────────────────────── */
/* The audience pages were one narrow column of prose down the left of a 1320px
   page. Breaking each section into a panel does three things at once: it uses
   the width, it caps the measure per panel rather than per page, and it gives
   the eye a boundary between arguments. Alternating surfaces keep adjacent
   panels distinguishable without adding a border colour per section. */

.panels {
  display: grid; gap: 16px; margin: 26px 0 8px;
  grid-template-columns: repeat(auto-fit, minmax(430px, 1fr));
}
.panels.three { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }

.panel {
  border: 1px solid var(--line-2); border-left: 3px solid var(--cyan);
  border-radius: 10px;
  background: var(--surface); padding: 22px 24px 20px;
}
/* Scoped past `.tight h3`, which sets a 30px top margin for headings that
   open a section. Inside a panel that stacked on the panel's own padding and
   left 53px of dead space above every card title. */
.panels .panel h3 {
  margin: 0 0 13px; font-size: 16.5px;
  color: var(--paper);
}
.panel p { margin: 0 0 12px; max-width: none; font-size: 13.5px; line-height: 1.62;
            color: var(--body); }
.panel p:last-child { margin-bottom: 0; }

/* Inside a panel, emphasis is weight only. Colour is already carrying the
   panel boundary and the heading; a third signal made the pages busy. */
.panel strong, .way strong { color: inherit; font-weight: 700; }

/* A heading that labels a row of cards rather than opening a section. */
.row-h { margin: 34px 0 14px; }

/* Sections can be panels too, when two of them are alternatives to each other.
   They bring section's own padding with them, which has to go. */
.panels section.panel { padding: 22px 24px 20px; }
.panels .panel h2 {
  margin: 0 0 12px; font-size: 19px; color: var(--paper);
}
.panels .panel ul.qs, .panels .panel p { max-width: none; }
.panels .panel .cta-row { margin-top: 18px; }
.panels.outreach { margin-top: 34px; }

/* ── Numbered steps ──────────────────────────────────────────────────────── */
/* Same numeral treatment as the pipeline diagram, so a sequence looks like a
   sequence wherever it appears. */

ol.steps { list-style: none; margin: 16px 0 22px; padding: 0; display: grid; gap: 10px; }
ol.steps li {
  display: flex; align-items: flex-start; gap: 13px;
  max-width: 72ch; color: var(--muted);
}
.step-n {
  flex: 0 0 auto; width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 1px solid var(--line-3); border-radius: 5px;
  font-size: 13px; font-weight: 700; color: var(--ink);
}

/* ── The two ways to engage ──────────────────────────────────────────────── */
/* Side by side rather than stacked: they are alternatives, and a reader has to
   see both to pick one. */

.ways {
  display: grid; gap: 14px; margin: 18px 0 22px;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}
.way {
  border: 1px solid var(--line-2); border-left: 3px solid var(--cyan);
  border-radius: 8px; background: var(--surface); padding: 17px 19px;
}
.way-h {
  display: block; margin-bottom: 10px;
  font-size: 16.5px; font-weight: 700; color: var(--paper);
}
.way p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--body); }

/* Inner-page headings carry more air here, since these pages are one long
   argument rather than a stack of short sections. A step up in size too: at
   15px against 13.5px body the difference read as bold, not as a heading. */
.tight h3 { margin-top: 30px; font-size: 19px; }

/* ── How it works page ───────────────────────────────────────────────────── */
/* The diagram was drawn for a 1080px column. At the 1320px page width it
   stretched to fill, which put a lot of air inside the panels and made the row
   read as three billboards. Hold it to something closer to its natural size. */

/* Centred in the page column: at 1320px the 1040 block left ~250px of dead
   space down the right-hand side, which read as the section hanging off the
   left edge rather than as a narrower measure. */
.hiw { max-width: 1100px; margin-left: auto; margin-right: auto; }
.hiw #how-it-works { padding-top: 26px; }

/* Homepage explanation: keep the full visual story, but remove the billboard
   spacing and let secondary capability tiles recede behind the central model. */
.hiw-home { padding-top: 46px; padding-bottom: 52px; }
.hiw-home .side { min-height: 132px; border-radius: var(--r); }
.hiw-home .core { border-radius: var(--r); padding: 15px 18px 17px; }
.hiw-home .cap-h {
  margin-top: 26px; color: var(--cyan); border-left-color: var(--cyan);
}
.hiw-home .features { gap: 8px; }
.hiw-home .features li {
  padding: 11px 13px; border-radius: var(--r);
  border-color: var(--line); background: rgba(6,11,6,.58);
}
.hiw-home .ip { margin-top: 18px; padding-top: 15px; }
.hiw-home .ip .ico { color: var(--cyan); }

/* The directory is an interface, not reading copy. It gets the full page
   column; the editorial debrief material below returns to a narrower measure. */
.directory-shell { padding-top: 24px; }
.directory-shell section { padding-top: 0; }
.regatta-secondary { max-width: 1040px; margin-inline: auto; }

@media (max-width: 900px) {
  /* One up: the track minimums are wider than a phone's content column, so
     auto-fit could not collapse them and the cards overflowed the page. */
  .panels, .panels.three, .ways, .ways.three { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .aud-sec { padding-top: 40px; }
}

/* ── Homepage "How it works" band ────────────────────────────────────────── */
/* The section heading wears the audience-hero h1 clothes — it opens a band,
   not the page, so it stays an h2. */
.hero-hiw h2.hiw-title {
  margin: 0 0 24px; max-width: 700px;
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 700; line-height: 1.14; letter-spacing: -0.02em;
  color: var(--paper);
  text-shadow: 0 2px 18px rgba(0,0,0,.85);
}

/* ── Contact dialog (site.js) ────────────────────────────────────────────── */
/* The two ways in: email (copyable) and the WhatsApp group. */
.contact { position: relative; }
/* Both variants lead straight from the heading into the content, so the copy
   slot collapses rather than leaving its bottom margin behind. */
.contact p:empty { display: none; }
.contact .con-row { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.contact .con-row:last-child { margin-bottom: 0; }
.contact .con-l {
  flex: 0 0 84px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint);
}
.contact .con-row .addr { margin: 0; flex: 1 1 auto; }
.contact .con-wa { text-decoration: none; display: inline-block; }
.contact .con-community { display: grid; gap: 7px; }
.contact .con-community small {
  max-width: 36ch; color: var(--body); font-size: 11px; line-height: 1.4;
}

/* Copy sits with the address, not in a button row at the foot of the panel —
   so what it acts on is never in doubt. Underlined and in the data hue, which
   is what makes it read as a control rather than as a caption. */
.contact .con-copy {
  flex: 0 0 auto;
  font: inherit; font-size: 12.5px;
  padding: 4px 2px; border: 0; background: none;
  color: var(--cyan); text-decoration: underline; cursor: pointer;
}
.contact .con-copy:hover, .contact .con-copy:focus-visible { color: var(--ink); outline: none; }
.contact .con-copy.done { color: var(--ink); text-decoration: none; }

/* Close is the corner ✕ — Escape and a click outside do it too. */
.contact h3 { padding-right: 34px; }
.contact .con-x {
  position: absolute; top: 14px; right: 14px;
  width: 28px; height: 28px; display: grid; place-items: center;
  padding: 0; border: 1px solid transparent; border-radius: var(--r);
  background: none; color: var(--faint);
  font: inherit; font-size: 19px; line-height: 1; cursor: pointer;
}
.contact .con-x:hover, .contact .con-x:focus-visible {
  color: var(--paper); border-color: var(--line-3); outline: none;
}

/* The regatta variant's two lines (past vs upcoming events). Empty for the
   generic contact dialog, which collapses this list to nothing. */
.contact .con-notes { list-style: none; margin: 0 0 18px; padding: 0; }
.contact .con-notes:empty { display: none; }
.contact .con-notes li {
  position: relative; padding-left: 18px; margin-bottom: 7px;
  color: var(--body); font-size: 13.5px; line-height: 1.55;
}
.contact .con-notes li::before {
  content: "\25B8"; position: absolute; left: 0; top: 1px;
  color: var(--cyan); font-size: 10px;
}
.contact .con-notes b { color: var(--paper); font-weight: 700; }

@media (max-width: 480px) {
  dialog.mailer.contact { width: calc(100vw - 24px); padding: 20px; }
  .contact .con-row {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: center; gap: 7px 10px; margin-bottom: 15px;
  }
  .contact .con-l { grid-column: 1 / -1; flex: none; }
  .contact .con-row .addr { min-width: 0; }
  .contact .con-wa { grid-column: 1 / -1; text-align: center; }
}
