@charset "UTF-8";
/* ==========================================================================
   Digital Assure Limited
   Hand-authored stylesheet. No framework, no build step, no generated output.
   Edit this file directly.

   Contents
     1. Fonts
     2. Tokens
     3. Reset
     4. Base typography
     5. Layout
     6. Components
     7. Utilities
     8. Motion and accessibility

   House rules, enforced throughout:
     - No gradients of any kind. Flat fills only.
     - Font weights 400 and 500 only.
     - Orange text on a light surface is always --rust, never --signal.
     - Text on an orange fill is always --on-orange.
   ========================================================================== */


/* 1. Fonts
   ========================================================================== */

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Display face, used by the hero card and nowhere else. Section 4 names Inter
   as the only sans; see BUILD-PROMPT.md amendment A12 for why this one was
   added and why it is confined to the hero. Same two weights as everything
   else — 400 for the sub-line, 500 for the headline. */
@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}


/* 2. Tokens
   ========================================================================== */

:root {
  /* Orange family */
  --signal:       #FF6B1A;   /* fills only: buttons, logo mark, CTA band, active state */
  --ember:        #FF8A3D;   /* secondary emphasis, hover */
  --flare:        #FFA76B;   /* tertiary, tonal progression */
  --rust:         #C2470C;   /* the only orange permitted as text on light. 4.89:1 */
  --on-orange:    #2A0F02;   /* text on orange fills. 6.31:1 on signal */
  --on-orange-2:  #7A2E05;   /* only 3.32:1 on signal — not for text on an orange
                                fill. Fine on light surfaces (9.25:1 on page),
                                where it serves as the link hover colour. */

  /* Light surfaces */
  --page:         #FFFCF8;
  --surface:      #FFFFFF;
  --tint:         #FFF3EA;
  --tint-2:       #FFF0E3;
  --hairline:     #F0E2D4;
  --hairline-2:   #E4D5C6;

  /* Light-surface text */
  --ink:          #10161F;   /* headings. 17.5:1 */
  --body:         #55616F;   /* body copy. 6.17:1 */
  --muted:        #8A7768;   /* 4.17:1 — FAILS AA as text. Decorative and non-text use only.
                                See BUILD-PROMPT.md amendment A2. */
  --label:        #7A6857;   /* small labels. 5.20:1. Added by A2 to replace --muted as text */

  /* Dark surfaces */
  --dark:         #10161F;
  --dark-2:       #1B2836;
  --dark-line:    #232C38;
  --dark-text:    #B8C2CE;   /* 9.93:1 on --dark */
  --dark-muted:   #7A8694;   /* 4.83:1 on --dark */

  /* Accents */
  --steel:        #2D7FD3;
  --alert:        #E24B4A;   /* 3.93:1 against white — use for borders, icons and
                                large text, not as a background for body copy */
  --alert-text:   #B3201F;   /* 6.68:1 on white, 6.09:1 on --alert-tint. The form
                                error text. Same shade A5 gave the dev banner. */
  --alert-tint:   #FDF2F1;   /* flat fill behind an error summary */

  /* Type */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Hero card only. The fallbacks are the humanist faces already on the three
     desktop platforms, so the headline keeps its character during the swap and
     if the download fails. Amendment A12. */
  --font-display: "Source Sans 3", "Lucida Grande", "Lucida Sans Unicode",
                  "Segoe UI", var(--font-sans);

  /* Fluid type. Interpolates between a 390px and a 1280px viewport.
     Values are the desktop -> mobile pairs from section 4 of the brief. */
  --t-hero:   clamp(1.875rem, 1.2725rem + 2.4719vw, 3.25rem);    /* 30 -> 52 */
  --t-h1:     clamp(1.75rem,  1.4214rem + 1.3483vw, 2.5rem);     /* 28 -> 40 */
  --t-h2:     clamp(1.375rem, 1.1559rem + 0.8989vw, 1.875rem);   /* 22 -> 30 */
  --t-h3:     clamp(1.125rem, 1.0428rem + 0.3371vw, 1.3125rem);  /* 18 -> 21 */
  --t-body:   clamp(0.9375rem, 0.8827rem + 0.2247vw, 1.0625rem); /* 15 -> 17 */
  --t-small:  clamp(0.8125rem, 0.7851rem + 0.1124vw, 0.875rem);  /* 13 -> 14 */
  --t-kicker: 0.75rem;                                           /* 12, fixed */

  /* Space */
  --gutter:    1.5rem;
  --container: 75rem;        /* 1200px */
  --radius:    9px;
  --radius-sm: 5px;
  --tap:       44px;         /* minimum touch target */

  /* Section rhythm */
  --section-y: clamp(3.5rem, 2.4rem + 4.5vw, 6rem);
}


/* 3. Reset
   ========================================================================== */

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

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

body,
h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol {
  margin: 0;
}

ul[class], ol[class] {
  list-style: none;
  padding: 0;
}

img, picture, svg, video {
  display: block;
  max-width: 100%;
}

img { height: auto; }

input, button, textarea, select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

table {
  border-collapse: collapse;
  width: 100%;
}

/* Never rely on browser-default weights above 500. */
strong, b, th, optgroup { font-weight: 500; }


/* 4. Base typography
   ========================================================================== */

body {
  background: var(--page);
  color: var(--body);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  color: var(--ink);
  font-weight: 500;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); letter-spacing: -0.02em;  line-height: 1.2; }
h2 { font-size: var(--t-h2); letter-spacing: -0.018em; line-height: 1.25; }
h3 { font-size: var(--t-h3); letter-spacing: -0.015em; line-height: 1.3; }
h4 { font-size: var(--t-body); letter-spacing: -0.01em; line-height: 1.4; }

p { text-wrap: pretty; }

a {
  color: var(--rust);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover { color: var(--on-orange-2); }

small, .small {
  font-size: var(--t-small);
  line-height: 1.6;
}

.kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: 0.18em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--rust);
}

.kicker--muted { color: var(--label); }
.kicker--on-dark { color: var(--dark-muted); }

.lede {
  font-size: clamp(1rem, 0.93rem + 0.29vw, 1.1875rem);
  line-height: 1.6;
  color: var(--body);
  max-width: 62ch;
}

/* Long-form prose blocks */
.prose > * + * { margin-top: 1.1em; }
.prose h2 { margin-top: 2em; }
.prose h3 { margin-top: 1.6em; }
.prose ul { padding-left: 1.15rem; list-style: disc; }
.prose li + li { margin-top: 0.4em; }
.prose { max-width: 68ch; }


/* 5. Layout
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: 52rem; }

.section { padding-block: var(--section-y); }

.section--tint    { background: var(--tint); }
.section--surface { background: var(--surface); }

.section--dark {
  background: var(--dark);
  color: var(--dark-text);
}

.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4 { color: #FFFFFF; }

.section--dark a { color: var(--flare); }

/* A hairline between two same-coloured sections */
.section--ruled { border-top: 1px solid var(--hairline); }

.section-head {
  max-width: 46rem;
  margin-bottom: clamp(2rem, 1.4rem + 2.4vw, 3.25rem);
}

.section-head .kicker { margin-bottom: 0.75rem; }
.section-head p { margin-top: 0.85rem; }

.stack > * + * { margin-top: var(--stack-gap, 1rem); }

.grid {
  display: grid;
  gap: 1.25rem;
}

.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 900px) {
  .grid--3, .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }
}

/* Two-column split used for editorial rows */
.split {
  display: grid;
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
}

@media (max-width: 860px) {
  .split { grid-template-columns: minmax(0, 1fr); }
}


/* 6. Components
   ========================================================================== */

/* --- Skip link ----------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: 0.5rem;
  top: -100%;
  z-index: 200;
  padding: 0.75rem 1.1rem;
  background: var(--ink);
  color: #FFFFFF;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: var(--t-small);
}

.skip-link:focus { top: 0.5rem; color: #FFFFFF; }


/* --- Top bar ------------------------------------------------------------- */

.top-bar {
  background: var(--dark);
  color: var(--dark-text);
  font-size: var(--t-small);
  border-bottom: 1px solid var(--dark-line);
}

.top-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 40px;
  flex-wrap: wrap;
}

.top-bar__group {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

/* Above 640px the pairs are not slides at all — display:contents dissolves the
   grouping so every item lays out in one row of the rail. */
.top-bar__rail {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  min-width: 0;
}

.top-bar__pair { display: contents; }

.top-bar__dots { display: none; }

.top-bar a {
  color: var(--dark-text);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding-block: 0.5rem;
}

.top-bar a:hover { color: #FFFFFF; text-decoration: underline; }

.top-bar svg {
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--dark-muted);
}

.top-bar__hours {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--dark-muted);
}

/* Hiding rules are qualified with .top-bar because `.top-bar a` above is a class
   plus a type selector, which outweighs either class on its own. Written
   unqualified they are silently ignored and the bar wraps instead. */

/* 641 to 1024px: four items in one row starts to crowd, so the second address
   is withdrawn. It reaches the same inbox as the first, so dropping it costs
   the visitor nothing. Below 641px the rotator takes over and needs it back,
   hence the lower bound. */
@media (min-width: 641px) and (max-width: 1024px) {
  .top-bar .top-bar__extra { display: none; }
}

/* Under 640px there is no room for four items, so each pair becomes a slide.
   The rail is a fixed-height stack: slides are taken out of flow so switching
   between them cannot shift the page, which keeps CLS at zero here. */
@media (max-width: 640px) {
  .top-bar__inner {
    justify-content: center;
    gap: 0.5rem;
    flex-wrap: nowrap;
  }

  .top-bar .top-bar__hours-group { display: none; }

  .top-bar__rail {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 40px;
    gap: 0;
    flex-wrap: nowrap;
  }

  .top-bar__pair {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.9rem;
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
  }

  .top-bar__pair[data-current] {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.4s ease, visibility 0s;
  }

  /* Without JavaScript nothing sets data-current, so the first pair is shown
     and the dots are withdrawn — there is no rotation for them to control. */
  html:not(.js) .top-bar__pair:first-child { opacity: 1; visibility: visible; }
  html:not(.js) .top-bar__dots { display: none; }

  /* The icons are decorative and already aria-hidden. Dropping them buys the
     ~40px that lets a number and an address share a 360px row. */
  .top-bar__pair svg { display: none; }

  .top-bar a { font-size: 0.75rem; padding-block: 0.35rem; white-space: nowrap; }

  .top-bar__dots {
    display: flex;
    align-items: center;
    gap: 0.125rem;
    flex: none;
  }

  /* 24px square meets SC 2.5.8; the visible dot inside stays small. */
  .top-bar__dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    background: none;
    border: 0;
  }

  .top-bar__dot::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--dark-muted);
    transition: background-color 0.2s ease;
  }

  .top-bar__dot[aria-current="true"]::before { background: var(--signal); }
}


/* --- Header -------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 72px;
}

/* Logo lockup */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  text-decoration: none;
  flex: none;
}

/* Pulled 8px out of the 24px gutter, so the lockup sits nearer the edge than
   the text below it. Christian asked for it and the artwork wants it: the mark
   carries a baked-in drop shadow (A27), which is transparent pixels down the
   left of the file, so the logo already reads as further right than it is
   measured. 16px of clearance is left at every width. Header only — the footer
   logo heads a grid column and has to stay on that column's left edge.
   Amendment A37. */
.header__inner .logo { margin-left: -0.5rem; }

/* The company's own logo artwork. No orange tile behind it and no radius —
   it is a supplied mark with its own colours and a baked-in drop shadow, not
   an icon in a chip. 34px tall keeps the header column at the width A22
   measured; the file is 3x that so it stays crisp on dense screens. A27. */
.logo__mark {
  width: auto;
  height: 34px;
  flex: none;
}

/* One line, not two. This was a stacked lockup — "Digital Assure" over a small
   mono "LIMITED" — and Christian asked for the name written out whole, on one
   line, as DIGITAL ASSURE Limited. Baselines rather than centres, so the two
   sizes sit on the same line of type instead of floating against each other.
   Amendment A37. */
.logo__text {
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  line-height: 1.15;
}

/* The caps are done here and not in the markup. The DOM keeps "Digital Assure"
   in its own case, so it copies and pastes as a name and a screen reader reads
   it as one rather than spelling out fourteen letters. Tracking flips from
   negative to positive: -0.015em was tightening mixed-case, and caps set solid
   need the opposite. */
.logo__name {
  color: var(--ink);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* "Limited" is the legal suffix, not part of the wordmark, so it keeps its
   sentence case and steps back a size and a shade. No longer mono and no
   longer letterspaced: sitting inline after the name it has to read as a word,
   where stacked underneath it was reading as a tag. --label on --surface is
   5.3:1, so it clears AA at this size. */
.logo__sub {
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--label);
  white-space: nowrap;
}

/* Two nowrap spans cannot wrap out of trouble, so the narrow widths step the
   whole lockup down instead. Measured against the real font: at 320px, the
   narrowest viewport WCAG 1.4.10 asks for, the header holds the lockup, its
   gap and the burger in 272px of inner width with room to spare. */
@media (max-width: 480px) {
  .logo__mark { height: 30px; }
  .logo__name { font-size: 0.875rem; }
  .logo__sub  { font-size: 0.75rem; }
}

@media (max-width: 360px) {
  .logo__mark { height: 28px; }
  .logo__name { font-size: 0.8125rem; }
  .logo__sub  { font-size: 0.6875rem; }
}

/* The header CTA never shrinks and never wraps. It is the one signal button on
   the page and it has to hold its shape at every width the desktop header is
   shown at; the navigation beside it is what gives, not this. Slightly smaller
   than a body button because it sits in a 72px bar rather than in a section.
   Amendment A22. */
.header__cta { flex: none; }

.header__cta .btn {
  font-size: 0.875rem;
  padding-inline: 1rem;
}


/* --- Navigation ---------------------------------------------------------- */

/* One set of markup, two presentations. Above 1199px a mega item opens as a
   container-width card below the header. Below 1200px the same panel becomes a
   second-level slide-over inside a full-height drawer. aria-expanded on the
   toggle drives both, so nothing has to infer state from a class. */

.nav { display: flex; align-items: center; gap: 0.25rem; }

.nav__list {
  display: flex;
  align-items: center;
  gap: 0.125rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__item { position: relative; }

/* 14px and 0.55rem of padding, not the 15px and 0.7rem this started at.
   A18 replaced the six invented menu items with the live site's five, and those
   labels are much longer — "Cloud Computing Training" and "Cyber-Security
   Academy" alone are 446px of the row. Measured out of the font files, the old
   sizing needed 1194px of a 1200px column, so the header CTA wrapped to two
   lines below 1248px and had six pixels of slack above it. This buys 83px.
   Amendment A22. */
.nav__link,
.nav__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: var(--tap);
  padding: 0 0.55rem;
  color: var(--body);
  font-size: 0.875rem;
  text-decoration: none;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}

.nav__link:hover,
.nav__toggle:hover { color: var(--ink); background: var(--tint); }

.nav__link[aria-current="page"] {
  color: var(--ink);
  font-weight: 500;
}

/* Current-section marker. Underline carries the meaning, not colour alone. */
.nav__link[aria-current="page"]::after,
.nav__item--current > .nav__toggle::after {
  content: "";
  position: absolute;
  left: 0.55rem;
  right: 0.55rem;
  bottom: 0.55rem;
  height: 2px;
  background: var(--signal);
  border-radius: 2px;
}

.nav__toggle svg {
  width: 14px;
  height: 14px;
  color: var(--label);
  transition: transform 0.18s ease;
}

.nav__toggle[aria-expanded="true"] svg { transform: rotate(180deg); }


/* --- Mega panel: the desktop card ---------------------------------------- */

/* The card spans the content container rather than its toggle, so it is
   positioned against .header__inner and the mega items opt out of being the
   containing block. */
.header__inner { position: relative; }

.nav__item--mega { position: static; }

.nav__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px -18px rgba(16, 22, 31, 0.22);
  display: none;
}

.nav__toggle[aria-expanded="true"] + .nav__panel { display: block; }

/* Bridges the 6px between the header and the card. The card is a descendant of
   .nav__item, so a pointer inside it never leaves the item — but the gap is
   not, and crossing it would fire pointerleave and start the close timer. The
   strip is transparent, exists only while the card is displayed, and covers
   nothing interactive. Amendment A17. */
.nav__panel::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -7px;
  height: 7px;
}

/* Keyboard fallback when JavaScript has not loaded. nav.js adds .js to the
   root element, which stands this down so aria-expanded stays authoritative. */
html:not(.js) .nav__item:focus-within .nav__panel { display: block; }

/* The drawer header belongs to the mobile presentation only. */
.nav__panel-head { display: none; }

/* Columns, not a grid of groups. The live menu has no groups — it is one
   ordered list of children per top-level item, and A18 mirrors it. CSS columns
   let a panel of three items and a panel of eight both look right without the
   data declaring how many columns it wants. */
.mega { display: block; }

ul.mega__list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 3;
  column-gap: 1.5rem;
}

/* A parent and its third level must not be split across a column boundary. */
.mega__item {
  break-inside: avoid;
  page-break-inside: avoid;   /* Safari still wants the old name */
}

/* The third level, nested under its parent rather than beside it. The rule is
   the visual link back to the item above, since these carry no icon chip. */
ul.mega__sublist {
  list-style: none;
  margin: 0.1rem 0 0.4rem 1.6rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--hairline);
}

.mega__link {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--body);
}

.mega__link:hover { background: var(--tint); }

/* rust on tint-2 measures 4.48:1 — below the text threshold, above the 3:1 for
   non-text. The chip only ever contains an icon. Amendment A5. */
.mega__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 7px;
  background: var(--tint-2);
  color: var(--rust);
}

.mega__link:hover .mega__icon { background: var(--surface); }

.mega__icon svg { width: 17px; height: 17px; }

.mega__text { display: block; min-width: 0; }

.mega__label {
  display: block;
  color: var(--ink);
  font-size: 0.9375rem;
  line-height: 1.35;
}

.mega__link[aria-current="page"] .mega__label { font-weight: 500; }

.mega__note {
  display: block;
  margin-top: 0.1rem;
  font-size: var(--t-small);
  line-height: 1.35;
  color: var(--label);
}

.mega__link--nested {
  padding: 0.3rem 0.6rem;
  color: var(--body);
}

.mega__link--nested .mega__label {
  font-size: var(--t-small);
  color: var(--body);
}

.mega__link--nested[aria-current="page"] .mega__label { color: var(--ink); }

.mega__overview {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline);
  color: var(--rust);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
}

.mega__overview:hover { color: var(--on-orange-2); }

.mega__overview svg { width: 16px; height: 16px; }


/* --- Hamburger ----------------------------------------------------------- */

.nav__burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: var(--surface);
}

.nav__burger svg { width: 20px; height: 20px; display: block; }

.nav__burger-close { display: none; }
.nav__burger[aria-expanded="true"] .nav__burger-open { display: none; }
.nav__burger[aria-expanded="true"] .nav__burger-close { display: block; }

/* The drawer footer belongs to the drawer; above 1199px the header CTA carries it. */
.nav__foot { display: none; }


/* --- Below 1200px: drawer with a slide-over second level ------------------ */

/* This was 900px until amendment A22. The five live menu labels need 718px of
   row at 14px, and with the logo, the CTA and the gaps the desktop header needs
   1111px of column. A 1200px viewport gives it 1152px. Below that it does not
   fit, so below that it is the drawer — which is a better answer at those
   widths than a header that wraps. */
@media (max-width: 1199px) {
  .nav__burger { display: inline-flex; }

  .header__cta { display: none; }

  .nav {
    position: fixed;
    inset: auto 0 0 0;
    top: var(--header-offset, 112px);
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
    background: var(--surface);
    border-top: 1px solid var(--hairline);
  }

  .nav[data-open="true"] { display: flex; }

  /* Without JavaScript the burger cannot open anything, so the navigation
     renders inline and stacked instead, and the burger is withdrawn. Both
     levels fall back to a plain nested list, so every link stays reachable
     with scripting disabled. */
  html:not(.js) .nav__burger { display: none; }

  html:not(.js) .nav {
    position: static;
    display: flex;
  }

  html:not(.js) .header__inner { flex-wrap: wrap; }

  /* Qualified with .nav because the reset's ul[class] carries an attribute
     selector, which outweighs a lone class no matter where it sits. */
  .nav .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0.5rem var(--gutter) 1rem;
    -webkit-overflow-scrolling: touch;
  }

  /* Level one is taken out of the accessibility tree while level two is open.
     visibility inherits, and the open panel asserts it back — so the covered
     links stop being reachable by keyboard or screen reader without needing
     inert or a second state attribute per item. */
  .nav[data-level="2"] .nav__list { visibility: hidden; }

  .nav__link,
  .nav__toggle {
    width: 100%;
    justify-content: space-between;
    padding: 0.75rem 0;
    font-size: 1.0625rem;
    color: var(--ink);
    border-bottom: 1px solid var(--hairline);
    border-radius: 0;
  }

  .nav__link:hover,
  .nav__toggle:hover { background: transparent; }

  /* The chevron points into the next level rather than down, in both states —
     on mobile the toggle never becomes an in-place disclosure. */
  .nav__toggle svg,
  .nav__toggle[aria-expanded="true"] svg { transform: rotate(-90deg); }

  .nav__link[aria-current="page"]::after,
  .nav__item--current > .nav__toggle::after { display: none; }

  .nav__link[aria-current="page"],
  .nav__item--current > .nav__toggle { color: var(--rust); font-weight: 500; }

  /* Level two. Fixed rather than absolute: .nav__list is the scroll container
     and would otherwise clip it, since the clipping ancestor sits between the
     panel and its containing block. Stops short of the drawer footer, so the
     CTA and the phone number stay put across both levels. */
  .nav__panel {
    position: fixed;
    top: var(--header-offset, 112px);
    left: 0;
    right: 0;
    bottom: var(--nav-foot, 8rem);
    display: flex;
    flex-direction: column;
    padding: 0;
    background: var(--surface);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    visibility: hidden;
    transform: translateX(100%);
    /* Hiding waits for the slide-out to finish; revealing happens on the same
       tick as the class change, so the back control is focusable immediately
       and nav.js does not have to wait a frame before moving focus into it. */
    transition: transform 0.26s ease, visibility 0s linear 0.26s;
  }

  .nav__toggle[aria-expanded="true"] + .nav__panel {
    display: flex;
    visibility: visible;
    transform: translateX(0);
    transition: transform 0.26s ease, visibility 0s;
  }

  /* With no JavaScript there is no slide-over to drive, so level two renders
     as a plain indented list under its parent. */
  html:not(.js) .nav__panel {
    position: static;
    visibility: visible;
    transform: none;
    transition: none;
    padding-left: 0.85rem;
  }

  html:not(.js) .nav__panel-head { display: none; }

  /* Source order puts the feature rail before the overview link, which suits
     the desktop card. The drawer wants head, overview, then groups. */
  .nav__panel-head { order: 1; }
  .nav__panel > .mega__overview { order: 2; }
  .nav__panel > .mega { order: 3; }

  .nav__panel-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    padding: 0.25rem var(--gutter);
    border-bottom: 1px solid var(--hairline);
  }

  .nav__back {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: var(--tap);
    padding-right: 0.5rem;
    color: var(--rust);
    font-size: 0.9375rem;
    font-weight: 500;
    background: none;
  }

  .nav__back svg { width: 18px; height: 18px; }

  .nav__panel-title {
    color: var(--ink);
    font-size: 0.9375rem;
    font-weight: 500;
  }

  /* Everything below the panel head scrolls as one column. */
  .mega {
    display: block;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0.75rem var(--gutter) 1.25rem;
    -webkit-overflow-scrolling: touch;
  }

  /* One column in the drawer — the panel is 100vw wide but only ~350px of it. */
  ul.mega__list { columns: 1; }

  .mega__link { padding: 0.6rem 0; gap: 0.75rem; }

  .mega__link:hover { background: transparent; }

  .mega__label { font-size: 1rem; }

  ul.mega__sublist { margin-left: 2.5rem; }

  .mega__link--nested { padding: 0.45rem 0; }

  .mega__link--nested .mega__label { font-size: 0.9375rem; }

  .mega__overview {
    flex: none;
    margin: 0 var(--gutter);
    padding: 0.7rem 0;
    border-top: 0;
    border-bottom: 1px solid var(--hairline);
  }

  /* Drawer footer: primary CTA and the phone number, held below both levels. */
  .nav__foot {
    display: block;
    flex: none;
    padding: 1rem var(--gutter) 1.25rem;
    border-top: 1px solid var(--hairline);
    background: var(--page);
  }

  .nav__foot-tel {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: var(--tap);
    margin-top: 0.25rem;
    color: var(--body);
    font-size: 0.9375rem;
    text-decoration: none;
  }

  .nav__foot-tel svg { width: 17px; height: 17px; color: var(--rust); }

  html:not(.js) .nav__foot { border-top: 0; background: transparent; }
}

/* The two-column fallback this held for 901-1080px is gone with A22: the mega
   card is only ever shown at 1200px and up, where the container is at least
   1152px and three columns of the live menu's long labels have room. */


/* --- Buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0.6875rem 1.25rem;
  border-radius: var(--radius);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  /* A button is one line. A wrapped label turns a 44px control into an 80px
     slab, which reads as a panel rather than a button — see amendment A22. If
     a label will not fit, the label is too long or the space is too small;
     neither is fixed by letting it wrap. */
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.btn svg { width: 17px; height: 17px; flex: none; }

.btn--primary {
  background: var(--signal);
  color: var(--on-orange);
}

.btn--primary:hover {
  background: var(--ember);
  color: var(--on-orange);
}

.btn--secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--hairline-2);
}

.btn--secondary:hover {
  background: var(--tint);
  color: var(--ink);
  border-color: var(--rust);
}

.btn--ghost {
  background: transparent;
  color: var(--rust);
  padding-inline: 0.5rem;
}

.btn--ghost:hover { color: var(--on-orange-2); text-decoration: underline; }

/* Dark button, used on the signal CTA band and on dark sections. */
.btn--dark {
  background: var(--ink);
  color: #FFFFFF;
}

.btn--dark:hover { background: var(--dark-2); color: #FFFFFF; }

.btn--on-dark {
  background: transparent;
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.28);
}

.btn--on-dark:hover { background: rgba(255, 255, 255, 0.08); color: #FFFFFF; }

.btn--full { width: 100%; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}


/* --- Hero slider --------------------------------------------------------- */

/* Nine slides, all of them rendered by PHP. hero.js hides the inactive ones and
   reveals the controls, so with scripting off this degrades to a readable stack
   of nine sections rather than an empty box. Nothing here rotates on its own.

   Contrast. Section 6 asks for text over the photograph on a flat dark overlay
   at 55%. Measured against the brightest patch each photograph puts behind the
   copy, that overlay alone leaves white text at 4.06:1 to 11.52:1 — five of the
   nine below the 4.5:1 section 10 demands of small text. The 55% overlay is kept
   as the art direction across the whole frame, and the copy additionally sits on
   a flat --dark-2 panel at 92%, which lifts the worst slide to 13.63:1 for white
   and 7.56:1 for --dark-text. See BUILD-PROMPT.md amendment A6.

   --dark-muted is deliberately absent below: on the panel it measures 3.68:1 and
   would fail as the kicker. --flare carries the kicker at 7.13:1 instead, which
   is the same choice .section--dark already makes for links. */

.hero {
  position: relative;
  background: var(--dark);
}

.hero__viewport { position: relative; }

.hero__slide {
  position: relative;
  display: grid;
  align-content: center;
  min-height: clamp(30rem, 24rem + 18vw, 38rem);
  padding-block: clamp(3rem, 2rem + 4vw, 5rem);
  overflow: hidden;
}

/* Without JavaScript every slide is present, so they need separating. */
.hero:not([data-ready]) .hero__slide + .hero__slide {
  border-top: 1px solid var(--dark-line);
}

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.hero__media picture,
.hero__img {
  width: 100%;
  height: 100%;
}

.hero__img { object-fit: cover; }

/* Flat fill at 55%. Not a gradient — section 12. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(16, 22, 31, 0.55);
}

.hero__inner { position: relative; }

/* The panel is pulled left so the copy inside it starts on the site's content
   column instead of its own padding-width right of it. Everything down that
   edge then shares one vertical: the logo and nav above, the tab strip below —
   whose first tab's box, and so its active top border, starts in the same
   place — and every section on the page under it.

   The pull is the panel's own padding plus its border, which is exactly what
   puts the text back on the column.

   Pulling by the container gutter instead was tried and rejected. It keeps the
   panel inside the viewport at every width, but it forces horizontal padding
   down to 23px, and the optically aligned button below then sits 3px off the
   panel's own border — one alignment fixed by breaking another. Keeping the
   padding generous costs a left corner instead: below about 1226px the fill
   reaches past the container and .hero__slide clips it, so the panel reads as
   anchored to the screen edge on a small laptop and as a floating card on a
   wide desktop. No visitor sees both, and .hero__slide is already
   overflow: hidden for the photograph, so nothing here can produce a horizontal
   scrollbar. */
.hero__panel {
  --hero-panel-pad: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);

  max-width: 40rem;
  margin-left: calc(-1 * (var(--hero-panel-pad) + 1px));   /* padding plus the border */
  padding: var(--hero-panel-pad);
  background: rgba(27, 40, 54, 0.92);   /* --dark-2 */
  border: 1px solid var(--dark-line);
  border-radius: var(--radius);
}

/* The badge is a separate object, so it keeps its distance — and gains some,
   now that the kicker has closed up under it. Amendment A16. */
.hero__badge { margin-bottom: 1.4rem; }

/* A third of the headline, where the section 4 kicker size of a flat 12px left
   it at under a quarter and reading as a caption under a 52px line. 17px on
   desktop, and floored at 13px so the mobile end never goes under the briefed
   size. Only the hero moves: the 12px kicker is right above the 30px h2s it
   sits on everywhere else on the site.

   Mono, uppercase and 0.18em tracking are all kept, so the kicker still reads
   as the same component — this is a size change, not a restyle. Amendment A15. */
.hero__kicker {
  font-size: clamp(0.8125rem, calc(var(--t-hero) / 3), 1.125rem);
  color: var(--flare);
}

/* Everything in the panel starts on one vertical line. For the badge and the
   button that line is the edge of the box; for the text it is the edge of the
   ink, which is not the same thing as the edge of the text box.

   A glyph carries a left side bearing — built-in space between its origin and
   where it starts drawing — and it scales with the type size. Source Sans 3's
   cap N bears 0.086em, which is 4.5px at 52px, while the mono kicker directly
   above it bears well under 1.5px. Box-aligned, the headline therefore sits
   four pixels inside everything else and reads as indented.

   So the headline and the sub-line hang left by their own first glyph's
   bearing, supplied per slide by da_ink_hang() in partials/hero-slider.php and
   measured out of the font files themselves. The value is in em, so it holds
   across the whole clamp without a second breakpoint. Amendment A14.

   The kicker is left alone: JetBrains Mono bears 0.021em to 0.083em, so at the
   17px it reaches on desktop the worst case is 1.4px — not worth carrying a
   second bearing table for. */
.hero__headline,
.hero__sub { margin-left: var(--ink-hang, 0); }

/* Negative, because the gap between the kicker and the headline is mostly
   leading rather than margin. Half of a 52px line box sits above the cap and
   below the baseline where no ink ever falls, so the briefed 12px margin was
   producing a 30px optical gap — wider than the 27px between two lines of the
   headline itself, which is why a kicker and a headline that are one sentence
   read as two blocks.

   -0.08em of the headline brings it to 14px, about half the headline's own
   line gap, so the pair reads as one unit. In em, so it tracks the fluid size:
   14px at 52px, 9px at 30px, both comfortably clear of collision. The figures
   come from the fonts' own ascender, descender and cap height. Amendment A16. */
.hero__headline {
  margin-top: -0.08em;
  font-family: var(--font-display);
  font-size: var(--t-hero);
  letter-spacing: -0.018em;   /* Source Sans 3 sets tighter than Inter at 52px */
  line-height: 1.18;
  color: #FFFFFF;
}

/* Two thirds of the headline at every viewport width, rather than its own
   clamp — 35px under 52px on desktop, 20px under 30px on mobile. Tied to
   --t-hero so the pair keeps its ratio across the whole scale instead of
   drifting apart at the ends. Leading comes down from 1.6 to 1.35: 1.6 is a
   body-copy figure and reads as a gap at 35px. */
.hero__sub {
  margin-top: 0.9rem;
  font-family: var(--font-display);
  font-size: calc(var(--t-hero) * 2 / 3);
  line-height: 1.35;
  color: var(--dark-text);
  max-width: 30ch;
}

/* The button keeps its distance and gains a little, so that the tightened
   kicker cannot make the panel read as one undifferentiated block. Amendment
   A16. */
.hero__cta { margin-top: 2rem; }

/* Arrows bottom right — section 6. They sit on the same 92% panel as the copy,
   because white directly on the darkened photograph is only 4.03:1 against the
   brightest frame and these are small.

   Offset from .hero__viewport, not .hero. The section wraps the tab strip too,
   so positioning against it put the arrows a clamped 28px above the bottom of
   the strip — on top of it. The briefed 01 / 09 counter is withdrawn with it;
   see BUILD-PROMPT.md amendment A11. */
.hero__controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1rem, 0.6rem + 1.6vw, 1.75rem);
  z-index: 2;
  pointer-events: none;   /* the strip spans the frame; only the buttons take clicks */
}

.hero__controls-inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
}

/* Mobile only. The tab strip becomes this. */
.hero__progress { display: none; }

.hero__arrows {
  display: flex;
  gap: 0.5rem;
  pointer-events: auto;
}

.hero__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  background: rgba(27, 40, 54, 0.92);
  border: 1px solid var(--dark-line);
  border-radius: var(--radius-sm);
  color: #FFFFFF;
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.hero__arrow svg { width: 20px; height: 20px; }

.hero__arrow:hover {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--on-orange);
}

/* The tab strip is the point of the component: it exposes all nine
   propositions to someone who never clicks. Desktop only. */
.hero__tabs {
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}

/* Equal columns for however many slides data/slides.php holds, rather than a
   hardcoded nine. Nine labels fit the 1200px container; a tenth slide, or a
   longer label, scrolls the strip rather than truncating a proposition. The
   floor is the widest current label at its own font size. */
.hero__tablist {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(6.5rem, 1fr);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

.hero__tab {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  width: 100%;
  min-height: var(--tap);
  padding: 0.8rem 0.7rem 0.9rem;
  text-align: left;
  border-top: 3px solid transparent;
  color: var(--body);
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.hero__tab-n {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--label);
}

.hero__tab-label {
  font-size: var(--t-small);
  font-weight: 500;
  line-height: 1.3;
  overflow-wrap: break-word;
}

.hero__tab:hover {
  background: var(--tint);
  border-top-color: var(--hairline-2);
  color: var(--ink);
}

/* Active indicator. signal is a fill here, which section 3 permits for exactly
   this. Colour is not the only carrier: aria-current announces the state, and
   the ink label and rust numeral mark it visually — section 10. */
.hero__tab[aria-current="true"] {
  background: var(--tint);
  border-top-color: var(--signal);
  color: var(--ink);
}

.hero__tab[aria-current="true"] .hero__tab-n { color: var(--rust); }

/* Below 860px the photograph moves above the copy, matching the media query the
   art-directed <picture> switches crops at. Off the photograph the panel has no
   contrast work left to do, so the copy reverts to light-surface colours. */
@media (max-width: 860px) {
  .hero { background: var(--tint); }

  .hero__slide {
    display: block;
    min-height: 0;
    padding-block: 0;
    overflow: visible;
  }

  .hero:not([data-ready]) .hero__slide + .hero__slide {
    border-top: 1px solid var(--hairline);
  }

  .hero__media {
    position: relative;
    inset: auto;
    aspect-ratio: 3 / 2;
  }

  .hero__inner { padding-block: 1.75rem 0; }

  /* No panel here, so there is no padding to pull back out of. The copy already
     starts on the container edge and the pull would drag it into the gutter. */
  .hero__panel {
    max-width: none;
    margin-left: 0;
    padding: 0;
    background: none;
    border: 0;
  }

  .hero__kicker   { color: var(--rust); }
  .hero__headline { color: var(--ink); }
  .hero__sub      { color: var(--body); }

  /* One full-width call to action — section 6. */
  .hero__cta .btn { width: 100%; }

  .hero__controls {
    position: static;
    padding-block: 1.5rem 1.75rem;
    pointer-events: auto;   /* back in flow, so nothing sits under it */
  }

  .hero__progress {
    display: block;
    flex: 1;
    height: 3px;
    background: var(--hairline-2);
    border-radius: 999px;
    overflow: hidden;
  }

  .hero__progress-bar {
    display: block;
    height: 100%;
    background: var(--signal);
    transition: width 0.2s ease;
  }

  .hero__arrow {
    background: var(--surface);
    border-color: var(--hairline-2);
    color: var(--ink);
  }

  .hero__tabs { display: none; }
}


/* --- Card ---------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}

.card--link { text-decoration: none; transition: border-color 0.16s ease; }
.card--link:hover { border-color: var(--hairline-2); }

.card__chip {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-sm);
  background: var(--tint-2);
  color: var(--rust);
  margin-bottom: 1.1rem;
  flex: none;
}

.card__chip svg { width: 21px; height: 21px; }

.card__title {
  font-size: var(--t-h3);
  letter-spacing: -0.015em;
  line-height: 1.3;
  margin-bottom: 0.5rem;
}

.card--link:hover .card__title { color: var(--rust); }

.card__body {
  color: var(--body);
  font-size: var(--t-body);
  margin: 0;
}

.card__foot {
  margin-top: auto;
  padding-top: 1.1rem;
}

.card__more {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--rust);
  font-size: var(--t-small);
  font-weight: 500;
}

.card__more svg { width: 15px; height: 15px; }


/* --- Taxonomy tags ------------------------------------------------------- */

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.tag {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--hairline-2);
  border-radius: 4px;
  background: var(--page);
  color: var(--label);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}


/* --- Badge pill ---------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  background: var(--surface);
  color: var(--rust);
  border-radius: 999px;
  font-size: var(--t-small);
  font-weight: 500;
}

.badge svg { width: 15px; height: 15px; flex: none; }


/* --- Stat block ---------------------------------------------------------- */

.stat {
  display: flex;
  flex-direction: column;
}

.stat__figure {
  color: var(--signal);        /* permitted: display size, not body text */
  font-size: clamp(2.75rem, 1.9rem + 3.6vw, 4.5rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}

.stat__label {
  color: var(--ink);
  font-size: var(--t-body);
  margin-top: 0.75rem;
  max-width: 30ch;
}

.stat__source {
  display: block;
  color: var(--label);
  font-size: var(--t-small);
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hairline);
  max-width: 34ch;
}

.stat__source cite { font-style: normal; }

/* The figure sits on dark in some placements. */
.section--dark .stat__label { color: #FFFFFF; }
.section--dark .stat__source { color: var(--dark-muted); border-top-color: var(--dark-line); }


/* --- Process steps ------------------------------------------------------- */

.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
}

@media (max-width: 900px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .steps { grid-template-columns: minmax(0, 1fr); } }

.step {
  padding-top: 1.1rem;
  border-top: 3px solid var(--hairline-2);
}

/* Tonal progression across the four steps. */
.step:nth-child(1) { border-top-color: var(--rust); }
.step:nth-child(2) { border-top-color: var(--signal); }
.step:nth-child(3) { border-top-color: var(--ember); }
.step:nth-child(4) { border-top-color: var(--flare); }

.step__n {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--label);
  margin-bottom: 0.6rem;
}

.step__title {
  font-size: var(--t-h3);
  letter-spacing: -0.015em;
  margin-bottom: 0.4rem;
}

.step__body { margin: 0; font-size: var(--t-body); }


/* --- CTA band ------------------------------------------------------------ */

.cta-band {
  background: var(--signal);
  color: var(--on-orange);
  padding-block: clamp(2.75rem, 2rem + 3.2vw, 4.25rem);
}

.cta-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.5rem, 1rem + 2.4vw, 3rem);
  flex-wrap: wrap;
}

.cta-band__text { max-width: 46rem; }

.cta-band h2 {
  color: var(--on-orange);
  font-size: var(--t-h2);
}

/* --on-orange-2 on --signal is only 3.32:1, so it cannot carry body text here.
   It stays legitimate on light surfaces (9.25:1 on --page), which is where the
   link hover states use it. See BUILD-PROMPT.md amendment A5. */
.cta-band p {
  color: var(--on-orange);
  margin-top: 0.6rem;
  max-width: 54ch;
}

/* The ">>>" that points at the button. Letterspaced, because three chevrons set
   solid read as one blot rather than as an arrow, and pushed off the last word
   so it does not look like punctuation on the sentence. Amendment A39.

   It is withdrawn below 860px. .cta-band__inner wraps when the text and the
   button stop fitting side by side, and once the button has dropped underneath,
   an arrow pointing right is pointing at nothing. 860px is where that wrap
   happens for the longest copy the band carries; it errs early, since a missing
   arrow costs nothing and one aimed at the margin looks like a mistake. */
.cta-band__point {
  margin-left: 0.4em;
  letter-spacing: 0.12em;
  white-space: nowrap;
}

@media (max-width: 860px) {
  .cta-band__point { display: none; }
}

.cta-band .btn--dark { flex: none; }


/* --- Breadcrumbs --------------------------------------------------------- */

/* The separator is a pseudo-element rather than a character in the markup. The
   ordered list already carries the relationship, so the slash is decoration —
   which is also why it can use --muted, barred as text by amendment A2 but fine
   here at 3.92:1 on --tint for a non-text mark.

   Text in the trail is --label (4.88:1 on --tint) and the current page is --ink,
   so the position is not carried by colour alone: the last item is also the only
   one that is not a link, and it is the only one with aria-current. */
.crumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem 0.5rem;
  font-size: var(--t-small);
}

.crumbs__item { color: var(--label); }

.crumbs__item + .crumbs__item::before {
  content: "/";
  margin-right: 0.5rem;
  color: var(--muted);
}

.crumbs a { color: var(--label); text-decoration-color: var(--hairline-2); }
.crumbs a:hover { color: var(--rust); }
.crumbs [aria-current="page"] { color: var(--ink); }


/* --- Interior page header ------------------------------------------------ */

/* The band every page below the homepage opens with. Tint rather than a
   photograph: the hero is the homepage's, and repeating it here would cost the
   LCP on eleven service pages for no editorial gain. */
.page-head {
  background: var(--tint);
  border-bottom: 1px solid var(--hairline);
  padding-block: clamp(2rem, 1.4rem + 2.4vw, 3.25rem) clamp(2.5rem, 1.8rem + 2.8vw, 3.75rem);
}

.page-head .crumbs { margin-bottom: 1.5rem; }

.page-head__title {
  margin-top: 0.75rem;
  max-width: 24ch;
}

.page-head__tags { margin: 1.1rem 0 0; }

.page-head__lede { margin-top: 1.1rem; }

.page-head__actions { margin-top: 1.75rem; }

/* Header with a representative image (A29). Two columns from 861px up — the
   copy keeps its measure on the left, the photo sits to the right at its 3:2
   crop. Below that the photo drops beneath the copy. A page with no image keeps
   the plain single column: .page-head__inner is an ordinary block until the
   modifier turns it into a grid, so the other pages are untouched. */
.page-head--media .page-head__inner {
  display: grid;
  gap: clamp(1.75rem, 1rem + 3vw, 3.5rem);
  align-items: center;
}

@media (min-width: 861px) {
  .page-head--media .page-head__inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
}

.page-head__media { margin: 0; }

.page-head__img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
}

/* An image set inside body prose — /about/ carries one (A29). The picture's
   own <img> keeps the border and radius from .page-head__img; the figure only
   owns the vertical rhythm around it. */
.prose-media {
  margin: 2.25rem 0;
}

/* A body photo that sits in a .split column beside its copy rather than in the
   flow above it. The vertical margin goes: the grid gap already spaces it, and
   the margin would only push it out of line with the text it belongs to.
   Amendment A44. */
.prose-media--split { margin: 0; }


/* --- Course e-flyers ----------------------------------------------------- */

/* A topic list and the flyer that illustrates it, side by side above 900px and
   stacked below. The list takes the free space and the flyer holds a fixed
   420px, because the artwork has a fixed amount of detail in it — letting it
   grow with the column would only make a JPEG bigger, not clearer. Amendment
   A43. */
.syllabus {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  margin: 1.5rem 0 2.25rem;
}

/* The basis figures have to add up to less than the column they sit in or the
   flyer wraps underneath and the whole point is lost. .prose is capped at 68ch,
   which is 686px in Inter, so 240 + 24 of gap + 340 = 604 leaves room to spare.
   Measured, not guessed: the first version of this used 20rem and 420px, came
   to 780px, and stacked on every screen there is. */
.syllabus__topics {
  flex: 1 1 240px;
  min-width: 0;
}

/* The list's own top margin is dropped so it starts level with the flyer. */
.syllabus__topics > :first-child { margin-top: 0; }

.flyer {
  flex: 0 1 340px;
  margin: 0;
}

/* .prose is left-aligned in the container, not centred, so on a wide screen
   there is dead space to its right. The syllabus reaches into it — 240px, which
   is well inside the 366px spare at 1100px and the 466px spare at 1200px — so
   the flyer and the list both get room instead of the list being squeezed to
   pay for the flyer. Only this block breaks out; the reading measure of the
   paragraphs above and below is untouched. */
@media (min-width: 1100px) {
  .syllabus { width: calc(100% + 240px); }
}

.flyer__link {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  /* The artwork is busy at every edge and sits on a white page, so it needs a
     boundary of its own or it bleeds into the column beside it. */
  border: 1px solid var(--hairline-2);
}

.flyer__link:hover { border-color: var(--rust); }

.flyer__link:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.flyer__img {
  display: block;
  width: 100%;
  height: auto;
}

.flyer__cap {
  margin-top: 0.5rem;
  font-size: var(--t-small);
  color: var(--label);
}

@media (max-width: 720px) {
  /* Below this the two columns are both too narrow to be worth having, so the
     flyer drops under the list. Held to 380px and centred, because run to the
     full width of a phone it would be 3:2 taller than the screen and become a
     page of its own to scroll past. */
  .flyer {
    flex: 1 1 100%;
    max-width: 380px;
    margin-inline: auto;
  }
}


/* --- Prose lists --------------------------------------------------------- */

/* Ticked list. The mark is decorative and aria-hidden — the list semantics
   already carry the structure, and colour is not the only signal.

   Qualified with the element, not left as a lone class. These lists live inside
   .prose, and `.prose ul` above sets disc bullets and a left indent at the same
   specificity — a bare `.checklist` would lose to it. Amendment A9 records the
   same trap catching .top-bar__secondary and .nav__list. */
ul.checklist {
  display: grid;
  gap: 0.7rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.checklist__item {
  display: grid;
  grid-template-columns: 1.35rem minmax(0, 1fr);
  gap: 0.65rem;
  align-items: start;
}

.checklist__mark {
  display: grid;
  place-items: center;
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.2rem;
  border-radius: 4px;
  background: var(--tint-2);
  color: var(--rust);
}

.checklist__mark svg { width: 14px; height: 14px; }

/* Definition list. Two columns on desktop, stacked below 700px — the terms are
   short labels and reading them beside the description is the point. */
.terms {
  display: grid;
  gap: 1.1rem;
  margin: 0;
}

.terms__row {
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  gap: 0.35rem 1.5rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--hairline);
}

.terms__row:first-child { padding-top: 0; border-top: 0; }

.terms__term {
  color: var(--ink);
  font-weight: 500;
}

.terms__desc { margin: 0; }

@media (max-width: 700px) {
  .terms__row { grid-template-columns: minmax(0, 1fr); }
}


/* --- Accordion ----------------------------------------------------------- */

/* The folded form of .terms, built on <details>. Amendment A44. */
.accordion {
  border-top: 1px solid var(--hairline);
}

.accordion__item { border-bottom: 1px solid var(--hairline); }

/* Both of these are needed to clear the native disclosure triangle: Safari
   wants the vendor pseudo-element, everyone else honours list-style. The
   chevron in the markup replaces it, on the other side of the row. */
.accordion__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--tap);
  padding: 0.75rem 0;
  color: var(--ink);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}

.accordion__head::-webkit-details-marker { display: none; }

.accordion__head:hover { color: var(--rust); }

.accordion__head:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}

.accordion__mark {
  flex: none;
  display: inline-flex;
  color: var(--label);
  transition: transform 0.18s ease;
}

.accordion__mark svg { width: 18px; height: 18px; }

.accordion__item[open] > .accordion__head { color: var(--rust); }
.accordion__item[open] > .accordion__head .accordion__mark {
  transform: rotate(180deg);
  color: var(--rust);
}

/* The paragraph inside carries the indent, not the row, so a closed accordion
   is a flush column of module names. */
.accordion__body { padding: 0 0 1.1rem; }
.accordion__body p { margin: 0; }


/* --- Partner note -------------------------------------------------------- */

.partners {
  margin-top: 2.5rem;
  padding: 1.35rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}

/* Element-qualified for the same reason as ul.checklist above. */
ul.partners__list {
  list-style: none;
  margin: 0.9rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.1rem;
}

.partners__name {
  margin: 0;
  color: var(--ink);
  font-weight: 500;
}

.partners__note {
  margin: 0.3rem 0 0;
  color: var(--body);
}


/* --- Enquiry form -------------------------------------------------------- */

/* Narrower than the prose column. A form field wider than about 44rem is hard
   to scan back along, and the two-up rows would stretch a name field across
   half the screen. */
.form-wrap {
  max-width: 44rem;
  margin-inline: auto;
}

.form-wrap__title { margin-bottom: 0.75rem; }

.form {
  margin-top: 2rem;
  display: grid;
  gap: 1.25rem;
}

/* Two-up above 640px, stacked below. Fields inside a row share the width
   evenly rather than sizing to their content. */
.form__row {
  display: grid;
  gap: 1.25rem;
}

@media (min-width: 40em) {
  .form__row { grid-template-columns: 1fr 1fr; }
}

.field { display: grid; gap: 0.4rem; }

.field__label {
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--ink);
}

.field__optional {
  font-weight: 400;
  color: var(--label);
}

.field__hint {
  margin: 0;
  font-size: var(--t-small);
  color: var(--label);
  line-height: 1.5;
}

.field__control {
  width: 100%;
  min-height: var(--tap);
  padding: 0.6rem 0.75rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
  font-size: var(--t-body);
  line-height: 1.5;
}

textarea.field__control {
  min-height: 9rem;
  resize: vertical;
  line-height: 1.6;
}

/* The native arrow is left alone. Removing it would mean drawing one, and a
   select that does not look like a select is a worse trade than a control that
   varies slightly by platform. */
select.field__control { padding-block: 0.55rem; }

.field__control::placeholder { color: var(--label); }

.field__control:hover { border-color: var(--muted); }

/* Error state. The border carries it visually, the message carries it in text,
   and aria-invalid carries it to assistive technology — never colour alone. */
.field__control--error,
.field__control--error:hover { border-color: var(--alert); }

.field__error {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--alert-text);
}

.field__error-mark svg {
  width: 16px;
  height: 16px;
  margin-top: 0.15em;
}

/* Honeypot. Off-screen, out of the tab order and out of the accessibility
   tree. Not display:none — some bots skip hidden fields, and a field they skip
   catches nothing. */
.form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: 0.5rem;
}

.form__legal {
  flex: 1 1 18rem;
  margin: 0;
  font-size: var(--t-small);
  color: var(--label);
  line-height: 1.5;
}

/* --- Form status panels --- */

.form-alert {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 1.25rem;
  margin-bottom: 1.5rem;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
  background: var(--tint);
}

.form-alert p { margin: 0.5rem 0 0; }
.form-alert p:first-of-type { margin-top: 0.35rem; }

.form-alert__title {
  margin: 0;
  font-size: var(--t-h3);
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.form-alert__mark svg {
  width: 22px;
  height: 22px;
  margin-top: 0.1em;
}

/* Success keeps to the brand palette. There is no green in section 3 and this
   is not the place to invent one — the tick and the heading carry the meaning,
   so the fill does not have to. */
.form-alert--ok .form-alert__mark { color: var(--rust); }

.form-alert--error {
  background: var(--alert-tint);
  border-color: var(--alert);
}

.form-alert--error .form-alert__mark { color: var(--alert-text); }
.form-alert--error .form-alert__title { color: var(--alert-text); }

.form-alert__list {
  margin: 0.6rem 0 0;
  padding-left: 1.1rem;
}

.form-alert__list li { margin-top: 0.3rem; }

.form-alert__list a { color: var(--alert-text); }


/* --- Self-assessment ----------------------------------------------------- */

/* "Is my company at risk?": three stages in one form — intro, sixty-seven
   checkboxes in fourteen fieldsets, and the result. Amendments A31 and A32.

   The six band colours are the one place this file adds a palette. Each pair is
   a text colour and the flat tint behind it, and every pair clears 4.5:1 on
   white, on --page and on its own tint — the same bar A2 and A5 set. The tints
   are flat fills; there are no gradients here either. Amber reuses --rust
   rather than inventing a seventh orange, on a slightly lighter tint than
   --tint-2 because --rust on --tint-2 measures 4.48:1 and misses AA.

   Both the result panel and the scoring table below it are toned, so the pairs
   are set on whichever element carries the band and read from there. */
.sa-band--green,  .sa-scale__row--green  { --band-text: #1A6B3D; --band-tint: #EDF6F1; }
.sa-band--lime,   .sa-scale__row--lime   { --band-text: #4A6410; --band-tint: #F4F7E9; }
.sa-band--yellow, .sa-scale__row--yellow { --band-text: #7A5600; --band-tint: #FBF4E2; }
.sa-band--amber,  .sa-scale__row--amber  { --band-text: var(--rust); --band-tint: #FFF5EC; }
.sa-band--red,    .sa-scale__row--red    { --band-text: var(--alert-text); --band-tint: var(--alert-tint); }
.sa-band--deep,   .sa-scale__row--deep   { --band-text: #8E1512; --band-tint: #FAEBEA; }

/* The stages. JavaScript shows one at a time; without it the intro and the
   questionnaire are both simply visible, one after the other, which is what the
   margin is for. `hidden` is the toggle, so it has to win. */
.sa-stage[hidden] { display: none; }

.sa-stage + .sa-stage { margin-top: 3rem; }


/* Intro */
.sa-facts__heading,
.sa-directions__heading {
  font-size: var(--t-h3);
  font-weight: 500;
  color: var(--ink);
}

.sa-facts__heading { margin: 2rem 0 1rem; }

.sa-directions {
  margin-top: 2rem;
  padding: 1.5rem;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
  background: var(--tint);
}

/* The reset strips markers from any list carrying a class. Here they earn their
   place: five separate instructions, read before starting rather than in order. */
.sa-directions__list {
  margin: 0.75rem 0 0;
  padding-left: 1.15rem;
  list-style: disc;
  color: var(--body);
}

.sa-directions__list li { margin-top: 0.5rem; }

.sa-directions__list strong { color: var(--ink); }

.sa-directions__gauge {
  margin: 1.25rem 0 0;
  color: var(--ink);
}

.sa-start { margin-top: 2rem; }


/* Running score. Sticks to the top of the viewport through a long form; the
   sticky is dropped under reduced motion, where a panel that slides over the
   questions as you scroll is the kind of movement the setting is asking to
   avoid. Hidden in the markup and revealed by self-assessment.js. */
.sa-live {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin-bottom: 2rem;
  padding: 0.75rem 1.25rem;
  background: var(--tint);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
}

.sa-live[hidden] { display: none; }

.sa-live__label {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label);
}

.sa-live__score {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.sa-live__of,
.sa-band__of {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--label);
}

.sa-live__count {
  margin: 0 0 0 auto;
  font-size: 0.875rem;
  color: var(--body);
  font-variant-numeric: tabular-nums;
}


/* The sections */
.sa-sections {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sa-sections > li + li { margin-top: 1.5rem; }

.sa-section {
  margin: 0;
  padding: 1.5rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
}

/* A legend cannot be a flex container in every engine, so the number and the
   title are inline-block and the spacing is margin rather than gap. */
.sa-section__legend {
  padding: 0;
  margin-bottom: 0.25rem;
}

.sa-section__n {
  display: inline-block;
  min-width: 1.75rem;
  margin-right: 0.5rem;
  padding: 0.125rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--signal);
  color: var(--on-orange);
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.sa-section__title {
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--ink);
}

.sa-questions {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

.sa-question {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: start;
  padding: 0.6rem 0;
  border-top: 1px solid var(--hairline);
}

.sa-question:first-child { border-top: 0; }

/* 22px rather than the 44px tap target the rest of the site holds to: the label
   beside it is part of the same control and carries the target, so the pair
   comfortably clears 44px in both directions. */
.sa-question__box {
  width: 22px;
  height: 22px;
  margin: 0.1rem 0 0;
  accent-color: var(--signal);
  flex: none;
  cursor: pointer;
}

.sa-question__label {
  color: var(--body);
  line-height: 1.55;
  cursor: pointer;
}

.sa-question__box:checked + .sa-question__label { color: var(--ink); }

.sa-section__tally {
  margin: 1rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hairline-2);
  text-align: right;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--label);
  font-variant-numeric: tabular-nums;
}

.sa-section__tally[hidden] { display: none; }

.sa-section__tally[data-sa-complete] { color: #1A6B3D; }

.sa-finish { margin-top: 2rem; }

.sa-finish__note {
  margin: 0.75rem 0 0;
  font-size: var(--t-small);
  color: var(--label);
}


/* The result */
.sa-band {
  padding: 1.75rem;
  border-left: 4px solid var(--band-text);
  border-radius: var(--radius);
  background: var(--band-tint);
}

.sa-band__label {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--band-text);
}

.sa-band__score {
  margin: 0.25rem 0 0;
  font-size: clamp(2.5rem, 7vw, 3.5rem);
  font-weight: 500;
  line-height: 1.05;
  color: var(--band-text);
  font-variant-numeric: tabular-nums;
}

.sa-band__name {
  margin: 0.25rem 0 0;
  font-size: 1.125rem;
  font-weight: 500;
  color: var(--band-text);
}

.sa-band__sum {
  margin: 0.25rem 0 0;
  font-size: 0.9375rem;
  color: var(--body);
}

.sa-band__message {
  margin: 1rem 0 0;
  max-width: 62ch;
  color: var(--ink);
}

/* The blocks below the band. Spaced explicitly rather than with a child
   combinator, because the first child of the result stage is the screen-reader
   status paragraph and it is out of flow. */
.sa-band + .form-alert { margin-top: 1.5rem; }

.sa-breakdown,
.sa-scale,
.sa-offer,
.sa-next { margin-top: 2.5rem; }


/* Section by section, weakest first. The bar is decorative — the count beside
   it carries the value — so it is a flat fill in the band tones and nothing
   depends on being able to see it. */
.sa-breakdown__heading {
  font-size: var(--t-h3);
  font-weight: 500;
  color: var(--ink);
}

.sa-breakdown__lede {
  margin: 0.5rem 0 0;
  max-width: 62ch;
  color: var(--body);
}

.sa-breakdown__lede strong { color: var(--ink); }

.sa-bars {
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hairline);
}

.sa-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 9rem auto;
  gap: 1rem;
  align-items: center;
  padding: 0.7rem 0.25rem;
  border-bottom: 1px solid var(--hairline);
}

.sa-bar__title { color: var(--body); }

.sa-bar__track {
  display: block;
  height: 8px;
  border-radius: 999px;
  background: var(--hairline);
  overflow: hidden;
}

.sa-bar__fill {
  display: block;
  height: 100%;
  background: var(--label);
}

.sa-bar__fill--green { background: #1A6B3D; }
.sa-bar__fill--amber { background: var(--rust); }
.sa-bar__fill--deep  { background: #8E1512; }

.sa-bar__count {
  font-weight: 500;
  color: var(--label);
  font-variant-numeric: tabular-nums;
}


/* The scoring table — the PDF's scoring page, whole. */
.sa-scale__heading {
  font-size: var(--t-h3);
  font-weight: 500;
  color: var(--ink);
}

.sa-scale__formula {
  margin: 0.5rem 0 0;
  max-width: 62ch;
  color: var(--body);
}

.sa-scale__formula-note {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--t-small);
  color: var(--label);
}

.sa-scale__table { margin-top: 1.25rem; }

.sa-scale__table thead th {
  padding: 0 0.75rem 0.5rem;
  border-bottom: 1px solid var(--hairline-2);
  text-align: left;
  font-size: var(--t-kicker);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label);
}

.sa-scale__table tbody th,
.sa-scale__table tbody td {
  padding: 0.85rem 0.75rem;
  border-bottom: 1px solid var(--hairline);
  text-align: left;
  vertical-align: top;
}

.sa-scale__score {
  white-space: nowrap;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* The row a visitor landed in. The tint alone would be a colour-only
   distinction, so the row also names itself in words. */
.sa-scale__row--current { background: var(--band-tint); }

.sa-scale__you {
  display: block;
  margin-top: 0.35rem;
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--band-text);
}

.sa-scale__dot {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  background: var(--band-text);
}

.sa-scale__name { color: var(--ink); }

.sa-scale__band { white-space: nowrap; }

.sa-scale__comment { color: var(--body); }

.sa-scale__caveat {
  margin: 1rem 0 0;
  max-width: 62ch;
  font-size: var(--t-small);
  color: var(--body);
}


/* Where the report goes */
.sa-offer {
  padding: 1.5rem;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius);
  background: var(--tint);
}

.sa-offer__heading {
  font-size: var(--t-h3);
  font-weight: 500;
  color: var(--ink);
}

.sa-offer__note {
  margin: 0.5rem 0 1.25rem;
  max-width: 62ch;
  font-size: 0.9375rem;
  color: var(--body);
}

/* The enquiry form gets its row rhythm from `.form`; this one is a panel inside
   a larger form, so the rows space themselves. */
.sa-offer .form-alert { margin-bottom: 1.25rem; }

.sa-offer .form__row + .form__row { margin-top: 1.25rem; }

.sa-offer .form__actions { margin-top: 1.5rem; }

/* Two ways to finish, side by side above 480px and stacked below it. */
.sa-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

@media (max-width: 480px) {
  .sa-actions { display: grid; }
}


/* What to do about it */
.sa-next {
  padding-top: 2rem;
  border-top: 1px solid var(--hairline-2);
}

.sa-next__heading {
  font-size: var(--t-h3);
  font-weight: 500;
  color: var(--ink);
}

.sa-next p {
  margin: 0.5rem 0 0;
  max-width: 62ch;
  color: var(--body);
}

.sa-next__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.sa-next__urgent {
  font-size: var(--t-small);
  color: var(--body);
}


@media (max-width: 700px) {
  /* Three columns of prose do not fit. The header row is dropped rather than
     scrolled sideways, and each band becomes a block that reads top to bottom;
     the row header still names the score, so nothing is lost with it gone. */
  .sa-scale__table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .sa-scale__table,
  .sa-scale__table tbody,
  .sa-scale__row,
  .sa-scale__table tbody th,
  .sa-scale__table tbody td { display: block; }

  .sa-scale__row {
    padding: 1rem 0.75rem;
    border-bottom: 1px solid var(--hairline);
  }

  .sa-scale__table tbody th,
  .sa-scale__table tbody td {
    padding: 0;
    border-bottom: 0;
  }

  .sa-scale__band,
  .sa-scale__comment { margin-top: 0.35rem; }

  .sa-scale__you { display: inline-block; margin: 0 0 0 0.6rem; }
}

@media (max-width: 560px) {
  .sa-section,
  .sa-directions,
  .sa-offer { padding: 1.25rem 1rem; }

  .sa-live__count { margin-left: 0; width: 100%; }

  /* The bar loses its track before it loses the count. */
  .sa-bar { grid-template-columns: minmax(0, 1fr) auto; }

  .sa-bar__track { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .sa-live { position: static; }
}


/* --- Client strip -------------------------------------------------------- */

/* A slider with no JavaScript in it. The row of logos is rendered twice inside
   one track; the track travels left by exactly half its own width and starts
   over, so at the instant the first copy leaves the frame the second is sitting
   where the first began. The join never shows and the loop never resets
   visibly. See client_strip() in partials/components.php.

   Three things make the seam exact. The track is width:max-content, so its -50%
   is measured against the two rows rather than against the rail. Each row
   carries half the logo gap as inside padding, so the space where the copies
   meet is one gap wide, the same as every other space in the row. And each row
   is held to the width of the window, so the pair always spans twice the frame
   — see the note on .clients__row. Amendment A35. */

.clients {
  --clients-gap: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);

  background: var(--surface);
  border-top: 1px solid var(--hairline);
  padding-block: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.clients__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: clamp(1.25rem, 1rem + 1vw, 1.75rem);
}

.clients__kicker { margin: 0; }

/* The rail is full-bleed, not held inside the container. A logo should leave at
   the edge of the window; stopping it at the gutter would read as a bug. */
.clients__rail { overflow: hidden; }

.clients__track {
  display: flex;
  width: max-content;
  animation: clients-drift 45s linear infinite;
}

.clients__rail:hover .clients__track { animation-play-state: paused; }

/* min-width is what keeps two copies enough. The trick only holds while one row
   is at least as wide as the window: eight logos measure about 1500px, so on a
   1920px monitor the track would run out and trail an empty stretch behind it.
   Holding each row to the viewport width means the pair always spans twice the
   frame, whatever the screen. space-around then shares the slack out evenly,
   and it shares it out in a way that keeps the join invisible — each item takes
   half a share at the row's edge, so the two halves that meet across the seam
   add up to exactly the space between any other pair of logos. */
.clients__row {
  display: flex;
  align-items: center;
  justify-content: space-around;
  gap: var(--clients-gap);
  min-width: 100vw;
  margin: 0;
  padding: 0 calc(var(--clients-gap) / 2);
  list-style: none;
}

.clients__item { flex: 0 0 auto; }

/* Height is set rather than capped. A cap only ever shrinks, and Chaka's vector
   is 124x33 in its own coordinates — it would have sat at 33px next to five
   logos at 48. Setting the height levels them; the width cap then pulls back
   the two wordmarks that are four times as wide as they are tall, so a
   horizontal name does not dwarf a stacked lockup beside it. When the cap bites
   the height follows it down, which is what keeps every logo in proportion.

   The rasters are 96px tall, twice what is drawn here, so they stay sharp at
   2x. */
.clients__logo {
  --clients-h: 48px;

  display: block;
  width: auto;
  height: var(--clients-h);
  max-width: 170px;
}

@keyframes clients-drift {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* The pause control. WCAG 2.2 SC 2.2.2 wants a way to stop anything that moves
   on its own for more than five seconds, and hovering is not one a keyboard can
   reach. This is a real checkbox behind its label, so it needs no script: it is
   in the tab order, space toggles it, and it works on the first paint. */

.clients__pause {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--tap);
  padding-inline: 0.75rem;
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
  font-size: var(--t-small);
  color: var(--label);
  cursor: pointer;
}

.clients__pause:hover { border-color: var(--rust); color: var(--rust); }

.clients__glyph { width: 15px; height: 15px; }
.clients__glyph--play { display: none; }

/* Checked means paused. The chip takes the site's tint fill so the state is not
   carried by the glyph alone, and the glyph flips to a play triangle so it is
   obvious that clicking again starts it again. */
.clients__switch:checked ~ .clients__rail .clients__track { animation-play-state: paused; }

.clients__switch:checked ~ .clients__head .clients__pause {
  background: var(--tint);
  border-color: var(--rust);
  color: var(--rust);
}

.clients__switch:checked ~ .clients__head .clients__glyph--pause { display: none; }
.clients__switch:checked ~ .clients__head .clients__glyph--play  { display: block; }

/* The input itself is visually hidden, so its focus ring has to be drawn on the
   label the visitor can actually see. */
.clients__switch:focus-visible ~ .clients__head .clients__pause {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--ink);
  border-radius: var(--radius-sm);
}

@media (max-width: 480px) {
  .clients__logo { --clients-h: 38px; max-width: 130px; }
}

@media (prefers-reduced-motion: reduce) {
  /* The blanket rule in section 8 forces animation-duration to 0.001ms with
     !important, which would not stop this — it would finish it, snapping the
     track to its -50% end state. Cancelling by name is what actually stops it:
     with no animation-name there is nothing to run, whatever the duration says.
     `animation: none` would not work here either, since the shorthand's own
     duration loses to that !important. */
  .clients__track { animation-name: none; }

  /* Nothing is moving, so the strip becomes an ordinary row the visitor scrolls
     themselves. The second copy would only be six logos of noise to scroll
     past, and the pause control has nothing left to pause. */
  .clients__rail { overflow-x: auto; }
  .clients__row[aria-hidden="true"] { display: none; }
  .clients__pause { display: none; }
}


/* --- Footer -------------------------------------------------------------- */

.footer {
  background: var(--dark);
  color: var(--dark-text);
  padding-block: clamp(3rem, 2.2rem + 3.2vw, 4.5rem) 0;
}

.footer__cols {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: clamp(2rem, 1.2rem + 3vw, 3.5rem);
}

@media (max-width: 900px) { .footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .footer__cols { grid-template-columns: minmax(0, 1fr); } }

.footer__title {
  color: #FFFFFF;
  font-family: var(--font-mono);
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 1.1rem;
}

.footer__list { list-style: none; margin: 0; padding: 0; }

.footer__list li + li { margin-top: 0.15rem; }

.footer__list a,
.footer__contact a {
  display: inline-block;
  color: var(--dark-text);
  font-size: var(--t-small);
  text-decoration: none;
  padding-block: 0.35rem;
}

.footer__list a:hover,
.footer__contact a:hover { color: #FFFFFF; text-decoration: underline; }

.footer__blurb {
  color: var(--dark-muted);
  font-size: var(--t-small);
  margin-top: 1rem;
  max-width: 32ch;
}

.footer .logo__name { color: #FFFFFF; }
.footer .logo__sub  { color: var(--dark-muted); }

.footer__contact {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--t-small);
}

.footer__contact li {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding-block: 0.2rem;
}

.footer__contact svg {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 0.55rem;
  color: var(--dark-muted);
}

.footer__contact span { padding-block: 0.35rem; }

.footer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: clamp(2.5rem, 2rem + 2vw, 3.5rem);
  padding-block: 1.5rem;
  border-top: 1px solid var(--dark-line);
  color: var(--dark-muted);
  font-size: var(--t-small);
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer__legal a {
  color: var(--dark-muted);
  text-decoration: none;
  padding-block: 0.35rem;
  display: inline-block;
}

.footer__legal a:hover { color: #FFFFFF; text-decoration: underline; }


/* --- Placeholder marker -------------------------------------------------- */
/* Phase 1 scaffolding. Every instance is removed by Phase 4. */

.placeholder {
  border: 1px dashed var(--hairline-2);
  border-radius: var(--radius);
  padding: clamp(2rem, 1.4rem + 2.4vw, 3.5rem) 1.5rem;
  text-align: center;
  color: var(--label);
  background: var(--surface);
}

.placeholder__tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rust);
  margin-bottom: 0.6rem;
}


/* --- Development notice -------------------------------------------------- */
/* Rendered by head.php when page metadata is missing or out of spec.
   Never appears in production. */

/* White on --alert is 3.93:1, short of AA. This banner is development-only and
   never ships, but it is held to the same bar as everything else. The darker
   red gives 6.68:1. See BUILD-PROMPT.md amendment A5. */
.dev-notice {
  position: relative;
  z-index: 500;
  background: #B3201F;
  color: #FFFFFF;
  padding: 0.85rem var(--gutter);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.6;
}

.dev-notice ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.dev-notice strong { font-weight: 500; }


/* 7. Utilities
   ========================================================================== */

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

.text-center { text-align: center; }
.mx-auto    { margin-inline: auto; }
.mt-0       { margin-top: 0; }
.measure    { max-width: 62ch; }
.flow-lg    { --stack-gap: 1.5rem; }

[hidden] { display: none !important; }


/* 8. Motion and accessibility
   ========================================================================== */

/* Focus ring.
   The brief specifies a 2px signal ring at 2px offset. Signal on white is only
   2.85:1, below the 3:1 that WCAG 2.2 SC 1.4.11 requires. The box-shadow fills
   the 2px offset gap with ink, so on light surfaces the ink ring carries the
   contrast (17.5:1) and on dark surfaces the signal ring does (6.29:1).
   See BUILD-PROMPT.md amendment A3. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--ink);
  border-radius: var(--radius-sm);
}

.section--dark :where(a, button, input, select, textarea, [tabindex]):focus-visible,
.footer :where(a, button, [tabindex]):focus-visible,
.top-bar :where(a, button, [tabindex]):focus-visible,
.cta-band :where(a, button, [tabindex]):focus-visible {
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.75);
}

/* --------------------------------------------------------------------------
   The multiple-choice awareness tests (A52)
   --------------------------------------------------------------------------
   One question per page load, so none of this needs a script and none of it
   hides anything. The radio is visually replaced by its label, which is the
   whole tap target — 44px minimum, per --tap.
   -------------------------------------------------------------------------- */

.quiz-notice {
  padding: 1.5rem;
  background: var(--tint);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
}

.quiz-notice__title { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 500; }
.quiz-notice p { margin: 0; }

.quiz-start__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  margin: 0 0 1.25rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--hairline);
  color: var(--label);
  font-size: var(--t-small);
}

.quiz-start__facts strong { color: var(--ink); font-weight: 500; }

.quiz-form { margin-top: 2rem; }

/* --- Progress ------------------------------------------------------------ */

.quiz-progress { margin: 0 0 1.5rem; }

.quiz-progress__label {
  display: block;
  margin-bottom: 0.5rem;
  color: var(--label);
  font-size: var(--t-small);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.quiz-progress__track {
  display: block;
  height: 4px;
  background: var(--hairline);
  border-radius: 2px;
  overflow: hidden;
}

.quiz-progress__fill {
  display: block;
  height: 100%;
  background: var(--signal);
  transition: width 0.2s ease;
}

/* --- The question -------------------------------------------------------- */

.quiz-q { margin: 0; padding: 0; border: 0; }

.quiz-q__text {
  padding: 0;
  margin-bottom: 1.25rem;
  color: var(--ink);
  font-size: clamp(1.125rem, 1.05rem + 0.35vw, 1.375rem);
  font-weight: 500;
  line-height: 1.35;
}

.quiz-options { margin: 0; padding: 0; list-style: none; }
.quiz-option + .quiz-option { margin-top: 0.5rem; }

/* Off-screen rather than display:none, so it stays focusable and keeps the
   arrow-key group behaviour a radio set is supposed to have. */
.quiz-option__input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.quiz-option__label {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-height: var(--tap);
  padding: 0.75rem 1rem;
  background: var(--surface);
  border: 1px solid var(--hairline-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.quiz-option__label:hover { border-color: var(--rust); }

.quiz-option__letter {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  background: var(--tint);
  border-radius: var(--radius-sm);
  color: var(--label);
  font-size: var(--t-small);
  font-weight: 500;
}

.quiz-option__input:checked + .quiz-option__label {
  border-color: var(--rust);
  background: var(--tint);
}

/* --signal, not --rust. The rule at the top of this file is that text on an
   orange fill is always --on-orange, and --on-orange was calibrated against
   --signal: it is 6.31:1 there but only 3.60:1 on --rust, which fails AA. The
   border stays --rust; the fill that carries text is --signal. */
.quiz-option__input:checked + .quiz-option__label .quiz-option__letter {
  background: var(--signal);
  color: var(--on-orange);
}

.quiz-option__input:focus-visible + .quiz-option__label {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.quiz-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

/* --- The result ---------------------------------------------------------- */

.quiz-score {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding: 1.5rem;
  border: 1px solid;
  border-radius: var(--radius-sm);
  background: var(--band-tint);
  border-color: var(--band-text);
  color: var(--band-text);
}

.quiz-score--pass { --band-text: #1A6B3D; --band-tint: #EDF6F1; }
.quiz-score--fail { --band-text: var(--alert-text); --band-tint: var(--alert-tint); }

.quiz-score__figure { margin: 0; line-height: 1; }
.quiz-score__figure strong { font-size: clamp(2.5rem, 2rem + 2vw, 3.5rem); font-weight: 500; }
.quiz-score__unit { font-size: 1.5rem; font-weight: 400; }
.quiz-score__detail { margin: 0; }

.quiz-result__sent {
  margin: 1rem 0 2.5rem;
  color: var(--label);
  font-size: var(--t-small);
}

.quiz-review { margin: 1.5rem 0 0; padding: 0; list-style: none; }
.quiz-review__item + .quiz-review__item { margin-top: 1.25rem; }

.quiz-review__item {
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--hairline-2);
  border-left: 3px solid var(--hairline-2);
  border-radius: var(--radius-sm);
}

.quiz-review__item--ok { border-left-color: #1A6B3D; }
.quiz-review__item--no { border-left-color: var(--alert-text); }

.quiz-review__mark {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.5rem;
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.quiz-review__mark svg { width: 18px; height: 18px; }
.quiz-review__item--ok .quiz-review__mark { color: #1A6B3D; }
.quiz-review__item--no .quiz-review__mark { color: var(--alert-text); }

.quiz-review__q { margin: 0 0 0.875rem; color: var(--ink); font-weight: 500; }

.quiz-review__options { margin: 0; padding: 0; list-style: none; }

.quiz-review__option {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0;
  color: var(--label);
}

.quiz-review__option.is-answer { color: var(--ink); }

.quiz-review__option.is-answer .quiz-option__letter {
  background: #1A6B3D;
  color: #FFFFFF;
}

.quiz-review__option.is-chosen .quiz-option__letter {
  background: var(--alert-text);
  color: #FFFFFF;
}

.quiz-review__tag {
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--tint);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.quiz-review__why {
  margin: 0.875rem 0 0;
  padding-top: 0.875rem;
  border-top: 1px solid var(--hairline);
  color: var(--label);
  font-size: var(--t-small);
}

.quiz-again {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.5rem;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .top-bar, .header, .cta-band, .skip-link, .clients { display: none; }
  body { background: #FFFFFF; color: #000000; }
}
