/* =========================================================================
   Beyond Broadband — design system
   Dark canvas throughout. Light panels only where someone must compare or type.
   Editors never touch this file; components consume these tokens.
   ========================================================================= */

@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Brand */
  --ink: #000101;
  --ink-raised: #0b1220;
  --ink-line: rgba(255, 255, 255, 0.12);

  --blue: #1450d3;
  --signal: #3181dd;
  --sky: #53b7eb;
  --cyan: #b5e8f3;

  /* Light panel family */
  --panel: #f7faff;
  --panel-well: #eef3fb;
  --panel-line: #dbe4f2;
  --panel-ink: #0c1b33;
  --panel-body: #45566f;

  /* Text on the canvas */
  --on-dark: #ffffff;
  --on-dark-body: rgba(255, 255, 255, 0.72);
  --on-dark-quiet: rgba(255, 255, 255, 0.52);

  --grad: linear-gradient(126deg, var(--blue) 0%, var(--signal) 46%, var(--sky) 100%);
  --grad-soft: linear-gradient(126deg, rgba(20, 80, 211, 0.22) 0%, rgba(83, 183, 235, 0.12) 100%);

  /* Scale */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;

  --gutter: clamp(20px, 5vw, 56px);
  --measure: 34em;
  --maxw: 1240px;

  --section-y: clamp(56px, 7vw, 100px);
  --shadow: 0 24px 60px -24px rgba(0, 1, 1, 0.65);
  --shadow-panel: 0 30px 70px -30px rgba(0, 1, 1, 0.8);

  /* sticky header height, used by the full-bleed hero to sit underneath it */
  --header-h: 73px;
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--on-dark-body);
  font-family: "Montserrat", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 17px;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { max-width: 100%; height: auto; display: block; }
/* No coloured placeholder: the reserved area is the page itself. */
img { background: none; }

h1, h2, h3, h4 {
  color: var(--on-dark);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.3rem, 5.6vw, 3.85rem); letter-spacing: -0.035em; }
h2 { font-size: clamp(1.85rem, 4.1vw, 2.9rem); letter-spacing: -0.03em; }
h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); letter-spacing: -0.02em; }

p { margin: 0 0 1.1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--sky); text-underline-offset: 3px; }
a:hover { color: var(--cyan); }

:focus-visible {
  outline: 3px solid var(--sky);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--on-dark); color: var(--ink);
  padding: 12px 20px; border-radius: 0 0 var(--r-sm) 0; font-weight: 700;
}
.skip:focus { left: 0; }

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

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: clamp(44px, 6vw, 80px); }
.section--flush-top { padding-top: 0; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--sky); margin: 0 0 18px;
}
.eyebrow::before {
  content: ""; width: 26px; height: 2px; background: var(--sky); display: block;
}

.lede { font-size: clamp(1.05rem, 1.7vw, 1.28rem); color: var(--on-dark-body); }

/* ---------- ambient texture ---------- */
.mesh {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  z-index: 0;
}
.mesh::before,
.mesh::after {
  content: ""; position: absolute; border-radius: 50%;
  filter: blur(90px); opacity: 0.5;
}
.mesh::before {
  width: 62vw; height: 62vw; max-width: 780px; max-height: 780px;
  top: -24%; right: -16%;
  background: radial-gradient(circle, rgba(20, 80, 211, 0.55), transparent 68%);
}
.mesh::after {
  width: 46vw; height: 46vw; max-width: 560px; max-height: 560px;
  bottom: -28%; left: -14%;
  background: radial-gradient(circle, rgba(83, 183, 235, 0.3), transparent 70%);
}
.section > .wrap { position: relative; z-index: 1; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 28px; border-radius: 999px;
  font-weight: 700; font-size: 0.97rem; letter-spacing: -0.01em;
  text-decoration: none; border: 1.5px solid transparent;
  cursor: pointer; transition: transform 0.16s ease, background 0.16s ease,
    border-color 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--blue); color: #fff; box-shadow: 0 14px 32px -14px rgba(20, 80, 211, 0.9); }
.btn--primary:hover { background: var(--signal); color: #fff; }

.btn--grad { background: var(--grad); color: #fff; box-shadow: 0 14px 32px -14px rgba(20, 80, 211, 0.9); }
.btn--grad:hover { color: #fff; filter: brightness(1.08); }

.btn--ghost { border-color: rgba(255, 255, 255, 0.28); color: var(--on-dark); background: transparent; }
.btn--ghost:hover { border-color: var(--sky); color: var(--on-dark); background: rgba(83, 183, 235, 0.1); }

.btn--onlight { background: var(--blue); color: #fff; }
.btn--onlight:hover { background: var(--signal); color: #fff; }

.btn--quiet-onlight {
  background: transparent; color: var(--panel-ink); border-color: var(--panel-line);
}
.btn--quiet-onlight:hover { border-color: var(--blue); color: var(--blue); }

.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-top: 30px; }

.btn-link {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--sky); font-weight: 700; font-size: 0.95rem; text-decoration: none;
  padding: 6px 2px; transition: gap 0.16s ease, color 0.16s ease;
}
.btn-link svg { width: 15px; height: 15px; }
.btn-link:hover { color: var(--cyan); gap: 12px; }

/* ---------- light panel ---------- */
.panel {
  background: var(--panel);
  color: var(--panel-body);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-panel);
}
.panel h1, .panel h2, .panel h3, .panel h4, .panel strong { color: var(--panel-ink); }
.panel a { color: var(--blue); }
.panel a:hover { color: var(--signal); }

/* =========================================================================
   Header
   ========================================================================= */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: rgba(0, 1, 1, 0.82);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--ink-line);
}
.site-header__inner {
  display: flex; align-items: center; gap: 18px;
  min-height: 72px;
}
.brand {
  display: flex; align-items: center; text-decoration: none; margin-right: auto;
  gap: clamp(9px, 1.1vw, 13px); min-width: 0;
}
/* The wordmark beside the logo. Sized to sit optically level with the mark and
   to stay on one line down to the narrowest phone, where the nav is a burger
   and the only competition for the row is that button. */
.brand__name {
  color: #fff; font-weight: 800; line-height: 1;
  letter-spacing: -0.015em; white-space: nowrap;
  font-size: 0.98rem;
}
@media (min-width: 560px) { .brand__name { font-size: 1.08rem; } }
@media (min-width: 1000px) { .brand__name { font-size: 1.14rem; } }
@media (max-width: 359px) { .brand__name { font-size: 0.82rem; } }
.brand__logo {
  width: auto; height: 30px; flex: none;
}
@media (min-width: 560px) { .brand__logo { height: 34px; } }
@media (min-width: 1000px) { .brand__logo { height: 36px; } }

.brand--footer { margin-right: 0; display: inline-flex; }
.brand__lockup { width: auto; height: 104px; }
@media (min-width: 760px) { .brand__lockup { height: 118px; } }

.nav { display: none; }
/* The desktop nav appears only once the logo, the wordmark beside it and the
   nav items all fit on one row with room to breathe. Measured with the header
   button gone: the nav clears the wordmark by 49px at 900px and by 120px at
   980px, so 1000px is the first comfortable width. Narrower than that, the
   burger carries the same navigation. Re-measure if a header button returns —
   it needs roughly 180px more. */
@media (min-width: 1000px) {
  .nav { display: flex; align-items: center; gap: 4px; }
}
.nav__item { position: relative; }
.nav__link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 14px; border-radius: 999px;
  color: var(--on-dark-body); text-decoration: none;
  font-size: 0.93rem; font-weight: 600;
  transition: color 0.16s ease, background 0.16s ease;
  background: none; border: 0; font-family: inherit; cursor: pointer;
}
.nav__link:hover, .nav__item:hover .nav__link,
.nav__item:focus-within .nav__link { color: #fff; background: rgba(255, 255, 255, 0.07); }
.nav__link svg { width: 10px; height: 10px; opacity: 0.6; }

.nav__panel {
  position: absolute; top: calc(100% + 10px); left: 0;
  min-width: 300px; padding: 12px;
  background: var(--panel); border-radius: var(--r-md);
  box-shadow: var(--shadow-panel);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}
.nav__item:hover .nav__panel,
.nav__item:focus-within .nav__panel { opacity: 1; visibility: visible; transform: none; }
/* The last dropdown hangs off its own right edge instead of its left, so the
   panel can never reach past the viewport. A hidden panel still takes part in
   layout, so one sticking out adds a horizontal scrollbar to every page even
   though nothing is visible there. */
.nav__item:last-child .nav__panel { left: auto; right: 0; }
.nav__panel a {
  display: block; padding: 11px 14px; border-radius: var(--r-sm);
  text-decoration: none; color: var(--panel-ink); font-weight: 700; font-size: 0.93rem;
}
.nav__panel a small {
  display: block; font-weight: 500; color: var(--panel-body); font-size: 0.8rem; margin-top: 2px;
}
.nav__panel a:hover { background: var(--panel-well); color: var(--blue); }

.header-cta { display: none; }
@media (min-width: 1000px) { .header-cta { display: inline-flex; } }

.burger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--ink-line);
  color: #fff; cursor: pointer;
}
@media (min-width: 1000px) { .burger { display: none; } }
.burger svg { width: 20px; height: 20px; }

.mobile-nav {
  position: fixed; inset: 72px 0 0; z-index: 55;
  background: var(--ink); padding: 8px var(--gutter) 40px;
  overflow-y: auto; display: none;
}
.mobile-nav[data-open="true"] { display: block; }
.mobile-nav__group { border-bottom: 1px solid var(--ink-line); padding: 18px 0; }
.mobile-nav__group > p {
  font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--sky); font-weight: 700; margin: 0 0 10px;
}
.mobile-nav a {
  display: block; padding: 10px 0; color: #fff; text-decoration: none;
  font-weight: 600; font-size: 1.02rem;
}
.mobile-nav a small { display: block; font-weight: 500; color: var(--on-dark-quiet); font-size: 0.82rem; }
.mobile-nav .btn { width: 100%; margin-top: 26px; }

/* =========================================================================
   Hero
   ========================================================================= */
.hero { padding-block: clamp(56px, 8vw, 104px) clamp(56px, 8vw, 110px); overflow: hidden; }
.hero__grid { display: grid; gap: clamp(36px, 5vw, 64px); align-items: center; }
@media (min-width: 980px) { .hero__grid { grid-template-columns: 1.16fr 0.84fr; } }

.hero h1 { margin-bottom: 22px; }
.hero h1 em { font-style: normal; background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero__lede { font-size: clamp(1.08rem, 1.9vw, 1.35rem); max-width: 30em; }
.hero__visual { position: relative; }
.hero__visual svg { width: 100%; height: auto; }
@media (min-width: 980px) { .hero__visual { margin-right: calc(var(--gutter) * -0.5); } }
.hero__pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 30px; }
.hero__pills span {
  font-size: 0.78rem; font-weight: 600; color: var(--on-dark-body);
  border: 1px solid var(--ink-line); border-radius: 999px; padding: 7px 15px;
}

/* =========================================================================
   Trust bar
   ========================================================================= */
.trust { border-block: 1px solid var(--ink-line); padding-block: 26px; }
.trust__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 18px 34px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.trust__list li {
  display: flex; align-items: center; gap: 11px;
  font-size: 0.9rem; font-weight: 600; color: var(--on-dark-body);
}
.trust__list svg { width: 19px; height: 19px; flex: none; color: var(--sky); }

/* =========================================================================
   Community band
   ========================================================================= */
.community__grid { display: grid; gap: clamp(32px, 5vw, 60px); align-items: center; }
@media (min-width: 900px) { .community__grid { grid-template-columns: 0.95fr 1.05fr; } }

.figure-card {
  background: var(--grad); border-radius: var(--r-xl);
  padding: clamp(32px, 4.5vw, 52px); color: #fff; position: relative; overflow: hidden;
  box-shadow: 0 40px 80px -40px rgba(20, 80, 211, 0.9);
}
.figure-card__n {
  font-size: clamp(3.6rem, 10vw, 6rem); font-weight: 800; line-height: 0.9;
  letter-spacing: -0.06em; color: #fff; overflow-wrap: anywhere;
}
.figure-card__n--placeholder {
  font-size: clamp(1.5rem, 3.6vw, 2.2rem); line-height: 1.15; letter-spacing: -0.03em;
}
.figure-card__t { font-size: 1.08rem; font-weight: 600; margin-top: 16px; max-width: 18em; color: #fff; }
.figure-card__f {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.28);
  font-size: 0.76rem; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 700;
  color: rgba(255, 255, 255, 0.9);
}

.steps { list-style: none; margin: 30px 0 0; padding: 0; display: grid; gap: 20px; }
.steps li { display: flex; gap: 16px; align-items: flex-start; }
.steps b {
  flex: none; width: 34px; height: 34px; border-radius: 10px;
  border: 1px solid rgba(83, 183, 235, 0.5); color: var(--sky);
  display: grid; place-items: center; font-size: 0.85rem;
}
.steps span { color: var(--on-dark-body); }
.steps strong { display: block; color: #fff; margin-bottom: 2px; }

/* =========================================================================
   Services router
   ========================================================================= */
.lanes { display: grid; gap: 20px; margin-top: 44px; }
@media (min-width: 880px) { .lanes { grid-template-columns: repeat(3, 1fr); align-items: start; } }

.lane {
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  padding: clamp(26px, 3vw, 34px); position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.lane:hover { border-color: rgba(83, 183, 235, 0.55); transform: translateY(-3px); }
.lane__icon { width: 40px; height: 40px; color: var(--sky); margin-bottom: 20px; }
.lane h3 { margin-bottom: 8px; }
.lane > p { font-size: 0.94rem; margin-bottom: 22px; }
.lane__links { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.lane__links a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 14px; margin-inline: -14px; border-radius: 12px;
  text-decoration: none; color: #fff; font-weight: 600; font-size: 0.95rem;
  transition: background 0.16s ease, color 0.16s ease;
}
.lane__links a small { display: block; font-weight: 500; color: var(--on-dark-quiet); font-size: 0.8rem; }
.lane__links a svg { width: 16px; height: 16px; flex: none; opacity: 0; transform: translateX(-4px); transition: all 0.16s ease; color: var(--sky); }
.lane__links a:hover { background: rgba(255, 255, 255, 0.06); }
.lane__links a:hover svg, .lane__links a:focus-visible svg { opacity: 1; transform: none; }

/* =========================================================================
   Feature grid (Why Beyond Broadband)
   ========================================================================= */
.features { display: grid; gap: 18px; margin-top: 44px; }
@media (min-width: 760px) { .features { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) {
  .features { grid-template-columns: repeat(2, 1fr); }
  .features > :first-child { grid-column: 1 / -1; display: grid; gap: 4px 34px; }
  .features > :first-child h3 { font-size: clamp(1.35rem, 2.3vw, 1.75rem); }
  .features > :first-child p { max-width: 46em; }
}
.feature {
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  padding: clamp(26px, 3vw, 36px);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent);
}
.feature:first-child { background: var(--grad-soft); border-color: rgba(83, 183, 235, 0.32); }
.feature svg { width: 30px; height: 30px; color: var(--sky); margin-bottom: 18px; }
.feature h3 { margin-bottom: 8px; }
.feature p { font-size: 0.95rem; }

/* =========================================================================
   Address checker  (light panel on the dark canvas)
   ========================================================================= */
.checker { padding: clamp(28px, 4vw, 44px); }
.checker__head { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: baseline; justify-content: space-between; }
.checker h2 { font-size: clamp(1.4rem, 2.6vw, 1.95rem); margin-bottom: 6px; }
.checker__sub { color: var(--panel-body); font-size: 0.97rem; margin: 0; max-width: 40em; }
.checker__form { display: grid; gap: 12px; margin-top: 24px; }
@media (min-width: 720px) { .checker__form { grid-template-columns: 1fr auto; align-items: end; } }
.checker__form .field__hint { display: none; }
.checker__hint { font-size: 0.82rem; color: var(--panel-body); margin: 10px 0 0; }

.field { display: grid; gap: 7px; }
.field label { font-weight: 700; color: var(--panel-ink); font-size: 0.9rem; }
.field input, .field select, .field textarea {
  width: 100%; padding: 15px 18px; font: inherit; font-size: 1rem;
  color: var(--panel-ink); background: #fff;
  border: 1.5px solid var(--panel-line); border-radius: 14px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.field input::placeholder { color: #93a2b8; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--blue); outline-offset: 1px;
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(20, 80, 211, 0.18);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--blue);
}
.field__hint { font-size: 0.82rem; color: var(--panel-body); margin: 0; }
.field__error { font-size: 0.85rem; color: #b3261e; font-weight: 600; margin: 0; }
.field[data-invalid="true"] input { border-color: #b3261e; }

.checker__note {
  margin-top: 18px; padding: 14px 16px; border-radius: 12px;
  background: var(--panel-well); color: var(--panel-body);
  font-size: 0.87rem; border-left: 3px solid var(--blue);
}
.checker__result { margin-top: 18px; }
.checker__result:empty { display: none; }

/* =========================================================================
   Plan carousel  (light cards on the dark canvas)
   ========================================================================= */
.plans__head { display: grid; gap: 14px; }
@media (min-width: 900px) {
  .plans__head { grid-template-columns: 1fr auto; align-items: end; }
}
.plans__group { margin-top: 44px; }
.plans__group + .plans__group { margin-top: 56px; }
.plans__grouplabel {
  display: flex; align-items: center; gap: 14px;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--on-dark-quiet); margin: 0 0 18px;
}
.plans__grouplabel::after { content: ""; flex: 1; height: 1px; background: var(--ink-line); }

/* Segmented control. Switches between plan groups without leaving the page.
   Rendered hidden and revealed by site.js, so it never appears without the
   script that drives it. */
.segmented {
  display: inline-flex; gap: 4px; margin-top: 34px;
  padding: 5px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--ink-line);
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.segmented::-webkit-scrollbar { display: none; }
.segmented[hidden] { display: none; }
.segmented button {
  flex: 0 0 auto; border: 0; cursor: pointer;
  font: inherit; font-size: 0.92rem; font-weight: 700; letter-spacing: -0.01em;
  padding: 12px 26px; border-radius: 999px; white-space: nowrap;
  background: transparent; color: var(--on-dark-quiet);
  transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
.segmented button:hover:not([aria-selected="true"]) { color: #fff; background: rgba(255, 255, 255, 0.07); }
.segmented button[aria-selected="true"] {
  background: var(--grad); color: #fff;
  box-shadow: 0 6px 18px rgba(20, 80, 211, 0.35);
}
.segmented button:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
@media (max-width: 420px) {
  .segmented { display: flex; width: 100%; }
  .segmented button { flex: 1 1 0; padding: 12px 14px; text-align: center; }
}

/* Explanatory line that sits where the row heading would be, in tabbed mode. */
.plans__groupnote {
  font-size: 0.88rem; color: var(--on-dark-quiet); margin: 0 0 18px; max-width: 60ch;
}
.plans__groupnote:empty { margin: 0; }
.plans__group[role="tabpanel"] { margin-top: 24px; }
.plans__group[role="tabpanel"]:focus { outline: none; }
.plans__group[role="tabpanel"][hidden] { display: none; }

.rail {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: minmax(268px, 85%);
  gap: 18px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  padding: 4px var(--gutter) 22px;
  margin-inline: calc(var(--gutter) * -1);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.28) transparent;
}
@media (min-width: 680px) { .rail { grid-auto-columns: minmax(300px, 48%); } }
@media (min-width: 1020px) { .rail { grid-auto-columns: minmax(300px, 31.4%); } }
.rail::-webkit-scrollbar { height: 8px; }
.rail::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.24); border-radius: 99px; }
.rail > * { scroll-snap-align: start; }

.plan {
  display: flex; flex-direction: column;
  padding: 28px 26px 26px; border-radius: var(--r-lg);
  background: var(--panel); color: var(--panel-body);
  box-shadow: var(--shadow-panel);
  border: 1.5px solid transparent;
  transition: transform 0.18s ease, border-color 0.18s ease;
}
.plan:hover { transform: translateY(-4px); }
.plan--featured { background: var(--grad); color: rgba(255, 255, 255, 0.86); }
.plan--featured .plan__name,
.plan--featured .plan__speed b,
.plan--featured .plan__price,
.plan--featured .plan__inc li { color: #fff; }
.plan--featured .plan__speed,
.plan--featured .plan__gst,
.plan--featured .plan__desc { color: rgba(255, 255, 255, 0.82); }
.plan--featured .plan__divider { background: rgba(255, 255, 255, 0.3); }
.plan--featured .plan__inc li::before { border-color: rgba(255, 255, 255, 0.7); }

.plan__badge {
  align-self: flex-start; font-size: 0.68rem; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 999px;
  background: rgba(20, 80, 211, 0.1); color: var(--blue); margin-bottom: 14px;
}
.plan--featured .plan__badge { background: rgba(255, 255, 255, 0.2); color: #fff; }
.plan__badge--empty { visibility: hidden; }

.plan__name { font-size: 1.16rem; font-weight: 800; color: var(--panel-ink); letter-spacing: -0.02em; }
.plan__speed { display: flex; align-items: baseline; gap: 8px; margin-top: 14px; font-size: 0.86rem; }
.plan__speed b { font-size: 2.1rem; font-weight: 800; color: var(--panel-ink); letter-spacing: -0.04em; line-height: 1; }
.plan__up { font-size: 0.84rem; margin-top: 4px; }

.plan__divider { height: 1px; background: var(--panel-line); margin: 20px 0; }

.plan__price { font-size: 1.85rem; font-weight: 800; color: var(--panel-ink); letter-spacing: -0.04em; line-height: 1; }
.plan__price sup { font-size: 0.95rem; font-weight: 700; top: -0.7em; }
.plan__price span { font-size: 0.92rem; font-weight: 600; letter-spacing: 0; }
.plan__gst { font-size: 0.78rem; margin-top: 6px; }
.plan__desc { font-size: 0.9rem; margin-top: 14px; }

.plan__inc { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 9px; }
.plan__inc li { position: relative; padding-left: 24px; font-size: 0.88rem; }
.plan__inc li::before {
  content: ""; position: absolute; left: 0; top: 5px;
  width: 13px; height: 7px; border-left: 2px solid var(--blue); border-bottom: 2px solid var(--blue);
  transform: rotate(-45deg);
}
.plan__meta { font-size: 0.78rem; margin-top: 14px; }

/* Connection types on a plan card. Only appears when a plan lists them. */
.plan__tech { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--panel-line); }
.plan__tech-label {
  display: block; font-size: 0.66rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--panel-body); margin-bottom: 4px;
}
.plan__tech-list { font-size: 0.85rem; font-weight: 700; color: var(--panel-ink); }
.plan--featured .plan__tech { border-top-color: rgba(255, 255, 255, 0.3); }
.plan--featured .plan__tech-label { color: rgba(255, 255, 255, 0.82); }
.plan--featured .plan__tech-list { color: #fff; }
.plan__cta { margin-top: auto; padding-top: 22px; }
.plan__cta .btn { width: 100%; }
.plan--featured .plan__cta .btn { background: #fff; color: var(--blue); }

.rail-nav { display: none; gap: 8px; }
@media (min-width: 1020px) { .rail-nav { display: flex; } }
.rail-nav button {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--ink-line); background: rgba(255, 255, 255, 0.06);
  color: #fff; cursor: pointer; display: grid; place-items: center;
  transition: background 0.16s ease, border-color 0.16s ease;
}
.rail-nav button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.14); border-color: var(--sky); }
.rail-nav button:disabled { opacity: 0.32; cursor: default; }
.rail-nav svg { width: 17px; height: 17px; }

.plans__foot { font-size: 0.85rem; color: var(--on-dark-quiet); margin-top: 8px; }

/* =========================================================================
   Speed guide
   ========================================================================= */
.speeds { display: grid; gap: 14px; margin-top: 40px; }
@media (min-width: 700px) { .speeds { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .speeds { grid-template-columns: repeat(4, 1fr); } }
.speed {
  border: 1px solid var(--ink-line); border-radius: var(--r-md);
  padding: 24px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent);
}
.speed b { display: block; color: var(--sky); font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; }
.speed h3 { font-size: 1.05rem; margin: 10px 0 6px; }
.speed p { font-size: 0.88rem; margin: 0; }

/* =========================================================================
   Testimonials / partners — only render when real content exists
   ========================================================================= */
.quotes { display: grid; gap: 18px; margin-top: 40px; }
@media (min-width: 820px) { .quotes { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } }
.quote { padding: 28px 26px; border-radius: var(--r-lg); background: var(--panel); box-shadow: var(--shadow-panel); }
.quote p { color: var(--panel-ink); font-size: 1.02rem; font-weight: 600; }
.quote footer { margin-top: 16px; font-size: 0.86rem; color: var(--panel-body); }

.logo-strip { display: flex; flex-wrap: wrap; gap: 26px 44px; align-items: center; margin-top: 34px; }
.logo-strip img { max-height: 44px; width: auto; opacity: 0.86; }

/* =========================================================================
   PARTNER LOCKUP — two marks side by side on a partnership landing page
   ========================================================================= */
.lockup { display: grid; justify-items: center; gap: 18px; text-align: center; }
.lockup__marks {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(18px, 4vw, 38px); flex-wrap: nowrap;
}
.lockup__bb { height: clamp(64px, 11vw, 92px); width: auto; }

/* The divider is a glyph between two brands, so it stays quiet: thin, small
   and dimmed, never competing with either mark. */
.lockup__x { display: inline-flex; color: var(--on-dark-muted); opacity: 0.5; flex: 0 0 auto; }
.lockup__x svg { width: clamp(16px, 2.6vw, 22px); height: clamp(16px, 2.6vw, 22px); }

/* Sized by height so any supplied logo sits optically level with ours, and
   contained rather than cropped so a partner's mark is never cut into. */
.lockup__partner { display: flex; align-items: center; min-width: 0; }
.lockup__partner .imgframe {
  width: clamp(130px, 22vw, 200px); height: clamp(64px, 11vw, 92px);
  aspect-ratio: auto; background: none; border: 0;
}
.lockup__partner .imgframe img { object-fit: contain; object-position: center; }

/* Text stand-in until an approved logo is supplied. Reads as a wordmark, not
   as a missing image. */
.lockup__name {
  font-size: clamp(1.9rem, 5.2vw, 2.9rem); font-weight: 800;
  letter-spacing: -0.03em; line-height: 1; color: #fff;
}
.lockup__line {
  margin: 0; max-width: 46ch; color: var(--on-dark-muted);
  font-size: 0.95rem; line-height: 1.6;
}

/* =========================================================================
   FAQ
   ========================================================================= */
.faq { max-width: 860px; margin-top: 40px; }
.faq details {
  border-bottom: 1px solid var(--ink-line);
}
.faq summary {
  cursor: pointer; list-style: none; padding: 22px 44px 22px 0; position: relative;
  color: #fff; font-weight: 700; font-size: 1.03rem; letter-spacing: -0.015em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 50%;
  width: 11px; height: 11px; margin-top: -7px;
  border-right: 2px solid var(--sky); border-bottom: 2px solid var(--sky);
  transform: rotate(45deg); transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.faq summary:hover { color: var(--sky); }
.faq__a { padding: 0 44px 24px 0; }
.faq__a p { font-size: 0.97rem; }

/* =========================================================================
   Partner recruitment + final CTA
   ========================================================================= */
.band {
  border-radius: var(--r-xl); padding: clamp(36px, 5vw, 68px);
  background: linear-gradient(140deg, rgba(20, 80, 211, 0.24), rgba(0, 1, 1, 0.1)),
              rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(83, 183, 235, 0.26);
}
.band__grid { display: grid; gap: 30px; align-items: center; }
@media (min-width: 900px) { .band__grid { grid-template-columns: 1.15fr 0.85fr; } }

.finale { text-align: center; }
.finale h2 { font-size: clamp(2rem, 5vw, 3.2rem); margin-inline: auto; max-width: 16em; }
.finale p { margin-inline: auto; text-align: center; }
.finale .btn-row { justify-content: center; }

/* =========================================================================
   Forms
   ========================================================================= */
.form-panel { padding: clamp(28px, 4vw, 44px); }
.form-grid { display: grid; gap: 16px; margin-top: 22px; }
@media (min-width: 700px) { .form-grid--2 { grid-template-columns: repeat(2, 1fr); } }
.form-grid .field--full { grid-column: 1 / -1; }
.form-consent { display: flex; gap: 11px; align-items: flex-start; font-size: 0.88rem; }
.form-consent input { width: 20px; height: 20px; flex: none; margin-top: 2px; accent-color: var(--blue); }
/* The consent line as a statement rather than a tick box. Quieter than a field
   label — it is something being told, not something being asked. */
.form-consent-note {
  margin: 0; font-size: 0.84rem; line-height: 1.55; color: var(--panel-body);
}
.form-status { margin-top: 16px; font-size: 0.9rem; font-weight: 600; }
.form-status[data-state="error"] { color: #b3261e; }
/* The confirmation is the whole point of pressing the button, so it reads as a
   panel rather than another line of small print under the form. */
.form-status[data-state="ok"] {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 15px 17px; border-radius: 13px;
  background: #e8f6ee; border-left: 3px solid #12734a; color: #0f5c3b;
  font-size: 0.95rem; line-height: 1.55;
}
.form-status[data-state="ok"]::before {
  content: ""; flex: 0 0 auto; width: 19px; height: 19px; margin-top: 1px;
  background: currentColor;
  -webkit-mask: var(--tick) center / contain no-repeat;
          mask: var(--tick) center / contain no-repeat;
}
.form-status:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
:root {
  --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4.5 10.5 8 14l7.5-8' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.form-disabled-note {
  margin-top: 18px; padding: 14px 16px; border-radius: 12px;
  background: #fff6d6; border-left: 3px solid #c9a227; color: #6b5300;
  font-size: 0.86rem;
}

/* =========================================================================
   Footer
   ========================================================================= */
.site-footer { border-top: 1px solid var(--ink-line); padding-block: clamp(48px, 6vw, 76px) 34px; }
.site-footer__grid { display: grid; gap: 36px; }
@media (min-width: 760px) { .site-footer__grid { grid-template-columns: 1.4fr repeat(2, 1fr); } }
@media (min-width: 1040px) { .site-footer__grid { grid-template-columns: 1.6fr repeat(4, 1fr); } }
.site-footer__h {
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--sky); margin: 0 0 14px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.site-footer ul a { color: var(--on-dark-body); text-decoration: none; font-size: 0.92rem; }
.site-footer ul a:hover { color: #fff; }
.site-footer__tag { font-size: 0.95rem; max-width: 24em; margin-top: 16px; }
.site-footer__bottom {
  margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--ink-line);
  display: flex; flex-wrap: wrap; gap: 12px 26px; align-items: center;
  font-size: 0.82rem; color: var(--on-dark-quiet);
}
.site-footer__bottom nav { display: flex; flex-wrap: wrap; gap: 12px 22px; margin-left: auto; }
.site-footer__bottom a { color: var(--on-dark-quiet); text-decoration: none; }
.site-footer__bottom a:hover { color: #fff; }

/* =========================================================================
   Development placeholder marker — deliberately obvious, never subtle
   ========================================================================= */
.devflag {
  display: inline-block; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em;
  background: #ffd84d; color: #3d2f00; padding: 3px 9px; border-radius: 5px;
  text-transform: uppercase;
}
.devblock {
  border: 2px dashed #c9a227; background: rgba(255, 216, 77, 0.08);
  border-radius: var(--r-md); padding: 20px 22px; margin-top: 22px;
  color: #ffe9a3; font-size: 0.89rem;
}
.devblock p { color: inherit; font-size: inherit; }
.devblock p:last-child { margin-bottom: 0; }


/* =========================================================================
   Image slot
   A real image renders with no colour underneath it — the reserved area is the
   page background. Until one is supplied, a development-only placeholder holds
   exactly the same space and states what belongs there. It disappears the
   moment an image is set and never appears as a loading state.
   ========================================================================= */
/* Image frame — holds the ratio, clips the radius, never distorts the picture. */
.imgframe {
  width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  position: relative;
}
.imgframe > picture,
.imgframe > img { display: block; width: 100%; height: 100%; }
.imgframe img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.imgframe--contain img { object-fit: contain; }

.imgslot {
  width: 100%;
  border: 1.5px dashed rgba(255, 255, 255, 0.26);
  border-radius: var(--r-lg);
  background: none;
  display: grid;
  place-items: center;
  padding: clamp(20px, 3vw, 34px);
  text-align: center;
}
.imgslot__inner { max-width: 32em; }
.imgslot__tag {
  display: inline-block;
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--on-dark-quiet);
  border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 999px;
  padding: 5px 12px; margin-bottom: 16px;
}
.imgslot__subject {
  margin: 0; max-width: none;
  color: var(--on-dark-body); font-size: 0.97rem; line-height: 1.55;
}
.imgslot__spec {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 10px;
  margin: 18px 0 0;
}
.imgslot__spec > div {
  display: flex; align-items: baseline; gap: 7px; white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 999px;
  padding: 6px 14px;
}
.imgslot__spec dt {
  margin: 0; font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--on-dark-quiet); font-weight: 700;
}
.imgslot__spec dd { margin: 0; font-size: 0.85rem; font-weight: 700; color: #fff; }

/* On a light panel the slot inverts so it stays legible. */
.panel .imgslot { border-color: var(--panel-line); }
.panel .imgslot__tag { color: var(--panel-body); border-color: var(--panel-line); }
.panel .imgslot__subject { color: var(--panel-body); }
.panel .imgslot__spec > div { border-color: var(--panel-line); }
.panel .imgslot__spec dt { color: var(--panel-body); }
.panel .imgslot__spec dd { color: var(--panel-ink); }


/* =========================================================================
   Image containers added when every content image became editable.
   Each one reserves its ratio, so an empty slot and a filled slot occupy the
   same space and nothing moves when a picture is added.
   ========================================================================= */

/* Hero and text-and-image fall back to a single column when no picture is set,
   so the public site never shows an empty half. */
.hero__grid--solo,
.community__grid--solo { grid-template-columns: 1fr !important; }

/* Feature card media */
.feature__media { margin-bottom: 22px; }
.feature__media .imgframe,
.feature__media .imgslot { border-radius: var(--r-md); }

/* Community band media, above the figure card */
.community__media { margin-bottom: 20px; }

/* Partner band media */
.band__media .imgframe,
.band__media .imgslot { border-radius: var(--r-lg); }

/* Section background image — sits behind the content, never on top of it. */
.section--bg { isolation: isolate; }
.section__bg {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  pointer-events: none;
}
.section__bg > picture,
.section__bg > img { display: block; width: 100%; height: 100%; }
.section__bg img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.section__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0, 1, 1, 0.78), rgba(0, 1, 1, 0.9));
}

/* Testimonial author photo */
.quote__by { display: flex; align-items: center; gap: 12px; }
.quote__avatar {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  overflow: hidden; display: block;
}
.quote__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Team */
.team { display: grid; gap: 26px 20px; margin-top: 44px; }
@media (min-width: 620px) { .team { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .team { grid-template-columns: repeat(4, 1fr); } }
.team__media { margin-bottom: 16px; }
.team__media .imgframe,
.team__media .imgslot { border-radius: var(--r-md); }
.team__name { font-size: 1.05rem; margin: 0 0 2px; }
.team__role {
  margin: 0 0 8px; font-size: 0.8rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--sky);
}
.team__bio { font-size: 0.9rem; margin: 0; }


/* =========================================================================
   Give-back calculator
   Lives inside the existing community section. Uses the same light panel,
   radii, button and field styles as the address checker and plan cards —
   no new visual language.
   ========================================================================= */
.figure-card--compact { padding: clamp(26px, 3.4vw, 38px); margin-top: 28px; }
.figure-card--compact .figure-card__n { font-size: clamp(3rem, 7vw, 4.4rem); }
.community__media--below { margin: 26px 0 0; }

/* With the calculator on, both columns start at the top rather than centring. */
.community__grid--calc { align-items: start; }

.calc { padding: clamp(26px, 3.6vw, 40px); }

.calc__title {
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  color: var(--panel-ink);
  letter-spacing: -0.025em;
  margin: 0 0 8px;
}
.calc__lede { color: var(--panel-body); font-size: 0.97rem; margin: 0 0 4px; max-width: none; }

.calc__inputs { margin-top: 24px; }

.calc__amount label {
  display: block; font-weight: 700; color: var(--panel-ink);
  font-size: 0.9rem; margin-bottom: 8px;
}
.calc__amount-field {
  display: flex; align-items: center; gap: 2px;
  border: 1.5px solid var(--panel-line); border-radius: 14px;
  background: #fff; padding: 4px 16px 4px 18px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.calc__amount-field:focus-within {
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(20, 80, 211, 0.18);
}
.calc__currency {
  font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 800;
  color: var(--panel-ink); letter-spacing: -0.04em; line-height: 1;
}
.calc__amount-field input {
  flex: 1 1 auto; width: 100%; min-width: 0;
  border: 0; outline: none; background: none; padding: 12px 0;
  font: inherit; font-size: clamp(1.9rem, 4vw, 2.6rem); font-weight: 800;
  letter-spacing: -0.045em; color: var(--panel-ink);
  -moz-appearance: textfield;
}
.calc__amount-field input::-webkit-outer-spin-button,
.calc__amount-field input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.calc__amount-field input:focus-visible { outline: none; }
.calc__amount .field__hint { margin-top: 8px; }

/* Second input on the partner calculator. Same field, smaller type: the dollar
   figure stays the loudest thing in the panel, the count beside it is support. */
.calc__supporters { margin-top: 22px; }
.calc__supporters .calc__amount-field input { font-size: clamp(1.4rem, 3vw, 1.9rem); }

/* Slider — brand blue track fill, generous touch target */
.calc__slider { margin-top: 22px; }
.calc__slider input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 30px; background: none; cursor: pointer; display: block;
}
.calc__slider input[type="range"]::-webkit-slider-runnable-track {
  height: 8px; border-radius: 99px;
  background: linear-gradient(90deg, var(--blue) var(--calc-pct, 20%), var(--panel-well) var(--calc-pct, 20%));
}
.calc__slider input[type="range"]::-moz-range-track {
  height: 8px; border-radius: 99px; background: var(--panel-well);
}
.calc__slider input[type="range"]::-moz-range-progress {
  height: 8px; border-radius: 99px; background: var(--blue);
}
.calc__slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; margin-top: -9px;
  border-radius: 50%; background: #fff;
  border: 5px solid var(--blue);
  box-shadow: 0 3px 10px rgba(12, 27, 51, 0.28);
  transition: transform 0.14s ease;
}
.calc__slider input[type="range"]::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%; background: #fff;
  border: 5px solid var(--blue); box-shadow: 0 3px 10px rgba(12, 27, 51, 0.28);
}
.calc__slider input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.08); }
.calc__slider input[type="range"]:focus-visible { outline: none; }
.calc__slider input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 4px rgba(20, 80, 211, 0.3);
}
.calc__slider input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 4px rgba(20, 80, 211, 0.3);
}
/* Scale labels sit at the band boundaries, which are evenly spaced along the
   track even though the dollar gaps between them are not. */
.calc__scale {
  display: flex; justify-content: space-between;
  font-size: 0.74rem; font-weight: 600; color: var(--panel-body); margin-top: 2px;
}
.calc__scale span { flex: 0 0 auto; }
.calc__scale span:first-child { margin-left: -2px; }
.calc__scale span:last-child { margin-right: -2px; }

/* Results */
.calc__results {
  display: grid; gap: 12px; margin-top: 26px;
}
@media (min-width: 480px) { .calc__results { grid-template-columns: 1fr 1fr; } }
.calc__result {
  background: var(--panel-well); border-radius: var(--r-md);
  padding: 18px 20px;
}
.calc__result--lead { background: var(--grad); }
.calc__result-label {
  display: block; font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--panel-body); margin-bottom: 6px;
}
.calc__result--lead .calc__result-label { color: rgba(255, 255, 255, 0.88); }
.calc__result-value {
  display: block; font-size: clamp(1.5rem, 3.2vw, 2rem); font-weight: 800;
  letter-spacing: -0.04em; color: var(--panel-ink); line-height: 1;
  font-variant-numeric: tabular-nums;
}
.calc__result--lead .calc__result-value { color: #fff; }

.calc__impact {
  margin: 20px 0 0; font-size: 0.97rem; line-height: 1.55;
  color: var(--panel-ink); font-weight: 600; max-width: none;
}
.calc__impact strong { color: var(--blue); }
.calc__impact:empty { display: none; }

.calc__note {
  margin: 16px 0 0; font-size: 0.83rem; line-height: 1.5;
  color: var(--panel-body); max-width: none;
}

/* Stacks neatly on narrow screens; the panel keeps its own breathing room. */
@media (max-width: 899px) {
  .calc { margin-top: 28px; }
}

/* =========================================================================
   Community pages — editorial sections
   Everything below is additive and scoped to the new section types, so no
   existing page's rendering changes. Same tokens, same radii, same gradient.
   ========================================================================= */

/* Gradient emphasis on a section heading, matching the hero treatment. Scoped
   to .section--story so headings elsewhere are untouched. */
.section--story h2 em,
.finale h2 em,
.statement__line em {
  font-style: normal;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.sechead { max-width: 30em; }
.sechead .lede { margin-bottom: 0; }
.sechead__foot {
  margin: 30px 0 0; font-size: 0.9rem; color: var(--on-dark-quiet); max-width: 54em;
}

/* ---------- scroll reveal ----------
   No JS, reduced motion, or no IntersectionObserver: nothing here applies and
   the content is simply visible. The hidden state only exists once the script
   has set data-reveal on <html>. */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal="on"] .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
                transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
    transition-delay: calc(var(--i, 0) * 70ms);
    will-change: opacity, transform;
  }
  [data-reveal="on"] .reveal[data-shown="true"] {
    opacity: 1;
    transform: none;
  }
}

/* ---------- statement ---------- */
/* The big line sets its own measure in its own em units, so it holds roughly the
   same number of words per line at every size. The wrapper is only a ceiling. */
.statement__inner { max-width: 860px; }
.statement--centred .statement__inner { max-width: 940px; margin-inline: auto; text-align: center; }
.statement--centred .statement__line,
.statement--centred .statement__body { margin-inline: auto; }
.statement--centred .eyebrow { justify-content: center; }
.statement--centred .btn-row { justify-content: center; }

.statement__line {
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  line-height: 1.16;
  letter-spacing: -0.03em;
  font-weight: 800;
  color: var(--on-dark);
  margin: 0;
  max-width: 13.5em;
  text-wrap: balance;
}
.statement__body {
  margin: 22px 0 0;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  color: var(--on-dark-body);
  max-width: 34em;
}

/* ---------- numbered cards ---------- */
.numcards {
  list-style: none; margin: 46px 0 0; padding: 0;
  display: grid; gap: 18px;
}
@media (min-width: 720px) { .numcards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) {
  .numcards[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
  .numcards[data-count="4"] { grid-template-columns: repeat(4, 1fr); }
}

.numcard {
  position: relative; overflow: hidden;
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  padding: clamp(26px, 3vw, 34px);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  transition: border-color 0.22s ease, transform 0.22s ease, background 0.22s ease;
}
.numcard::before {
  content: ""; position: absolute; inset: 0 auto auto 0;
  height: 2px; width: 100%; background: var(--grad);
  transform: scaleX(0); transform-origin: left; transition: transform 0.4s ease;
}
.numcard:hover {
  transform: translateY(-4px);
  border-color: rgba(83, 183, 235, 0.34);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.015));
}
.numcard:hover::before { transform: scaleX(1); }

.numcard__n {
  display: block; font-size: 2.1rem; font-weight: 800; line-height: 1;
  letter-spacing: -0.05em; margin-bottom: 18px;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
  font-variant-numeric: tabular-nums;
}
.numcard__icon { display: block; margin-bottom: 14px; }
.numcard__icon svg { width: 26px; height: 26px; color: var(--sky); }
.numcard h3 { margin-bottom: 8px; }
.numcard p { font-size: 0.95rem; margin: 0; }

/* ---------- story cards ---------- */
.scards__media { margin-top: 40px; }
.scards {
  display: grid; gap: 18px; margin-top: 44px;
}
@media (min-width: 680px) { .scards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) {
  .scards[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
  .scards[data-count="5"],
  .scards[data-count="6"] { grid-template-columns: repeat(3, 1fr); }
}
.scards__media + .scards { margin-top: 28px; }

.scard {
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  padding: clamp(24px, 2.8vw, 32px);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.01));
  transition: border-color 0.22s ease, transform 0.22s ease, background 0.22s ease;
}
.scard:hover {
  transform: translateY(-4px);
  border-color: rgba(83, 183, 235, 0.34);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.015));
}
.scard__icon {
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 14px; margin-bottom: 18px;
  background: var(--grad-soft); border: 1px solid rgba(83, 183, 235, 0.3);
}
.scard__icon svg { width: 23px; height: 23px; color: var(--sky); }
.scard h3 { margin-bottom: 8px; }
.scard p { font-size: 0.94rem; margin: 0; }

/* ---------- impact statistics ---------- */
.stats { display: grid; gap: 18px; margin-top: 44px; }
@media (min-width: 680px) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .stats[data-count="3"] { grid-template-columns: repeat(3, 1fr); } }

.stat {
  border: 1px solid rgba(83, 183, 235, 0.26); border-radius: var(--r-lg);
  padding: clamp(28px, 3vw, 38px);
  background: linear-gradient(140deg, rgba(20, 80, 211, 0.22), rgba(0, 1, 1, 0.1)),
              rgba(255, 255, 255, 0.03);
  display: grid; gap: 6px; align-content: start;
}
.stat__v {
  font-size: clamp(2.4rem, 5vw, 3.4rem); font-weight: 800; line-height: 1;
  letter-spacing: -0.045em; color: var(--on-dark);
  font-variant-numeric: tabular-nums;
}
.stat__l { font-size: 0.95rem; font-weight: 700; color: var(--on-dark); }
.stat__n { font-size: 0.84rem; color: var(--on-dark-quiet); }
.stats__asof { margin: 22px 0 0; font-size: 0.82rem; color: var(--on-dark-quiet); }
.stats__pending {
  margin: 28px 0 0; font-size: clamp(1rem, 1.5vw, 1.12rem);
  color: var(--on-dark-body); max-width: 40em;
}

/* ---------- form additions ---------- */
.eyebrow--onlight { color: var(--blue); }
.eyebrow--onlight::before { background: var(--blue); }
.field__opt {
  font-weight: 500; font-size: 0.8rem; color: var(--panel-body); margin-left: 6px;
}
.form-foot { margin: 18px 0 0; font-size: 0.84rem; color: var(--panel-body); }

/* Partner attribution line, inside the white form panel. States which
   organisation the enquiry is credited to, before the person sends it. */
.form-attrib {
  display: flex; align-items: flex-start; gap: 10px;
  margin: 18px 0 0; padding: 13px 15px; border-radius: 12px;
  background: var(--panel-well); color: var(--panel-ink);
  font-size: 0.88rem; font-weight: 600; line-height: 1.55;
}
.form-attrib svg { width: 19px; height: 19px; flex: 0 0 auto; margin-top: 1px; color: var(--blue); }

/* =========================================================================
   Page-builder wrappers
   The Visual Editor's Array and Array Item regions in base.njk. They exist
   only to give CloudCannon an editing context; they must stay layout-neutral,
   so they are plain block boxes that add nothing of their own. Do not give
   them padding, margin, display:flex/grid or a background.
   ========================================================================= */
.sections, .section-slot { display: block; margin: 0; padding: 0; border: 0; }

/* An image slot with nothing in it yet. Left transparent rather than painted
   solid black: several sections sit over the soft blue mesh glow, and a solid
   fill there shows up as a dark rectangle. Transparent lets whatever is behind
   it show through, so on the live site the slot is genuinely invisible, while
   in CloudCannon's Visual Editor it is still a real, clickable image element. */
.imgframe--filler { background: transparent; }
/* Opt-in: a large empty slot that would otherwise read as a hole in the layout
   gets a quiet surface and hairline instead, so it looks like a space waiting
   for a photograph. Replaced exactly when a real image is added. */
.imgframe--filler-shown {
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--ink-line);
}

/* On phones and small tablets the grids stack, so an empty slot would be a tall
   band of dead scrolling on the live site. Editing happens at desktop width, so
   the slot stays clickable there and simply collapses below 900px. It comes
   back the moment a real image is set, because a filled slot is a plain
   .imgframe and this rule does not touch it. */
@media (max-width: 899px) {
  .imgframe--filler { display: none; }
}

/* Give-back section, calculator variant: the figure card and the steps that
   explain it sit side by side on their own full-width row under the grid.
   Stacks back to the original order below 900px. */
.community__pair { display: grid; gap: clamp(26px, 4vw, 44px); margin-top: clamp(34px, 4.5vw, 56px); }
@media (min-width: 900px) { .community__pair { grid-template-columns: 0.82fr 1.18fr; align-items: center; } }
.community__pairtext .steps { margin-top: 0; }

/* =========================================================================
   Feature cards with a photograph
   The image fills the card and the words sit over the bottom of it behind a
   scrim. Only applies to a card that actually has a photograph set; a card
   without one keeps the original bordered treatment above.
   ========================================================================= */
.imgframe--fill { position: absolute; inset: 0; height: 100%; border-radius: inherit; }
.imgframe--fill > picture, .imgframe--fill > img { height: 100%; }

.feature--photo {
  position: relative; overflow: hidden; padding: 0;
  background: var(--ink-raised);
  border-color: rgba(255, 255, 255, 0.14);
  aspect-ratio: 4 / 3;
  transition: border-color 0.22s ease, transform 0.22s ease;
}
.feature--photo .feature__photo { position: absolute; inset: 0; }

/* Narrow screens: the card grows to fit its words instead of holding a fixed
   shape, so a long paragraph can never swallow the photograph. The image still
   fills the card behind the text. */
@media (max-width: 659px) {
  .feature--photo {
    aspect-ratio: auto; min-height: 400px;
    display: flex; flex-direction: column; justify-content: flex-end;
  }
  .feature--photo .feature__cap { position: static; }
}
.feature--photo:hover { transform: translateY(-4px); border-color: rgba(83, 183, 235, 0.4); }
.feature--photo .imgframe img { transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1); }
.feature--photo:hover .imgframe img { transform: scale(1.03); }

@media (min-width: 660px) { .feature--photo { aspect-ratio: 16 / 10; } }
@media (min-width: 1060px) {
  .features > .feature--photo { aspect-ratio: 2 / 1; }
  .features > .feature--photo:first-child { aspect-ratio: 3 / 1; display: block; }
}

.feature__cap {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: clamp(22px, 2.8vw, 34px);
  padding-top: clamp(60px, 9vw, 110px);
  background: linear-gradient(to top,
    rgba(0, 1, 1, 0.93) 0%, rgba(0, 1, 1, 0.86) 34%,
    rgba(0, 1, 1, 0.5) 68%, rgba(0, 1, 1, 0) 100%);
}
.feature__cap svg { width: 26px; height: 26px; color: var(--sky); margin-bottom: 10px; }
.feature__cap h3 { margin-bottom: 6px; color: #fff; }
.feature__cap p { font-size: 0.94rem; color: rgba(255, 255, 255, 0.82); margin: 0; max-width: 54em; }
@media (min-width: 1060px) {
  .features > .feature--photo:first-child .feature__cap h3 { font-size: clamp(1.35rem, 2.3vw, 1.75rem); }
  .features > .feature--photo:first-child .feature__cap p { max-width: 60em; }
}

/* =========================================================================
   Hero — full-bleed background layout
   Opt-in per section (hero_layout: background). The photograph runs edge to
   edge behind the words and up under the sticky header; scrims fade it out on
   the left and into the page background at the bottom so there is no seam and
   no visible container. The words are ordinary elements over the top.
   ========================================================================= */
.hero--bg {
  position: relative; overflow: hidden; isolation: isolate;
  /* pull up behind the translucent sticky header so the picture starts at the
     very top of the page rather than below a hard edge */
  margin-top: calc(-1 * var(--header-h, 73px));
  padding-top: calc(var(--header-h, 73px) + clamp(48px, 7vw, 96px));
  padding-bottom: clamp(56px, 9vw, 128px);
  min-height: clamp(560px, 78vh, 860px);
  display: grid; align-items: center;
}
.hero--bg .hero__bg { position: absolute; inset: 0; z-index: -2; }
.hero--bg .hero__bg .imgframe { border-radius: 0; box-shadow: none; border: 0; }
.hero--bg .hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 70% 50%; }

/* Scrims. The picture already carries its own darkening on the left, so these
   are light — enough to guarantee contrast without flattening the sunset. */
.hero--bg .hero__scrim { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.hero--bg .hero__scrim::before {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to right, var(--ink) 0%, rgba(0, 1, 1, 0.86) 24%, rgba(0, 1, 1, 0.56) 44%, rgba(0, 1, 1, 0.2) 60%, rgba(0, 1, 1, 0) 76%);
}
.hero--bg .hero__scrim::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(0, 1, 1, 0.55) 0%, rgba(0, 1, 1, 0) 24%),
    linear-gradient(to bottom, rgba(0, 1, 1, 0) 38%, rgba(0, 1, 1, 0.3) 60%, rgba(0, 1, 1, 0.72) 80%, rgba(0, 1, 1, 0.95) 93%, var(--ink) 100%);
}

.hero__grid--bg { grid-template-columns: 1fr; }
@media (min-width: 980px) {
  .hero__grid--bg { grid-template-columns: 1fr; }
  .hero__grid--bg > div { max-width: 42rem; }
}

/* Tablet and below: the hero sizes to its content rather than holding a tall
   minimum, so there is no large empty band under the buttons. */
@media (max-width: 979px) {
  .hero--bg { min-height: 0; padding-bottom: clamp(52px, 8vw, 92px); }
  .hero--bg .hero__bg img { object-position: 74% 48%; }
  /* The content column is wider here, so the left fade alone cannot carry the
     contrast. A gentle downward wash protects the buttons without hiding the
     sunset at the top right. */
  .hero--bg .hero__scrim::before {
    background:
      linear-gradient(to right, var(--ink) 0%, rgba(0, 1, 1, 0.8) 30%, rgba(0, 1, 1, 0.42) 60%, rgba(0, 1, 1, 0.26) 100%),
      linear-gradient(to bottom, rgba(0, 1, 1, 0) 10%, rgba(0, 1, 1, 0.26) 48%, rgba(0, 1, 1, 0.52) 100%);
  }
}

/* Phones: the photograph is too wide to crop down to a phone's shape and still
   read as a landscape, so it stops being a background here. The words come
   first on clean black, and the scenery follows as a full-width band that
   emerges from the black and sinks back into it — no hard edges either side,
   and nothing sitting on top of the type. */
@media (max-width: 739px) {
  .hero--bg {
    display: flex; flex-direction: column;
    margin-top: 0;
    min-height: 0;
    padding-top: clamp(40px, 10vw, 64px);
    padding-bottom: 0;
    background: var(--ink);
  }
  .hero--bg > .wrap { order: 1; }
  .hero--bg .hero__scrim { display: none; }

  .hero--bg .hero__bg {
    position: relative; order: 2;
    margin-top: clamp(30px, 8vw, 48px);
  }
  .hero--bg .hero__bg .imgframe--fill {
    position: static; height: auto;
    aspect-ratio: 16 / 9;
    border-radius: 0;
  }
  .hero--bg .hero__bg img { object-position: 62% 50%; }

  /* Fade the band out at both ends so it reads as part of the page, not a card. */
  .hero--bg .hero__bg::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      linear-gradient(to bottom, var(--ink) 0%, rgba(0, 1, 1, 0.45) 12%, rgba(0, 1, 1, 0) 30%),
      linear-gradient(to bottom, rgba(0, 1, 1, 0) 58%, rgba(0, 1, 1, 0.45) 78%, rgba(0, 1, 1, 0.88) 93%, var(--ink) 100%);
  }
}

/* A feature grid that mixes photo cards with plain ones: the plain card should
   size to its own content rather than stretching to match a photo card's shape,
   which would leave a tall empty box beside it. Grids where no card has a
   photograph are untouched and keep their equal heights. */
.features:has(.feature--photo) > .feature:not(.feature--photo) { align-self: start; }
/* ...and its empty image slot collapses, so it reads as a compact card rather
   than a card with a hole in it. Adding a photograph brings it back into the
   photo treatment automatically. */
.features:has(.feature--photo) > .feature:not(.feature--photo) .feature__media { display: none; }

/* =========================================================================
   Service cards — image-led links through to another page
   Same border, radius, hover lift and type as the feature cards; only the
   arrangement differs. The whole card is clickable via the CTA's ::after.
   ========================================================================= */
.svccards { display: grid; gap: 20px; margin-top: 44px; }
/* grid-auto-rows keeps every card the same height when the grid runs to more
   than one row, so a longer description on one card does not make its whole
   row taller than the one above it. */
@media (min-width: 760px) { .svccards { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 1fr; } }

.svccard {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  transition: border-color 0.22s ease, transform 0.22s ease, background 0.22s ease;
}
.svccard:hover {
  transform: translateY(-4px);
  border-color: rgba(83, 183, 235, 0.38);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.016));
}
.svccard:focus-within { border-color: var(--sky); }

.svccard__media .imgframe { border-radius: 0; }
.svccard__media img { transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1); }
.svccard:hover .svccard__media img { transform: scale(1.03); }

/* An image slot that is still empty: a quiet, defined area at the right size,
   so it is obvious where the photograph goes without a bright placeholder
   graphic sitting on the page. Dropping an image in replaces it exactly. */
.svccard__media .imgframe--filler {
  background: rgba(255, 255, 255, 0.035);
  border-bottom: 1px solid var(--ink-line);
}

.svccard__body { padding: clamp(24px, 3vw, 32px); display: grid; gap: 8px; align-content: start; }
.svccard__body h3 { margin: 0; }
.svccard__body p { font-size: 0.95rem; margin: 0; }
.svccard__cta { margin-top: 10px; align-self: start; }
/* Covers the whole card so the card itself is the click target. */
.svccard__cta::after { content: ""; position: absolute; inset: 0; }

/* =========================================================================
   Flat brand-blue closing section
   An alternative tone for the closing call to action. Solid colour, no
   gradient, white type. Only applies when a section asks for it.
   ========================================================================= */
.section--blue { background: var(--blue); }
.section--blue h2,
.section--blue .lede { color: #fff; }
.section--blue .lede { opacity: 0.92; }
.section--blue .eyebrow { color: #fff; }
.section--blue .eyebrow::before { background: rgba(255, 255, 255, 0.72); }
.section--blue .btn--grad {
  background: #fff; color: var(--blue); box-shadow: 0 14px 32px -16px rgba(0, 1, 1, 0.6);
}
.section--blue .btn--grad:hover { background: #fff; color: var(--signal); filter: none; }
.section--blue .btn--ghost { border-color: rgba(255, 255, 255, 0.6); color: #fff; }
.section--blue .btn--ghost:hover { border-color: #fff; background: rgba(255, 255, 255, 0.12); }

/* =========================================================================
   CONTACT PAGE
   Two additions, both scoped: a fieldset that looks like the other fields
   (so radio and checkbox groups sit in the form without looking bolted on),
   and the address / phone / email cards, which reuse the story-card grid and
   only restyle the value line.
   ========================================================================= */
/* .field sets display:grid, which would otherwise beat the browser's own
   [hidden] rule and leave a hidden field on screen. */
.field[hidden] { display: none; }

.fieldset-inline { border: 0; padding: 0; margin: 0; min-width: 0; }
.fieldset-inline legend {
  padding: 0; font-weight: 700; color: var(--panel-ink); font-size: 0.9rem;
}
.choice-row, .choice-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.choice-grid { display: grid; grid-template-columns: 1fr; }
@media (min-width: 560px) { .choice-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .choice-grid { grid-template-columns: repeat(3, 1fr); } }

.choice {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border: 1.5px solid var(--panel-line); border-radius: 14px;
  background: #fff; font-size: 0.93rem; font-weight: 500; color: var(--panel-ink);
  cursor: pointer; transition: border-color 0.16s ease, background 0.16s ease;
}
.choice:hover { border-color: var(--blue); }
.choice input { width: 19px; height: 19px; flex: none; accent-color: var(--blue); margin: 0; }
.choice:has(input:checked) { border-color: var(--blue); background: rgba(20, 80, 211, 0.06); }
.choice:has(input:focus-visible) { outline: 2px solid var(--blue); outline-offset: 1px; }
.choice span { font-weight: 600; }

.contact-cards__v { font-size: 1rem; line-height: 1.6; margin: 0; }
.contact-cards__v a { color: var(--sky); text-decoration: none; overflow-wrap: break-word; }
.contact-cards__v a:hover { color: #fff; text-decoration: underline; }

/* =========================================================================
   INFO CARDS
   Two related explanations side by side in one section. Understated on
   purpose — a charcoal surface barely above the page, a thin blue-grey
   hairline, no shadow and no gradient, so these never read as plan cards.
   ========================================================================= */
.infocards { display: grid; gap: 20px; margin-top: 40px; align-items: start; }
@media (min-width: 880px) { .infocards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .infocards[data-count="3"] { grid-template-columns: repeat(3, 1fr); } }
.sechead + .infocards { margin-top: clamp(30px, 3.6vw, 44px); }

.infocard {
  background: #0a0f18;
  border: 1px solid rgba(110, 140, 175, 0.26);
  border-radius: var(--r-lg);
  padding: clamp(26px, 3vw, 38px);
  transition: border-color 0.22s ease;
}
.infocard:hover { border-color: rgba(110, 140, 175, 0.42); }

.infocard .eyebrow { margin-bottom: 14px; }
.infocard h3 {
  font-size: clamp(1.25rem, 2vw, 1.55rem);
  line-height: 1.22; letter-spacing: -0.02em; margin: 0;
}
.infocard__body {
  color: var(--on-dark-body); font-size: 0.97rem; line-height: 1.65;
  margin: 14px 0 0;
}

.infocard__points { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 13px; }
.infocard__points li { display: flex; gap: 12px; align-items: flex-start; }
/* The tick sits on the first line of text, not centred against the block. */
.infocard__points svg {
  flex: none; width: 19px; height: 19px; margin-top: 2px; color: var(--sky);
}
.infocard__points span { color: var(--on-dark-body); font-size: 0.95rem; line-height: 1.55; }

.devblock--inset { margin-top: 24px; padding: 16px 18px; font-size: 0.84rem; }

/* =========================================================================
   BUSINESS FIBRE
   Two selectors in one dark container above the rail, and the white plan
   card with the fibre-specific rows. The card itself reuses .plan, so it
   stays visually identical to the plan cards on the other service pages.
   ========================================================================= */
.fibrectl {
  margin-top: clamp(28px, 3.4vw, 40px);
  padding: clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--ink-line); border-radius: var(--r-lg);
  background: rgba(255, 255, 255, 0.028);
  display: grid; gap: clamp(16px, 2vw, 22px);
}
.fibrectl[hidden] { display: none; }
@media (min-width: 900px) { .fibrectl { grid-template-columns: repeat(2, 1fr); } }
.fibrectl__row { display: grid; gap: 10px; align-content: start; min-width: 0; }
/* An author `display` beats the browser's own [hidden] rule, so a hidden row
   needs saying twice. This is what keeps a single-option control out of sight
   while leaving it in the DOM for the script to read. */
.fibrectl__row[hidden] { display: none; }
.fibrectl__label {
  margin: 0; font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--on-dark-quiet);
}
/* The shared segmented control sits flush here rather than carrying its own
   top margin, because the container already provides the spacing. */
.fibrectl .segmented { margin-top: 0; }
@media (max-width: 560px) {
  .fibrectl .segmented { display: flex; width: 100%; }
  .fibrectl .segmented button { flex: 1 1 0; padding: 12px 10px; text-align: center; font-size: 0.86rem; }
}

.fibre__railhead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; margin-top: clamp(26px, 3vw, 36px);
}
.fibre__count { margin: 0; font-size: 0.86rem; color: var(--on-dark-quiet); }

.plan--fibre .plan__name { margin-bottom: 2px; }
.plan__fibresub {
  margin: 0 0 4px; font-size: 0.82rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--blue);
}
.plan__pending {
  display: inline-block; font-style: normal;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: #6b5300;
  background: rgba(201, 162, 39, 0.16); border-radius: 999px;
  padding: 2px 8px; margin-left: 4px; white-space: nowrap;
}
/* The contract term sits at the foot of the card, above the button. Only
   monthly pricing is advertised, so no total over the term appears here.
   margin-top:auto keeps every card's button on the same line. */
.plan__term {
  margin-top: auto; padding-top: 18px;
  border-top: 1px solid var(--panel-line);
  display: grid; gap: 10px;
}
.plan__term > div { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.plan__term span { font-size: 0.86rem; color: var(--panel-body); }
.plan__term b { font-size: 1rem; font-weight: 800; color: var(--panel-ink); letter-spacing: -0.01em; }
/* .plan__term already takes the flex column's free space, so the button sits
   directly under it rather than carrying the default .plan__cta top padding. */
.plan--fibre .plan__cta { margin-top: auto; padding-top: 20px; }

/* The fibre rail shows a whole number of cards rather than part of a fourth:
   three across on desktop, two on a tablet, one on a phone. The percentages
   resolve against the rail's content box, so three cards plus two 18px gaps
   fill it exactly. */
.rail--fibre { grid-auto-columns: calc(100% - 4px); }
@media (min-width: 680px) { .rail--fibre { grid-auto-columns: calc((100% - 18px) / 2); } }
@media (min-width: 1020px) { .rail--fibre { grid-auto-columns: calc((100% - 36px) / 3); } }
/* Arrows stay available on a phone here, where one card at a time means the
   rail is the only way to reach the other six speeds. */
.fibre__railhead .rail-nav { display: flex; }

/* Two products on one pricing section: a product row across the top of the
   control panel, then the selected product's own term and option rows. */
.fibrectl__row--wide { grid-column: 1 / -1; }
.fibrectl__panel { display: contents; }
.fibrectl__panel[hidden] { display: none; }
.fibrectl__note {
  margin: 2px 0 0; font-size: 0.8rem; line-height: 1.5; color: var(--on-dark-quiet);
  max-width: 44em;
}
.fibre__product[hidden] { display: none; }

/* Ex-GST headline with the inc-GST equivalent under it, and the POA line that
   replaces both when a price is on application. */
.plan__pricewrap { display: grid; gap: 2px; }
.plan__incgst { font-size: 0.86rem; font-weight: 600; color: var(--panel-body); }
.plan__incgst[hidden], .plan__poa[hidden] { display: none; }
/* .plan__term sets display:grid, which would otherwise beat the browser's own
   [hidden] rule and leave "0 months" on a product with no confirmed terms. */
.plan__term[hidden] { display: none; }
.plan__poa {
  font-size: clamp(1.3rem, 2.4vw, 1.65rem); font-weight: 800;
  letter-spacing: -0.02em; color: var(--blue); line-height: 1.2;
}
.plan--poa .plan__term { visibility: hidden; }


/* =========================================================================
   ═══ REFINEMENT LAYER ═══
   Premium pass. Everything below tunes what is already here — rhythm,
   typographic colour, card density and the small interactions that make a
   site feel built rather than assembled. No new classes are invented and no
   markup changed, so every CloudCannon editable region still resolves.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Vertical rhythm
   The single biggest problem was air: sections, their headings and their
   grids each added their own generous margin, and three generous margins in
   a row read as a gap rather than as space. Tightened so sections relate to
   each other, with the air moved inside the cards where it does some work.
   ------------------------------------------------------------------------- */
:root {
  --section-y: clamp(54px, 6vw, 92px);
  --grid-gap-y: 34px;
  --measure: 36em;
}

.sechead { margin-bottom: 0; }
.section > .wrap > h2,
.section > .wrap > .sechead h2 { margin-bottom: 14px; }
.section > .wrap > .lede,
.sechead .lede { margin-bottom: 0; max-width: 46em; }

.lanes,
.features,
.svccards,
.steps { margin-top: var(--grid-gap-y); }
.plans__group { margin-top: var(--grid-gap-y); }
.plans__group + .plans__group { margin-top: 48px; }

/* -------------------------------------------------------------------------
   2. Typographic colour
   Montserrat is a geometric face: at display sizes it needs negative tracking
   to stop the counters opening up, and at small sizes it needs none at all.
   Figures are set tabular so prices and speeds line up down a column.
   ------------------------------------------------------------------------- */
h1 { letter-spacing: -0.038em; line-height: 1.04; }
h2 { letter-spacing: -0.032em; line-height: 1.06; }
h3 { letter-spacing: -0.018em; line-height: 1.18; }

.lede { line-height: 1.6; letter-spacing: -0.005em; }

.plan__price,
.plan__speed b,
.figure-card__n,
.calc__fig,
.stat__n { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* The eyebrow rule was a flat bar. A short gradient reads as part of the
   brand rather than as a divider that happens to be blue. */
.eyebrow::before {
  width: 28px; height: 2px; border-radius: 2px;
  background: var(--grad); opacity: 0.9;
}
.eyebrow--onlight::before { background: var(--blue); }

/* -------------------------------------------------------------------------
   3. Trust bar
   Was four ticks on a hairline strip, which read as fine print. Now four
   defined chips with the tick in a tinted tile — the same information,
   carrying the weight it should.
   ------------------------------------------------------------------------- */
.trust { padding-block: 22px; }
.trust__list { gap: 12px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.trust__list li {
  gap: 13px; padding: 14px 16px; border-radius: 14px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.015));
  border: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 0.875rem; line-height: 1.4; color: var(--on-dark);
  transition: border-color 0.22s ease, background 0.22s ease;
}
.trust__list li:hover { border-color: rgba(83, 183, 235, 0.38); }
.trust__list svg {
  width: 30px; height: 30px; padding: 7px; border-radius: 9px;
  background: rgba(83, 183, 235, 0.14); box-sizing: border-box;
}

/* -------------------------------------------------------------------------
   4. Services router
   The lanes were tall and sparse: a heading, a sentence, then links floating
   in space. Separators turn the links into a list you can scan, and the icon
   now sits in a tile so the card has a visual anchor at the top.
   ------------------------------------------------------------------------- */
.lane { padding: clamp(24px, 2.6vw, 30px); }
.lane__icon {
  width: 46px; height: 46px; padding: 10px; box-sizing: border-box;
  border-radius: 13px; margin-bottom: 18px;
  background: rgba(83, 183, 235, 0.12);
  border: 1px solid rgba(83, 183, 235, 0.2);
}
.lane > p { margin-bottom: 18px; }
.lane__links { gap: 0; border-top: 1px solid rgba(255, 255, 255, 0.07); }
.lane__links li + li { border-top: 1px solid rgba(255, 255, 255, 0.07); }
.lane__links a { padding: 12px 14px; border-radius: 10px; }
.lane__links a small { margin-top: 1px; }
.lane:hover { transform: translateY(-4px); border-color: rgba(83, 183, 235, 0.5); }

/* -------------------------------------------------------------------------
   5. Feature grid
   The lead card ran at 3:1 — on a wide screen that is a 1240x413 band of
   mostly dark photograph with a caption along the bottom, which reads as a
   hole in the page. Shortened, and the caption given enough type weight to
   hold the space it occupies.
   ------------------------------------------------------------------------- */
@media (min-width: 1060px) {
  .features > .feature--photo { aspect-ratio: 16 / 9; }
  .features > .feature--photo:first-child { aspect-ratio: 2.5 / 1; }
  .features > .feature--photo:first-child .feature__cap {
    padding-inline: clamp(28px, 3.4vw, 44px);
  }
  .features > .feature--photo:first-child .feature__cap h3 {
    font-size: clamp(1.5rem, 2.6vw, 2rem); max-width: 18em;
  }
  .features > .feature--photo:first-child .feature__cap p {
    font-size: 1.02rem; max-width: 52em;
  }
}
/* A hairline inside the frame separates a dark photograph from the dark page
   behind it, so the card has an edge instead of bleeding away. */
.feature--photo { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05); }
.feature__cap h3 { letter-spacing: -0.025em; }
.feature__cap p { color: rgba(255, 255, 255, 0.86); }

/* Non-photo feature cards: same density as everything else. */
.feature { padding: clamp(24px, 2.8vw, 32px); }
.feature svg {
  width: 44px; height: 44px; padding: 9px; box-sizing: border-box;
  border-radius: 12px; margin-bottom: 16px;
  background: rgba(83, 183, 235, 0.12);
  border: 1px solid rgba(83, 183, 235, 0.2);
}

/* -------------------------------------------------------------------------
   6. Plan cards
   These carry the commercial weight of the site and were the most generic
   thing on it. The price is now the largest element on the card, figures are
   tabular so a column of prices aligns, and the featured card is marked by a
   ring and a lift rather than by colour alone.
   ------------------------------------------------------------------------- */
.plan {
  padding: 26px 24px 24px;
  box-shadow: 0 18px 44px -26px rgba(0, 1, 1, 0.75);
  border-color: rgba(219, 228, 242, 0.9);
}
.plan:hover {
  transform: translateY(-5px);
  box-shadow: 0 28px 60px -28px rgba(0, 1, 1, 0.85);
  border-color: rgba(49, 129, 221, 0.45);
}

.plan__name { font-size: 1.05rem; letter-spacing: -0.015em; }

/* Speed is the headline on an internet plan, price on everything else. Both
   get the same treatment so the cards read consistently either way. */
.plan__speed { margin-top: 12px; align-items: baseline; }
.plan__speed b { font-size: 2.35rem; letter-spacing: -0.05em; }

.plan__divider { margin: 18px 0; }

.plan__price { font-size: 2.3rem; letter-spacing: -0.05em; }
.plan__price sup { font-size: 1.05rem; top: -0.62em; margin-right: 1px; }
.plan__price span { font-size: 0.9rem; font-weight: 600; color: var(--panel-body); margin-left: 2px; }
.plan--featured .plan__price span { color: rgba(255, 255, 255, 0.86); }
.plan__gst { font-size: 0.76rem; letter-spacing: 0.01em; margin-top: 7px; }
/* The pricing basis follows straight under the GST line as part of the same
   caption, rather than reading as a second, separate statement. */
.plan__pricenote { margin-top: 2px; opacity: 0.85; }
.plan__pricenote[hidden] { display: none; }

.plan__inc li { padding-left: 26px; line-height: 1.5; }
.plan__inc li::before { top: 6px; }

.plan__badge { font-size: 0.64rem; padding: 6px 11px; letter-spacing: 0.14em; }

/* The featured card lifts out of the row rather than only changing colour. */
.plan--featured {
  box-shadow: 0 26px 60px -24px rgba(20, 80, 211, 0.75);
  border-color: rgba(255, 255, 255, 0.28);
}
@media (min-width: 1020px) { .plan--featured { transform: translateY(-6px); } }
@media (min-width: 1020px) { .plan--featured:hover { transform: translateY(-11px); } }

.plan__cta { padding-top: 20px; }

/* Segmented control sits closer to the heading it belongs to. */
.segmented { margin-top: 26px; }

/* -------------------------------------------------------------------------
   7. Hero
   The pill row under the buttons was an undifferentiated line of chips. It
   is a list of what the company sells, so it now reads as one.
   ------------------------------------------------------------------------- */
.hero__pills { gap: 8px; margin-top: 26px; }
.hero__pills span {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.14);
  padding: 8px 16px; font-size: 0.8rem; color: var(--on-dark);
  transition: border-color 0.2s ease, background 0.2s ease;
}
.hero__pills span:hover { border-color: rgba(83, 183, 235, 0.45); background: rgba(83, 183, 235, 0.08); }

/* -------------------------------------------------------------------------
   8. Service cards
   ------------------------------------------------------------------------- */
.svccard__body { padding: clamp(22px, 2.6vw, 28px); gap: 7px; }
.svccard__cta { margin-top: 12px; }

/* -------------------------------------------------------------------------
   9. FAQ
   A row of summaries with no separation reads as a wall. A hairline between
   them, and a plus that turns, makes it obvious they open.
   ------------------------------------------------------------------------- */
.faq details { border-bottom: 1px solid rgba(255, 255, 255, 0.09); }
.faq summary { padding-block: 20px; transition: color 0.18s ease; }
.faq summary:hover { color: var(--sky); }
.faq details[open] summary { color: #fff; }

/* -------------------------------------------------------------------------
   10. Footer
   The brand column ran to a different baseline from the link columns. Both
   now start at the same line, and the link rows have a touch more room.
   ------------------------------------------------------------------------- */
.site-footer__grid { gap: 40px 32px; align-items: start; }
.site-footer ul { gap: 11px; }
.site-footer ul a { transition: color 0.16s ease; }
.site-footer__tag { margin-top: 14px; color: var(--on-dark-quiet); }
.site-footer__bottom { margin-top: 40px; }

/* -------------------------------------------------------------------------
   11. Motion
   A single shared curve, and a stagger so a grid arrives as a group rather
   than all at once. Anything that opts out of motion is untouched.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .lane, .feature, .svccard, .plan, .trust__list li {
    transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .svccard[style*="--i"] { transition-delay: calc(var(--i, 0) * 40ms); }
}

/* -------------------------------------------------------------------------
   12. Hero legibility
   The lede ran across the brightest part of the sunset and the left fade
   released too early to carry it. Widened and deepened through the middle;
   the sun sits at about 88% across, so the picture keeps its drama.
   ------------------------------------------------------------------------- */
@media (min-width: 980px) {
  .hero--bg .hero__scrim::before {
    background: linear-gradient(to right,
      var(--ink) 0%,
      rgba(0, 1, 1, 0.92) 26%,
      rgba(0, 1, 1, 0.78) 42%,
      rgba(0, 1, 1, 0.5) 56%,
      rgba(0, 1, 1, 0.18) 70%,
      rgba(0, 1, 1, 0) 84%);
  }
  .hero--bg { padding-bottom: clamp(52px, 7vw, 100px); }
}

/* -------------------------------------------------------------------------
   13. Partner band
   With the points restored the band is a two-column layout again, so the
   columns need to relate to each other rather than float.
   ------------------------------------------------------------------------- */
.band__grid > .steps { margin-top: 0; }
.band__grid .steps li { align-items: flex-start; }
.band__grid .steps b {
  background: rgba(83, 183, 235, 0.12);
  border-color: rgba(83, 183, 235, 0.42);
}
.band__grid .steps span { color: var(--on-dark); font-weight: 500; }

/* -------------------------------------------------------------------------
   14. Section separation
   On a single black canvas every band runs into the next. A barely-there
   surface tint on alternating sections gives the page a rhythm you feel
   rather than notice — no lines, no boxes, just a change of ground.
   ------------------------------------------------------------------------- */
.sections > .section-slot:nth-of-type(even) > .section:not(.section--blue):not(.hero) {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.022) 0%,
    rgba(255, 255, 255, 0.008) 55%,
    transparent 100%);
}

/* -------------------------------------------------------------------------
   15. Section headings
   A heading, its eyebrow and its lede are one unit and should read as one.
   ------------------------------------------------------------------------- */
.section > .wrap > .eyebrow { margin-bottom: 14px; }
.section > .wrap > h2 + .lede { margin-top: 0; }

/* =========================================================================
   ═══ SPACING SYSTEM ═══
   One scale, applied everywhere. Before this, section padding ran at 86, 104
   and 80px depending on the component; the gap between a heading and the grid
   under it ran at 34, 26, 24 and 16; and card grids used 18, 20 and 12px
   gutters. Each value was reasonable on its own and the combination read as
   carelessness — the thing that separates a premium site from a competent one
   is that the same relationship is always the same distance.
   ========================================================================= */
:root {
  /* The scale. Every spacing value below is a step on it, never an ad-hoc number. */
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 40px;
  --s-8: 56px;

  /* Rhythm. Fluid, but one source for each relationship. */
  --section-y:       clamp(60px, 6.6vw, 96px);  /* every full section */
  --section-y-tight: clamp(44px, 4.8vw, 68px);  /* a section deliberately closer to its neighbour */
  --hero-y:          clamp(64px, 7.4vw, 108px); /* the one section allowed more room */
  --head-gap:        clamp(30px, 3.4vw, 46px);  /* heading block → the grid beneath it */
  --grid-gap:        clamp(16px, 1.7vw, 24px);  /* between cards, in every grid */
  --stack-gap:       var(--s-5);                /* between stacked blocks inside a column */
}

/* ---------- sections ---------- */
.section            { padding-block: var(--section-y); }
.section--tight     { padding-block: var(--section-y-tight); }
.section--flush-top { padding-top: 0; }
.hero               { padding-block: var(--hero-y); }
.trust              { padding-block: var(--s-5); }

/* ---------- the heading block ----------
   Eyebrow, heading and lede are one unit with fixed internal spacing, and the
   distance from that unit to whatever follows is always --head-gap. */
.section > .wrap > .eyebrow,
.sechead .eyebrow            { margin-bottom: var(--s-4); }
.section > .wrap > h2,
.sechead h2                  { margin-bottom: var(--s-3); }
.section > .wrap > .lede,
.sechead .lede               { margin-bottom: 0; max-width: 46em; }
.sechead                     { margin-bottom: 0; }

/* ---------- grids ----------
   Every card grid: same gutter, same distance from the heading above it. */
.lanes,
.features,
.svccards,
.bar-grid,
.team,
.trust__list,
.plans__group,
.steps,
.rail                        { margin-top: var(--head-gap); }
.lanes,
.features,
.svccards,
.bar-grid,
.team                        { gap: var(--grid-gap); }
.trust__list                 { gap: var(--s-3); margin-top: 0; }
.rail                        { gap: var(--grid-gap); margin-top: var(--s-5); }
.plans__group + .plans__group { margin-top: var(--section-y-tight); }
.segmented                   { margin-top: var(--s-6); }

/* A grid that follows body copy rather than a heading sits closer — it is a
   continuation of the sentence above it, not a new idea. */
.steps                       { margin-top: var(--s-6); gap: var(--s-5); }
.band__grid > .steps         { margin-top: 0; }

/* ---------- images ----------
   Media blocks sit on the same rhythm as text, and a single odd ratio (5:4)
   has been brought onto the three the rest of the site uses: 3:2 for card
   media, 4:3 for a section image, 21:9 for a full-width band. */
.feature__media,
.community__media,
.band__media                 { margin-bottom: var(--s-5); }
.team__media                 { margin-bottom: var(--s-4); }
.imgframe[style*="5 / 4"],
.imgframe[style*="5/4"]      { aspect-ratio: 4 / 3 !important; }

/* ---------- card interiors ----------
   One padding for every card that sits on the dark canvas, so a row of mixed
   card types still reads as one row. */
.lane,
.feature:not(.feature--photo),
.brew                        { padding: clamp(24px, 2.6vw, 32px); }
.svccard__body               { padding: clamp(24px, 2.6vw, 32px); }
.feature__cap                { padding: clamp(22px, 2.6vw, 32px); padding-top: clamp(56px, 8vw, 100px); }

/* ---------- buttons under a block ---------- */
.btn-row                     { margin-top: var(--s-6); gap: var(--s-3) var(--s-5); }
.hero__cta                   { margin-top: var(--s-6); }
.hero__pills                 { margin-top: var(--s-5); gap: var(--s-2); }

/* -------------------------------------------------------------------------
   Spacing system, part 2: the inline styles that were defeating it.
   Five components carried hard-coded margins in a style attribute — 26px,
   34px, 22px, a 20px flex gap and a margin:0. An inline style beats every
   stylesheet rule, so the system above could never reach those elements and
   the same list rendered at a different distance depending on which component
   drew it. The values now live here, on the scale.
   ------------------------------------------------------------------------- */

/* A step list is one of two things, and the distance differs because the
   relationship does: inside a column it continues the copy above it; as a
   section's own content it answers the heading. */
.steps                        { margin-top: var(--s-6); gap: var(--s-5); }
.section > .wrap > .steps     { margin-top: var(--head-gap); max-width: 46em; }
.band__grid > .steps,
.community__pairtext .steps   { margin-top: 0; }

.plans__foot                  { margin-top: var(--s-5); }
.plans__headrow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-5); flex-wrap: wrap;
}

/* Two-column splits — a text column beside a media column. One distance for
   that relationship, where it used to be 64px, 60px and 30px by component. */
:root { --split-gap: clamp(32px, 4.2vw, 60px); }
.hero__grid,
.community__grid,
.band__grid,
.split,
.find                         { gap: var(--split-gap); }

/* Forms keep a tighter gutter than content grids: fields belong together. */
.form-grid                    { gap: var(--s-4); }

/* -------------------------------------------------------------------------
   Equal card heights
   The lanes were top-aligned, so a column with two links finished well short
   of one with four and the row ended on a ragged edge. Stretching them buys a
   straight line across the bottom of the row, which is the thing the eye
   actually reads.

   The links used to be pushed down with margin-top:auto so every card's list
   started at the same line. That only works while the cards hold a similar
   number of links: a card with one link ended up with its link stranded at
   the bottom, a long gap above it, and nothing under the heading. Content now
   runs from the top of every card and the spare room falls to the bottom,
   where it reads as breathing space rather than as something missing.
   ------------------------------------------------------------------------- */
@media (min-width: 880px) {
  .lanes { align-items: stretch; }
  .lane  { display: flex; flex-direction: column; }
  .lane__links { padding-top: var(--s-4); }
}

/* The info-card grid predates the scale: 20px gutter, 40px from its heading,
   top-aligned. Brought onto the same rhythm as every other card grid. */
.infocards { gap: var(--grid-gap); margin-top: var(--head-gap); align-items: stretch; }
@media (min-width: 880px) { .infocards > * { display: flex; flex-direction: column; } }

/* -------------------------------------------------------------------------
   SPACING SYSTEM — part 3: the remaining off-scale distances
   Everything above put the big relationships on one scale. These are the
   components that predate it and were still carrying hand-set numbers —
   40px here, 34px there, 44px somewhere else — for the same relationship.
   Each one is moved to the token that matches what it is, not to a new
   number, so nothing changes size noticeably; it just stops being arbitrary.
   Small internal offsets (a GST line 7px under a price, a slider thumb's
   negative margin) are deliberate optical nudges and are left alone.
   ------------------------------------------------------------------------- */

/* A card grid, list or media block directly under a section heading. Same
   relationship as .lanes and .features, so the same distance. */
.speeds,
.quotes,
.faq,
.stats,
.scards,
.scards__media,
.logo-strip                   { margin-top: var(--head-gap); }

/* .sechead + .infocards was the one measured outlier — 44px against 46px
   everywhere else — and it outranks the .infocards rule above on
   specificity, so it has to be restated rather than removed. */
.sechead + .infocards         { margin-top: var(--head-gap); }

/* Those same grids kept their own gutters: 14px, 18px, 18px, 18px. */
.speeds,
.quotes,
.stats,
.scards                       { gap: var(--grid-gap); }
.logo-strip                   { gap: var(--s-5) var(--s-7); }

/* A block that follows another block inside the same section — a continuation,
   closer than a new section but further than a grid under its own heading. */
.scards__media + .scards      { margin-top: var(--s-6); }
.community__pair              { margin-top: var(--s-8); }
.figure-card--compact         { margin-top: var(--s-6); }

/* Controls and panels: fluid, but with both ends on the scale. */
.fibrectl                     { margin-top: clamp(var(--s-6), 3.4vw, var(--s-7)); }
.fibre__railhead              { margin-top: var(--s-6); }

/* Inside a panel — the calculator's rows and the figure card's footer. */
.form-grid,
.calc__slider,
.calc__results,
.figure-card__foot            { margin-top: var(--s-5); }
@media (max-width: 899px) {
  .calc                       { margin-top: var(--s-6); }
}

/* The fallback shown while no form endpoint is configured. It has to read as
   a useful alternative to the form, not as a broken-site warning, so the two
   ways through sit on their own line in the panel's own type. */
.form-disabled-note strong { display: block; font-weight: 700; }
.form-disabled-note__ways {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  margin-top: var(--s-2); font-weight: 600;
}
.form-disabled-note__ways a { color: inherit; }
.form-disabled-note__ways i { opacity: 0.5; font-style: normal; }
/* The address is one long unbreakable word. On a 320px screen it pushed a
   scrollbar onto every page carrying a form, so it is allowed to break. */
.form-disabled-note__ways > * { min-width: 0; overflow-wrap: anywhere; }

/* Copy-to-clipboard control beside the email address. Deliberately quiet: it
   is an affordance on a value, not an action the page is asking for. */
.copybtn {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: var(--s-2); padding: 5px 10px;
  font: inherit; font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--on-dark-quiet); background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--ink-line); border-radius: 999px;
  cursor: pointer; vertical-align: middle;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.copybtn svg { width: 14px; height: 14px; }
.copybtn:hover { color: var(--on-dark); border-color: rgba(83, 183, 235, 0.45); background: rgba(83, 183, 235, 0.1); }
.copybtn:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
.copybtn.is-done { color: var(--sky); border-color: rgba(83, 183, 235, 0.5); }

/* =========================================================================
   GRADIENT EDGE FIX
   A gradient background is POSITIONED against the padding box by default but
   PAINTED out to the border box. Any element carrying both a gradient and a
   border therefore has a ring, outside the gradient's own box, that the
   browser fills by extending the gradient's edge band — which wrapped the pale
   sky end of the brand gradient around to the opposite edge and read as a
   mismatched rim, most visibly on the rounded corners of the pill buttons.

   Every .btn carries a 1.5px transparent border so the ghost variants can
   colour it, so the artefact appeared on every filled gradient button.

   Sizing the gradient to the border box makes it continuous across the whole
   shape. It changes nothing for a solid background, nothing for an element
   with no border, and nothing about size, radius, type or colour.
   ========================================================================= */
.btn,
.plan,
.lane,
.scard,
.svccard,
.feature { background-origin: border-box; }

/* =========================================================================
   ABOUT PAGE
   Two additions, both built from the existing scale and tokens: editorial
   paragraphs under a section lede, and the headline figure.
   ========================================================================= */

/* Running prose under a lede. Narrower measure than the lede so a three
   paragraph passage still reads as a column rather than a wall. */
.prose { margin-top: 18px; display: grid; gap: 16px; max-width: 36em; }
.prose p { color: var(--on-dark-body); font-size: 1rem; line-height: 1.7; margin: 0; }
.section--blue .prose p { color: rgba(255, 255, 255, 0.88); }

/* The headline figure. The number is set at display size and sits beside its
   explanation on a wide screen, above it on a phone, where it scales down with
   the viewport rather than overflowing. */
.bigfig { display: grid; gap: clamp(28px, 4vw, 56px); align-items: center; }
@media (min-width: 900px) { .bigfig { grid-template-columns: 0.8fr 1.2fr; } }

.bigfig__figure { display: grid; gap: 10px; justify-items: start; min-width: 0; }
.bigfig__n {
  font-size: clamp(5.5rem, 17vw, 11rem);
  font-weight: 800; line-height: 0.82; letter-spacing: -0.06em;
  color: #fff; display: block;
}
.bigfig__label {
  font-size: clamp(0.68rem, 1.1vw, 0.78rem); font-weight: 800;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78); max-width: 20em; line-height: 1.5;
}
.bigfig__body { min-width: 0; }
.bigfig__body h2 { color: #fff; }
/* Elsewhere an <em> in a heading is clipped to the brand gradient, which has
   nothing to key against on a blue field. The palest brand blue gives the same
   two-tone heading at a contrast that stays readable here. */
.bigfig__body h2 em { font-style: normal; color: var(--cyan); }
.bigfig__body .lede { color: rgba(255, 255, 255, 0.9); }
.bigfig__body .eyebrow { color: #fff; }
.bigfig__body .eyebrow::before { background: rgba(255, 255, 255, 0.85); }

/* Buttons on the blue field: a white solid and a white outline, matching the
   shape, size and transitions of every other button on the site. */
.btn--onblue { background: #fff; color: var(--blue); }
.btn--onblue:hover { background: var(--cyan); color: var(--blue); }
.btn--ghost-onblue { border-color: rgba(255, 255, 255, 0.55); color: #fff; background: transparent; }
.btn--ghost-onblue:hover { border-color: #fff; background: rgba(255, 255, 255, 0.12); color: #fff; }

/* The calculator section reuses the two-column give-back layout from the home
   page, so the copy sits beside the panel rather than leaving the row empty. */
.section--calc .community__grid { margin-top: 0; }

/* =========================================================================
   FOOTER CONTACT AND SOCIALS
   ========================================================================= */
.site-footer .site-footer__contact { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 7px; }
.site-footer .site-footer__contact a {
  color: var(--on-dark-body); text-decoration: none;
  font-size: 0.92rem; overflow-wrap: anywhere;
  transition: color 0.16s ease;
}
.site-footer .site-footer__contact a:hover { color: var(--sky); }

/* Round icon buttons, sized close to the 44px touch target the rest of the
   site uses, with the same hairline and hover as the rail arrows.
   Scoped under .site-footer so it outranks `.site-footer ul`, which lays the
   navigation columns out as a stacked grid and would otherwise stack these. */
.site-footer .social {
  list-style: none; margin: 20px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px;
}
.social__link {
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--ink-line); color: var(--on-dark-body);
  background: rgba(255, 255, 255, 0.04);
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}
.social__link svg { width: 19px; height: 19px; display: block; }
.social__link:hover {
  color: #fff; border-color: var(--sky);
  background: rgba(83, 183, 235, 0.14); transform: translateY(-2px);
}
.social__link:focus-visible { outline: 2px solid var(--sky); outline-offset: 3px; }
