/* ==========================================================================
   Nextage Group — site stylesheet

   Built on the Nextage design system. Every value here is a var(--*) token
   from nextage-tokens.css, which is loaded FIRST and is the single source of
   truth. Do not hardcode a hex, an off-scale px, or a radius outside 4/8/14.
   See docs/DESIGN_SYSTEM.md and its checklist before editing.

   Surfaces: pages alternate --color-surface-page (white) and
   --color-surface-sunken (gray-50). Blue is an accent, never a page wash —
   the one exception is the home hero and the footer, which carry the
   letterhead's blue band, once each.
   ========================================================================== */

/* --- 0. Local token extension -------------------------------------------
   The design system states: "No status color scale exists in the brand. If you
   need success/error, keep them functional and quiet (a green/red used only for
   form validation), and don't promote them to brand colors."

   The contact form needs exactly that, and nextage-tokens.css has no token for
   it. Rather than hardcode a hex in a component — which the system forbids —
   the two values are declared once here, scoped to form validation only, and
   named so they can never be mistaken for brand colours. If an error colour is
   ever added to nextage-tokens.css, delete this block and point at that instead.
   Contrast on white: 5.9:1, clears the 4.5:1 body floor. */
:root {
  --color-form-error: #b3261e;
  --color-form-error-tint: #fdf3f2;
}

/* --- 0b. Contrast correction (design-system defect) ----------------------
   MEASURED, not assumed: --blue-500 (#3784d7) is only **3.86:1 on white**.
   WCAG AA needs 4.5:1 for normal text, so as shipped the design system fails
   its own stated rule ("Contrast floor: 4.5:1 for body text") in two places:

     * `--color-link` is blue-500, so any body-size link fails.
     * `.btn-primary` is white text on blue-500 — 3.86:1 — so the primary
       button label fails too.

   --blue-600 (#2b6bb3) measures 5.45:1 and clears it comfortably while still
   reading as the brand blue. Blue-500 stays exactly where it is legitimate:
   accent bars, borders, focus rings and large type, which only need 3:1.

   These overrides live here rather than in nextage-tokens.css so that file
   stays byte-identical to what Claude Design generated. **The real fix is at
   source** — see the launch checklist. If the token file is regenerated with a
   compliant link colour, delete this block. */
:root {
  --color-link: var(--blue-600);
  --color-link-hover: var(--blue-700);

  /* Second defect, found 7 Sep and fixed properly 8 Sep. --color-text-muted is
     slate-500 (#6b7280), which measures:

       on white (--color-surface-page)    4.83:1  barely passes
       on gray-50 (--color-surface-sunken) 4.47:1  FAILS
       on gray-100 (--color-surface-panel) 4.32:1  FAILS

     So muted text fails AA on two of the three surfaces the system defines for
     it, including form hints and the pending tags. #565e6b measures 6.54, 6.05
     and 5.85 on the same three, and still reads as secondary next to
     slate-700 body copy.

     This was first patched on 7 Sep as a separate --color-text-muted-aa token
     used only by .crumbs, which fixed breadcrumbs and left the other eleven
     usages broken. Overriding the token itself is the correct fix: every
     consumer inherits it and no component has to opt in. */
  --color-text-muted: #565e6b;
}

/* Third instance of the same defect, found 16 Sep 2026 by sweeping every text
   node on eight pages against its real composited background, rather than by
   reading the stylesheet. Blue-500 was still being used as a TEXT colour in
   four places at body size or smaller, where it measures 3.86:1 on white and
   3.56:1 on the sunken ground and fails the 4.5:1 floor both times:

     .nav a[aria-current="page"]   the current page in the header, every page
     .nav a:hover, .drawer a:hover, .crumbs a:hover
     .pillar-n                     the numerals in the reasons list
     .card-num                     the numerals on the packages page

   .blk-n, the numeral on the service tiles, was already on blue-600, so these
   four were the stragglers rather than a deliberate choice. Corrected at the
   component rather than by moving --color-brand-primary, because blue-500 is
   still correct for accent bars, borders and focus rings, which only need 3:1.
   The pillars case became visible when that section moved onto the sunken
   ground on 16 Sep; it was already failing on white before the move. */

/* --- 1. Base ------------------------------------------------------------- */
/* nextage-tokens.css already sets box-sizing, body, h1-h4, a and :focus-visible. */

/* The token file sets 15px. The approved concept uses 16px, and the design
   system's own note allows 15-17px for the web. */
body { font-size: 16px; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--space-8);
}

img, svg, video { max-width: 100%; height: auto; display: block; }
hr { border: 0; border-top: 1px solid var(--color-border); margin: 0; }

p { margin: 0 0 var(--space-4); }
p:last-child { margin-bottom: 0; }

h1, h2, h3, h4 { margin: 0 0 var(--space-3); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--color-brand-deep); color: var(--color-text-on-brand);
  padding: var(--space-3) var(--space-5);
  font-weight: var(--weight-semibold);
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus { left: 0; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- 2. Type ------------------------------------------------------------- */
/* Display sizes come from an A4 print document. The system permits scaling the
   hero up for web while keeping the ratios and holding body at 15–17px. */
/* Matched to the approved Field/Signal concept, measured at 1280px: the concept
   renders h1 at 72px and this was rendering 56px, which flattened the hierarchy
   and is why the built site read as a different design. The design system says
   hero type "may go larger (clamp up to ~64px)"; 72px honours that intent, and
   the h1:h2 ratio now lands at 2.25 instead of 1.75. */
h1 { font-size: clamp(36px, 5.6vw, 72px); letter-spacing: -0.03em; }
h2 { font-size: clamp(24px, 3.2vw, var(--text-2xl)); letter-spacing: -0.02em; }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }

.lead {
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--color-text-body);
  font-weight: var(--weight-regular);
}

.eyebrow {
  display: block;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0 0 var(--space-2);
}

/* A trailing qualifying paragraph: the caveat that follows a list. Quieter
   than .lead, still full reading size, so it reads as part of the argument
   rather than as small print nobody is meant to notice. */
.note {
  max-width: 68ch;
  margin-top: var(--space-5);
  color: var(--color-text-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
}

.prose { max-width: 68ch; }
.prose p + p { margin-top: var(--space-4); }

/* The definitional answer paragraph. AEO load-bearing — this is the block a
   model quotes, so it is styled distinctly enough that nobody deletes it as
   decoration. Uses the system's blue accent bar, turned vertical. */
.answer {
  border-left: 3px solid var(--color-brand-primary);
  padding: var(--space-1) 0 var(--space-1) var(--space-4);
  margin: 0 0 var(--space-6);
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--color-text-heading);
  max-width: 68ch;
}

/* --- 3. Layout ----------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}
@media (min-width: 48rem) { .wrap { padding-inline: var(--space-7); } }
.wrap-narrow { max-width: 860px; }

section { padding-block: var(--space-7); }
@media (min-width: 48rem) { section { padding-block: var(--space-9); } }
section.tight { padding-block: var(--space-7); }

/* Two sections on the same ground, 16 Sep 2026.
   Every section carries 96px top and bottom at desktop, which is right when the
   ground changes and wrong when it does not: where two white sections meet the
   reader gets 192px of nothing and no signal that a new idea started. On the
   home page that happened three times in a row and read as one flat field.
   Trim the shared boundary to 64px, which is still on the 4px scale. Sections
   that already opt into .tight are left alone, and any boundary where the
   ground actually changes keeps its full separation. */
@media (min-width: 48rem) {
  section:not(.sunken):not(.on-brand):not(.tight):has(+ section:not(.sunken):not(.on-brand)) {
    padding-block-end: var(--space-8);
  }
  section:not(.sunken):not(.on-brand) + section:not(.sunken):not(.on-brand):not(.tight) {
    padding-block-start: var(--space-8);
  }
}

/* Sunken band. Replaces the old charcoal sections — the system alternates
   white and gray-50 rather than light and dark. */
.sunken { background: var(--color-surface-sunken); }

.grid { display: grid; gap: var(--space-4); }
@media (min-width: 48rem) { .grid { gap: var(--space-5); } }
.g-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }

.split { display: grid; gap: var(--space-6); align-items: start; }
@media (min-width: 60rem) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
  .split.lopsided { grid-template-columns: 5fr 7fr; }
}

/* --- 4. Section heading + the accent bar --------------------------------- */
/* The short blue bar is the design system's signature device. Applied to
   section heads only — not to every heading on the page. */
.section-head { max-width: 46rem; margin-bottom: var(--space-6); }
@media (min-width: 48rem) { .section-head { margin-bottom: var(--space-7); } }

.section-head::before,
.accent-bar::before {
  content: "";
  display: block;
  width: 36px; height: 4px;
  background: var(--color-brand-primary);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-4);
}
.section-head .eyebrow { margin-top: 0; }

/* --- 5. Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}

/* Fill is blue-600, not blue-500: white on blue-500 measures 3.86:1 and fails
   AA for the label. Blue-600 is 5.45:1. Hover goes deeper still. */
.btn-primary {
  background: var(--blue-600);
  color: var(--color-text-on-brand);
  border-color: var(--blue-600);
}
.btn-primary:hover {
  background: var(--blue-700);
  border-color: var(--blue-700);
  color: var(--color-text-on-brand);
}

.btn-secondary {
  background: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text-heading);
}
.btn-secondary:hover {
  background: var(--color-surface-sunken);
  border-color: var(--color-brand-primary);
  color: var(--color-text-heading);
}

/* On a blue ground */
.on-brand .btn-secondary {
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--color-text-on-brand);
}
.on-brand .btn-secondary:hover {
  background: var(--color-text-on-brand);
  color: var(--color-brand-deep);
  border-color: var(--color-text-on-brand);
}
.on-brand .btn-primary {
  background: var(--color-text-on-brand);
  color: var(--color-brand-deep);
  border-color: var(--color-text-on-brand);
}
.on-brand .btn-primary:hover {
  background: var(--blue-100);
  border-color: var(--blue-100);
  color: var(--color-brand-deep);
}

.btn-row {
  display: flex; flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* Text link with a trailing arrow. Not an icon set — a single UI affordance. */
.arrow {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  text-decoration: none;
  color: var(--color-link);
}
.arrow:hover { color: var(--color-link-hover); text-decoration: underline; }
.arrow svg { flex: none; transition: transform var(--dur-base) var(--ease-out); }
.arrow:hover svg { transform: translateX(3px); }
.on-brand .arrow { color: var(--color-text-on-brand); }

/* --- 6. Header ----------------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 100;
  background: var(--color-surface-page);
  border-bottom: 1px solid var(--color-border);
}
.header-in {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 64px;
}

.brand {
  display: inline-flex; align-items: center;
  margin-right: auto;
  text-decoration: none;
  line-height: 0;
}
/* The lockup source is 507x150. Height-constrained so it never outgrows the
   64px header; width follows the intrinsic ratio. Clear space around the
   lockup is at least the mark's height, per the design system. */
/* Sized against the nav, not against the header box. The lockup is 507x150 and
   the "nextage" wordmark is roughly 57% of that height, so a 32px logo renders
   the wordmark at ~18px against 15px nav links — a logo that reads as primary
   without shouting. At 46px it rendered ~26px and overpowered everything.
   The "GROUP" line is a texture at this size, not readable copy; that is
   inherent to the lockup at header scale and is how the old site handled it
   too. Do not fix it by scaling the logo up. */
.brand img { height: 28px; width: auto; }
@media (min-width: 48rem) { .brand img { height: 32px; } }

/* Footer lockup — white knockout on the blue band. Larger than the header
   because there is no nav competing with it. */
.brand-img { height: 30px; width: auto; margin-bottom: var(--space-3); }

.nav { display: none; gap: var(--space-1); align-items: center; }
@media (min-width: 64rem) { .nav { display: flex; } }
.nav a {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  text-decoration: none;
  color: var(--color-text-body);
  border-radius: var(--radius-sm);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav a:hover { color: var(--blue-600); }
.nav a[aria-current="page"] {
  color: var(--blue-600);
  font-weight: var(--weight-semibold);
}

.header-cta { display: none; }
@media (min-width: 48rem) { .header-cta { display: inline-flex; } }

/* Burger */
.burger {
  display: inline-flex; flex-direction: column; justify-content: center;
  gap: 5px;
  width: 44px; height: 44px; padding: 0 var(--space-3);
  background: transparent;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
@media (min-width: 64rem) { .burger { display: none; } }
.burger span {
  display: block; height: 2px;
  background: var(--color-text-heading);
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Off-canvas */
.drawer {
  position: fixed; inset: 0; z-index: 99;
  background: var(--color-surface-page);
  padding: var(--space-9) var(--space-5) var(--space-6);
  display: flex; flex-direction: column;
  overflow-y: auto;
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur-base) var(--ease-out), visibility var(--dur-base);
}
.drawer.is-open { opacity: 1; visibility: visible; }
.drawer a {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  text-decoration: none;
  color: var(--color-text-heading);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
  min-height: 44px;
  display: flex; align-items: center;
}
.drawer a:hover { color: var(--blue-600); }
.drawer .drawer-foot {
  margin-top: auto; padding-top: var(--space-6);
  font-size: var(--text-sm); color: var(--color-text-muted);
}
.drawer .drawer-foot a {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  border: 0; padding: var(--space-2) 0;
  color: var(--color-link);
}
body.nav-open { overflow: hidden; }

/* --- 7. Hero ------------------------------------------------------------- */
/* The letterhead's diagonal-cut blue band. Allowed ONCE per page — it is the
   home hero, and nothing else on the site may repeat it. No photo backgrounds:
   the system rules them out. */
.hero {
  position: relative;
  background: var(--color-brand-deep);
  color: var(--color-text-on-brand);
  /* Concept proportions on desktop; tighter on phones, where 96px of empty
     colour above the headline is just scrolling. */
  padding-block: var(--space-7) var(--space-8);
  overflow: hidden;
}
@media (min-width: 48rem) {
  .hero { padding-block: var(--space-9) calc(var(--space-9) + var(--space-6)); }
}
.hero::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px; height: 56px;
  background: var(--color-surface-page);
  clip-path: polygon(0 100%, 100% 0, 100% 100%);
}
.hero h1, .hero h2, .hero h3 { color: var(--color-text-on-brand); }
.hero .lead {
  color: var(--color-text-on-brand);
  max-width: 46ch;
  margin-top: var(--space-4);
}
.hero .eyebrow { color: var(--blue-100); }
.hero .wrap { position: relative; z-index: 1; }

/* The short promise line. Competitor research shows this market carries its
   memorable claim as a separate third line ("one call, one contact, zero
   headaches"), not in the headline. Sized between the lead and the creds so it
   reads as a statement rather than more body copy. */
/* Browsers are allowed to break a line after a hyphen, which was splitting
   "multi-site" across two lines in the headline. Wrap hyphenated compounds that
   must stay whole in this. */
.nb { white-space: nowrap; }

.promise {
  margin: var(--space-5) 0 0;
  font-family: var(--font-display);
  font-size: clamp(18px, 2vw, 22px);
  font-weight: var(--weight-bold);
  letter-spacing: -0.01em;
  color: #fff;
}

.hero-sub {
  display: flex; flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.28);
  font-size: var(--text-sm);
  color: var(--color-text-on-brand);
}


/* Phone hero height. Measured 7 Sep 2026 at 375x812: the hero ran 1280px, so a
   phone user scrolled 1.6 screens of blue before reaching any content. The lead
   was the main culprit, set at --text-lg (19px) and running to six lines. These
   rules only apply below the tablet breakpoint; the desktop proportions that
   were matched to the Signal concept are untouched. */
@media (max-width: 47.99rem) {
  .hero { padding-block: var(--space-6) var(--space-7); }
  .hero .lead { font-size: 17px; margin-top: var(--space-3); }
  .hero .promise { margin-top: var(--space-4); }
  .hero-split { gap: var(--space-6); }
  .hero-sub {
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    gap: var(--space-1) var(--space-5);
  }
}

/* --- 7b. Hero screen unit -----------------------------------------------
   Carried over from the Signal concept. A simulated Nextage screen beside the
   headline, portrait 3:4 like the totems they actually operate in centres.

   The message, promise and CTAs beside it never move. Only this panel rotates,
   and what it rotates is a demonstration of the work rather than the sales
   message. Rotating headlines test 25 to 40 per cent worse than static ones,
   so this split is deliberate, not decorative.

   WCAG 2.2.2 applies: it has a pause control, stops on hover and on keyboard
   focus, and does not auto advance at all under prefers-reduced-motion. */
.hero-split { display: grid; gap: var(--space-7); align-items: center; }
@media (min-width: 60rem) {
  .hero-split { grid-template-columns: 1.15fr 0.85fr; gap: var(--space-8); }
}
.hero-copy { min-width: 0; }
/* The split hero gives the headline about 600px rather than the full 1200px,
   so the 72px full-width size wrapped "National multi-site retail services."
   onto three lines with an awkward rag. 58px lands it on two. */
@media (min-width: 60rem) {
  .hero-split h1 { font-size: clamp(40px, 4.4vw, 58px); }
}

.unit { width: 100%; max-width: 300px; margin: 0 auto; }
@media (min-width: 60rem) { .unit { max-width: 340px; } }

.bezel {
  position: relative;
  background: #0b0f14;
  border-radius: 18px;
  padding: 14px;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.7),
              0 0 0 1px rgba(255, 255, 255, 0.08) inset;
}
.panel {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: linear-gradient(165deg, #16202b 0%, #0d141b 70%);
  display: grid; place-items: center;
}
.dwell {
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: rgba(255, 255, 255, 0.14); z-index: 3;
}
.dwell b {
  display: block; height: 100%; width: 0;
  background: var(--color-brand-primary);
  transition: width 0.18s linear;
}
.msg {
  position: absolute; inset: 0;
  display: grid; place-items: center; text-align: center;
  padding: var(--space-6) var(--space-5);
  opacity: 0; transform: scale(0.985);
  transition: opacity 0.45s var(--ease-out), transform 0.6s var(--ease-out);
}
.msg.on { opacity: 1; transform: none; }
/* Full width so the picture's 62% is measured against the screen, not the text:
   otherwise it changed size from slide to slide as the headline length changed. */
.msg > div { display: flex; flex-direction: column; align-items: center; width: 100%; }
/* Slide picture, 17 Sep 2026. Framed, never a background, and capped at the
   supplied 200px so it stays sharp. */
.msg-img {
  display: block;
  width: 62%; max-width: 12.5rem; height: auto;
  aspect-ratio: 10 / 7; object-fit: cover;
  border-radius: var(--radius-md);
  margin-bottom: var(--space-5);
}
.msg-lab {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--blue-300);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-3);
}
.msg-h {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: var(--weight-extrabold);
  color: #fff;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0;
}
.msg-p {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.7);
  max-width: 26ch;
}
.stand { width: 34%; height: 14px; margin: 0 auto; background: #0b0f14; border-radius: 0 0 6px 6px; }
.stand2 { width: 52%; height: 8px; margin: 0 auto; background: #0b0f14; border-radius: 3px; opacity: 0.75; }

.unit-ctrls { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-4); }
.dots { display: flex; gap: var(--space-2); margin-right: auto; }
.dots button {
  width: 26px; height: 4px; padding: 0; border: 0;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
}
.dots button.on { background: #fff; }   /* white, not blue: the ground is blue */
.dots button:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }
.pause {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.45);
  color: #fff;
  border-radius: var(--radius-sm);
  min-height: 36px;
  padding: 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.pause:hover { border-color: #fff; background: rgba(255, 255, 255, 0.12); }

@media (prefers-reduced-motion: reduce) {
  .msg { transition: none; }
}

/* Interior page header — sunken, no blue wash. */
.pagehero {
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
  padding-block: var(--space-7);
}
@media (min-width: 48rem) { .pagehero { padding-block: var(--space-8); } }
.pagehero .lead { max-width: 52ch; margin-top: var(--space-4); }

.crumbs {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  display: flex; flex-wrap: wrap; gap: var(--space-2);
}
.crumbs a { color: var(--color-text-muted); text-decoration: none; }

/* Retail media now uses the blue hero, so its breadcrumbs sit on a dark ground.
   Same trap as .lead had: the default muted grey is near invisible there. */
.hero .crumbs, .hero .crumbs a { color: rgba(255, 255, 255, 0.75); }
.hero .crumbs a:hover { color: #fff; }
.hero .crumbs span[aria-hidden] { color: rgba(255, 255, 255, 0.4); }
.crumbs a:hover { color: var(--blue-600); text-decoration: underline; }
.crumbs span[aria-hidden] { color: var(--color-border-strong); }

/* --- 8. Cards ------------------------------------------------------------ */
.card {
  display: flex; flex-direction: column;
  background: var(--color-surface-page);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  text-decoration: none;
  color: var(--color-text-body);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
a.card:hover, a.card:focus-visible {
  border-color: var(--color-brand-primary);
  box-shadow: var(--shadow-card);
}
.card h3 { font-size: var(--text-lg); margin-bottom: var(--space-2); }
.card p { font-size: var(--text-base); color: var(--color-text-body); }
.card .arrow { margin-top: auto; padding-top: var(--space-4); align-self: flex-start; }

.card-num {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--blue-600);
  margin-bottom: var(--space-3);
}

/* The "not sure which line" tile that closes the services grid. */
.card-cta {
  background: var(--color-brand-primary-tint);
  border-color: var(--blue-100);
}
.card-cta h3 { color: var(--color-brand-deep); }

/* Problem strip */
.problem {
  border-left: 3px solid var(--color-brand-primary);
  padding-left: var(--space-4);
}
.problem h3 { font-size: var(--text-lg); margin-bottom: var(--space-1); }
.problem p { font-size: var(--text-base); color: var(--color-text-body); margin: 0; }

/* Pillars — a rule-separated list, so an odd count never strands a card. */
.pillars { display: grid; gap: 0; border-top: 1px solid var(--color-border); }
@media (min-width: 52rem) {
  .pillars { grid-template-columns: 1fr 1fr; column-gap: var(--space-8); }
}
.pillar {
  display: flex; gap: var(--space-4); align-items: flex-start;
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--color-border);
}
.pillar-n {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--blue-600);
  padding-top: 3px; flex: none; min-width: 24px;
}
.pillar h3 { font-size: var(--text-lg); margin-bottom: var(--space-1); }
.pillar p { font-size: var(--text-base); color: var(--color-text-body); margin: 0; }


/* --- 8b. Service blocks (the Field treatment) ---------------------------
   Adopted 7 Sep 2026 when Scott chose the Field concept. Edge to edge, hairline
   gaps rather than gutters, and the whole tile inverts to the deep brand colour
   on hover so the affordance is unmistakable. Used only for the service grid;
   everything else keeps the quieter .card. */
.blocks {
  display: grid;
  gap: 1px;
  margin-top: var(--space-6);
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
@media (min-width: 52rem) { .blocks { grid-template-columns: repeat(3, 1fr); } }

.blk {
  background: var(--color-surface-page);
  padding: var(--space-6) var(--space-5);
  min-height: 15rem;
  display: flex; flex-direction: column;
  text-decoration: none;
  color: var(--color-text-body);
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.blk-n {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  color: var(--blue-600);
  margin-bottom: auto;
}
.blk h3 { font-size: var(--text-xl); margin: var(--space-6) 0 var(--space-2); }
.blk p { font-size: var(--text-base); margin: 0; }
.blk-go {
  margin-top: var(--space-4);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
  color: var(--blue-600);
}
.sunken .blk { background: var(--color-surface-sunken); }
.sunken .blocks { background: var(--color-border-strong); border-color: var(--color-border-strong); }

/* The "not sure which line" tile keeps its tint but joins the block grid. */
.blk.blk-cta { background: var(--color-brand-primary-tint); }
.blk.blk-cta h3 { color: var(--color-brand-deep); }
/* With ten lines the grid leaves two empty cells, so the ask tile spans both. */
@media (min-width: 52rem) {
  .blk-cta-wide { grid-column: span 2; }
  .blk-cta-full { grid-column: 1 / -1; min-height: 0; }
}

/* Hover and focus invert the tile. Declared LAST in this block on purpose,
   16 Sep 2026: these selectors have the same specificity as `.sunken .blk` and
   `.blk.blk-cta`, so when they sat above those rules the ground rule won the
   background while the hover still won the text colour. On the home page, where
   the grid sits on the sunken band, hovering a tile turned its text white on
   near white and it could not be read. Order is the fix; do not move these up. */
.blk:hover, .blk:focus-visible {
  background: var(--color-brand-deep);
  color: var(--color-text-on-brand);
}
.blk:hover h3, .blk:focus-visible h3,
.blk:hover .blk-n, .blk:focus-visible .blk-n,
.blk:hover .blk-go, .blk:focus-visible .blk-go { color: var(--color-text-on-brand); }

/* --- 8b2. Guides, 16 Sep 2026 -------------------------------------------
   Long form pages under /guides/. One reading column, a short contents list,
   and tables that scroll inside their own box at phone width rather than
   pushing the page sideways. */
.guide { max-width: 72ch; }
.guide-meta {
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.guide-toc {
  margin: 0 0 var(--space-7);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.guide-toc .eyebrow { margin: 0 0 var(--space-3); }
.guide-toc ol { margin: 0; padding-left: var(--space-5); display: grid; gap: var(--space-2); }
.guide-toc a { color: var(--color-link); }
.guide-toc a:hover { color: var(--color-link-hover); text-decoration: underline; }
.guide-body h2 {
  font-size: var(--text-xl);
  margin: var(--space-8) 0 var(--space-3);
  scroll-margin-top: var(--space-9);
}
.guide-body h2:first-child { margin-top: 0; }
.guide-body ul { margin: var(--space-4) 0; padding-left: var(--space-5); display: grid; gap: var(--space-2); }
.guide-body ul + p, .guide-table + p { margin-top: var(--space-4); }
.guide .btn-row { margin-top: var(--space-7); }
.guide-table {
  margin: var(--space-5) 0;
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.guide-table table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.guide-table th, .guide-table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}
.guide-table thead th {
  background: var(--color-surface-sunken);
  color: var(--color-text-heading);
  font-weight: var(--weight-semibold);
}
.guide-table tbody th { color: var(--color-text-heading); font-weight: var(--weight-semibold); }
.guide-table tbody tr:last-child th, .guide-table tbody tr:last-child td { border-bottom: 0; }

/* --- 8b3. Guides redesign, 17 Sep 2026 ----------------------------------
   The first cut was one long grey column and read as a document dump. This
   adds a photo slot to every guide and every card, a two column reading
   layout with a sticky contents and "at a glance" rail, and a related band.
   Photos use the system's photo frame: radius md, hairline, no filters. */

/* Hero: title left, photo right. H1 is capped at the system's 44px page
   title size here because guide titles are questions, and a 72px question
   runs to five lines beside a photo. */
.guidehero-grid { display: grid; gap: var(--space-6); align-items: center; }
@media (min-width: 60rem) {
  .guidehero-grid { grid-template-columns: 7fr 5fr; gap: var(--space-8); }
}
.guidehero h1 { font-size: clamp(30px, 4vw, var(--text-3xl)); line-height: var(--leading-tight); }
.guidehero .eyebrow { color: var(--blue-600); }

/* Reading layout. The rail comes first in the source so phones get the
   contents list before the long read; on desktop it moves to the right. */
.guide-answer { max-width: 72ch; }
.guide-layout { display: grid; gap: var(--space-7); align-items: start; }
@media (min-width: 60rem) {
  .guide-layout { grid-template-columns: minmax(0, 1fr) 18rem; gap: var(--space-8); }
  .guide-aside { grid-column: 2; grid-row: 1; position: sticky; top: var(--space-9); }
  .guide-layout > .guide { grid-column: 1; grid-row: 1; }
}
.guide-aside { display: grid; gap: var(--space-4); }
.guide-aside .guide-toc { margin: 0; }
.guide-toc ol { font-size: var(--text-sm); }

.guide-facts, .guide-next {
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-page);
}
.guide-facts { border-top: 3px solid var(--color-brand-primary); }
.guide-facts .eyebrow, .guide-next .eyebrow { margin: 0 0 var(--space-3); }
.guide-facts dl { margin: 0; display: grid; gap: var(--space-3); }
.guide-facts dt {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.guide-facts dd {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-heading);
  font-weight: var(--weight-medium);
}
.guide-next ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--space-2); }
.guide-next a { color: var(--color-link); font-size: var(--text-sm); font-weight: var(--weight-medium); }
.guide-next a:hover { color: var(--color-link-hover); text-decoration: underline; }

.guide-body > h2:first-child { margin-top: 0; }
.guide-body p { margin: 0; }
.guide-body p + p { margin-top: var(--space-4); }
.guide-body h2 {
  display: flex; flex-direction: column; gap: var(--space-3);
}
.guide-body h2::before {
  content: "";
  width: 32px; height: 3px;
  border-radius: var(--radius-sm);
  background: var(--color-brand-primary);
}
.guide-fig { margin: var(--space-6) 0; }
.guide-fig figcaption {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.guide-example { margin: var(--space-5) 0; }
.guide-example p { font-size: var(--text-base); }
.guide-example .eyebrow { color: var(--blue-700); margin-bottom: var(--space-2); }
.guide-notice {
  max-width: 72ch;
  margin: 0 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface-panel);
  font-size: var(--text-sm);
  color: var(--color-text-body);
}
.guide-notice strong { color: var(--color-text-heading); }
.guide .btn-row { flex-wrap: wrap; }

/* Guide cards: photo on top, then the text. */
.gcard { padding: 0; overflow: hidden; }
.gcard .shot { border: 0; border-radius: 0; border-bottom: 1px solid var(--color-border); }
.gcard-body { display: flex; flex-direction: column; flex: 1; padding: var(--space-5); }
.gcard-chips { margin: 0 0 var(--space-3); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.gcard-chips .eyebrow { margin: 0; }
.gcard h3 { font-size: var(--text-lg); line-height: var(--leading-snug); }
.gcard-meta { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--color-text-muted); }
.gcard .shot-hint { display: none; }

/* Featured guide on the hub: photo and text side by side on wide screens. */
.gfeature { padding: 0; overflow: hidden; margin-top: var(--space-6); }
.gfeature .shot { border: 0; border-radius: 0; border-bottom: 1px solid var(--color-border); }
@media (min-width: 52rem) {
  .gfeature { display: grid; grid-template-columns: 6fr 5fr; }
  /* Height comes from the row, so the fixed ratio must go or it forces the
     slot wider than its column and over the text. */
  .gfeature .shot { aspect-ratio: auto; min-width: 0; min-height: 22rem; height: 100%; border-bottom: 0; border-right: 1px solid var(--color-border); }
}
.gfeature .gcard-body { padding: var(--space-6); justify-content: center; }
.gfeature h2 { font-size: clamp(22px, 2.6vw, var(--text-2xl)); margin-bottom: var(--space-3); }

/* Topic jump links under the hub title. Square cornered, never pills. */
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-6); }
.chip {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface-page);
  color: var(--color-text-heading);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: border-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.chip:hover, .chip:focus-visible { border-color: var(--color-brand-primary); color: var(--color-link); }
.guide-group { scroll-margin-top: var(--space-8); }
.guide-group .section-head p:not(.eyebrow) { color: var(--color-text-body); margin-top: var(--space-2); }

/* A supplied photo fills its slot. */
.shot-real { padding: 0; }

/* --- 8b4. Service cards, 17 Sep 2026 ------------------------------------
   Replaces the flat Field blocks on the service grids, at Don's request. White
   cards with a large brand numeral, a one line summary and a photo beside the
   text. The photo slot shows a plain branded panel until a real job photo is
   supplied. The numeral is display size, so brand primary clears the 3:1 large
   text floor on white (3.86:1). */
.svc-grid {
  display: grid; gap: var(--space-4);
  grid-template-columns: 1fr;
  margin-top: var(--space-6);
}
@media (min-width: 40rem) { .svc-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .svc-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-5); } }
.svc-card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-5);
  background: var(--color-surface-page);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  color: var(--color-text-body);
  text-decoration: none;
  transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.svc-card:hover, .svc-card:focus-visible {
  border-color: var(--color-brand-primary);
  box-shadow: var(--shadow-card);
}
/* Revised 17 Sep 2026: every card shares one skeleton so a row lines up.
   Numeral and picture share the top row, title and summary run full width
   under it, and the link is pinned to the bottom of the card. */
.svc-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.svc-n {
  display: flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 1;
  color: var(--color-brand-primary);
}
.svc-n::after {
  content: ""; width: var(--space-6); height: 2px;
  background: var(--color-brand-primary);
}
.svc-card h3 { font-size: var(--text-lg); line-height: var(--leading-snug); color: var(--color-text-heading); margin: 0; }
.svc-card p { font-size: var(--text-sm); color: var(--color-text-body); margin: 0; }
.svc-go {
  margin-top: auto; padding-top: var(--space-3);
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
  color: var(--blue-600);
}
.svc-card:hover .svc-go svg { transform: translateX(3px); }
.svc-go svg { transition: transform var(--dur-base) var(--ease-out); }
/* The picture is capped near its supplied size (200px wide) so it stays sharp. */
.svc-media {
  flex: 0 0 40%; max-width: 9rem;
  aspect-ratio: 10 / 7;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-sunken);
}
.svc-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.svc-ph { display: grid; place-items: center; color: var(--color-border-strong); }
.svc-ph svg { width: 36%; height: auto; max-height: 70%; }
.svc-other { background: var(--color-brand-primary-tint); }
.svc-other .svc-n { font-size: var(--text-sm); letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--blue-600); }
.svc-other .svc-n::after { background: var(--blue-600); }
.svc-other h3 { color: var(--color-brand-deep); }
.head-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-5); }
.head-row .section-head { margin-bottom: 0; }
.head-row + .svc-grid { margin-top: var(--space-7); }

/* --- 8c. Method row (the Field treatment) ------------------------------- */
.methodrow {
  display: grid; gap: 0;
  margin-top: var(--space-6);
  border-top: 2px solid var(--color-text-heading);
}
@media (min-width: 48rem) { .methodrow { grid-template-columns: repeat(4, 1fr); } }
.methodrow > div {
  padding: var(--space-5) var(--space-5) var(--space-5) 0;
  border-right: 1px solid var(--color-border);
}
.methodrow > div:last-child { border-right: 0; }
.methodrow b {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  color: var(--blue-600);
}
.methodrow h3 { font-size: var(--text-lg); margin: var(--space-3) 0 var(--space-1); }
.methodrow p { font-size: var(--text-base); color: var(--color-text-muted); margin: 0; }

/* --- 9. Stepper ---------------------------------------------------------- */
.steps {
  position: relative; margin: 0; padding: 0; list-style: none;
  counter-reset: step;
}
.steps::before {
  content: "";
  position: absolute; left: 19px; top: var(--space-2); bottom: var(--space-2);
  width: 2px; background: var(--color-border);
}
.steps > li {
  position: relative;
  padding: 0 0 var(--space-6) var(--space-8);
}
.steps > li:last-child { padding-bottom: 0; }
.steps > li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  position: absolute; left: 0; top: 0;
  width: 40px; height: 40px;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  /* Filled rather than outlined, 16 Sep 2026. The pillars list two sections
     away uses a small brand blue numeral on white, and so did this, so four
     consecutive home page sections carried the same device at the same weight
     and the eye had nothing to hold on to. Solid brand deep separates the two
     without adding a colour to the palette. White on brand deep measures
     8.35:1, well clear of AA, where white on brand primary would have been
     3.86:1 and failed. */
  background: var(--color-brand-deep);
  color: var(--color-text-on-brand);
  border: 1px solid var(--color-brand-deep);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  font-family: var(--font-body);
}
.steps h3 { font-size: var(--text-lg); margin-bottom: var(--space-1); }
.steps p { font-size: var(--text-base); color: var(--color-text-body); margin: 0; }

/* Shopper-journey stepper */
.steps.journey h3 {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2);
}
.zone {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--blue-700);
  background: var(--color-brand-primary-tint);
  border-radius: var(--radius-sm);      /* no pills — system rule */
  padding: var(--space-1) var(--space-2);
}

/* --- 10. Lists ----------------------------------------------------------- */
.ticks, .crosses { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.ticks li, .crosses li { position: relative; padding-left: var(--space-6); }

.ticks li::before {
  content: ""; position: absolute; left: 2px; top: 8px;
  width: 11px; height: 6px;
  border-left: 2px solid var(--color-brand-primary);
  border-bottom: 2px solid var(--color-brand-primary);
  transform: rotate(-45deg);
}
.crosses li { color: var(--color-text-muted); }
.crosses li::before {
  content: ""; position: absolute; left: 4px; top: 11px;
  width: 12px; height: 1px;
  background: var(--color-border-strong);
}

.fit {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  background: var(--color-surface-page);
}
.fit h3 { font-size: var(--text-lg); }
.fit.no { background: var(--color-surface-sunken); }

/* --- 11. Proof band + case cards ---------------------------------------- */
.logoband {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.logoslot {
  background: var(--color-surface-page);
  min-height: 88px;
  display: grid; place-items: center;
  padding: var(--space-4);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-placeholder);
  text-align: center;
}

/* Completion report band. Stands in for the logo band while CLIENTS_APPROVED is
   empty, and borrows the logo band's hairline grid so the two read as the same
   slot in the page rather than two different ideas. */
.proofpack {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.proofpack-item {
  background: var(--color-surface-page);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.proofpack-item h3 { font-size: var(--text-lg); margin: 0; }
.proofpack-item p { font-size: var(--text-base); color: var(--color-text-body); margin: 0; }

.case { padding: 0; overflow: hidden; }
.case .case-media {
  aspect-ratio: 16 / 10;
  background: var(--color-surface-panel);
  display: grid; place-items: center;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  border-bottom: 1px solid var(--color-border);
}
.case .case-media { position: relative; overflow: hidden; }
.case .case-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.case .case-body { padding: var(--space-5); }

.tag, .pending {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
}
.tag { background: var(--color-brand-primary-tint); color: var(--blue-700); }
.pending { background: var(--color-surface-panel); color: var(--color-text-muted); }

/* --- 12. FAQ (native accordion, schema-backed) --------------------------- */
.faq { border-top: 1px solid var(--color-border); }
.faq-item { border-bottom: 1px solid var(--color-border); }
.faq-q {
  cursor: pointer; list-style: none;
  padding: var(--space-4) var(--space-7) var(--space-4) 0;
  position: relative;
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  color: var(--color-text-heading);
  min-height: 44px;
  display: flex; align-items: center;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: ""; position: absolute; right: var(--space-2); top: 50%;
  width: 9px; height: 9px; margin-top: -6px;
  border-right: 2px solid var(--color-brand-primary);
  border-bottom: 2px solid var(--color-brand-primary);
  transform: rotate(45deg);
  transition: transform var(--dur-base) var(--ease-out);
}
.faq-item[open] .faq-q::after { transform: rotate(-135deg); margin-top: -2px; }
.faq-a {
  padding: 0 var(--space-7) var(--space-5) 0;
  color: var(--color-text-body);
  max-width: 68ch; margin: 0;
}

/* --- 13. CTA band -------------------------------------------------------- */
/* The one blue band on interior pages. Blue is an action colour, so a band
   that exists purely to carry the primary action is a legitimate use. */
.ctaband {
  background: var(--color-brand-deep);
  color: var(--color-text-on-brand);
}
.ctaband .wrap { display: grid; gap: var(--space-5); align-items: center; }
@media (min-width: 54rem) {
  .ctaband .wrap { grid-template-columns: 1fr auto; gap: var(--space-8); }
}
.ctaband h2 { color: var(--color-text-on-brand); max-width: 24ch; margin-bottom: var(--space-2); }
.ctaband p { color: var(--color-text-on-brand); margin: 0; }
.ctaband .btn-row { margin-top: 0; }



/* --- Brand mark as a background graphic ---------------------------------
   The chevron, oversized and running off an edge rather than floating whole in
   the middle: a complete logo at low opacity reads as a stock watermark, a
   cropped one reads as a deliberate device. Decorative in every placement, so
   it is aria-hidden in the markup and never the only place the logo appears.

   Opacities are not taste, they are measured. Each one was checked against the
   text sitting on that band:
     .wm-cta   white on brand-deep  8.35:1 base -> 7.0:1 at 7%
     .wm-foot  white on near-black 14.99:1 base -> 12.5:1 at 6%
     .wm-hero  slate-900 on sunken 13.85:1 base -> 12.9:1 at 6%
   All well clear of the 4.5:1 AA floor. The mark is also kept off the left
   column, where the text actually sits, so in practice it never overlaps a
   glyph at any breakpoint. */
.wm {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  line-height: 0;
}
.wm svg { display: block; height: 100%; width: auto; }

/* Every band carrying a mark needs a stacking context and a clip, or the
   oversized svg escapes the section instead of being cropped by it. */
.ctaband, .pagehero, .footer { position: relative; overflow: hidden; }
.ctaband .wrap, .pagehero .wrap, .footer .wrap { position: relative; z-index: 1; }

/* Sized in px, not %, on purpose: the CTA band is short, so a percentage height
   produced a 213px mark that read as a small logo parked in the corner rather
   than an oversized graphic running off the edge. */
.wm-cta {
  top: 50%;
  right: -4%;
  height: 420px;
  transform: translateY(-50%);
  color: #fff;
  opacity: 0.07;
}
.wm-foot {
  bottom: -55%;
  right: 2%;
  height: 190%;
  color: #fff;
  opacity: 0.06;
}
.wm-hero {
  top: -30%;
  right: -6%;
  height: 200%;
  color: var(--blue-500);
  opacity: 0.06;
}

/* Below the point where the layout goes single column the text runs full width,
   so the mark would sit under it. Drop it rather than shrink it. */
@media (max-width: 60rem) {
  .wm-hero, .wm-foot { display: none; }
  .wm-cta { opacity: 0.05; right: -18%; }
}

/* A background graphic is exactly what nobody needs on paper. */
@media print { .wm { display: none !important; } }

.callout {
  background: var(--color-brand-primary-tint);
  border: 1px solid var(--blue-100);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}
.callout h2, .callout h3 { font-size: var(--text-lg); }
.callout p:last-child { margin-bottom: 0; }

/* --- 14. Forms ----------------------------------------------------------- */
.form { display: grid; gap: var(--space-4); }
@media (min-width: 44rem) {
  .form .row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
}

.field { display: grid; gap: var(--space-2); }
.field label {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text-heading);
}
.field .hint { font-size: var(--text-sm); color: var(--color-text-muted); font-weight: var(--weight-regular); }

.field input, .field select, .field textarea {
  font-family: var(--font-body);
  font-size: var(--text-base);
  min-height: 44px;
  padding: var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface-page);
  color: var(--color-text-body);
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.field textarea { min-height: 128px; resize: vertical; line-height: var(--leading-normal); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-color: var(--color-brand-primary);
}
.field input::placeholder { color: var(--color-text-placeholder); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--color-form-error); }

.err { font-size: var(--text-sm); color: var(--color-form-error); min-height: 1.2em; }
.form-note { font-size: var(--text-sm); color: var(--color-text-muted); }

.form-status {
  padding: var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-sunken);
  font-weight: var(--weight-medium);
}
.form-status.ok { border-color: var(--color-brand-primary); background: var(--color-brand-primary-tint); }
.form-status.bad { border-color: var(--color-form-error); background: var(--color-form-error-tint); }

.hp { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

/* --- 15. Contact details ------------------------------------------------- */
.contact-list { display: grid; gap: var(--space-5); margin: 0; }
.contact-list dt {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}
.contact-list dd {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--color-text-heading);
}
.contact-list dd a { text-decoration: none; }
.contact-list dd a:hover { text-decoration: underline; }
.contact-list dd small {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  color: var(--color-text-muted);
  margin-top: var(--space-1);
}

/* --- 16. Footer ---------------------------------------------------------- */
/* Mirrors the printed letterhead footer: blue band, contact details as plain
   text, no icons. */
.footer {
  /* Field uses a near-black footer rather than a second blue band, so the blue
     hero stays the only large brand-colour field on the page.
     Sized down 7 Sep 2026: it was running at body-copy size with 32px gaps,
     which made a utility block as tall as a content section. Footer links are
     navigation, not reading matter. */
  background: var(--color-text-heading);
  color: var(--color-text-on-brand);
  padding-block: var(--space-6) var(--space-5);
}
.footer a { color: var(--color-text-on-brand); text-decoration: none; }
.footer a:hover { text-decoration: underline; }
.footer .foot-h {
  color: var(--color-text-on-brand);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  margin-bottom: var(--space-2);
  opacity: 0.7;
}
.footer-grid {
  display: grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
}
/* The brand column can take more room than the four link columns. */
@media (min-width: 64rem) {
  .footer-grid { grid-template-columns: 1.4fr repeat(4, 1fr); }
}
.footer ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--space-2);
  font-size: var(--text-sm);
}
/* 1.9 here previously cancelled out the font-size reduction: rows went from
   33.6px to only 28.7px. Links still clear a comfortable target with 1.45
   plus the row gap. */
.footer li { line-height: 1.45; }
.footer p { font-size: var(--text-sm); line-height: 1.6; }
.footer-base {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  display: flex; flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  justify-content: space-between;
  font-size: var(--text-sm);
}

/* Sticky mobile call bar */
.callbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--color-surface-page);
  border-top: 1px solid var(--color-border);
  transform: translateY(105%);
  transition: transform var(--dur-base) var(--ease-out);
}
.callbar.is-on { transform: none; }
@media (min-width: 48rem) { .callbar { display: none; } }
.callbar a {
  min-height: 48px;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-3);
  text-decoration: none;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--color-text-heading);
}
.callbar a + a {
  background: var(--blue-600);   /* see the contrast note at the top */
  color: var(--color-text-on-brand);
}
body:has(.callbar.is-on) { padding-bottom: 48px; }
@media (min-width: 48rem) { body:has(.callbar.is-on) { padding-bottom: 0; } }

/* --- 17. Placeholder image slots ---------------------------------------- */
/* Neutral block + label, per the system. No hand-drawn illustration. */
.shot {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-panel);
  border: 1px solid var(--color-border);
  aspect-ratio: var(--ar, 4 / 3);
  display: grid; place-items: center; text-align: center;
  color: var(--color-text-muted);
  padding: var(--space-5);
}
.shot .shot-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text-body);
}
.shot .shot-hint { font-size: var(--text-sm); margin-top: var(--space-1); max-width: 28ch; }
.shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Photo frame — image in a radius-md container with a hairline border and a
   caption below, exactly as the design system's "Photo frame" pattern. */
.shotcard {
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-page);
}
.shotcard img { width: 100%; height: auto; display: block; }
.shotcard figcaption {
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  border-top: 1px solid var(--color-border);
}
.shotcard figcaption strong { color: var(--color-text-heading); }

/* Retail media screen types: photo frame on top, spec list under it. The photos
   arrive in four different shapes, so every frame is cropped to one 4:3 ratio and
   each image carries its own object-position to keep the screen in view. */
.rm-types, .rm-included .grid { display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
@media (min-width: 48rem) {
  .rm-types, .rm-included .grid { grid-template-columns: 1fr 1fr; }
}
.rm-type {
  display: flex; flex-direction: column;
  background: var(--color-surface-page);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.rm-type-img { position: relative; aspect-ratio: 4 / 3; background: var(--color-surface-sunken); }
.rm-type-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.rm-type-body {
  display: grid; gap: var(--space-3); align-content: start;
  padding: var(--space-5);
  border-top: 1px solid var(--color-border);
}
.rm-type-body h3 { font-size: var(--text-lg); }
.rm-type-body p { font-size: var(--text-base); color: var(--color-text-body); margin: 0; }
.rm-type-body .ticks { font-size: var(--text-sm); gap: var(--space-2); }
.rm-type-body .ticks li::before { top: 6px; }

.rm-included { display: grid; gap: var(--space-5); margin-top: var(--space-7); }
@media (min-width: 48rem) { .rm-included { margin-top: var(--space-8); } }
.rm-included h3 { font-size: var(--text-lg); }

/* The agreement terms table sits on the sunken band, so it needs its own white
   ground, and reads at body size because it is the argument, not a footnote. */
.rm-clauses { margin: 0; background: var(--color-surface-page); }
.rm-clauses table { font-size: var(--text-base); }
@media (min-width: 48rem) {
  .rm-clauses tbody th { width: 30%; }
  .rm-clauses th, .rm-clauses td { padding: var(--space-4) var(--space-5); }
}

/* --- 17b. Spacing utilities ---------------------------------------------
   For the handful of one-off gaps that don't justify a component. All land on
   the 4px scale — the system forbids arbitrary values, and inline styles were
   drifting to 1.75rem / .85rem before these existed. */
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }
.mt-7 { margin-top: var(--space-7); }
.mb-0 { margin-bottom: 0; }

/* Small qualifier under a footer link */
.footnote {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-on-brand);
  opacity: 0.7;
}

/* --- 18. Motion ---------------------------------------------------------- */
/* The design system calls for functional motion only. Entrance reveals are
   retained but reduced to a short opacity fade with no travel and no stagger,
   and the hero parallax has been removed outright.
   PENDING SCOTT: the system says "no scroll animations" while the brief said
   the animations on the old media site should be kept. See WEBSITE-PLAN.md —
   deleting the two rules below turns entrance motion off completely. */
[data-reveal] {
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
[data-reveal].is-in { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  [data-reveal] { opacity: 1 !important; transition: none !important; }
}

/* --- 19. Print ----------------------------------------------------------- */
@media print {
  .header, .drawer, .callbar, .ctaband, .btn-row { display: none !important; }
  body { background: var(--white); }
  [data-reveal] { opacity: 1 !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
}


/* Focus ring on dark grounds. WCAG 1.4.11 asks 3:1 for a focus indicator, and
   the system's ring is --blue-500, which measures:

     on white                 3.86:1  ok
     on the sunken surface    3.56:1  ok
     on brand-deep blue       2.16:1  FAILS
     on the near-black footer 3.89:1  ok

   Brand-deep is the hero and the CTA band, which is where the primary buttons
   live, so a keyboard user was getting a near invisible ring on the most
   important controls on the site. White measures 8.35:1 there. The dots control
   already did this; the buttons and links around it did not. */
.hero :focus-visible,
.on-brand :focus-visible,
.footer :focus-visible,
.callbar :focus-visible,
.drawer :focus-visible {
  outline-color: #fff;
}

/* --- Touch overrides, last on purpose ------------------------------------
   These sit at the end of the file because they are overrides: an earlier
   copy of this block lost the cascade to the form styles at equal
   specificity, so the 16px input fix silently did nothing.

   Touch targets. Measured 7 Sep 2026 at 375px: footer navigation links were
   rendering 42x16, which fails WCAG 2.5.8 Target Size (Minimum) at 24x24. The
   footer was compacted earlier the same day and this was the cost of it. Fixed
   on touch pointers only, so the tighter desktop rhythm is unchanged. */
@media (pointer: coarse) {
  .footer li a,
  .drawer a {
    display: inline-block;
    min-height: 24px;
    padding-block: var(--space-1);
  }
  .footer ul { gap: var(--space-1); }
  .arrow { display: inline-block; min-height: 24px; padding-block: var(--space-1); }
  .crumbs a { display: inline-block; min-height: 24px; padding-block: 2px; }

  /* iOS Safari zooms the whole page in when a focused field is under 16px, and
     the user then has to pinch back out to carry on. The fields were at 15px.
     This is the standard fix and it applies to every control, not just text
     inputs, because select and textarea zoom the same way. */
  .field input,
  .field select,
  .field textarea { font-size: 16px; }

  /* A checkbox is its own tap target and was rendering 21px high. */
  .field input[type="checkbox"],
  .field input[type="radio"] { min-width: 24px; min-height: 24px; }
}
