/* ============================================================
   YOUR Personal Training — operator staff briefing page
   Public. No login. Permanent URL behind a printed QR code.

   Design system is NOT invented here. It is the one already
   shipped on the YOUR PT / YOUR Academy landing page:
     canvas #0f0f0f, accent #95c11f as text-on-dark only,
     cards = 4% white fill at 16px radius, hairline rules,
     999px pills, no shadows, no gradients, no glows.
   See ../../reference and the Academy repo's design-notes.md.

   Hand-written. No build step, no framework, no runtime deps —
   a printed QR code cannot be recalled if a dependency breaks.
   ============================================================ */

:root {
  --canvas: #0f0f0f;
  --green: #95c11f;
  --white: #ffffff;
  --silver: #bababa;
  --ash: #878c91;

  --card: rgba(255, 255, 255, 0.04);
  --card-hi: rgba(255, 255, 255, 0.06);
  --line: rgba(255, 255, 255, 0.10);
  --line-strong: rgba(255, 255, 255, 0.15);

  --display: 'Bebas Neue Pro', 'Bebas Neue', 'Oswald', 'Arial Narrow', sans-serif;
  --body: 'Proxima Nova', 'Montserrat', system-ui, -apple-system, sans-serif;

  --maxw: 1120px;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --dur: 200ms;

  /* Sticky quick-nav height, used for scroll-margin on every section */
  --navh: 56px;
}

/* ---------- base ---------- */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* The light bands break out of the wrap with 50vw margins; 100vw includes the
     scrollbar on some platforms, so clip the sliver rather than growing the page. */
  overflow-x: clip;
}

body {
  background: var(--canvas);
  color: var(--white);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: var(--green);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* Visually hidden but available to screen readers */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- type ---------- */

.display {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1.05;
  letter-spacing: 0.01em;
}

.eyebrow {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--green);
  line-height: 1.5;
}

.lead {
  color: rgba(255, 255, 255, 0.70);
  font-size: 17px;
  line-height: 1.65;
  max-width: 62ch;
  margin-top: 14px;
}

/* ---------- header ---------- */

/* Not sticky: the quick nav below is what needs to persist, and two
   stacked sticky bars eat a third of a phone screen. No hairline under it
   either — on screen the header and the hero are one dark field. (Paper does
   rule under it; see the print block, where fills don't print and a rule is
   the only separator available.) */
.topbar-in {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 18px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.topbar img {
  height: 32px;
  width: auto;
}

/* The wordmark in the standard logo is white, which vanishes on the light
   printed page, so a dark-wordmark twin is swapped in for print. */
.logo-print {
  display: none;
}

/* ---------- split hero ---------- */

.hero-in {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 44px 24px 48px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 36px;
  align-items: center;
}

@media (min-width: 900px) {
  .hero-in {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: 64px;
    padding: 72px 24px 80px;
  }
}

/* Scale matches the live landing page, whose hero H1 is clamp(46px,10vw,90px) —
   46px is its floor, and 46px is also the largest size that still holds
   "PERSONAL TRAINING" on one line in this narrower split column at 390px.
   An earlier 36px floor was chosen to keep the quick nav at the fold; that
   traded away the type hierarchy, which is the wrong way round on a page whose
   display face is doing the work. */
.hero h1 {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(46px, 7vw, 62px);
  line-height: 0.94;
  letter-spacing: 0.01em;
  margin-top: 18px;
}

/* The moment the split kicks in, the headline column halves in width while the
   viewport has not changed — so a viewport-based clamp that was comfortable at
   899px is suddenly tight at 900px. This shallower ramp keeps "PERSONAL TRAINING"
   clear of its column at every width, reaching the 62px ceiling only once the
   column is wide enough to carry it.

   This block MUST stay after the base .hero h1 rule above: same specificity, so
   source order decides the winner. */
@media (min-width: 900px) {
  .hero h1 {
    font-size: clamp(46px, 5vw, 62px);
  }
}

/* The phrase takes its own line at every width, so the headline always reads
   YOUR ON-SITE / PERSONAL TRAINING / PARTNER. Left white on purpose: the green
   made the middle line shout over the two around it, and the headline is one
   sentence, not a highlight. The line break carries the emphasis instead. */
.hero h1 .g {
  display: block;
}

/* Landing page runs its subhead at clamp(15px,1.9vw,19px) with 1.45 leading.
   Matching it keeps the display-to-body ratio at roughly 3:1 on a phone; at
   17px/1.6 the lede crowded the headline. */
.hero .sub {
  margin-top: 18px;
  font-size: clamp(15px, 1.9vw, 17px);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.80);
  max-width: 46ch;
}

/* Accreditation logo strip.
   Treatment lifted verbatim from the live landing page's press row
   (https://start.yourpersonaltraininguk.co.uk) — see reference/academy-ui-css.md:
     .press-logo { filter: brightness(0) invert(); }  + opacity .9, w-auto, fixed height
   Forcing a uniform white keeps a row of mixed-colour accreditation marks reading as
   one set rather than a jumble. */
.accred {
  list-style: none;
  margin-top: 28px;
  padding-top: 24px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 26px 32px;
}

.accred img {
  height: 34px;
  width: auto;
  opacity: 0.9;
  filter: brightness(0) invert(1);
}

@media (max-width: 560px) {
  .accred {
    gap: 20px 24px;
    margin-top: 24px;
    padding-top: 20px;
  }

  .accred img {
    height: 28px;
  }

  .hero-in {
    padding-bottom: 40px;
  }
}

/* On a large display the four marks sit on ONE line. They cannot do it at 34px —
   their natural widths total ~617px against a ~516px copy column — so the row
   drops to 28px and tightens its gaps, which brings the set to ~489px. Below
   this width the 2x2 wrap stands. */
@media (min-width: 1120px) {
  .accred {
    flex-wrap: nowrap;
    gap: 20px;
  }

  .accred img {
    height: 28px;
  }
}

/* The photo is sized to sit alongside the copy block, not to set the height of
   the hero. Fixed height + cover keeps the whole hero inside one screen on a
   laptop; the 4:5 source is cropped by the browser, not letterboxed. */
/* Explicit heights rather than aspect-ratio: the <img> width/height attributes
   supply a used height, so aspect-ratio would be ignored here anyway. The 4:5
   source is cropped by object-fit, not letterboxed. */
.hero-media img {
  width: 100%;
  height: 210px;
  border-radius: 16px;
  object-fit: cover;
}

@media (min-width: 900px) {
  .hero-media img {
    height: clamp(340px, 52vh, 460px);
  }
}

/* ---------- sticky quick nav ---------- */

/* The bar sits one surface step above the canvas, a shade below where the cards
   resolve to (4% white over #0f0f0f ≈ #1b1b1b), so elevation reads as a surface
   change rather than an edge. The bottom hairline stays: when the bar is stuck
   and content scrolls beneath it, that edge is what separates bar from page.

   OPACITY IS LOAD-BEARING. This was a translucent gradient over a backdrop blur
   — rgba(15,15,15,.88) to rgba(27,27,27,.94) — which composites to #0f0f0f→#1a1a1a
   over the canvas but #2c2c2c→#292929 over the two light bands. So the bar
   lightened by ~28 levels as a white band scrolled under it, top edge first
   (the gradient's top stop is the more transparent one), with the blur smearing
   white content into grey behind it. A bar that half-flips to light and back is
   worse than one that never tries. #131313 is what the old bar already averaged
   over the dark canvas, so the dark sections look untouched — it simply stops
   moving. If a real dark/light nav swap is ever wanted, it needs doing properly:
   two crossfaded background layers driven by a sentinel at the band boundary,
   not translucency left to composite by accident. */
.qnav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: #131313;
  border-bottom: 1px solid var(--line);
}

.qnav-in {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 11px 24px;
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.qnav-in::-webkit-scrollbar {
  display: none;
}

.qnav a {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.90);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 7px 14px;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

.qnav a:hover,
.qnav a:focus-visible {
  color: var(--green);
  text-decoration: none;
}

/* The section you are currently in fills with the card shade, so the bar answers
   "where am I" without being read. Set by the scroll spy in index.html; if that
   script never runs no pill fills and the nav still works as plain anchors.

   This MUST sit after the hover rule: both are 0,2,0, so source order decides,
   and with it first the hover state was pulling the current pill's border back
   down to the resting shade mid-hover. */
.qnav a.is-current {
  background: var(--card);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--white);
}

/* ...which in turn means the current pill needs hovering back in explicitly,
   at 0,3,0, or it would be the one pill on the bar that ignores the cursor. */
.qnav a.is-current:hover,
.qnav a.is-current:focus-visible {
  color: var(--green);
}

/* ---------- sections ---------- */

/* Sections breathe: 64px on a phone, 96px from the split breakpoint up. This
   matters most where the surface flips — a dark-to-light swap with tight
   padding reads as a strip stuck onto the page rather than a new region.

   No dividing rules between sections, or anywhere else on screen. They were
   doing nothing the whitespace and the section headings weren't already doing,
   and on the light bands the ink hairline was actively ugly. Space is the only
   separator this page uses. The single exception is the sticky nav's bottom
   edge, which is not a divider but a functional one: it has to hold the bar
   off the content scrolling underneath it. Paper is a different document and
   declares its own rules — see the print block. */
.block {
  padding: 64px 0;
  scroll-margin-top: var(--navh);
}

@media (min-width: 900px) {
  .block {
    padding: 96px 0;
  }
}

h2.sec {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(30px, 4.6vw, 44px);
  line-height: 1.08;
  letter-spacing: 0.01em;
  margin-top: 10px;
}

/* ---------- alternating media / copy split ---------- */
/* The landing page's InfoSections pattern: two columns, vertically centred,
   square photo, alternating sides down the page. Mobile stacks copy first in
   both directions — the words are the point, the photo supports them. */

.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 56px;
  }

  /* Only the media-left variant reorders; source order already puts copy first,
     which is what the media-right variant and every mobile width want. */
  .split--media-left .split-copy {
    order: 2;
  }

  .split--media-left .split-media {
    order: 1;
  }
}

/* height:auto is load-bearing. The width/height attributes on the <img> supply a
   used height, and aspect-ratio is ignored unless one axis is auto — without it
   these render at their intrinsic 1000px tall instead of square. */
.split-media img {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 16px;
}

/* Inside a split column the copy is already narrow, so the section-level
   measure caps would fight it. First child loses its top margin so the eyebrow
   lines up with the top of the photo. */
.split-copy > :first-child {
  margin-top: 0;
}

/* ---------- the card primitive ---------- */
/* One card, repeated. Every panel on this page is this card. */

.card {
  background: var(--card);
  border-radius: 16px;
  padding: 26px 26px 28px;
}

/* The display face needs enough size to actually read as the card's header
   against the body text beneath it; at 21px it sat too close to the 15px list
   and the cards felt flat. */
.card h3 {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 25px;
  letter-spacing: 0.02em;
  line-height: 1.1;
  margin-bottom: 10px;
}

.card p {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.70);
}

/* The at-a-glance trio carries the Academy stat-card inset highlight and its
   hover rise. Everything else stays flat and static, so the lift means something.

   Both the shadow and the motion are the live landing page's `.stat-card`,
   captured verbatim from https://start.yourpersonaltraininguk.co.uk on
   12 Aug 2026 and recorded in reference/academy-ui-css.md:

     .stat-card       { transition: transform 0.45s cubic-bezier(0.2,0,0,1); }
     .stat-card:hover { transition-duration: 0.22s; transform: translateY(-4px); }

   The asymmetry is the point — the rise is brisk at 220ms, the settle back is
   the longer 450ms, which is what makes the unhover feel smooth rather than
   snapped. Do not "tidy" these into one duration. */
.card--lift {
  box-shadow:
    inset 0 1px 1px rgba(199, 211, 234, 0.12),
    inset 0 24px 48px rgba(199, 211, 234, 0.05);
  transition: transform 450ms var(--ease);
}

.card--lift:hover {
  transform: translateY(-4px);
  transition-duration: 220ms;
}

.grid {
  display: grid;
  gap: 14px;
  margin-top: 26px;
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
}

/* Three-up only once there is genuinely room for it. At 700px these columns fall
   to ~240px, which wraps headings like "Sales & membership" onto two lines and
   leaves the body text in a narrow ragged strip. A three-item row has no tidy
   two-up fallback — 2+1 orphans the last card — so it stays stacked until 900px. */
@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 940px) {
  .grid--3-wide { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 700px) and (max-width: 939px) {
  .grid--3-wide { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- plus-marker list ---------- */
/* The green "+" marker is the Academy info-section bullet. Used for
   unordered points only — sequences get numbers instead (see .steps). */

/* The marker is absolutely positioned, NOT a flex item. A flex row here would
   make every inline <strong> its own flex item and open the row gap up inside
   the sentence — e.g. a stray space before a full stop. */
.plus {
  list-style: none;
  margin-top: 26px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* The measure cap that used to live here is gone. The plus list and the step
   sequence both moved inside .split-copy, whose column already constrains them,
   so the rule matched nothing but the callout — and the callout is meant to run
   the full content width. Its own max-width sits on .callout. */

.plus li {
  position: relative;
  padding-left: 26px;
  font-size: 16px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.90);
}

.plus li::before {
  content: "+";
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--display);
  font-size: 19px;
  line-height: 1.35;
  color: var(--green);
}

/* Inside a card the list follows a heading, so it needs less air above. */
.card .plus {
  margin-top: 14px;
  gap: 11px;
}

.card .plus li {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.70);
}

.plus strong {
  font-weight: 700;
  color: var(--white);
}

/* ---------- ordered sequence ---------- */
/* Numbers appear here and nowhere else, because this is the only content
   on the page where order carries information the reader needs. */

.steps {
  list-style: none;
  counter-reset: step;
  margin-top: 18px;
}

/* Same rule as .plus: absolute marker, so inline <strong> doesn't become a
   flex item and split the sentence. No rule between steps — the 01/02/03
   counters already say "sequence", and a hairline per row on top of that is
   two devices doing one job. */
.steps li {
  position: relative;
  counter-increment: step;
  padding: 12px 0 12px 42px;
  font-size: 16px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.90);
}

.steps li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 16px;
  font-family: var(--body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.10em;
  color: var(--green);
  font-variant-numeric: tabular-nums;
}

.steps strong {
  font-weight: 700;
  color: var(--white);
}

/* ---------- callout ---------- */
/* No coloured left stripe — the card fill and the bold opener carry it. */

.callout {
  margin-top: 26px;
  background: var(--card-hi);
  border-radius: 16px;
  padding: 22px 24px;
  font-size: 16px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.80);
}

.callout strong {
  color: var(--white);
  font-weight: 700;
}

/* ---------- member question reference ---------- */

.qref {
  margin-top: 26px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qref .row {
  background: var(--card);
  border-radius: 16px;
  padding: 20px 24px;
}

@media (min-width: 760px) {
  .qref .row {
    display: grid;
    grid-template-columns: minmax(0, 38%) minmax(0, 62%);
    gap: 28px;
    align-items: start;
  }
}

.qref .q {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--white);
}

.qref .a {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.70);
  margin-top: 8px;
}

@media (min-width: 760px) {
  .qref .a {
    margin-top: 0;
  }
}

/* ---------- FAQ ---------- */

.faq {
  margin-top: 26px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.faq details {
  background: var(--card);
  border-radius: 16px;
  padding: 18px 24px;
}

.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.45;
  transition: color var(--dur) var(--ease);
}

/* The only hover state these rows get. The row is the target, so the whole
   question colours — not a background shift, which would fight the card fills
   either side of it. Hover only: green is never the resting colour here, or it
   would read as a link. */
.faq summary:hover {
  color: var(--green);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq .icon {
  flex: 0 0 auto;
  font-size: 24px;
  line-height: 1;
  color: var(--green);
  transition: transform var(--dur) var(--ease);
}

.faq details[open] .icon {
  transform: rotate(45deg);
}

.faq .body {
  margin-top: 12px;
  font-size: 15px;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.70);
  max-width: 68ch;
}

.faq .body strong {
  color: var(--white);
  font-weight: 600;
}

/* ---------- reporting "what to send" chip ---------- */

.need {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.70);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 14px;
}

.need b {
  color: var(--green);
  font-weight: 700;
}

/* ---------- contact + actions ---------- */

.contact {
  margin-top: 26px;
  background: var(--card);
  border-radius: 16px;
  padding: 26px 28px;
  max-width: 520px;
}

.contact .k {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ash);
}

.contact .v {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 18px;
  font-weight: 600;
}

.contact .v a {
  color: var(--white);
}

.contact .v a:hover {
  color: var(--green);
}

/* admin@yourpersonaltraininguk.com is 32 characters with no space in it, so it
   is one unbreakable word that sets a hard floor on how narrow this card can
   get. At the desktop 18px it measures 289px, which is *exactly* the inner
   width of the card on a 393px iPhone — no slack at all, so it reads as
   touching the wall, and on anything narrower it breaks out of the card and
   drags a horizontal scrollbar onto the whole page.

   Two changes below the 560px breakpoint: the card gives back some of its side
   padding, and the values step down to 15px. The phone number comes with it —
   they are one flex column with one font-size, and a shrunken email beside a
   full-size number would look like a mistake rather than a decision. */
@media (max-width: 560px) {
  .contact {
    padding: 22px 20px;
  }

  .contact .v {
    font-size: 15px;
  }
}

/* An iPhone 16 with Display Zoom switched on reports 320px, not 393px — and
   this page is read by reception and duty-manager teams, where zoomed displays
   are common. 15px wraps the address onto two lines there. 14px holds it on
   one, down to 320. */
@media (max-width: 360px) {
  .contact .v {
    font-size: 14px;
  }
}

/* Last line of defence, at every width. Nothing above can survive a reader who
   has Display Zoom on or text scaled up, and the failure mode for an
   unbreakable string is to punch out of its container and scroll the page.
   This makes it wrap instead — never pretty, always contained. It costs
   nothing while the text fits, which at 15px it does on every phone we care
   about. */
.contact .v a {
  overflow-wrap: anywhere;
}

.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 26px;
  border: 1px solid var(--white);
  border-radius: 999px;
  padding: 13px 26px;
  font-family: var(--body);
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--white);
  background: transparent;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.pill:hover,
.pill:focus-visible {
  background: var(--white);
  color: var(--canvas);
  text-decoration: none;
}

/* ---------- footer ---------- */

footer {
  padding: 40px 0 56px;
  color: var(--ash);
}

footer img {
  height: 28px;
  width: auto;
}

footer .meta {
  margin-top: 20px;
  font-size: 14px;
  line-height: 1.7;
  max-width: 62ch;
}

footer .meta a {
  color: rgba(255, 255, 255, 0.80);
}

/* ---------- light band ---------- */
/* Two sections flip to a light surface to break the page out of a single black
   run. The band bleeds to the viewport edge (the sections live inside the
   centred .wrap, so it escapes with 50vw margins and restores the content
   position with matching padding).

   The accents mirror the dark canvas: eyebrows and "+" markers are brand green
   here exactly as they are up there, so the same element reads the same way on
   both surfaces. Jon's call, 12 August. Note for whoever reads this next:
   #95c11f measures 2.1:1 on white, so these accents are below AA — they are
   labels and markers, never body copy, and the copy itself stays ink (≥5.97:1).
   Links stay ink with underlines for the same reason. */

.block--light {
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-left: calc(50vw - 50%);
  padding-right: calc(50vw - 50%);
  background: var(--white);
  color: #161616;
}

/* The two bands are one continuous white field, so the second one's top
   padding would stack on the first one's bottom padding and open a gap wide
   enough to read as a missing section. Halve the pair that meet. */
.block--light + .block--light {
  padding-top: 0;
}

/* Eyebrows are green on the dark canvas; they mirror that here rather than
   dropping to grey, so the same element reads the same way on both surfaces. */
.block--light .eyebrow {
  color: var(--green);
}

.block--light .lead {
  color: #5c5c5c;
}

.block--light .card {
  background: rgba(22, 22, 22, 0.05);
}

.block--light .card p {
  color: #5c5c5c;
}

.block--light .plus li {
  color: #2d2d2d;
}

.block--light .plus li::before {
  color: var(--green);
}

.block--light .qref .row {
  background: rgba(22, 22, 22, 0.05);
}

.block--light .qref .q {
  color: #161616;
}

.block--light .qref .a {
  color: #5c5c5c;
}

/* Links inside the band: green text fails AA on white, so they go ink with an
   underline doing the signalling. */
.block--light a {
  color: #161616;
  font-weight: 600;
  text-decoration: underline;
}

/* The global focus ring is white — invisible here. */
.block--light a:focus-visible,
.block--light button:focus-visible,
.block--light summary:focus-visible {
  outline-color: #161616;
}

/* ---------- scroll reveal ---------- */

/* Everything here hangs off `.js`, stamped on <html> by an inline script in the
   head. Without that guard opacity:0 applies at parse and only the bottom script
   ever clears it — so a blocked, failed or disabled script left the whole page
   below the hero invisible. The reveal is progressive enhancement; the text is
   not allowed to depend on it. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
}

.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* The two light bands do NOT reveal. .reveal is on the <section>, and on these
   sections the <section> carries the full-bleed white background — so animating
   it animates the surface: mid-transition the slab sits at grey over the dark
   canvas, and the 16px translate tears the seam open against the section above.
   A surface flip cannot crossfade. Its arrival IS the entrance.

   Deliberately one uncoupled rule rather than moving the fade to the band's
   children: that variant needs matching overrides in both the reduced-motion and
   print blocks, and since media queries add no specificity the reduced-motion one
   would silently lose the tie and freeze the content invisible. */
.js .block--light.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  /* Must carry `.js` to match the base selector above — a media query adds no
     specificity, so a bare `.reveal` here would lose the tie and leave these
     readers looking at an invisible page. */
  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* Killing the transition alone would leave the hover rise snapping into place
     instantly. The live landing page cancels the transform too — match it. */
  .card--lift:hover {
    transform: none;
  }
  * {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- print ---------- */
/* The SOP tells managers this page can go on a noticeboard or be handed
   out, so the printed version has to be the page, not a broken copy. */

/* Printed output is deliberately LIGHT, not a copy of the dark screen design.
   Chrome ships with "Background graphics" switched OFF by default, so a
   near-black page with white text prints as a blank sheet. The SOP tells
   managers this page can go on a noticeboard or be handed out, so the printed
   version has to work on a default printer with default settings.

   Structure is carried by rules and weight, never by background fills. Green is
   dropped entirely: #95c11f on white is 2.1:1 and fails AA — the brand system
   forbids it as text on a light surface. */

@media print {
  @page {
    margin: 14mm;
  }

  html,
  body {
    background: #ffffff !important;
    color: #161616 !important;
    font-size: 10.5pt;
    line-height: 1.45;
  }

  .qnav,
  .noprint,
  .faq .icon,
  .logo-screen {
    display: none !important;
  }

  .logo-print {
    display: block !important;
  }

  /* Blanket reset to near-black. This is deliberately a low-specificity
     selector (0,0,1) so the class-based greys below still win, while still
     beating every screen rule that paints text white — including the inline
     <strong> inside FAQ answers and callouts, which would otherwise print
     white-on-white and silently drop words out of sentences. */
  body,
  body * {
    color: #161616 !important;
  }

  .lead,
  .card p,
  .faq .body,
  .qref .a,
  footer .meta,
  .contact .k {
    color: #4a4a4a !important;
  }

  /* The accreditation logos are forced white for the dark screen, which would
     print as nothing at all. Drop the invert so they come out black. */
  .accred img {
    filter: brightness(0) !important;
    opacity: 1 !important;
  }

  .accred {
    gap: 18px 24px;
  }

  .eyebrow,
  .steps li::before,
  .plus li::before,
  .need b {
    color: #5c5c5c !important;
  }

  .hero h1,
  .hero h1 .g {
    color: #161616 !important;
    font-size: 30pt;
  }

  /* Fills disappear; hairlines become real rules that print. */
  .card,
  .callout,
  .qref .row,
  .faq details,
  .contact {
    background: transparent !important;
    box-shadow: none !important;
    border: 1px solid #cfcfcf !important;
    padding: 10px 12px;
  }

  /* Paper declares its own rules rather than recolouring the screen's, because
     the screen has none left — the dividers were dropped there on purpose. On
     paper they are not decoration: background fills do not print, so a rule is
     the only thing left that can say "new section". */
  .block {
    border-bottom: 1px solid #cfcfcf !important;
    padding: 18px 0;
  }

  .block:last-of-type {
    border-bottom: none !important;
  }

  .topbar {
    border-bottom: 1px solid #cfcfcf !important;
  }

  footer {
    border-top: 1px solid #cfcfcf !important;
  }

  .steps li {
    border-top: 1px solid #cfcfcf !important;
  }

  .steps li:first-child {
    border-top: none !important;
  }

  .need {
    border-color: #cfcfcf !important;
  }

  /* Everything prints on one white surface, so the light band's full-bleed
     breakout is meaningless on paper — and 50vw against an @page box would
     shove the content sideways. Neutralise it. */
  .block--light {
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    background: #ffffff !important;
  }

  /* On screen the second band drops its top padding so the pair reads as one
     white field. On paper there is no white field to unify — every section is
     the same surface — so it takes the normal section spacing back. */
  .block--light + .block--light {
    padding-top: 18px !important;
  }

  /* Photography is decorative on paper and costs a lot of ink and pages. The
     briefing's words are what go on the noticeboard. */
  .hero-media,
  .split-media {
    display: none !important;
  }

  /* With the photo gone the split collapses to a single column of copy. */
  .split {
    display: block;
  }

  .hero-in {
    display: block;
    padding: 16px 0 18px;
  }

  /* Bare `.reveal`, not `.js .reveal`, on purpose. It wins on !important either
     way, and unguarded it also covers the no-JS print, where the `js` class was
     never stamped. Belt and braces on the one output nobody can re-render.

     `transition: none` is load-bearing, not tidiness. Setting opacity to 1 on an
     element still carrying a 320ms opacity transition starts an animation rather
     than applying a value — measured at 0.53 mid-flight — and the print snapshot
     can be taken while it is still on its way. Half-faded text on paper. */
  .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* The FAQ answers must survive on paper even if the print JS never runs.
     A closed <details> hides its children through the UA's own mechanism, so
     `display:block` on the body alone is not enough — the content-visibility
     override is what actually reveals it. The beforeprint handler stays as the
     primary path; this is the no-JS fallback. */
  .faq details .body {
    display: block !important;
  }

  .faq details:not([open]) > *:not(summary) {
    display: block !important;
  }

  .faq details::details-content {
    content-visibility: visible !important;
    block-size: auto !important;
  }

  .faq details {
    content-visibility: visible !important;
  }

  /* Spell out the links, since a printed page has nothing to click. */
  .callout a::after,
  footer .meta a::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #4a4a4a;
  }

  .card,
  .callout,
  .qref .row,
  .faq details,
  .contact,
  .steps li,
  .plus li,
  section {
    break-inside: avoid;
  }
}
