/* UAA Network: the system.
 *
 * Structure comes from typography, rules and space. There is no utility
 * framework here and no component library; every rule below is written for
 * something this site actually shows, and anything that stops being shown
 * should be deleted rather than kept in case.
 *
 * HOW IT IS ORDERED: fonts, reset, type, layout, then components roughly in
 * the order a visitor meets them, then the console, then a short utility
 * layer. Read top to bottom and the page assembles itself.
 */

/* ── Type ─────────────────────────────────────────────────────────────── */
/* SELF-HOSTED, AND THAT IS A DECISION. The design this implements linked
 * fonts.googleapis.com, which costs two DNS lookups and a connection to a
 * third party on the critical path, tells that third party every visitor's
 * address, and is refused outright by this site's `font-src 'self'`. Both
 * families are OFL, so hosting them is simply allowed. `swap` because a
 * visitor reading text in a fallback face is better served than one reading
 * nothing. */
@font-face {
  font-family: "Libre Caslon Display";
  src: url("../fonts/libre-caslon-display-latin-400-normal.51b9d99d9c00.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "DM Sans";
  src: url("../fonts/dm-sans-latin-wght-normal.7c87a648293f.woff2") format("woff2");
  font-weight: 100 1000; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}

/* ── Reset ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--text-mid);
  font-family: var(--font-ui);
  font-size: var(--size-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; display: block; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }

/* FOCUS IS ALWAYS VISIBLE. A focus ring removed for tidiness is a keyboard
 * user navigating a page they cannot see themselves on. */
:focus-visible {
  outline: 2px solid var(--gold-ink);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: var(--space-4); top: -100%;
  background: var(--forest); color: var(--text-on-ink);
  padding: var(--space-3) var(--space-5); border-radius: var(--radius-sm);
  z-index: 100; font-weight: 600;
}
.skip-link:focus { top: var(--space-4); }

/* ── Headings and text ────────────────────────────────────────────────── */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.025em;
  color: var(--text);
  margin: 0 0 var(--space-4);
  text-wrap: balance;
}
.display, h1 { font-size: var(--size-display); line-height: var(--leading-tight); }
h2 { font-size: var(--size-h2); line-height: var(--leading-snug); }
h3 { font-size: var(--size-h3); line-height: 1.12; }
h4 { font-size: 1.125rem; line-height: 1.2; }
p { margin: 0 0 var(--space-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--gold-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--gold-dark); }

.lead {
  font-size: var(--size-lead);
  color: var(--text-mid);
  max-width: var(--measure);
}
.small { font-size: var(--size-small); }
.muted { color: var(--text-soft); }
.help  { font-size: var(--size-small); color: var(--text-soft); }

/* The eyebrow is the site's most repeated device: it says what KIND of thing
 * follows before the heading says what it is. */
.eyebrow {
  font-size: var(--size-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ok);
  margin: 0 0 var(--space-3);
}
.rule { border: 0; border-top: 1px solid var(--line); margin: var(--space-7) 0; }

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-4); }
.prose h2 { margin-top: var(--space-7); }
.prose h3 { margin-top: var(--space-6); }
.prose ul, .prose ol { padding-left: var(--space-5); }
.prose li { margin-bottom: var(--space-2); }
.prose a { font-weight: 500; }

/* ── Layout ───────────────────────────────────────────────────────────── */
.wrap {
  width: min(var(--page-max), 100% - (var(--gutter) * 2));
  margin-inline: auto;
}
.section { padding-block: var(--space-9); }

/* One dark section per page, and never two in a row: it is emphasiz, and
 * emphasiz repeated is just a different background. */
.section--ink {
  background: radial-gradient(circle at 77% 48%,
    var(--forest-lit) 0%, var(--forest) 32%,
    var(--forest-deep) 70%, var(--ink) 100%);
  color: var(--text-on-ink-soft);
}
.section--ink h1, .section--ink h2, .section--ink h3 { color: var(--text-on-ink); }
.section--ink .eyebrow { color: var(--eyebrow-on-ink); }
.section--ink .lead, .section--ink p { color: var(--text-on-ink-soft); }
.section--ink a { color: var(--link-on-ink); }

.section__head { max-width: var(--measure); margin-bottom: var(--space-7); }
.section__head .lead { margin-top: var(--space-4); }

.grid { display: grid; gap: var(--space-5); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--sidebar { grid-template-columns: 1.4fr 0.9fr; gap: var(--space-8); }

/* ── Masthead ─────────────────────────────────────────────────────────── */
.masthead {
  background: var(--paper-raised);
  border-bottom: 1px solid var(--line-soft);
  position: sticky; top: 0; z-index: 30;
}
.masthead__inner {
  display: flex; align-items: center; gap: var(--space-6);
  min-height: 70px;
}
.masthead__brand {
  display: flex; align-items: center; gap: var(--space-3);
  text-decoration: none; color: var(--text); white-space: nowrap;
}
/* THE LOCKUP IS ONE IMAGE NOW, not four drawn rectangles, so the two
 * `.brandmark__brass` rules that used to re-point it for the forest footer
 * are gone rather than left to be read as live. A raster carries its own
 * color on both grounds, which is what made the swap possible. */
/* 34px TALL. The mark is a closed ring of four heavy strokes, which is a
 * silhouette that holds far smaller than the detailed one it replaced: it
 * survived a six pixel cut that would have turned the previous mark into a
 * smudge. Sized against the wordmark beside it rather than against the bar,
 * so the lockup reads as one object. 420 by 350 makes 34 tall 41 wide. */
.masthead__brand img.brandmark { width: 41px; height: 34px; flex: none;
                                 object-fit: contain; }
.masthead__brand b {
  font-size: 1.3125rem; font-weight: 700; letter-spacing: .015em;
}
.masthead__brand span {
  font-size: var(--size-label); letter-spacing: var(--tracking-label);
  font-weight: 600; color: var(--text-soft);
}
.masthead__nav { display: flex; align-items: stretch; gap: var(--space-5); flex: 1; }
.masthead__cta { margin-left: auto; align-self: center; }

/* EVERY NAV ITEM IS THE SAME BOX, in both of the shapes it comes in.
 *
 * `.navlink` is an anchor. As a DIRECT child of the flex row it is
 * blockified, so its vertical padding and bottom border count toward its
 * height. Nested inside `.navgroup` — a plain block — it stays inline, and an
 * inline element's vertical padding does not affect the line box at all. So
 * the grouped items were shorter boxes than the ungrouped ones, `align-items`
 * centerd two different heights, and "Resources" and "About" sat visibly
 * higher than "Why UAA" and "Membership".
 *
 * Making the link a flex box itself removes the difference: it is the same
 * height wherever it appears, and the row stretches every item to match. */
.navlink {
  display: inline-flex; align-items: center;
  font-size: var(--size-small); font-weight: 600; color: var(--text);
  text-decoration: none; padding: var(--space-2) 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--transition);
  white-space: nowrap;
}
.navlink:hover, .navlink[aria-expanded="true"] {
  border-bottom-color: var(--gold); color: var(--text);
}

/* The grouped nav: four headings, not the ten-item bar the sector defaults
 * to. It opens on hover AND on focus, so it is reachable from a keyboard. */
.navgroup { position: relative; display: flex; align-items: stretch; }
.navgroup__panel {
  position: absolute; top: 100%; left: 0;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: var(--space-3); min-width: 15rem; display: none; z-index: 40;
}
/* THE BRIDGE. The panel hangs below the trigger, and the pointer has to cross
 * whatever sits between them. Any gap at all — even the 2px border — is a
 * strip where `:hover` is false, so the panel closes the moment somebody
 * moves toward it. This is an invisible extension of the panel's own hover
 * area upward across that strip. */
.navgroup__panel::before {
  content: ""; position: absolute; left: 0; right: 0; top: -0.75rem;
  height: 0.75rem;
}
.navgroup:hover .navgroup__panel,
.navgroup:focus-within .navgroup__panel,
.navgroup[data-open="true"] .navgroup__panel { display: block; }
.navgroup__panel a {
  display: block; padding: var(--space-2) var(--space-3);
  font-size: var(--size-small); color: var(--text); text-decoration: none;
  border-radius: var(--radius-sm); white-space: nowrap;
}
.navgroup__panel a:hover { background: var(--paper-sunk); color: var(--text); }

.navtoggle {
  display: none; margin-left: auto; background: none; border: 0;
  padding: var(--space-2); cursor: pointer; color: var(--text);
}
.navtoggle svg { width: 24px; height: 24px; }
/* `[data-open]` MATCHES ANY VALUE, INCLUDING "false".
 *
 * The template renders `data-open="false"` and the script flips it to
 * "true", which is the right contract — but the selector that read it was
 * `[data-open]`, an attribute-PRESENCE test. It matched the closed state,
 * so the mobile menu was permanently expanded, on every screen size, pushing
 * the hero a thousand pixels down the page. The site looked broken and the
 * markup was correct.
 *
 * Matched on the value, and confined to the breakpoint where the button that
 * opens it actually exists, so no attribute state can put it on a desktop. */
.mobilenav { display: none; }
@media (max-width: 62rem) {
  .mobilenav[data-open="true"] {
    display: block; padding-block: var(--space-4) var(--space-6);
    border-top: 1px solid var(--line-soft);
  }
}
.mobilenav a {
  display: block; padding: var(--space-3) 0; color: var(--text);
  text-decoration: none; font-weight: 600; border-bottom: 1px solid var(--line-soft);
}
/* Indented with padding rather than with two non-breaking spaces, so the
 * indent is a measurement instead of a typographic accident. */
.mobilenav__child {
  padding-left: var(--space-5) !important; font-weight: 400;
  color: var(--text-mid) !important;
}

/* The complete desktop navigation needs more room than the rest of the page.
 * Collapse it before it pushes the qualification button outside the viewport
 * on a small laptop; the layout breakpoint below remains at 62rem. */
@media (max-width: 82rem) {
  .masthead__nav, .masthead__cta { display: none; }
  .navtoggle { display: block; }
  .mobilenav[data-open="true"] {
    display: block; padding-block: var(--space-4) var(--space-6);
    border-top: 1px solid var(--line-soft);
  }
}

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  border-radius: var(--radius-sm); border: 1px solid transparent;
  padding: 0.9375rem 1.375rem;
  font-size: var(--size-small); font-weight: 700; line-height: 1;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background var(--transition), transform var(--transition),
              border-color var(--transition);
}
.btn:hover { transform: translateY(-1px); }
.btn--primary {
  background: var(--gold-ink); color: var(--on-gold);
  box-shadow: var(--shadow-lift);
}
.btn--primary:hover { background: var(--gold-dark); color: var(--on-gold); }
.btn--ghost {
  border-color: var(--line-strong); color: var(--gold-dark);
  background: rgba(255, 255, 255, .36);
}
.btn--ghost:hover { border-color: var(--gold); color: var(--gold-dark); }
.btn--small { padding: 0.75rem 1rem; font-size: var(--size-label); }
.section--ink .btn--ghost {
  border-color: var(--border-on-ink); color: var(--text-on-ink);
  background: transparent;
}
.btnrow { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }

/* ── Metrics strip ────────────────────────────────────────────────────── */
/* Five figures, hairline-separated, directly under the hero. Two of the
 * largest networks in this sector currently render "$0B" and "0+" here
 * because the figures are animated in by a script and are not in the page;
 * these come from the database and every
 * one of them is flagged until a human replaces it. */
/* THE COLUMN COUNT FOLLOWS THE FACTS. Hard-coding five meant three real
 * figures rendered as three facts and two gaps, which reads as missing data.
 * `data-count` carries how many there actually are. */
.stats {
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--paper-raised);
  border-block: 1px solid var(--line);
}
.stats[data-count="1"] { grid-template-columns: 1fr; }
.stats[data-count="2"] { grid-template-columns: repeat(2, 1fr); }
.stats[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
.stats[data-count="4"] { grid-template-columns: repeat(4, 1fr); }
.stat {
  padding: var(--space-6) var(--space-4);
  text-align: center; border-right: 1px solid var(--line);
}
.stat:last-child { border-right: 0; }
.stat__value {
  display: block; font-family: var(--font-display); font-weight: 400;
  font-size: 2.25rem; line-height: 1; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.stat__label {
  display: block; margin-top: var(--space-2);
  font-size: var(--size-label); letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-soft);
}
.stat__note { display: block; margin-top: var(--space-1); font-size: var(--size-label); color: var(--text-soft); }

/* ── Feature cards ────────────────────────────────────────────────────── */
.feature {
  border: 1px solid var(--line); border-radius: 9px;
  padding: var(--space-5); background: rgba(255, 255, 255, .18);
  display: flex; flex-direction: column;
}
.feature__icon { color: var(--gold); margin-bottom: var(--space-3); }
.feature__icon svg { width: 38px; height: 38px; }
.feature h3 { font-size: 1.5rem; margin-bottom: var(--space-2); }
.feature p { font-size: var(--size-small); line-height: 1.55; }

/* ── Steps ────────────────────────────────────────────────────────────── */
/* The rule behind the numbers is what makes four boxes read as a sequence.
 * It is decorative, so it is drawn with a pseudo-element and hidden from
 * assistive technology by never being content in the first place. */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); position: relative; }
.steps::before {
  content: ""; position: absolute; left: 2%; right: 2%; top: 18px;
  border-top: 1px solid var(--line-strong);
}
.step { position: relative; padding-right: var(--space-5); }
.step:not(:last-child) {
  border-right: 1px solid var(--line); margin-right: var(--space-5);
}
.step__num {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--gold-ink); color: var(--on-gold);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--size-small); font-weight: 700;
  position: relative; z-index: 2; margin-bottom: var(--space-4);
  box-shadow: 0 0 0 8px var(--paper-warm);
}
.step__icon { color: var(--gold-dark); margin-bottom: var(--space-3); }
.step__icon svg { width: 24px; height: 24px; }
.step h3 { font-size: 1.375rem; margin-bottom: var(--space-2); }
.step p { font-size: var(--size-small); }

/* ── Tiles (image cards) ──────────────────────────────────────────────── */
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.tile {
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: var(--paper-raised); display: flex; flex-direction: column;
}
.tile > img { width: 100%; height: 150px; object-fit: cover; }
.tile__body { padding: var(--space-4) var(--space-5) var(--space-5); flex: 1;
              display: flex; flex-direction: column; }
.tile h3 { font-size: 1.5rem; margin-bottom: var(--space-2); }
.tile p { font-size: var(--size-small); }
.tile__value {
  display: block; font-family: var(--font-display); font-size: 2rem;
  line-height: 1; color: var(--text); font-variant-numeric: tabular-nums;
}
.tile__label {
  display: block; margin-top: var(--space-2); font-size: var(--size-label);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-soft);
}
.textlink {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: auto; padding-top: var(--space-4);
  color: var(--gold-text); font-size: var(--size-small); font-weight: 600;
  text-decoration: none;
}
.textlink:hover { color: var(--gold-dark); text-decoration: underline; }

/* ── Articles ─────────────────────────────────────────────────────────── */
.articles { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.article {
  display: grid; grid-template-columns: 120px 1fr;
  background: var(--paper-raised); border: 1px solid var(--line);
  border-radius: 6px; overflow: hidden; min-height: 120px;
  text-decoration: none;
}
.article img { width: 100%; height: 100%; object-fit: cover; }
.article__body { padding: var(--space-3) var(--space-4);
                 display: flex; flex-direction: column; justify-content: center; }
.article__cat {
  font-size: var(--size-label); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-soft); font-weight: 700;
}
.article h3 { font-size: 1.125rem; margin: var(--space-2) 0; line-height: 1.2; }
.article__date { font-size: var(--size-label); color: var(--text-soft); text-transform: uppercase; }

/* ── Resource library ────────────────────────────────────────────────── */
.resource-library { padding-block: var(--space-8) var(--space-9); }
.resource-library__bar {
  display: flex; align-items: end; justify-content: space-between;
  gap: var(--space-5); margin-bottom: var(--space-6);
}
.resource-library__bar h2 { margin-bottom: 0; }
.resource-library__count {
  margin: 0; color: var(--text-soft); font-size: var(--size-small);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.resource-filters {
  display: flex; gap: var(--space-2); overflow-x: auto;
  padding: 0 0 var(--space-5); margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
}
.resource-filters::-webkit-scrollbar { display: none; }
.resource-filter {
  display: inline-flex; align-items: center; flex: none;
  min-height: 2.5rem; padding: .65rem .9rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: transparent; color: var(--text-mid); font-size: var(--size-small);
  font-weight: 600; text-decoration: none;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.resource-filter:hover { border-color: var(--gold); color: var(--text); }
.resource-filter.is-active { background: var(--forest); border-color: var(--forest); color: var(--text-on-ink); }

.resource-library .tiles { display: block; }
.resources-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0; border-top: 1px solid var(--line); border-left: 1px solid var(--line);
}
.resource-card {
  min-width: 0; background: rgba(255, 255, 255, .18);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.resource-card--featured { grid-column: span 2; background: var(--forest); }
.resource-card__link {
  display: flex; flex-direction: column; min-height: 25rem; height: 100%;
  padding: var(--space-5); color: var(--text); text-decoration: none;
  transition: background var(--transition);
}
.resource-card__link:hover { color: var(--text); background: var(--paper-raised); }
.resource-card__topline {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--space-3); padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--line);
}
.resource-card__number {
  font-family: var(--font-mono); font-size: var(--size-label); color: var(--gold-text);
}
.resource-card__meta {
  color: var(--text-soft); font-size: var(--size-label); text-transform: uppercase;
  letter-spacing: .1em;
}
.resource-card__body { padding-block: var(--space-6); }
.resource-card__signal {
  display: inline-block; margin-bottom: var(--space-3); padding: .2rem .45rem;
  border: 1px solid var(--gold-on-ink); border-radius: 2px;
  color: var(--gold-on-ink); font-size: .625rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
.resource-card h3 { font-size: clamp(1.55rem, 2.2vw, 2rem); margin: var(--space-3) 0; }
.resource-card p { color: var(--text-mid); font-size: var(--size-small); }
.resource-card__action {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: auto; padding-top: var(--space-4); border-top: 1px solid var(--line);
  color: var(--gold-text); font-size: var(--size-small); font-weight: 700;
}
.resource-card--featured .resource-card__link { min-height: 25rem; color: var(--text-on-ink); }
.resource-card--featured .resource-card__link:hover { color: var(--text-on-ink); background: var(--forest-lit); }
.resource-card--featured .resource-card__topline,
.resource-card--featured .resource-card__action { border-color: var(--ink-line); }
.resource-card--featured .resource-card__number,
.resource-card--featured .resource-card__action { color: var(--gold-on-ink); }
.resource-card--featured .resource-card__meta,
.resource-card--featured p { color: var(--text-on-ink-soft); }
.resource-card--featured .article__cat { color: var(--eyebrow-on-ink); }
.resource-card--featured h3 { color: var(--text-on-ink); max-width: 22ch; font-size: clamp(2rem, 3vw, 3rem); }
.resource-empty { padding: var(--space-7) 0; color: var(--text-soft); }

.resource-next { background: var(--paper-sunk); border-top: 1px solid var(--line); padding-block: var(--space-8); }
.resource-next__inner { display: grid; grid-template-columns: 1.2fr .8fr; gap: var(--space-8); align-items: center; }
.resource-next h2 { max-width: 19ch; margin-bottom: 0; }
.resource-next__inner > div:last-child { max-width: 30rem; justify-self: end; }
.resource-next .btn { margin-top: var(--space-4); }

@media (max-width: 62rem) {
  .resource-next__inner { grid-template-columns: 1fr; gap: var(--space-6); }
  .resources-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .resource-next__inner > div:last-child { justify-self: start; }
}
@media (max-width: 40rem) {
  .resource-library__bar { align-items: flex-start; }
  .resources-grid { grid-template-columns: 1fr; }
  .resource-card--featured { grid-column: auto; }
  .resource-card__link, .resource-card--featured .resource-card__link { min-height: 22rem; }
}

/* ── Quote ────────────────────────────────────────────────────────────── */
.quote { margin: 0; border-left: 3px solid var(--gold); padding-left: var(--space-5); }
.quote blockquote {
  margin: 0; font-family: var(--font-display); font-size: 1.5rem;
  line-height: 1.3; color: var(--text);
}
.quote figcaption { margin-top: var(--space-3); font-size: var(--size-small); color: var(--text-soft); }

/* ── Logos ────────────────────────────────────────────────────────────── */
.logos { display: flex; flex-wrap: wrap; gap: var(--space-5); align-items: center; }
.logos__name {
  font-family: var(--font-display); font-size: 1.125rem; color: var(--text-soft);
  padding: var(--space-3) var(--space-4); border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--paper-raised);
}

/* ── Tables ───────────────────────────────────────────────────────────── */
.table { width: 100%; border-collapse: collapse; font-size: var(--size-small); }
.table th, .table td {
  text-align: left; padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--line); vertical-align: top;
}
.table thead th {
  font-size: var(--size-label); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-soft); font-weight: 700; border-bottom: 1px solid var(--line-strong);
}
.table tbody tr:last-child td { border-bottom: 0; }
/* The market-access filter row. A plain GET form laid out on one line, so it
   reads as a control strip rather than as a stack of questions. Every part of
   it is an existing `.field`; only the arrangement is new, and the fields drop
   to full width on a narrow screen through the same breakpoint everything else
   uses. `align-items: end` keeps the button on the baseline of the selects
   rather than centerd against their labels. */
.market-filters {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  align-items: end; margin-bottom: var(--space-5);
  padding-bottom: var(--space-5); border-bottom: 1px solid var(--line);
}
.market-filters .field { margin-bottom: 0; min-width: 12rem; }
.market-filters .field:last-child { min-width: 0; }
@media (max-width: 40rem) {
  .market-filters { flex-direction: column; align-items: stretch; }
  .market-filters .field { min-width: 0; }
}

.table--scroll { overflow-x: auto; }
.terms { width: 100%; border-collapse: collapse; }
.terms th, .terms td {
  text-align: left; padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-bottom: 1px solid var(--line); vertical-align: top;
}
.terms th { width: 32%; font-weight: 600; color: var(--text); }
.section--ink .terms th { color: var(--text-on-ink); }
.section--ink .terms th, .section--ink .terms td { border-bottom-color: var(--ink-line); }
/* The comparison columns. Emitted by `section_comparison.html` and styled
 * nowhere until now, so the page that is this site's strongest SEO asset
 * rendered as undifferentiated stacked divs. */
.compare {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-4); align-items: start;
}
.compare__col {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-5); background: var(--paper-raised);
}
.compare__col h3 { font-size: 1.25rem; margin-bottom: var(--space-3); }
.compare__col ul { list-style: none; padding: 0; margin: 0; }
.compare__col li {
  padding: var(--space-3) 0; border-bottom: 1px solid var(--line);
  font-size: var(--size-small);
}
.compare__col li:last-child { border-bottom: 0; }
/* OURS IS MARKED, and marked honestly: a stronger edge and the accent, not a
 * different set of facts. These pages are read by people checking whether
 * the comparison is fair. */
.compare__col--ours {
  border-color: var(--gold); border-width: 2px;
  background: var(--white);
}

/* The funnel's answer.
 *
 * This is the screen the whole funnel exists to reach, and it was unstyled:
 * `outcome` and `outcome--fast_track` were emitted and matched nothing, so a
 * principal who completed four steps got their result as bare paragraphs.
 *
 * The three outcomes are differentiated by a rule and a word, never by
 * color alone — "not yet" is a real answer with a reason attached, not a
 * failure, and painting it red would say the opposite of what it says. */
.outcome {
  border-left: 3px solid var(--line-strong);
  padding: var(--space-5) 0 var(--space-5) var(--space-5);
  margin-bottom: var(--space-6);
}
.outcome h2 { font-size: var(--size-h2); margin-bottom: var(--space-3); }
.outcome--fast_track { border-left-color: var(--gold); }
.outcome--qualified  { border-left-color: var(--ok); }
.outcome--not_yet    { border-left-color: var(--line-strong); }
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); padding: var(--space-4) 0; }
.faq summary {
  cursor: pointer; font-weight: 600; color: var(--text);
  font-size: 1rem; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: " +"; color: var(--gold); float: right; }
.faq details[open] summary::after { content: " \2212"; }
.faq p { margin-top: var(--space-3); }

/* ── Forms ────────────────────────────────────────────────────────────── */
.form { max-width: 34rem; }
.field { margin-bottom: var(--space-5); }
.field label { display: block; font-weight: 600; color: var(--text); margin-bottom: var(--space-2); }
.field input, .field select, .field textarea {
  width: 100%; padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--white); color: var(--text);
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--gold); }
/* `field--error` IS WHAT THE TEMPLATE WRITES. This styled a `data-invalid`
 * attribute that nothing in the tree ever sets, so a field that failed
 * validation looked exactly like one that had not: the message was there
 * and the control it belonged to was unmarked. */
.field--error input, .field--error select, .field--error textarea {
  border-color: var(--danger);
}
.field--error > label { color: var(--danger); }
.errors { color: var(--danger); font-size: var(--size-small); font-weight: 600; }
.choices { display: grid; gap: var(--space-3); }
.choice {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4); border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--white); cursor: pointer;
}
.choice:hover { border-color: var(--gold); }
.choice input { margin-top: 0.2rem; }
.errors { list-style: none; padding: 0; margin: var(--space-2) 0 0; }
.formerror { color: var(--danger); font-size: var(--size-small); font-weight: 600; }
.notice {
  background: var(--gold-pale); border-left: 3px solid var(--gold);
  padding: var(--space-4); border-radius: var(--radius-sm);
}
.flash {
  padding: var(--space-4); border-radius: var(--radius-sm);
  background: var(--forest-pale); border-left: 3px solid var(--ok);
  margin-bottom: var(--space-5);
}
.flash--error { background: var(--danger-pale); border-left-color: var(--danger); }
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* STYLED AGAINST WHAT THE TEMPLATE EMITS, which it previously was not.
 * `join.html` renders `<div class="progress__step progress__step--done">`;
 * this matched `.progress span[data-done]` — the wrong element and the wrong
 * mechanism — so the funnel's progress bar was four invisible divs with no
 * height and no color. Nothing reported it, because nothing can: CSS is
 * silent about a selector that matches nothing. */
.progress { display: flex; gap: var(--space-2); margin-bottom: var(--space-6); }
.progress__step {
  flex: 1; height: 3px; background: var(--line); border-radius: 2px;
}
.progress__step--done { background: var(--gold); }
.progress__label {
  font-size: var(--size-label); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--text-soft); font-weight: 700;
  margin-bottom: var(--space-3);
}

/* ── Placeholders ─────────────────────────────────────────────────────── */
/* A figure nobody has confirmed says so, in the open. Outside production it
 * is impossible to miss; `manage.py launch_blockers` lists every one. */
.pill {
  display: inline-block; font-size: var(--size-label); font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 0.15rem 0.5rem; border-radius: 999px;
  background: var(--paper-sunk); color: var(--text-soft);
}
.pill--partial { background: var(--gold-pale); color: var(--gold-dark); }
.placeholder-warning {
  background: var(--danger-pale); border: 1px dashed var(--danger);
  color: var(--danger); padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm); font-size: var(--size-small);
  font-weight: 600; margin-bottom: var(--space-5);
}

/* ── Footer ───────────────────────────────────────────────────────────── */
.footer { background: var(--forest); color: var(--text-on-ink-soft);
          padding-block: var(--space-8) var(--space-5); }
.footer a { color: var(--text-on-ink-soft); text-decoration: none; }
.footer a:hover { color: var(--text-on-ink); text-decoration: underline; }
.footer__cols {
  display: grid; grid-template-columns: 1.25fr repeat(4, 0.75fr);
  gap: var(--space-7); padding-bottom: var(--space-7);
  border-bottom: 1px solid var(--ink-line);
}
.footer__brand b { font-size: 1.375rem; color: var(--text-on-ink); }
.footer__brand p { color: var(--text-on-ink-soft); font-size: var(--size-small);
                   margin-top: var(--space-4); }
.footer__group-title {
  display: block; font-size: var(--size-label); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--on-ink-muted);
  margin-bottom: var(--space-3); font-weight: 700;
}
.footer__links { list-style: none; padding: 0; margin: 0; }
.footer__links li { margin: var(--space-2) 0; }
.footer__links a { font-size: var(--size-small); }
.footer__base {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--space-5); padding-top: var(--space-4);
  font-size: var(--size-label); color: var(--on-ink-muted); flex-wrap: wrap;
}

/* ── The operator console ─────────────────────────────────────────────── */
/* SAME TOKENS AS THE PUBLIC SITE. The sibling project redeclared its brand
 * colors in the console's own inline style block, so the two drifted and
 * the console slowly became a different product to look at. It reads this
 * file, and there is no second palette to keep in step. */
.console { display: grid; grid-template-columns: 15rem 1fr; min-height: 100vh; }
.console__side {
  background: var(--forest); color: var(--text-on-ink-soft);
  padding: var(--space-5);
}
.console__side a { color: var(--text-on-ink-soft); display: block;
                   padding: var(--space-2) 0;
                   font-size: var(--size-small); text-decoration: none; }
.console__side a:hover, .console__side a[aria-current] { color: var(--text-on-ink); }
.console__main { padding: var(--space-6); background: var(--paper); }
.console__title { font-size: var(--size-h2); margin-bottom: var(--space-5); }

/* ── Motion ───────────────────────────────────────────────────────────── */
/* THERE IS NONE, AND THAT IS THE DESIGN. The mockup this implements animates
 * nothing, and the CSS that used to sit here animated nothing either: it was
 * written against `[data-reveal]` and `[data-shown]` while the script set a
 * class called `is-visible`, so the two never met. The rules did nothing,
 * which is the only reason nobody noticed for as long as they were there.
 *
 * Transitions that DO run are on the things a person operates — buttons,
 * links, the nav panel — and each honors `--transition`, which the token
 * file neutralises under `prefers-reduced-motion`. If a scroll entrance is
 * ever wanted, the content must be visible at rest and the animation added
 * to it, never the reverse: an element parked at `opacity: 0` waiting for an
 * observer is invisible to every crawler, reader mode and screenshot that
 * never runs one. */

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width: 62rem) {
  .masthead__nav { display: none; }
  .masthead__cta { display: none; }
  .navtoggle { display: block; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat { border-bottom: 1px solid var(--line); }
  .stat:nth-child(2n) { border-right: 0; }
  .grid--2, .grid--sidebar { grid-template-columns: 1fr; }
  .tiles, .articles { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
  .steps::before { display: none; }
  .step:not(:last-child) { border-right: 0; margin-right: 0; }
  .footer__cols { grid-template-columns: 1.4fr 1fr 1fr; }
  .console { grid-template-columns: 1fr; }
}

@media (max-width: 40rem) {
  .section { padding-block: var(--space-7); }
  .stats { grid-template-columns: 1fr; }
  .stat { border-right: 0; }
  .tiles, .articles, .steps { grid-template-columns: 1fr; }
  .article { grid-template-columns: 100px 1fr; }
  .footer__cols { grid-template-columns: 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }
  .footer__base { flex-direction: column; align-items: flex-start; }
  .btn { width: 100%; }
  .btnrow .btn { width: auto; flex: 1 1 12rem; }
}

/* ── Print ────────────────────────────────────────────────────────────── */
/* The terms table is the one page people print and take to a partner, so it
 * is worth the twenty lines. Navigation, buttons and photographs are noise
 * on paper; a URL after every link is not. */
@media print {
  .masthead, .footer, .btnrow, .navtoggle, .mobilenav, .hero__visual,
  .hero__sunwash, .heronet,
  .skip-link, .tile > img, .article img { display: none !important; }
  /* The banner's copy is PLACED over the picture on screen. With the picture
   * gone there is nothing to place it over, and an absolute block prints on
   * top of whatever follows it. */
  .hero__plate--photo .hero__copy {
    position: static !important; width: auto !important;
  }
  .hero__plate--photo .display { font-size: 22pt; line-height: 1.15; }
  .hero__plate--photo .lead { font-size: 12pt; line-height: 1.45; }
  body { background: #FFF; color: #000; font-size: 11pt; }
  .section, .section--ink {
    background: #FFF !important; color: #000 !important;
    padding-block: 0.5cm; break-inside: avoid;
  }
  .section--ink h1, .section--ink h2, .section--ink h3,
  .section--ink p, .section--ink .lead { color: #000 !important; }
  .terms, .table { break-inside: auto; }
  .terms tr, .table tr { break-inside: avoid; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}

/* ── Utilities ────────────────────────────────────────────────────────── */
/*
 * WHY THESE EXIST, since everything above is component-shaped and this file
 * is deliberately not a utility framework.
 *
 * Every one replaced an inline `style="…"` attribute. Sixty-two of them
 * across twenty-eight templates, each small and reasonable alone, and
 * together they were the reason `style-src` could not be written at all: an
 * inline attribute cannot carry a nonce, so permitting it means
 * `'unsafe-inline'`, which is the difference between a policy that stops an
 * injected `<style>` repainting this page as somebody else's login form and
 * one that does not.
 *
 * Spacing, width and a few typographic switches. Nothing here is a
 * component; anything that becomes one belongs above this line.
 */
.u-mt-2 { margin-top: var(--space-2); }
.u-mt-4 { margin-top: var(--space-4); }
.u-mt-5 { margin-top: var(--space-5); }
.u-mt-6 { margin-top: var(--space-6); }
.u-mt-7 { margin-top: var(--space-7); }
.u-mb-5 { margin-bottom: var(--space-5); }
.u-mb-6 { margin-bottom: var(--space-6); }
.u-mb-7 { margin-bottom: var(--space-7); }
.u-pb-8 { padding-block: var(--space-8); }
.u-pb-9 { padding-block: var(--space-9); }

.u-measure       { max-width: var(--measure); }
.u-measure-tight { max-width: var(--measure-tight); }
.u-w-12 { max-width: 12rem; }
.u-w-16 { max-width: 16rem; }
.u-w-18 { max-width: 18rem; }
.u-w-24 { max-width: 24rem; }
.u-w-26 { max-width: 26rem; }
.u-w-40 { max-width: 40rem; }
.u-w-44 { max-width: 44rem; }
.u-minw-8 { min-width: 8rem; }

.u-nodecor  { text-decoration: none; }
.u-nowrap   { white-space: nowrap; }
.u-mono     { font-family: var(--font-mono); }
.u-inline   { display: inline; }
.u-push-right { margin-left: auto; }
.u-text-lg  { font-size: 1.1rem; }
.u-on-ink-soft { color: var(--text-on-ink-soft); }
.u-label    { font-weight: 600; font-size: var(--size-small);
              margin-bottom: var(--space-3); }
.u-bare-list { list-style: none; padding: 0; margin: 0; }
.u-bare      { border: 0; padding: 0; margin: 0; }

/* The four that were not one-liners. Named for what they are rather than for
 * what they set, because each appears once and a reader meeting it in the
 * template should learn its purpose, not its declarations. */
.u-console-eyebrow {
  font-family: var(--font-mono); font-size: var(--size-label);
  letter-spacing: var(--tracking-label); color: var(--gold);
  margin-bottom: var(--space-5);
}
.u-console-foot {
  margin-top: var(--space-6); border-top: 1px solid var(--ink-line);
  padding-top: var(--space-4);
}
.u-danger-chip {
  background: var(--danger-pale); color: var(--danger);
  border-color: var(--danger);
}
.u-code-block {
  background: var(--paper-sunk); padding: var(--space-4);
  border-radius: var(--radius); overflow: auto;
}

/* The wordmark beside the drawn mark. Live text rather than a path, so it is
 * selectable and searchable, and so the two weights stay in step with the
 * type scale instead of being frozen into an SVG. */
.masthead__brand-name b {
  font-size: 1.3125rem; font-weight: 700; letter-spacing: .015em;
  font-family: var(--font-ui);
}
.masthead__brand-name > span {
  font-size: var(--size-label); letter-spacing: var(--tracking-label);
  font-weight: 600; color: var(--text-soft); margin-left: 4px;
}
/* THE EXPANSION SITS ON ITS OWN LINE UNDER THE LOCKUP.
 *
 * `flex-basis: 100%` is what breaks the line: `.masthead__brand` sets
 * `white-space: nowrap`, which stops text wrapping but does not stop a flex
 * item claiming a row of its own. Wrapping the lockup in another element
 * would have been the obvious move and would have broken the two rules
 * above, which both select direct children of `.masthead__brand-name`.
 *
 * The selector carries `span` as well as the class so it outranks
 * `.masthead__brand-name > span` and keeps the 4px indent off. */
.masthead__brand-name {
  display: flex; flex-wrap: wrap; align-items: baseline;
  line-height: 1.1;
}
.masthead__brand-name > span.masthead__brand-full {
  flex-basis: 100%; margin-left: 0; margin-top: 2px;
  font-size: .6875rem; font-weight: 500;
  letter-spacing: .04em; text-transform: none;
  color: var(--text-soft);
}
/* The phone header is already tight and the lockup still reads without it. */
@media (max-width: 560px) {
  .masthead__brand-name > span.masthead__brand-full { display: none; }
}
.footer .masthead__brand-name > span.masthead__brand-full {
  color: var(--on-ink-muted);
}
.footer .masthead__brand-name b { color: var(--text-on-ink); font-size: 1.375rem; }
.footer .masthead__brand-name > span { color: var(--on-ink-muted); }
.footer .masthead__brand { color: var(--forest-pale); }

/* ── The hero banner and its living network ───────────────────────────── */
/*
 * THE PLATE IS A PHOTOGRAPH NOW, AND THAT IS THE WHOLE STORY OF THIS BLOCK.
 *
 * The render that arrived with the design had the navigation, the headline,
 * the subheading, both buttons and the small-caps line PAINTED INTO IT. The
 * first port cropped the nav band off the top and laid an opaque wash over
 * the left third to bury the painted headline. It never matched: a wash
 * strong enough to hide printed letters also flattens the haze the picture
 * makes its living from, and the ghosts were legible at every window width
 * anyway. `dev/tools/clean_plate.py` lifts that interface out of the pixels
 * instead, so the plate is 2172x724 of sky, ridge and lake and nothing else.
 *
 * Everything the visitor reads is therefore live text, placed where the
 * design painted it — to the pixel, in the design's own coordinates.
 *
 * `--u` IS ONE PLATE PIXEL. The design is 2172 wide; `--u` is the plate's
 * rendered width divided by 2172, so every number below is lifted straight
 * off the render and needs no conversion. It is expressed in `cqw` rather
 * than `vw` deliberately: `vw` includes the scrollbar, which on a 1440
 * window slides the whole composition about ten pixels left of where the
 * design puts it.
 */
.hero {
  position: relative;
  background: var(--paper);
  isolation: isolate;
}
.hero__plate {
  position: relative;
  max-width: 2172px;
  margin-inline: auto;
  container-type: inline-size;
  --u: 0.046040516cqw;
}
.hero__plate--photo { overflow: hidden; }

/* THE PICTURE SETS THE BAND'S HEIGHT, which is why it is in flow rather than
 * absolute. Nothing computes the band from a viewport unit and nothing can
 * disagree with the file: the plate is exactly as tall as 2172x724 makes it,
 * `cover` has nothing to crop, and the drawn network — which slices the same
 * box — lands on the painted globe every time. */
.hero__visual-wrap { position: relative; }
/* `<picture>` GENERATES A BOX. An <img> sized inside it resolves against the
 * picture rather than the band, so `object-fit` crops from the wrong
 * rectangle and drifts the composition sideways. `display: contents` takes
 * the wrapper out of the box tree. */
.hero picture { display: contents; }
.hero__visual {
  display: block; width: 100%; height: auto;
  animation: hero-breath 12s ease-in-out infinite alternate;
  transform: scale(1.005);
}
@keyframes hero-breath {
  to { transform: scale(1.018) translate3d(-.15%, .08%, 0); }
}

/* The sun catching the peak. `screen` so it lifts the highlights rather than
 * laying a gray film over everything. */
.hero__sunwash {
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(circle at 81% 35%,
    rgba(255, 232, 170, .18), transparent 22%);
  animation: hero-sun 5s ease-in-out infinite;
}
@keyframes hero-sun { 0%, 100% { opacity: .35; } 50% { opacity: .8; } }

.heronet {
  position: absolute; inset: 0; z-index: 2;
  width: 100%; height: 100%; pointer-events: none; overflow: visible;
  transform: translate3d(var(--net-x, 0), var(--net-y, 0), 0);
  transition: transform 220ms cubic-bezier(.2, .8, .3, 1);
}

/* THE COPY IS PLACED, NOT FLOWED, on a plated hero. Its left edge, its
 * measure and the first baseline are the design's own numbers; the rhythm
 * below the headline is margins between the blocks, so a longer sentence
 * still pushes the ones under it rather than colliding. */
.hero__plate--photo .hero__copy {
  position: absolute; z-index: 3;
  left: calc(146 * var(--u));
  top: calc(166 * var(--u));
  width: calc(790 * var(--u));
}
.hero__plate--photo .display {
  /* THE RENDER'S LETTERING IS NOT A FONT. It was drawn by the image model
   * that made the picture, and it is about a tenth narrower than real Libre
   * Caslon at the same cap height. Matching the cap height alone pushed
   * every line of the headline ten per cent long, which is the first thing
   * the eye catches when it compares the two. These two numbers hold the
   * line LENGTHS the design set — the rag down the right of the headline is
   * the signature — and give up two points of cap height to do it. */
  font-size: calc(96.5 * var(--u));
  line-height: calc(89.5 * var(--u));
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0;
}
.hero__plate--photo .lead {
  font-size: calc(24 * var(--u));
  line-height: calc(34.5 * var(--u));
  color: var(--text-mid);
  /* THE MEASURE IS WHAT SETS THE RAG. The design breaks after "Expert
   * support.", again after "your book", and leaves "of business." alone on
   * the third line, and that shape is as much a part of the picture as the
   * type size. The window between "All" staying down and "of" coming up is
   * about four pixels wide at this size, so this is its middle, not the
   * longest line rounded up. */
  max-width: calc(691 * var(--u));
  margin: calc(15 * var(--u)) 0 0;
}
/* ── The interior hero ─────────────────────────────────────────────────────
 *
 * THE SAME PLATE AND THE SAME NETWORK AS THE HOME PAGE. Identical picture,
 * identical geometry, identical drawn overlay, identical transparent header.
 * Nothing here touches the image.
 *
 * An earlier version cropped the plate to a shorter band to make room for
 * longer headlines. That worked on the type and ruined the picture: the
 * network is drawn across the full 2172x724 frame, so slicing the frame
 * squashes the orbits and cuts the routes, and the band stopped looking like
 * the thing it is on the home page.
 *
 * The real constraint was never the height. It was that the home headline is
 * sized to ONE sentence of known length: 96.5 plate-pixels, three lines, and
 * the copy block flows downward from a fixed top so a fourth line walks off
 * the bottom. "The appointment you cannot get is the business you cannot
 * write" is four lines at that size. So the only thing that changes on an
 * interior page is the type scale, and the picture is left exactly alone.
 */
/* THE COPY IS CENTERD IN THE SPACE BELOW THE HEADER, NOT PINNED TO A
 * BASELINE. The home hero's top edge is one of the design's own numbers and
 * is correct for the sentence it was drawn around. On an interior page the
 * sentence is whatever an editor last typed into the console, and a block
 * that flows downward from a fixed top clips as soon as it runs one line
 * longer than expected. Nothing in a test suite sees that; the reader sees it
 * immediately.
 *
 * Centring between the header and the bottom of the plate means a longer
 * headline grows in both directions instead of one, which roughly doubles the
 * copy it takes to reach an edge, and the top edge is the header rather than
 * the top of the picture so it can never slide underneath the navigation.
 * With the type below, the longest headline currently shipped uses a little
 * over four fifths of the room available. */
.hero__plate--photo.hero__plate--interior .hero__copy {
  top: calc(103 * var(--u));
  bottom: 0;
  height: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.hero__plate--interior .display {
  font-size: calc(72 * var(--u));
  line-height: calc(78 * var(--u));
}
.hero__plate--interior .lead {
  /* The design's measure holds; only the headline above it moved. */
  max-width: calc(720 * var(--u));
}

.hero__plate--photo .btnrow {
  gap: calc(11 * var(--u));
  margin-top: calc(19 * var(--u));
}
.hero__plate--photo .btn {
  height: calc(64 * var(--u));
  padding: 0 calc(38 * var(--u));
  gap: calc(15 * var(--u));
  font-size: calc(18.5 * var(--u));
  font-weight: 600;
  border-radius: calc(8 * var(--u));
}
.hero__plate--photo .btn--primary { background: var(--brass-run); box-shadow: none; }
.hero__plate--photo .btn--ghost {
  background: transparent;
  border-color: var(--gold-hairline);
  color: var(--gold-text);
}
.hero__note {
  font-size: calc(14 * var(--u));
  line-height: 1.4;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin: calc(15 * var(--u)) 0 0;
}

/* A hero with no picture is not a broken hero. Imagery is content on this
 * site, never structure, so the copy simply sits on the paper at the normal
 * type scale and looks deliberate. */
.hero__plate:not(.hero__plate--photo) {
  width: min(var(--page-max), 100% - (var(--gutter) * 2));
  padding-block: var(--space-8);
}
/* ── The moving parts, 1:1 with the mockup ───────────────────────────── */
.heronet__orbit-group {
  transform-origin: 1536px 370px;
  animation: heronet-float 7s ease-in-out infinite;
}
@keyframes heronet-float {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(0, -7px); }
}

/* AN ORBIT TURNS ABOUT THE EMBLEM. IT USED TO SLIDE ACROSS THE PICTURE.
 *
 * `heronet-spin` was written with a `to` and no `from`, so the browser
 * supplied the missing half from the element's own computed transform — the
 * `rotate(-18 1536 370)` the markup used to carry, which is not a rotation
 * about the origin but a rotation WITH A LARGE TRANSLATION folded into it.
 * A three-function underlying value against a one-function `rotate(360deg)`
 * is not a matching list, so the two were interpolated as matrices, and the
 * translation went along for the ride. Rendered with nothing but the four
 * ellipses on white, the painted extent was plate x 1196..2170 and y 0..1066
 * across the cycle — a picture that is 2172x724 — which is what the faint
 * dashed arcs sliding over the navigation and out onto the paper were. With
 * the keyframes below it is x 1230..1840, y 66..674 at every phase, which is
 * exactly the envelope four ellipses centerd on the emblem can reach.
 *
 * It was invisible to reasoning about `transform-origin`: the origin was
 * right all along, and setting it three different ways changes nothing,
 * because a matrix interpolation never consults it. Only the pixels showed
 * it.
 *
 * SO THE TILT LIVES HERE, ONCE, AS `--tilt`. The base rule is the still
 * frame, the keyframes start there and come back to it a full turn later,
 * and both ends are a single `rotate()` so the browser interpolates the
 * angle and nothing else. Under `prefers-reduced-motion` the blanket rule in
 * `tokens.css` runs the animation out in 1ms, which lands on `--tilt` plus a
 * whole turn — the drawn angle again. One number, one place, both paths.
 *
 * The fourth ellipse is `d` rather than a second `a` for that reason: it is
 * drawn eight degrees off where `a` is drawn, and a shared class cannot
 * carry two angles. It keeps `a`'s color and period, so the pair holds the
 * ten degrees between them exactly as the design has it. */
.heronet__orbit {
  fill: none; stroke-linecap: round; stroke-width: 2.1; opacity: .33;
  stroke-dasharray: 9 13;
  transform-box: fill-box; transform-origin: center;
  transform: rotate(var(--tilt));
}
.heronet__orbit.a { --tilt: -18deg; stroke: #0B4D3D;
                    animation: heronet-spin 22s linear infinite; }
.heronet__orbit.b { --tilt:  25deg; stroke: #B58A2A;
                    animation: heronet-spin-back 29s linear infinite; }
.heronet__orbit.c { --tilt:  65deg; stroke: #FFF; stroke-width: 1.55; opacity: .5;
                    animation: heronet-spin 35s linear infinite; }
.heronet__orbit.d { --tilt:  -8deg; stroke: #0B4D3D;
                    animation: heronet-spin 22s linear infinite; }
@keyframes heronet-spin {
  from { transform: rotate(var(--tilt)); }
  to   { transform: rotate(calc(var(--tilt) + 360deg)); }
}
@keyframes heronet-spin-back {
  from { transform: rotate(var(--tilt)); }
  to   { transform: rotate(calc(var(--tilt) - 360deg)); }
}

.heronet__route {
  fill: none; stroke: #F3CF6A; stroke-width: 3.5; stroke-linecap: round;
  opacity: .16; filter: url(#heronet-glow);
  animation: heronet-route 3.6s ease-in-out infinite;
}
@keyframes heronet-route { 0%, 100% { opacity: .13; } 45%, 60% { opacity: .85; } }

/* `paint-order: stroke` PUTS THE RING UNDER THE DISC. By default the stroke
 * is drawn on top and straddles the edge, so half of a cream ring eats into
 * a dot this small and the green reads as gray. */
.heronet__node {
  filter: url(#heronet-dot);
  paint-order: stroke;
  transform-box: fill-box; transform-origin: center;
  animation: heronet-node 2.6s ease-in-out infinite;
}
.heronet__node.green { fill: #0B4D3D; stroke: #F6F0DF; stroke-width: 3; }
.heronet__node.gold  { fill: #D6A83B; stroke: #FFF3CF; stroke-width: 3; }
.heronet__node.n2 { animation-delay: .45s; }
.heronet__node.n3 { animation-delay: .90s; }
.heronet__node.n4 { animation-delay: 1.35s; }
.heronet__node.n5 { animation-delay: 1.80s; }
@keyframes heronet-node {
  0%, 100% { transform: scale(1); opacity: .72; }
  50%      { transform: scale(1.5); opacity: 1; }
}

/* THE MARK SITS ON THE MOUNTAINS WITH NOTHING BEHIND IT. The plate used to
 * paint a dark disc under it; `clean_plate.py` clones that out, which is what
 * lets the logo be an asset instead of pixels. The cost is that the ridge
 * line reads straight through a mark with no ground, so it carries one soft
 * shadow, warm rather than neutral, belonging to the photograph's own light.
 *
 * It floats with the rest of the drawing because it is inside
 * `.heronet__orbit-group`, so the emblem and the orbits move as one object
 * rather than the rings drifting around a pinned logo. */
.heronet__emblem {
  filter: drop-shadow(0 6px 16px rgba(8, 37, 29, .5))
          drop-shadow(0 1px 2px rgba(8, 37, 29, .35));
}

.heronet__core {
  fill: none; stroke: #D9AD45; stroke-width: 3; opacity: 0;
  transform-origin: 1536px 370px;
  animation: heronet-core 3.4s ease-out infinite;
}
@keyframes heronet-core {
  0%        { r: 72;  opacity: .5; }
  70%, 100% { r: 116; opacity: 0; }
}

/* The packets. `offset-path` carries each one along the route it belongs to,
 * so the light travels the connection rather than across the box. */
.heronet__packet { filter: url(#heronet-bright); }
.heronet__packet.carrier {
  offset-path: path('M 1282 222 C 1352 251, 1412 310, 1536 370');
  animation: heronet-travel 3.8s cubic-bezier(.38,.02,.22,1) infinite;
}
.heronet__packet.expert {
  offset-path: path('M 1536 370 C 1619 432, 1651 484, 1710 541');
  animation: heronet-travel 3.8s cubic-bezier(.38,.02,.22,1) .65s infinite;
}
.heronet__packet.growth {
  offset-path: path('M 1536 370 C 1604 338, 1676 328, 1769 342');
  animation: heronet-travel 4.6s cubic-bezier(.38,.02,.22,1) 1.3s infinite;
}
.heronet__packet.tech {
  offset-path: path('M 1536 370 C 1460 408, 1379 457, 1282 484');
  animation: heronet-travel 4.4s cubic-bezier(.38,.02,.22,1) 2s infinite;
}
@keyframes heronet-travel {
  0%   { offset-distance: 0%;   opacity: 0; transform: scale(.55); }
  10%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; transform: scale(1.35); }
}

.heronet__spark {
  fill: #FFF3C7; opacity: 0; filter: url(#heronet-bright);
  animation: heronet-spark 4.2s linear infinite;
}
.heronet__spark.s2 { animation-delay: .7s; }
.heronet__spark.s3 { animation-delay: 1.3s; }
.heronet__spark.s4 { animation-delay: 2.1s; }
.heronet__spark.s5 { animation-delay: 2.9s; }
@keyframes heronet-spark {
  0%, 88%, 100% { opacity: 0; }
  92% { opacity: 1; r: 7; }
  96% { opacity: .2; r: 12; }
}

/* A PACKET IS A THING IN TRANSIT, so with motion turned off it is not a
 * smaller dot at the start of its route — it is nothing. Left visible it
 * parks its bright glow exactly on the node it departs from and bleaches it,
 * which is how the dot beside "Carrier access" came out cream in a still
 * frame while the other four were green. */
@media (prefers-reduced-motion: reduce) {
  .heronet__packet { display: none; }
}

/* The copy arrives once, in sequence. Base state is the finished state. */
.hero__copy > * { animation: hero-rise 700ms cubic-bezier(.22,.8,.3,1) backwards; }
.hero__copy > :nth-child(1) { animation-delay: .05s; }
.hero__copy > :nth-child(2) { animation-delay: .14s; }
.hero__copy > :nth-child(3) { animation-delay: .26s; }
.hero__copy > :nth-child(4) { animation-delay: .38s; }
.hero__copy > :nth-child(5) { animation-delay: .48s; }
@keyframes hero-rise { from { opacity: 0; transform: translateY(14px); } }

@media (max-width: 62rem) {
  /* THE MOCKUP SCALES THE WHOLE BAND DOWN BY TRANSFORM at this width, which
   * takes the headline down with it — eighteen pixels of Caslon on a phone.
   * That is a property of a picture of a page, not of a page. Here the
   * picture becomes a band across the top and the words go under it at the
   * site's own type scale, which is the same composition a reader can use. */
  .hero__plate { container-type: normal; }
  .hero__plate--photo { overflow: visible; }
  .hero__plate--photo .hero__copy {
    position: static; width: min(var(--page-max), 100% - (var(--gutter) * 2));
    margin-inline: auto;
    padding-block: var(--space-7) var(--space-8);
  }
  /* THE PICTURE AND THE DRAWING ARE ONE COMPOSITION, SO THEY CROP AS ONE.
   *
   * At full width the plate's box IS 2172x724, the drawn network slices the
   * same box, and every pulse sits inside the disc the photograph prints. A
   * phone is not 3:1, so the band has to crop, and it used to crop TWICE,
   * differently: the photograph moved its window right with
   * `object-position: 72%`, while the SVG's `xMidYMid slice` kept its own
   * window in the middle of the plate. The two windows sat 237 plate pixels
   * apart and neither was centerd on the mark, so on a 411px phone the mark
   * landed at 375.5 of 411 — hard against the right edge, on top of the
   * printed "Agency growth" label — while the globe it belongs in sat near
   * the middle. Measured, not judged.
   *
   * So the crop happens ONCE, in the wrapper, and all three layers are
   * simply the plate: one width, one offset, one box. The SVG's box then
   * carries its viewBox's own 3:1 ratio, `slice` has nothing left to slice,
   * and the drawing lands on the photograph exactly as it does on a desktop.
   * Anything added to this band later joins that one rule and cannot drift
   * out of register — which is the failure this replaces.
   */
  .hero__visual-wrap {
    --band-h: 17rem;
    /* The plate is 2172x724, so it renders three times as wide as it is
       tall — unless the band is wider than that, when the picture has to
       grow to fill it and crops from the top and bottom instead. */
    --plate-w: max(100%, calc(var(--band-h) * 3));
    /* One plate pixel is --band-h/724 tall and wide, and the mark's own x in
       the design's coordinates is 1536 of them. */
    --emblem-x: calc(var(--band-h) * 1536 / 724);
    height: var(--band-h);
    overflow: hidden;
  }
  .hero__visual, .hero__sunwash, .heronet {
    position: absolute;
    top: 0; right: auto; bottom: auto;
    /* Put 1536 plate-pixels of picture left of the band's middle and the
       mark is in the middle of the phone. The two bounds are the edges of
       the picture: it can never be pulled far enough to show paper on
       either side, which is what caps the shift on the wider phones and
       small tablets in this range, where the mark simply gets as close to
       centre as the frame allows. */
    left: clamp(min(0px, calc(100% - var(--plate-w))),
                calc(50% - var(--emblem-x)),
                0px);
    width: var(--plate-w); max-width: none;
    height: var(--band-h);
  }
  /* The picture already has the plate's box, so there is nothing left for
     `object-position` to decide horizontally; vertically it matches the
     SVG's `yMid`. */
  .hero__visual { object-fit: cover; object-position: 50% 50%; }
  .hero__plate--photo .display { font-size: var(--size-display);
                                 line-height: var(--leading-tight); }
  .hero__plate--photo .lead { font-size: var(--size-lead); line-height: 1.6;
                              max-width: 34rem; margin-top: var(--space-4); }
  .hero__plate--photo .btnrow { gap: var(--space-3); margin-top: var(--space-5); }
  .hero__plate--photo .btn {
    height: auto; padding: 0.9375rem 1.375rem; gap: var(--space-2);
    font-size: var(--size-small); border-radius: var(--radius-sm);
  }
  .hero__note { font-size: var(--size-label); letter-spacing: .19em;
                margin-top: var(--space-4); }
  .heronet { opacity: .55; }
}

/* ── The header, floating on the banner ──────────────────────────────── */
/*
 * The design has no bar behind the navigation: the logo, the links and the
 * gold button sit straight on the sky at the top of the picture. That works
 * because the top-left of the plate is pale, and it only works on a page
 * whose first section IS the banner — which is why the modifier comes from
 * the content rather than being baked into the header.
 *
 * STICKY IS DROPPED FOR THIS VARIANT AND THAT IS DELIBERATE. A transparent
 * bar that stays put while dark sections scroll under it becomes unreadable
 * within one screen. Scrolling past the banner should leave the header
 * behind; anything else needs a scroll listener, a solid state to swap to,
 * and a class of bug this page does not need.
 *
 * EVERY NUMBER HERE IS A PLATE PIXEL, same as the banner below it, because
 * the header is part of the same composition: the brand sits 140 in from the
 * left of the picture and the button ends 139 in from its right. Measuring
 * the header against the page's own grid instead is what left the links
 * crowding the button.
 */
.masthead--over {
  position: absolute; inset: 0 0 auto 0; z-index: 20;
  background: transparent; border-bottom: 0;
  container-type: inline-size;
  --u: 0.046040516cqw;
}
.masthead--over .masthead__inner {
  width: 100%; max-width: 2172px; margin-inline: auto;
  min-height: 0; height: calc(103 * var(--u));
  padding-inline: calc(140 * var(--u)) calc(139 * var(--u));
  gap: 0;
}

/* The lockup: the drawn mark, a hairline, then the wordmark. The rule is a
 * border on the wordmark rather than an element of its own, so there is
 * nothing to keep in step when the lockup is reused in the footer. */
.masthead--over .masthead__brand { gap: 0; color: var(--ink); }
/* MEASURED IN THE PLATE'S UNITS, AND THE NUMBERS ARE THE MARK'S OWN.
 * 41 by 46 was the drawn lockup's viewBox, and left in place it squashes any
 * mark wider than it is tall. 58 by 48 is the current mark's ratio (420 by
 * 350) at a height that still reads.
 *
 * It is larger than the bars were, deliberately. Four rectangles are legible
 * at any size; a mane is not, and at the old height this came out as a
 * colored dot beside the wordmark. Even here it is close to the floor for
 * this mark, which is an argument for a simplified small-size variant rather
 * than for shrinking it further. */
.masthead--over .masthead__brand img.brandmark {
  width: calc(58 * var(--u)); height: calc(48 * var(--u)); flex: none;
  object-fit: contain;
}
.masthead--over .masthead__brand-name {
  display: inline-flex; align-items: center;
  height: calc(48 * var(--u));
  margin-left: calc(15 * var(--u));
  padding-left: calc(10 * var(--u));
  border-left: 1px solid var(--line-strong);
}
.masthead--over .masthead__brand-name b {
  font-size: calc(41 * var(--u)); font-weight: 700; letter-spacing: .005em;
}
.masthead--over .masthead__brand-name > span {
  font-size: calc(24 * var(--u)); font-weight: 400; letter-spacing: .17em;
  color: var(--text); margin-left: calc(9 * var(--u));
}

.masthead--over .masthead__nav {
  align-items: center; gap: calc(31 * var(--u));
  margin-left: calc(87 * var(--u)); flex: 1;
}
/* Same story as the headline: the render's nav lettering is narrower than DM
 * Sans, so nine links set at the design's own size overran by sixty pixels
 * and closed the gap in front of the button. The size gives up half a point
 * and the space between links takes the rest, which keeps the row ending
 * where the design ends it. */
.masthead--over .navlink {
  font-size: calc(16.5 * var(--u)); font-weight: 500; letter-spacing: 0;
  padding: calc(6 * var(--u)) 0; border-bottom-width: calc(2 * var(--u));
}

/* THE GRADIENT STOPS WHERE WHITE STOPS PASSING. The design's pill runs from
 * a deep brass to a light one, and white on that light end measures 3.4:1 —
 * under AA for a label this size. The run below keeps the design's move and
 * ends at the darkest gold the brand already uses for white labels, which is
 * the one number on this page that is not taken from the render. */
.masthead--over .masthead__cta {
  margin-left: auto; align-self: center;
  height: calc(62 * var(--u));
  padding: 0 calc(37 * var(--u));
  gap: calc(15 * var(--u));
  font-size: calc(18 * var(--u)); font-weight: 600;
  border-radius: calc(8 * var(--u));
  background: var(--brass-run); box-shadow: none;
}

/* Past the design's own width the plate stops growing and is centerd, so a
 * plate pixel is a pixel. Without this the container units keep scaling
 * against the window and the header drifts off the picture below it. */
@media (min-width: 2172px) {
  .masthead--over, .hero__plate { --u: 1px; }
}

@media (max-width: 62rem) {
  /* On a phone the plate is a band across the top rather than a backdrop, so
   * a transparent header would float over the page, not over the picture. It
   * gets its bar back. */
  .masthead--over {
    position: static; background: var(--paper-raised);
    border-bottom: 1px solid var(--line-soft);
    container-type: normal;
  }
  .masthead--over .masthead__inner {
    height: auto; min-height: 70px;
    width: min(var(--page-max), 100% - (var(--gutter) * 2));
    padding-inline: 0; gap: var(--space-6);
  }
  .masthead--over .masthead__brand svg { width: 31px; height: 31px; }
  .masthead--over .masthead__brand-name {
    height: auto; margin-left: var(--space-3);
    padding-left: 0; border-left: 0;
  }
  .masthead--over .masthead__brand-name b { font-size: 1.3125rem; }
  .masthead--over .masthead__brand-name > span {
    font-size: var(--size-label); letter-spacing: var(--tracking-label);
    font-weight: 600; color: var(--text-soft);
  }
}

/* ══ The home page, below the banner ═══════════════════════════════════════
 *
 * Seven bands, each a composition rather than a container: the advantage
 * row, the network map, the ownership split, the carrier flow, the process
 * track, the Book Check panel and the closing strip.
 *
 * THE PALETTE IS THIS SITE'S, NOT THE MOCKUP'S. The supplied redesign is
 * drawn in navy and cold gray with a bright brass. Dropped in as given it
 * would have put a second identity on the same page as the banner, which is
 * warm paper, forest and a muted gold. Every color below reads a token, so
 * the bands move with the brand and there is no second place to update.
 *
 * NOTHING HERE IS PARKED AT `opacity: 0`. The design shipped with a scroll
 * observer that faded each band in, which means a crawler, a reader mode, a
 * screenshot and anybody whose JavaScript did not arrive get a blank page
 * that is technically present. Content is visible at rest; the only motion
 * is the map's pulse, and that honors `prefers-reduced-motion` through the
 * blanket rule in `tokens.css`.
 *
 * NO INLINE STYLE ATTRIBUTES. The mockup set twenty-four bar heights, four
 * plate offsets and a donut's five stops in `style="…"`. Each one would need
 * `style-src 'unsafe-inline'`, which is the permission that lets an injected
 * `<style>` repaint this page as somebody else's login form. Fixed steps
 * live here; anything computed is an SVG attribute, which is markup rather
 * than CSS and needs no exception.
 */

/* A band that owns its own gutter. Dispatched without a `.wrap` so the dark
 * stage inside it can reach the edge of the window. */
.section--bleed { padding-block: 0; }

/* ── The advantage row ────────────────────────────────────────────────── */
.advantage__intro {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: var(--space-8); align-items: start;
}
.advantage__title {
  font-size: clamp(2.25rem, 4.4vw, 3.5rem); line-height: var(--leading-tight);
  letter-spacing: -0.02em;
}
.advantage__lede { display: grid; gap: var(--space-4); padding-top: 0.35rem; }
.advantage__lede .lead { margin: 0; max-width: 34rem; }
/* The small-caps line the mockup sets beside the paragraph. It is a motto,
 * not a fact, so it is typeset as one: a gold rule, wide tracking, and no
 * competition with the heading. */
.advantage__motto {
  border-left: 2px solid var(--gold); padding-left: var(--space-4);
  font-size: var(--size-label); letter-spacing: 0.16em; line-height: 1.9;
  text-transform: uppercase; color: var(--text-soft); font-weight: 600;
}

.advantage__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4); margin-top: var(--space-7);
}
.advcard {
  display: flex; flex-direction: column; min-height: 23rem;
  padding: var(--space-5); border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--paper-raised);
  box-shadow: var(--shadow);
}
.advcard h3 {
  font-size: 1.375rem; line-height: 1.15; margin: var(--space-4) 0 var(--space-2);
}
.advcard p { font-size: var(--size-small); line-height: 1.55; color: var(--text-mid); }
.advcard__icon {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--gold-hairline); color: var(--gold-text);
}
/* THE DARK CARDS ARE FIRST AND THIRD, and the modifier is applied by
 * `:nth-child` in the template rather than stored per card, so inserting a
 * fifth card in the console keeps the alternation instead of putting two
 * dark cards side by side. */
.advcard--ink {
  background: linear-gradient(170deg, var(--forest) 0%, var(--forest-deep) 78%);
  border-color: var(--forest-lit); color: var(--text-on-ink-soft);
}
.advcard--ink h3 { color: var(--text-on-ink); }
.advcard--ink p { color: var(--text-on-ink-soft); }
.advcard--ink .advcard__icon {
  border-color: rgba(201, 165, 74, .45); color: var(--gold-on-ink);
}

/* The figure sits on the bottom edge of the card whatever the copy above it
 * runs to, which is what keeps four cards of different lengths reading as
 * one row. */
.advcard__figure {
  margin-top: auto; padding-top: var(--space-5); height: 8.5rem;
}
.advcard__bars {
  display: flex; align-items: flex-end; gap: 6px; height: 100%;
  position: relative;
  border-bottom: 1px solid var(--line);
}
.advcard--ink .advcard__bars { border-bottom-color: var(--ink-line); }
.advcard__bars > i {
  flex: 1; border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--gold-on-ink), rgba(14, 84, 67, .55));
}
.advcard:not(.advcard--ink) .advcard__bars > i {
  background: linear-gradient(180deg, var(--gold) , rgba(150, 123, 53, .18));
}
.advcard__bars > i:nth-child(1) { height: 22%; }
.advcard__bars > i:nth-child(2) { height: 31%; }
.advcard__bars > i:nth-child(3) { height: 40%; }
.advcard__bars > i:nth-child(4) { height: 53%; }
.advcard__bars > i:nth-child(5) { height: 68%; }
.advcard__bars > i:nth-child(6) { height: 85%; }
.advcard__bars--climb > i:nth-child(1) { height: 25%; }
.advcard__bars--climb > i:nth-child(2) { height: 35%; }
.advcard__bars--climb > i:nth-child(3) { height: 46%; }
.advcard__bars--climb > i:nth-child(4) { height: 57%; }
.advcard__bars--climb > i:nth-child(5) { height: 70%; }
.advcard__bars--climb > i:nth-child(6) { height: 83%; }
.advcard__trend {
  position: absolute; right: 2px; top: 4px; width: 64px; height: 44px;
  fill: none; stroke: var(--gold-on-ink); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}

.advcard__curve { width: 100%; height: 100%; display: block; }
.advcard__curve-fill { fill: rgba(150, 123, 53, .14); }
.advcard__curve-line { fill: none; stroke: var(--gold); stroke-width: 2; }
.advcard--ink .advcard__curve-fill { fill: rgba(201, 165, 74, .18); }
.advcard--ink .advcard__curve-line { stroke: var(--gold-on-ink); }

/* Five plates on one axis: the book, the staff, the clients, the brand and
 * the decisions, stacked and skewed so they read as a solid object rather
 * than as five rules. */
.advcard__stack { position: relative; height: 100%; }
.advcard__stack > i {
  position: absolute; left: 50%; width: 8.5rem; height: 1.6rem;
  transform: translateX(-50%) skewY(-13deg);
  border: 1px solid var(--gold-hairline);
  background: linear-gradient(120deg, var(--paper-sunk) 0%, var(--white) 45%,
                              var(--gold-pale) 70%, var(--gold-hairline) 100%);
  box-shadow: 0 6px 12px rgba(8, 37, 29, .16);
}
/* Far enough apart to read as five things rather than as one hatched block,
 * which is what a 0.95rem step gave: the plates overlapped and the figure
 * came out as a scribble. */
.advcard__stack > i:nth-child(1) { bottom: 0.1rem; }
.advcard__stack > i:nth-child(2) { bottom: 1.4rem; }
.advcard__stack > i:nth-child(3) { bottom: 2.7rem; }
.advcard__stack > i:nth-child(4) { bottom: 4rem; }
.advcard__stack > i:nth-child(5) { bottom: 5.3rem; }

.advcard__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-top: var(--space-5);
  font-size: var(--size-label); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-text); text-decoration: none;
}
.advcard--ink .advcard__foot { color: var(--gold-on-ink); }
.advcard__go {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  border: 1px solid currentColor; display: grid; place-items: center;
  transition: transform var(--transition), background var(--transition);
}
.advcard__foot:hover .advcard__go { transform: translateX(3px); }

/* ── The network band and the map ─────────────────────────────────────── */
.netband {
  display: grid; grid-template-columns: 0.92fr 1.3fr 0.52fr;
  gap: var(--space-6); align-items: center;
}
/* No confirmed figures means no rail, and no column of air where one would
 * have gone. */
.netband--nostats { grid-template-columns: 0.9fr 1.35fr; }
.netband__copy h2 { font-size: clamp(2.125rem, 3.6vw, 3.25rem); }
.netband__copy .lead { margin-block: var(--space-4) var(--space-6); }
.netband__map { min-width: 0; }

.usmap { display: block; width: 100%; height: auto; }
.usmap__land > path {
  fill: rgba(14, 84, 67, .58);
  stroke: rgba(184, 214, 200, .38); stroke-width: 0.6;
  vector-effect: non-scaling-stroke;
}
.usmap__arcs > path {
  fill: none; stroke: var(--gold-on-ink); stroke-width: 1;
  stroke-opacity: .3; vector-effect: non-scaling-stroke;
}
/* The six arcs that carry a light are brighter, and breathe, so the wiring
 * reads as live even at the moment no light happens to be on it. The same
 * move as `.heronet__route` on the banner. */
.usmap__arcs > .usmap__arc--live {
  stroke-opacity: .5; animation: usmap-route 5.2s ease-in-out infinite;
}
@keyframes usmap-route {
  0%, 100% { stroke-opacity: .28; }
  45%, 60% { stroke-opacity: .72; }
}

.usmap__halos > circle { fill: url(#usmap-node); opacity: .5; }
.usmap__nodes > circle { fill: #FFF4D2; }
/* The pulse is staggered by class rather than by a script writing an
 * `animation-delay` into sixty style attributes at load. Six phases is
 * enough for the row never to blink in unison and few enough to read as one
 * living map rather than as noise. */
.usmap__node { animation: usmap-pulse 3.8s ease-in-out infinite; }
.usmap__node--p1 { animation-delay: .55s; }
.usmap__node--p2 { animation-delay: 1.1s; }
.usmap__node--p3 { animation-delay: 1.65s; }
.usmap__node--p4 { animation-delay: 2.2s; }
.usmap__node--p5 { animation-delay: 2.75s; }
.usmap__node--hub { filter: drop-shadow(0 0 6px rgba(255, 226, 150, .85)); }
@keyframes usmap-pulse {
  0%, 100% { opacity: .62; }
  50%      { opacity: 1; }
}

/* ── The traveling lights ────────────────────────────────────────────────
 *
 * The banner sends a packet along each route with `offset-path`, which takes
 * the route's `d` string written out a second time INSIDE THE STYLESHEET.
 * That is fine for four hand-placed curves and impossible here: these arcs
 * are generated from city coordinates, and duplicating twenty-two path
 * strings into a CSS file that a tool does not write is a copy that is wrong
 * the first time anybody moves a node.
 *
 * So the light is a DASH ON THE ARC ITSELF, and `pathLength="100"` in the
 * generated markup is what makes one rule fit every arc: it rescales the
 * dash to a path's own length, so `2 98` is a two percent spark whether the
 * arc is a transcontinental sweep or a short hop, and one duration runs both
 * at the same apparent speed. The spark is the dash; the ninety-eight is the
 * dark it travels through.
 *
 * Nothing here needs JavaScript, and `prefers-reduced-motion` stops all of
 * it through the blanket rule in `tokens.css`. */
.usmap__runner {
  fill: none; stroke: #FFF6DC; stroke-width: 2.4; stroke-linecap: round;
  vector-effect: non-scaling-stroke; filter: url(#usmap-bright);
  stroke-dasharray: 2 98;
  animation: usmap-run 5.6s cubic-bezier(.4, 0, .5, 1) infinite;
}
.usmap__runner--r1 { animation-delay: .9s; animation-duration: 6.4s; }
.usmap__runner--r2 { animation-delay: 1.8s; animation-duration: 5.1s; }
.usmap__runner--r3 { animation-delay: 2.7s; animation-duration: 6.9s; }
.usmap__runner--r4 { animation-delay: 3.6s; animation-duration: 5.9s; }
.usmap__runner--r5 { animation-delay: 4.5s; animation-duration: 6.2s; }
@keyframes usmap-run {
  0%        { stroke-dashoffset: 100; opacity: 0; }
  8%        { opacity: 1; }
  78%       { opacity: 1; }
  92%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}

/* A ring opening at five hubs and fading, which is the emblem's move on the
 * banner at a fifth of the size. `r` is animated rather than a transform so
 * the ring grows about its own center without needing a `transform-origin`
 * per circle, and the stroke thins as it goes the way a real one would. */
.usmap__ring {
  fill: none; stroke: var(--gold-on-ink); stroke-width: 1.4;
  vector-effect: non-scaling-stroke; opacity: 0;
  animation: usmap-ring 6.5s ease-out infinite;
}
.usmap__ring--r1 { animation-delay: 1.3s; }
.usmap__ring--r2 { animation-delay: 2.6s; }
.usmap__ring--r3 { animation-delay: 3.9s; }
.usmap__ring--r4 { animation-delay: 5.2s; }
@keyframes usmap-ring {
  0%       { r: 4;  opacity: .75; }
  55%, 100% { r: 26; opacity: 0; }
}

/* A LIGHT IN TRANSIT IS NOTHING WHEN NOTHING IS MOVING. Left in place with
 * the animation neutralised it parks its glow on the arc's first pixel,
 * which puts a bright smudge on six cities in a still frame. The banner's
 * packets are hidden for the same reason. */
@media (prefers-reduced-motion: reduce) {
  .usmap__runner, .usmap__ring { display: none; }
}

.netrail { display: grid; gap: var(--space-5); margin: 0; }
.netrail__item {
  display: grid; grid-template-columns: 1fr; gap: 0.2rem;
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--ink-line);
}
.netrail__value {
  margin: 0; font-family: var(--font-display); font-size: 2rem;
  line-height: 1; color: var(--text-on-ink);
}
.netrail__label {
  font-size: var(--size-label); letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--on-ink-muted); order: 2;
}
.netrail__note { margin: var(--space-2) 0 0; order: 3; }

/* ── The ownership split ──────────────────────────────────────────────── */
/* Light column, dark stage, and the join runs the full height of the band.
 * The left column's padding is computed from the page container so the copy
 * lines up with every other section's left edge even though this band has no
 * `.wrap` of its own. */
.ownsplit { display: grid; grid-template-columns: 0.74fr 1.26fr; }
.ownsplit__copy {
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--space-9) var(--space-7) var(--space-9)
           max(var(--gutter), calc((100vw - var(--page-max)) / 2));
}
.ownsplit__copy h2 { font-size: clamp(2.125rem, 3.8vw, 3.25rem); }
.ownsplit__copy .lead { margin-top: var(--space-4); }

.ownlist {
  display: grid; gap: var(--space-4); margin-top: var(--space-6);
  border-left: 2px solid var(--gold); padding-left: var(--space-5);
}
.ownlist__row { display: grid; grid-template-columns: 2rem 1fr; gap: var(--space-3); }
.ownlist__icon {
  width: 2rem; height: 2rem; border-radius: 50%; flex: none;
  border: 1px solid var(--gold-hairline); color: var(--gold-text);
  display: grid; place-items: center;
}
.ownlist strong { display: block; font-size: var(--size-body); }
.ownlist small { display: block; color: var(--text-soft); font-size: var(--size-small); }

.ownsplit__stage {
  background:
    radial-gradient(circle at 22% 18%, var(--forest-lit) 0%,
                    var(--forest) 38%, var(--forest-deep) 100%);
  padding: var(--space-8) var(--space-7);
  display: grid; align-content: center; gap: var(--space-4);
}
.ownsplit__note {
  margin: 0; font-size: var(--size-small); color: var(--text-on-ink-soft);
  max-width: 44rem;
}

/* The member view. A drawing of an interface, with nothing in it that is a
 * figure: the mockup's production, retention and opportunity numbers were
 * invented, and an invented number inside a picture of a product is the most
 * persuasive kind there is. What is left is the shape, which is the part of
 * the claim that is true today. */
.memberview {
  display: grid; grid-template-columns: 11.5rem 1fr;
  border: 1px solid rgba(201, 165, 74, .35); border-radius: var(--radius);
  background: var(--forest-deep); overflow: hidden;
  box-shadow: 0 30px 70px rgba(5, 46, 38, .45);
}
.memberview__side {
  padding: var(--space-4) var(--space-3);
  border-right: 1px solid var(--ink-line);
}
.memberview__brand { padding: var(--space-2); line-height: 1.1; }
.memberview__brand b {
  font-family: var(--font-display); font-size: 1.25rem; color: var(--gold-on-ink);
}
.memberview__brand span {
  font-size: 0.5625rem; letter-spacing: 0.2em; color: var(--text-on-ink);
}
.memberview__nav { display: grid; gap: 2px; margin-top: var(--space-4); }
.memberview__navitem {
  font-size: var(--size-label); color: var(--on-ink-muted);
  padding: 0.5rem var(--space-3); border-radius: var(--radius-sm);
}
.memberview__navitem.is-current {
  background: linear-gradient(90deg, var(--gold-ink), rgba(142, 115, 45, .25));
  color: var(--on-gold); font-weight: 600;
}
.memberview__main { padding: var(--space-5); }
.memberview__top {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--space-4);
}
.memberview__top small { font-size: var(--size-label); color: var(--on-ink-muted); }
.memberview__top strong {
  display: block; font-family: var(--font-display); font-size: 1.3125rem;
  color: var(--text-on-ink); margin: 0.15rem 0;
}
.memberview__top p { margin: 0; font-size: var(--size-label); color: var(--on-ink-muted); }
.memberview__chip {
  flex: none; font-size: var(--size-label); color: var(--text-on-ink-soft);
  border: 1px solid var(--ink-line); border-radius: var(--radius-sm);
  padding: 0.4rem var(--space-3);
}
.memberview__grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3);
  margin-top: var(--space-5);
}
.memberview__card {
  background: var(--paper-raised); border-radius: var(--radius-sm);
  padding: var(--space-3); min-height: 7rem;
  display: flex; flex-direction: column;
}
.memberview__card small {
  font-size: var(--size-label); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--gold-text); font-weight: 700;
}
.memberview__card p {
  margin: var(--space-2) 0 var(--space-3); font-size: var(--size-small);
  line-height: 1.35; color: var(--text);
}
.memberview__go {
  margin-top: auto; font-size: var(--size-label); font-weight: 700;
  color: var(--gold-text);
}

/* ── The carrier flow diagram ─────────────────────────────────────────── */
.flowband {
  display: grid; grid-template-columns: 0.62fr 1.38fr;
  gap: var(--space-8); align-items: center;
}
.flowband__copy h2 { font-size: clamp(2.125rem, 3.6vw, 3.25rem); }
.flowband__copy .lead { margin-block: var(--space-4) var(--space-6); }

/* FIXED BANKS, A FIXED HUB, AND THE WIRES TAKE WHAT IS LEFT. The three
 * widths below are the contract the wire drawings are written against: with
 * both neighbors fixed, each `.flow__wires` is exactly the gap, so its
 * `x=0` is the bank's edge and its `x=100` is the hub's at every window
 * size. As a fluid three-column grid it was in register at one width only. */
.flow {
  --flow-tile: 3.75rem;
  --flow-bank: calc((var(--flow-tile) * 3) + (var(--space-3) * 2));
  position: relative; min-width: 0;
  display: flex; align-items: center; gap: 0;
  padding-top: var(--space-6);
}
/* `<symbol>` definitions only: it draws nothing itself and must take no
 * space, which `display: none` on the element would also achieve at the cost
 * of Safari refusing to resolve the references out of it. */
.flow__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.flow__label {
  position: absolute; top: 0; margin: 0; text-align: center;
  font-size: var(--size-label); letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--text-soft); font-weight: 600;
}
.flow__label--left { left: 0; width: 30%; }
.flow__label--mid { left: 50%; transform: translateX(-50%); width: 30%; }
.flow__label--right { right: 0; width: 30%; }

.flow__bank {
  flex: none; width: var(--flow-bank); height: var(--flow-bank);
  display: grid; grid-template-columns: repeat(3, var(--flow-tile));
  grid-auto-rows: var(--flow-tile);
  gap: var(--space-3); position: relative; z-index: 2;
}
.flow__tile {
  aspect-ratio: 1; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--paper-raised);
  display: grid; place-items: center;
  box-shadow: 0 6px 14px rgba(8, 37, 29, .08);
}
.flow__tile svg {
  width: 26px; height: 26px; fill: none; stroke: var(--forest-lit);
  stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round;
}
.flow__tile--agency svg { stroke: var(--gold-text); }

.flow__hub {
  flex: none; width: 9.5rem; height: 9.5rem; border-radius: 50%;
  display: grid; place-content: center; text-align: center;
  background: radial-gradient(circle, var(--forest-lit) 0%,
                              var(--forest-deep) 70%);
  border: 2px solid var(--gold); color: var(--text-on-ink);
  box-shadow: 0 0 45px rgba(150, 123, 53, .35); position: relative; z-index: 3;
}
.flow__hub b { font-family: var(--font-display); font-size: 2rem; line-height: 1; }
.flow__hub small {
  font-size: 0.5625rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--gold-on-ink);
}

/* As tall as a bank, so the three wires leave at the three rows' center
 * lines, and as wide as whatever is left over. */
.flow__wires { flex: 1 1 0; min-width: 1rem; height: var(--flow-bank); }
.flow__wires path {
  fill: none; stroke: var(--gold); stroke-width: 1; stroke-opacity: .5;
  vector-effect: non-scaling-stroke;
}

/* ── The process track ────────────────────────────────────────────────── */
/* The interior pages keep the heading above four equal columns. The home
 * page puts it in its own column beside them, which is the only difference
 * between the two and the reason it is a container and not a second
 * partial. */
.steps-split {
  display: grid; grid-template-columns: 0.52fr 1.48fr;
  gap: var(--space-8); align-items: center;
}
.steps-split .steps__head .section__head,
.steps-plain .steps__head .section__head { margin-bottom: var(--space-5); }
.steps-split .steps { grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
.steps-split .step { padding-right: 0; }
.steps-split .step:not(:last-child) { border-right: 0; margin-right: 0; }
.steps-split .steps::before { top: 21px; left: 4%; right: 4%; }
/* On the forest the disc is an outline rather than a filled brass coin: a
 * gold fill at this size on this ground is a bright blob, and the numeral
 * inside it stops being the thing you read. */
.section--ink .step__num {
  width: 42px; height: 42px; background: transparent; box-shadow: none;
  border: 1px solid var(--gold-on-ink); color: var(--gold-on-ink);
  font-family: var(--font-display); font-size: var(--size-body);
}
.section--ink .steps::before { border-top-color: rgba(201, 165, 74, .3); }
.section--ink .step__icon { color: var(--text-on-ink-soft); }
.section--ink .step p { color: var(--text-on-ink-soft); }

/* ── The Book Check panel ─────────────────────────────────────────────── */
.bookband {
  display: grid; grid-template-columns: 0.56fr 1.44fr;
  gap: var(--space-8); align-items: center;
}
.bookband__copy h2 { font-size: clamp(2.125rem, 3.8vw, 3.375rem); }
.bookband__copy .lead { margin-block: var(--space-4) var(--space-6); }

.bookpanel {
  margin: 0; min-width: 0;
  border: 1px solid rgba(201, 165, 74, .32); border-radius: var(--radius);
  background: var(--forest-deep); overflow: hidden;
  box-shadow: 0 30px 70px rgba(5, 46, 38, .42);
}
.bookpanel__bar {
  display: flex; align-items: center; gap: var(--space-5);
  padding: 0 var(--space-4); height: 3rem;
  border-bottom: 1px solid var(--ink-line);
  font-size: var(--size-label); color: var(--on-ink-muted);
}
.bookpanel__bar strong { color: var(--text-on-ink); font-size: var(--size-small); }
.bookpanel__tab { white-space: nowrap; }
.bookpanel__tab.is-current {
  color: var(--gold-on-ink); font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--gold-on-ink);
  height: 3rem; display: flex; align-items: center;
}
/* Where the mockup put an agency selector. It says what the panel is, in the
 * place a reader looks to find out whose figures these are. */
.bookpanel__who {
  margin-left: auto; flex: none; color: var(--text-on-ink-soft);
  border: 1px solid var(--ink-line); border-radius: var(--radius-sm);
  padding: 0.35rem var(--space-3);
}

.bookpanel__grid {
  display: grid; grid-template-columns: 1.2fr 1fr 1fr;
  gap: 1px; background: var(--ink-line); border-bottom: 1px solid var(--ink-line);
}
.bookpanel__cell {
  background: linear-gradient(180deg, rgba(14, 84, 67, .42), transparent);
  padding: var(--space-4); min-width: 0;
}
.bookpanel__cell h3 {
  font-family: var(--font-ui); font-size: var(--size-label);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--on-ink-muted); font-weight: 700; margin-bottom: var(--space-3);
}
/* Placed explicitly, because auto-placement and a half-specified cell
 * disagree quietly: the ring asked for two rows and the mix asked for column
 * one, so the ring lost its span and the layout came out right by accident.
 * A layout that is right by accident is a layout that moves when somebody
 * adds a cell. */
.bookpanel__cell--ring  { grid-area: 1 / 1; }
.bookpanel__cell--mix   { grid-area: 2 / 1; }
.bookpanel__cell--scale {
  grid-area: 2 / 2 / 3 / -1;
  background: linear-gradient(120deg, rgba(150, 123, 53, .42), rgba(5, 46, 38, .6));
}
.bookpanel__big {
  display: block; font-family: var(--font-display); font-size: 1.75rem;
  line-height: 1; color: var(--text-on-ink);
}
.bookpanel__cell--scale .bookpanel__big { color: var(--gold-on-ink); }
.bookpanel__sub {
  margin: var(--space-2) 0 var(--space-3); font-size: var(--size-label);
  color: var(--on-ink-muted);
}
.bookpanel__note {
  margin: var(--space-3) 0 0; font-size: var(--size-label); line-height: 1.5;
  color: var(--text-on-ink-soft);
}
.bookpanel__note--warn { display: flex; gap: var(--space-2); align-items: baseline; }
.bookpanel__caption {
  padding: var(--space-4); font-size: var(--size-small); line-height: 1.55;
  color: var(--text-on-ink-soft); background: rgba(5, 46, 38, .55);
}
.bookpanel__caption a { color: var(--link-on-ink); }

.bookpanel__ringwrap {
  display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap;
}
.ring { width: 7.5rem; height: 7.5rem; flex: none; }
.ring__rest, .ring__top { fill: none; stroke-width: 13; }
.ring__rest { stroke: rgba(184, 214, 200, .28); }
.ring__top { stroke: var(--gold-on-ink); stroke-linecap: butt; }
.ring__value {
  font-family: var(--font-display); font-size: 17px; fill: var(--text-on-ink);
  text-anchor: middle;
}
.ring__unit {
  font-size: 8px; fill: var(--on-ink-muted); text-anchor: middle;
  letter-spacing: 0.1em; text-transform: uppercase;
}

.bookpanel__legend {
  display: grid; gap: var(--space-2); font-size: var(--size-label);
  color: var(--text-on-ink-soft); min-width: 9rem; flex: 1;
}
.bookpanel__legend--row { grid-template-columns: repeat(2, auto); align-items: center; }
.bookpanel__legend b { color: var(--text-on-ink); margin-left: 0.25rem; }
.bookpanel__aside { color: var(--on-ink-muted); line-height: 1.5; }
.bookpanel__legend--row .bookpanel__aside { grid-column: 1 / -1; }
.swatch {
  display: inline-block; width: 0.55rem; height: 0.55rem; border-radius: 2px;
  margin-right: 0.4rem;
}
.swatch--gold { background: var(--gold-on-ink); }
.swatch--rest { background: rgba(184, 214, 200, .5); }

/* A gauge, not a trend: one figure and the benchmark it is measured against.
 * The mockup drew a rising line, which describes a history the worked
 * example does not have. */
.gauge { width: 100%; height: 0.75rem; display: block; }
.gauge__track { fill: rgba(184, 214, 200, .22); }
.gauge__fill { fill: var(--gold-on-ink); }
.gauge__mark { fill: var(--text-on-ink); }
.mixbar { width: 100%; height: 0.6rem; display: block; margin-bottom: var(--space-3); }
.mixbar__a { fill: rgba(184, 214, 200, .5); }
.mixbar__b { fill: var(--gold-on-ink); }

/* ── The closing strip ────────────────────────────────────────────────── */
.ctastrip {
  display: grid; grid-template-columns: 1.15fr 0.95fr auto;
  gap: var(--space-7); align-items: center;
}
.ctastrip h2 { font-size: clamp(1.75rem, 2.8vw, 2.5rem); }
.ctastrip .lead { margin-top: var(--space-3); }
.ctastrip .btnrow { justify-content: flex-end; }
.quals { display: flex; gap: var(--space-6); flex-wrap: wrap; }
.quals__item {
  display: grid; grid-template-columns: 1.75rem auto;
  column-gap: var(--space-2); align-items: center;
}
.quals__icon {
  grid-row: 1 / 3; width: 1.75rem; height: 1.75rem; border-radius: 50%;
  border: 1px solid var(--gold-hairline); color: var(--gold-text);
  display: grid; place-items: center;
}
.quals strong { font-size: var(--size-body); line-height: 1.1; }
.quals small { font-size: var(--size-label); color: var(--text-soft); }

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width: 62rem) {
  .advantage__intro { grid-template-columns: 1fr; gap: var(--space-5); }
  .advantage__grid { grid-template-columns: repeat(2, 1fr); }
  .netband, .netband--nostats,
  .flowband, .steps-split, .bookband { grid-template-columns: 1fr; }
  /* The map leads on a narrow screen: the copy explains a picture, so the
   * picture goes first and the reading order still works. */
  .netband__map { order: -1; }
  .netrail { grid-template-columns: repeat(2, 1fr); }
  .ownsplit { grid-template-columns: 1fr; }
  .ownsplit__copy { padding: var(--space-8) var(--gutter); }
  .ownsplit__stage { padding: var(--space-7) var(--gutter); }
  .memberview { grid-template-columns: 1fr; }
  .memberview__side { display: none; }
  .memberview__grid { grid-template-columns: repeat(2, 1fr); }
  .steps-split .steps { grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
  .steps-split .steps::before { display: none; }
  .bookpanel__grid { grid-template-columns: 1fr 1fr; }
  .bookpanel__cell--ring { grid-row: auto; grid-column: 1 / -1; }
  .bookpanel__cell--mix, .bookpanel__cell--scale { grid-column: 1 / -1; }
  .ctastrip { grid-template-columns: 1fr; gap: var(--space-5); }
  .ctastrip .btnrow { justify-content: flex-start; }
}

@media (max-width: 40rem) {
  .advantage__grid { grid-template-columns: 1fr; }
  .advcard { min-height: 0; }
  .netrail { grid-template-columns: 1fr; }
  .memberview__grid { grid-template-columns: 1fr; }
  .steps-split .steps { grid-template-columns: 1fr; }
  .bookpanel__grid { grid-template-columns: 1fr; }
  .bookpanel__bar { gap: var(--space-3); overflow-x: auto; }
  .bookpanel__tab:not(.is-current) { display: none; }
  /* A LEFT-TO-RIGHT DIAGRAM HAS NO LEFT AND RIGHT ON A PHONE. Two banks and
   * a hub need 416 pixels of fixed width and a 390 pixel window has 358, and
   * because none of the three may shrink they simply lay on top of one
   * another: the hub landed across both banks and the three labels printed
   * over each other.
   *
   * So it becomes top to bottom, carriers then the hub then members, with
   * each label directly above the thing it names. The wires go with the
   * horizontal arrangement they were drawn to describe. */
  .flow {
    flex-direction: column; align-items: center;
    gap: var(--space-2); padding-top: 0;
  }
  .flow__wires { display: none; }
  .flow__label {
    position: static; width: auto; order: 1; margin: var(--space-5) 0 0;
  }
  .flow__bank--carriers { order: 2; }
  .flow__label--mid { order: 3; }
  .flow__hub { order: 4; width: 7rem; height: 7rem; }
  .flow__label--right { order: 5; }
  .flow__bank--agencies { order: 6; }
  .flow__hub b { font-size: 1.5rem; }
  .quals { gap: var(--space-4); }
}
