/*
 * FAST — the marketing site's whole design system.
 *
 * One stylesheet shared by every page, rather than the inline block the single
 * page used to carry. With five pages, one cached file beats five copies of the
 * same rules, and a change to a button no longer has to be made five times.
 *
 * No framework, no webfont, no CDN. This is the first thing a Zimbabwean
 * customer loads, usually on a phone and often on a metered connection, so every
 * external request is a chance to be slow or to fail and there are none. The
 * type is whatever the device already has.
 *
 * Colours come from the brand artwork: cyan #04ABBD from the bolt, ink #08141C
 * from the wordmark, and a deeper teal #067885 for anything carrying white text
 * — the cyan itself only reaches about 2.4:1 on white, so it is never used for
 * text on a pale ground.
 *
 * Motion is opt-out at the bottom of this file: every animation is disabled
 * under `prefers-reduced-motion`, and nothing is hidden until the script that
 * reveals it has run (see the `.js` guard) so the page is fully readable with
 * JavaScript switched off.
 */

/* ═══════════════════════════════════════════════════════════════════════════
   Tokens
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --cyan: #04ABBD;
  /* The same cyan, dark enough to be text.
   *
   * #04ABBD on white is 2.78:1 and on the tinted surface 2.60:1, against the
   * 4.5:1 that WCAG AA asks for body text — measured with axe, and it was 16
   * of the 20 real contrast failures on the site. This is 5.98:1 and 5.59:1.
   *
   * Both exist on purpose: the bright cyan stays for decoration, where
   * contrast rules do not apply, and anything a person reads uses this. */
  --cyan-deep: #0A6E78;
  --cyan-soft: #37C4D4;
  --teal: #067885;
  --teal-dark: #05606B;
  --ink: #08141C;
  --ink-2: #0F2430;
  --ink-3: #163544;
  --body: #33454F;
  --muted: #5C7280;
  --line: #DCE6EA;
  --wash: #F4F8FA;
  --white: #fff;

  --radius: 16px;
  --radius-lg: 24px;
  --radius-pill: 999px;

  --shadow-sm: 0 4px 14px -6px rgba(8, 20, 28, .18);
  --shadow: 0 18px 45px -20px rgba(8, 20, 28, .35);
  --shadow-lg: 0 30px 70px -28px rgba(8, 20, 28, .45);

  --pad: clamp(20px, 5vw, 40px);
  --maxw: 1180px;
  --maxw-narrow: 780px;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Base
   ═══════════════════════════════════════════════════════════════════════════ */

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Anchored sections would otherwise land under the sticky header. */
  scroll-padding-top: 90px;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--body);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.65;
  overflow-x: hidden;
}

/*
 * `height: auto` is load-bearing, not tidiness.
 *
 * Every <img> declares width and height so the browser reserves the right space
 * before the file arrives and the page does not jump. With only `max-width`, the
 * width scales to the column while the height attribute still applies literally
 * — a 1600x900 hero rendered 630 wide and 900 tall, stretched to near-portrait.
 */
img { max-width: 100%; height: auto; display: block; }

a { color: var(--teal); }

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

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--pad); }
.wrap-narrow { max-width: var(--maxw-narrow); margin: 0 auto; padding: 0 var(--pad); }

/* Visible only to screen readers — skip links, section labels. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--ink); color: #fff; padding: 12px 18px;
  border-radius: 0 0 10px 10px; text-decoration: none; font-weight: 600;
  transition: top .18s var(--ease);
}
.skip:focus { top: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Typography
   ═══════════════════════════════════════════════════════════════════════════ */

h1, h2, h3, h4 {
  color: var(--ink); line-height: 1.14; margin: 0 0 16px;
  letter-spacing: -.02em; font-weight: 800;
}
h1 { font-size: clamp(36px, 6.2vw, 62px); }
h2 { font-size: clamp(28px, 4.2vw, 44px); }
h3 { font-size: clamp(19px, 2.2vw, 23px); font-weight: 700; }
h4 { font-size: 17px; font-weight: 700; }

p { margin: 0 0 16px; }

.eyebrow {
  text-transform: uppercase; letter-spacing: .14em;
  font-size: 12px; font-weight: 700; color: var(--cyan-deep); margin: 0 0 12px;
}
.lede { font-size: clamp(17px, 2vw, 20px); color: var(--muted); margin: 0 0 28px; }
.lede-lg { font-size: clamp(18px, 2.4vw, 23px); color: var(--muted); line-height: 1.5; }

.on-ink { color: rgba(255, 255, 255, .78); }
.on-ink h1, .on-ink h2, .on-ink h3, .on-ink h4, .on-ink strong { color: #fff; }
.on-ink .lede, .on-ink .lede-lg { color: rgba(255, 255, 255, .78); }

/* ═══════════════════════════════════════════════════════════════════════════
   Buttons
   ═══════════════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 15px 28px; border-radius: var(--radius-pill);
  font-weight: 700; font-size: 16px; text-decoration: none;
  border: 2px solid transparent; cursor: pointer;
  /* 52px keeps it above the 48px minimum touch target on a phone. */
  min-height: 52px;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease), border-color .18s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--teal); color: #fff;
  box-shadow: 0 10px 26px -12px rgba(6, 120, 133, .9);
}
.btn-primary:hover {
  background: var(--teal-dark); transform: translateY(-2px);
  box-shadow: 0 16px 34px -14px rgba(6, 120, 133, .95);
}

.btn-ghost { border-color: rgba(255, 255, 255, .42); color: #fff; }
.btn-ghost:hover { background: rgba(255, 255, 255, .12); transform: translateY(-2px); }

.btn-outline { border-color: var(--line); color: var(--ink); background: #fff; }
.btn-outline:hover { border-color: var(--cyan); color: var(--teal); transform: translateY(-2px); }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Header
   ═══════════════════════════════════════════════════════════════════════════ */

header.site {
  position: sticky; top: 0; z-index: 60;
  background: rgba(255, 255, 255, .9);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease),
              background .25s var(--ease);
}
/* Set by site.js once the page has scrolled: the header only earns its border
   and shadow when there is content behind it to separate from. */
header.site.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: 0 6px 24px -18px rgba(8, 20, 28, .5);
}

.nav { display: flex; align-items: center; gap: 18px; height: 74px; }
.brand { display: flex; align-items: center; text-decoration: none; margin-right: auto; }
.brand img { height: 34px; width: auto; }

.nav-links { display: flex; gap: 26px; align-items: center; }
.nav-links a {
  color: var(--body); text-decoration: none; font-weight: 600; font-size: 15px;
  padding: 6px 0; position: relative;
}
/* An underline that grows from the left rather than a border that snaps on. */
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 2px;
  background: var(--cyan); transition: right .22s var(--ease);
}
.nav-links a:hover::after, .nav-links a.current::after { right: 0; }
.nav-links a.current { color: var(--ink); }
.nav .btn { padding: 11px 22px; min-height: 44px; font-size: 15px; }

/* A button in the nav is a button, not a nav link.
 *
 * `.nav-links a` sets `color: var(--body)` at specificity 0,2,0 and beat
 * `.btn-primary`'s `color: #fff` at 0,1,0 — so the primary call to action, on
 * every page, rendered dark grey on teal at 1.92:1. Effectively unreadable,
 * and found by running axe rather than by looking at it, because at a glance
 * a dark label on a saturated teal still reads as "a button".
 *
 * The growing underline goes too: it belongs under a text link, and drawing a
 * cyan bar along the bottom edge of a filled button was never intended. */
.nav-links a.btn-primary { color: #fff; }
.nav-links a.btn::after { content: none; }

/* The menu is a checkbox so navigation needs no JavaScript. */
#navtoggle { position: absolute; opacity: 0; pointer-events: none; }
.burger {
  display: none; cursor: pointer; padding: 12px; margin: -12px -10px -12px 0;
  border-radius: 10px;
}
.burger span, .burger span::before, .burger span::after {
  content: ""; display: block; width: 24px; height: 2px;
  background: var(--ink); border-radius: 2px;
  transition: transform .24s var(--ease), opacity .18s var(--ease);
}
.burger span::before { transform: translateY(-7px); }
.burger span::after { transform: translateY(5px); }
#navtoggle:checked ~ .burger span { background: transparent; }
#navtoggle:checked ~ .burger span::before { transform: rotate(45deg); }
#navtoggle:checked ~ .burger span::after { transform: rotate(-45deg); }
#navtoggle:focus-visible ~ .burger { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Sections
   ═══════════════════════════════════════════════════════════════════════════ */

section { padding: clamp(60px, 8vw, 104px) 0; }
section.tight { padding: clamp(40px, 5vw, 64px) 0; }

.section-head { max-width: 720px; margin: 0 auto clamp(36px, 5vw, 58px); text-align: center; }
.section-head .lede { margin-bottom: 0; }

.wash { background: var(--wash); }
.ink-bg { background: var(--ink); color: rgba(255, 255, 255, .78); }

/* The eyebrow needs the *bright* cyan back on a dark section.
 *
 * No single colour can carry 12px bold text at 4.5:1 against both white and
 * near-black: the darker cyan that fixed the light sections is 3.12:1 on the
 * ink background, and a mid-tone fails against both. So it is two colours
 * chosen per background rather than one compromise that satisfies neither.
 *
 * #04ABBD on #08141c is 6.71:1. The same token that was too light on white is
 * comfortably right here. */
.ink-bg .eyebrow, footer.site .eyebrow { color: var(--cyan); }
.ink-bg h2, .ink-bg h3, .ink-bg h4 { color: #fff; }
.ink-bg .lede { color: rgba(255, 255, 255, .78); }

/* A soft brand-coloured wash behind a section, for depth without an image. */
.glow { position: relative; overflow: hidden; }
.glow::before {
  content: ""; position: absolute; pointer-events: none;
  width: 60vw; height: 60vw; max-width: 780px; max-height: 780px;
  top: -22%; right: -14%; border-radius: 50%;
  background: radial-gradient(circle, rgba(4, 171, 189, .16), transparent 68%);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Hero
   ═══════════════════════════════════════════════════════════════════════════ */

.hero {
  position: relative; color: #fff; overflow: hidden;
  background: linear-gradient(135deg, #041C24 0%, #063845 55%, #05606B 100%);
}
.hero::after {
  content: ""; position: absolute; inset: auto -10% -55% 40%;
  height: 90%; pointer-events: none;
  background: radial-gradient(circle, rgba(4, 171, 189, .30), transparent 68%);
}

/*
 * Light streaks drifting across the hero.
 *
 * The brand photography is full of motion blur and light trails; this is that
 * idea in CSS rather than a video file. It costs nothing to download, cannot
 * fail to load, and stops entirely under `prefers-reduced-motion`.
 */
.streaks { position: absolute; inset: 0; overflow: hidden; pointer-events: none; opacity: .5; }
.streaks i {
  position: absolute; height: 1px; left: -40%; width: 40%;
  background: linear-gradient(90deg, transparent, var(--cyan-soft), transparent);
  animation: streak 7s linear infinite;
}
.streaks i:nth-child(1) { top: 22%; animation-duration: 6.5s; animation-delay: 0s; }
.streaks i:nth-child(2) { top: 41%; animation-duration: 9s;   animation-delay: 1.4s; opacity: .6; }
.streaks i:nth-child(3) { top: 58%; animation-duration: 7.5s; animation-delay: 2.9s; }
.streaks i:nth-child(4) { top: 74%; animation-duration: 11s;  animation-delay: .7s;  opacity: .45; }
.streaks i:nth-child(5) { top: 88%; animation-duration: 8.2s; animation-delay: 3.6s; opacity: .35; }

@keyframes streak {
  0%   { transform: translateX(0);    opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateX(350%); opacity: 0; }
}

.hero-grid {
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: center;
  padding: clamp(52px, 8vw, 104px) 0;
  position: relative; z-index: 2;
}
.hero h1 { color: #fff; }
.hero h1 em { color: var(--cyan); font-style: italic; }
.hero .lede { color: rgba(255, 255, 255, .82); }
.hero-cta { margin-bottom: 34px; }
.hero-figure { position: relative; }
.hero-figure img { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }

/* A compact hero for the inner pages. */
.page-hero {
  position: relative; overflow: hidden; color: #fff;
  background: linear-gradient(135deg, #041C24 0%, #063845 60%, #05606B 100%);
  padding: clamp(52px, 7vw, 96px) 0 clamp(44px, 6vw, 76px);
}
.page-hero h1 { color: #fff; margin-bottom: 14px; }
.page-hero .lede { color: rgba(255, 255, 255, .8); margin-bottom: 0; max-width: 62ch; }

.crumbs { font-size: 14px; color: rgba(255, 255, 255, .6); margin-bottom: 18px; }
.crumbs a { color: rgba(255, 255, 255, .78); text-decoration: none; }
.crumbs a:hover { color: #fff; text-decoration: underline; }

.trust { display: flex; flex-wrap: wrap; gap: 12px 30px; }
.trust div { display: flex; align-items: center; gap: 9px; font-size: 14.5px; color: rgba(255, 255, 255, .9); }
.tick {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: rgba(4, 171, 189, .22); color: var(--cyan);
  display: grid; place-items: center; font-size: 12px; font-weight: 800;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Cards
   ═══════════════════════════════════════════════════════════════════════════ */

.grid { display: grid; gap: 22px; }
/* 360px, not 300: at 300 a 1180px row fitted three columns, so the four-tile
   groups these are used for came out as a row of three and one orphan. */
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

.card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; display: flex; flex-direction: column;
  transition: transform .24s var(--ease), box-shadow .24s var(--ease),
              border-color .24s var(--ease);
}
.card:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: transparent; }
/*
 * 16:9, matching the artwork exactly, so `cover` crops nothing.
 *
 * This was 3:2, which trimmed about 8% off each side. On a photograph that is
 * invisible. The brand artwork is not photography — it is finished poster
 * design with the logo hard against the left edge and the contact bar running
 * to the right — so the crop was taking the bolt and the F off the front of
 * every FAST on the site, leaving "AST", and cutting the email in half.
 */
.card img { aspect-ratio: 16 / 9; object-fit: cover; width: 100%; }
.card-body { padding: 24px 24px 26px; flex: 1; display: flex; flex-direction: column; }
.card-body p { margin: 0 0 16px; font-size: 15.5px; }
.tag {
  display: inline-block; align-self: flex-start; margin-top: auto;
  background: rgba(4, 171, 189, .12); color: var(--teal);
  font-size: 12.5px; font-weight: 700; padding: 6px 13px; border-radius: var(--radius-pill);
}
.ink-bg .tag { background: rgba(4, 171, 189, .2); color: var(--cyan); }
.card-wide { grid-column: 1 / -1; display: grid; grid-template-columns: 1.15fr 1fr; }
.card-wide img { aspect-ratio: auto; height: 100%; min-height: 300px; }
.card-wide .card-body { padding: clamp(26px, 4vw, 46px); justify-content: center; }

/* A plain card with no photograph — values, facts, contact routes. */
.tile {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 28px 26px;
  transition: transform .24s var(--ease), box-shadow .24s var(--ease),
              border-color .24s var(--ease);
}
.tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-sm); border-color: var(--cyan); }
.tile h3 { margin-bottom: 8px; }
.tile p:last-child { margin-bottom: 0; }

/* A tile that is itself the link. The whole card is the target rather than a
   "read more" at the bottom — on a phone the card is a comfortable tap and the
   link is not. */
a.tile {
  display: flex; flex-direction: column; align-items: flex-start;
  text-decoration: none; color: var(--body);
}
a.tile .tag { margin-top: auto; }
a.tile:hover h3 { color: var(--teal); }
.ink-bg .tile {
  background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .12);
}
.ink-bg .tile:hover { background: rgba(255, 255, 255, .08); }

.icon {
  width: 46px; height: 46px; border-radius: 13px; margin-bottom: 16px;
  background: linear-gradient(135deg, var(--cyan), var(--teal));
  color: #fff; display: grid; place-items: center; flex: none;
}

/*
 * The icon shapes themselves. Stroke and weight are set here, once, rather
 * than on each of the two dozen symbols in partials/icons.html — both are
 * inherited properties, so they reach into the <use> shadow tree, and a single
 * change here restyles the whole set.
 *
 * `currentColor` means an icon is always the colour of the text around it: on
 * the gradient tile it comes out white, in the footer it matches the links,
 * and neither needs a rule of its own.
 */
.ico {
  width: 23px; height: 23px; display: block; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.ico-sm { width: 17px; height: 17px; stroke-width: 1.8; }

/* ═══════════════════════════════════════════════════════════════════════════
   Steps, splits, stats
   ═══════════════════════════════════════════════════════════════════════════ */

.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 30px; counter-reset: step; }
.step { position: relative; padding-top: 58px; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: 0; left: 0;
  width: 44px; height: 44px; border-radius: 13px;
  background: linear-gradient(135deg, var(--cyan), var(--teal));
  color: #fff; font-weight: 800; font-size: 19px;
  display: grid; place-items: center;
}
.step h3 { margin-bottom: 8px; }
.step p { margin: 0; font-size: 15.5px; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.split img { border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.split ul { list-style: none; padding: 0; margin: 0 0 28px; }
/*
 * The tick is positioned, not a flex item.
 *
 * As a flex row, every contiguous run of text in the <li> became its own
 * anonymous flex item — so "<strong>No commission.</strong> A flat
 * subscription…" laid out as two side-by-side columns, and on a phone the
 * bold half wrapped to "No / commission." in a narrow column of its own.
 * Absolute positioning leaves the text as ordinary inline flow, which is what
 * it is.
 */
.split li { position: relative; padding-left: 34px; margin-bottom: 14px; font-size: 16px; }
.split li .tick { position: absolute; left: 0; top: 3px; }
.ink-bg .split li { color: rgba(255, 255, 255, .85); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 22px; }
.stat {
  background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius); padding: 26px 22px;
}
.stat b {
  display: block; color: var(--cyan); font-size: clamp(30px, 4vw, 40px);
  font-weight: 800; line-height: 1.1;
  /* Tabular figures so a counting animation does not make the row jitter. */
  font-variant-numeric: tabular-nums;
}
/*
 * The direct child only — the label under the figure.
 *
 * Unscoped, this also caught the <span data-count> *inside* the <b>, which is
 * where the counting animation writes. Being the more specific selector it
 * won, and the two animated figures rendered at label size in label grey while
 * the two static ones next to them were 40px cyan.
 */
.stat > span { color: rgba(255, 255, 255, .72); font-size: 14.5px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Showreel
   ═══════════════════════════════════════════════════════════════════════════

   The five service posters, full frame, dissolving one into the next.

   No zoom and no pan, deliberately. The usual Ken Burns push would look alive,
   but these are finished poster designs rather than photographs: the logo sits
   hard against the left edge and the contact bar runs the full width, so any
   movement that crops takes the mark or the email address with it. Held still
   and dissolved, they read as they were drawn.

   It costs nothing to load. Every frame is a file the service cards on the same
   page have already fetched, so the reel is the same five images shown large.
*/

.reel { position: relative; }

.reel-stage {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  background: var(--ink);
}

.reel-slide {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; transition: opacity .9s var(--ease);
}
.reel-slide.is-current { opacity: 1; }
.reel-slide img { width: 100%; height: 100%; object-fit: cover; }

/* Without the script the first slide is the one marked current in the markup
   and the rest stay at zero, so the band is a single poster rather than a
   stack of five or an empty box. */
.reel-dots { display: none; }
.js .reel-dots {
  display: flex; justify-content: center; flex-wrap: wrap;
  gap: 10px; margin-top: 20px;
}
.reel-dot {
  appearance: none; border: 0; padding: 0; cursor: pointer;
  width: 34px; height: 5px; border-radius: var(--radius-pill);
  background: var(--line); transition: background .25s var(--ease);
}
.reel-dot:hover { background: var(--cyan-soft); }
.reel-dot[aria-current="true"] { background: var(--teal); }
.ink-bg .reel-dot { background: rgba(255, 255, 255, .22); }
.ink-bg .reel-dot[aria-current="true"] { background: var(--cyan); }

/* The caption sits under the frame rather than over it: the posters carry
   their own headline, and a second one on top of that is two designs
   arguing. */
.reel-caption {
  text-align: center; margin: 18px auto 0; max-width: 58ch;
  min-height: 3em;   /* Reserved, so the row below does not jump on a change. */
}
.reel-caption b { display: block; color: var(--ink); font-size: 17px; }
.reel-caption span { color: var(--muted); font-size: 15.5px; }
.ink-bg .reel-caption b { color: #fff; }
.ink-bg .reel-caption span { color: rgba(255, 255, 255, .7); }

/* ═══════════════════════════════════════════════════════════════════════════
   Accordion — FAQ, without JavaScript
   ═══════════════════════════════════════════════════════════════════════════ */

.faq { max-width: var(--maxw-narrow); margin: 0 auto; }
.faq details {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; margin-bottom: 12px; overflow: hidden;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.faq details[open] { border-color: var(--cyan); box-shadow: var(--shadow-sm); }
.faq summary {
  cursor: pointer; padding: 20px 54px 20px 24px; position: relative;
  font-weight: 700; color: var(--ink); list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 22px; top: 50%;
  transform: translateY(-50%); font-size: 24px; font-weight: 400;
  color: var(--teal); transition: transform .25s var(--ease);
}
.faq details[open] summary::after { content: "\2212"; }
.faq .answer { padding: 0 24px 22px; color: var(--body); }
.faq .answer p:last-child { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Contact
   ═══════════════════════════════════════════════════════════════════════════ */

/* Secondary text: a subject line to use, a caveat, a pointer. Quieter than
   body copy but still large enough to read on a phone held at arm's length. */
.note { font-size: 14.5px; color: var(--muted); margin: 0 0 12px; }
.ink-bg .note { color: rgba(255, 255, 255, .6); }

/* The one address the whole site funnels into, given room to be the thing you
   see rather than a line of small print in the footer. */
.contact-card {
  max-width: var(--maxw-narrow); margin: clamp(34px, 5vw, 52px) auto 0;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); padding: clamp(30px, 4vw, 44px); text-align: center;
}
.contact-email {
  font-size: clamp(19px, 3.2vw, 28px); font-weight: 800;
  margin: 6px 0 18px; line-height: 1.25;
  /* Long on a narrow screen, and an address that overflows its card is worse
     than one that wraps mid-word. */
  overflow-wrap: anywhere;
}
.contact-email a { color: var(--teal-dark); text-decoration: none; }
.contact-email a:hover { text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════════════════
   Call to action band
   ═══════════════════════════════════════════════════════════════════════════ */

.cta {
  background: linear-gradient(135deg, var(--teal-dark), var(--cyan));
  color: #fff; text-align: center; border-radius: var(--radius-lg);
  padding: clamp(38px, 6vw, 64px) var(--pad);
}
.cta h2 { color: #fff; }
.cta p { color: rgba(255, 255, 255, .88); max-width: 56ch; margin: 0 auto 26px; }
.cta .btn-row { justify-content: center; }
.cta .btn-primary { background: #fff; color: var(--teal-dark); }
.cta .btn-primary:hover { background: rgba(255, 255, 255, .9); }

/* ═══════════════════════════════════════════════════════════════════════════
   Footer
   ═══════════════════════════════════════════════════════════════════════════ */

footer.site {
  background: var(--ink); color: rgba(255, 255, 255, .62);
  padding: clamp(48px, 6vw, 72px) 0 30px; font-size: 15px;
}
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.1fr; gap: 38px; margin-bottom: 38px; }
footer.site h4 {
  color: #fff; font-size: 13px; text-transform: uppercase;
  letter-spacing: .1em; margin: 0 0 16px;
}
footer.site ul { list-style: none; padding: 0; margin: 0; }
footer.site li { margin-bottom: 10px; }
footer.site a { color: rgba(255, 255, 255, .66); text-decoration: none; transition: color .18s var(--ease); }
footer.site a:hover { color: var(--cyan); }
.foot-brand img { height: 52px; width: auto; margin-bottom: 14px; }
.foot-tagline { margin: 0 0 18px; max-width: 38ch; }
.foot-contact li { display: flex; gap: 9px; align-items: flex-start; }
.foot-bottom {
  border-top: 1px solid rgba(255, 255, 255, .1); padding-top: 24px;
  display: flex; flex-wrap: wrap; gap: 12px 26px; justify-content: space-between;
  font-size: 14px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Scroll reveal
   ═══════════════════════════════════════════════════════════════════════════

   Guarded behind `.js`, which site.js puts on <html> as its first act. Without
   the script — disabled, blocked, or still loading — none of these rules apply
   and every element is simply visible. Content that depends on JavaScript to
   become visible is content that sometimes is not.
*/

.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .6s var(--ease-out), transform .6s var(--ease-out);
  will-change: opacity, transform;
}
.js [data-reveal].in { opacity: 1; transform: none; }

/* Children of a [data-stagger] arrive one after another rather than together. */
.js [data-stagger] > * { transition-delay: calc(var(--i, 0) * 80ms); }

/* ═══════════════════════════════════════════════════════════════════════════
   Responsive
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  html { scroll-padding-top: 84px; }
  .hero-grid, .split, .card-wide { grid-template-columns: 1fr; }
  .split .split-media { order: -1; }
  .card-wide img { min-height: 220px; }
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
  .foot-brand { grid-column: 1 / -1; }

  .burger { display: block; }
  .nav-links {
    position: absolute; top: 74px; left: 0; right: 0;
    background: #fff; border-bottom: 1px solid var(--line);
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 8px var(--pad) 18px;
    box-shadow: var(--shadow);
    display: none;
  }
  #navtoggle:checked ~ .nav-links { display: flex; }
  .nav-links a { padding: 14px 0; border-bottom: 1px solid var(--line); }
  .nav-links a::after { display: none; }
  .nav-links a:last-of-type { border-bottom: 0; }
  .nav .btn { margin-top: 12px; }
}

@media (max-width: 520px) {
  body { font-size: 16px; }
  .btn-row .btn { width: 100%; }
  .trust { gap: 10px 18px; }

  /* The footer, centred.
   *
   * Stacked into one left-aligned column it left most of the width empty beside
   * short link text, so on a phone it read as content pushed against one edge
   * rather than as a footer. The link lists stay side by side — they are short
   * enough at this width, and it halves how far the page runs on. */
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 30px 20px; text-align: center; }
  .foot-brand { grid-column: 1 / -1; }
  .foot-brand img { margin-left: auto; margin-right: auto; }
  .foot-tagline { margin-left: auto; margin-right: auto; }
  .foot-contact { grid-column: 1 / -1; }
  .foot-contact li { justify-content: center; }
  .foot-bottom { justify-content: center; text-align: center; gap: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Motion preferences
   ═══════════════════════════════════════════════════════════════════════════

   Everything above that moves is switched off here. Vestibular disorders make
   parallax and drifting elements genuinely unpleasant, and the setting exists to
   be honoured rather than detected and ignored.
*/

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .streaks { display: none; }
  .js [data-reveal] { opacity: 1; transform: none; }
}

@media print {
  header.site, footer.site, .streaks, .cta { display: none; }
  body { color: #000; font-size: 12pt; }
  .js [data-reveal] { opacity: 1; transform: none; }
}
