/* ============================================================
   ARDENT INSURANCE SOLUTIONS - Design System v1.0
   Vibe: Editorial Luxury + Soft Structuralism
   Layout: Asymmetrical Bento + Z-Axis Cascade
   ============================================================ */

/* Montserrat - self-hosted woff2 in /fonts/ (SIL Open Font License, see
   fonts/OFL-Montserrat.txt), the heading face the brand guidelines (October
   2026) name. Variable files from Fontsource, so one file covers every weight;
   Latin loads on every page and Latin Extended only where a page uses one of
   its letters. Upright only: the site sets no italic headings. */
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-Latin.woff2') format('woff2');
  font-weight: 500 800;
  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+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  src: url('/fonts/Montserrat-LatinExt.woff2') format('woff2');
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Noto Sans - self-hosted woff2 in /fonts/ (SIL Open Font License, see
   fonts/OFL-NotoSans.txt). These are the files Google Fonts served for the
   old <link>, with its unicode ranges: Latin, which every page loads, and
   Latin Extended, which loads only on a page that uses one of its letters.
   The upright file is variable, so one file covers weights 400 to 800;
   italic is 400 only. */
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Latin.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-LatinExt.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Italic-Latin.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Italic-LatinExt.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-stretch: 100%;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── 1. CSS RESET ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Whatever the page scrolls to (a #link, or a control that takes focus while
   the reader tabs back up the page) stops 6.5rem from the top, clear of the
   fixed nav pill. A view timeline left at view-timeline-inset: auto reads this
   padding as its own inset, so every view-timeline sets its inset. */
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 6.5rem; }
/* In-page moves glide. The jump to a #fragment on arrival from another page
   does not: a glide there fixes its end point before the page's late layout
   (the homepage deck and pins) has settled, and lands short. So the glide waits
   until something on the page has focus, as it does once a link is clicked or
   a key pressed, but not on a fresh load. Keyboard focus moves jump too: a
   glide across a long gap between two tab stops runs on after a quick
   Shift+Tab, and leaves the focused control off screen. So the glide holds
   only while nothing has keyboard focus. In-page links, back to top and the
   other scripts that scroll ask for smooth themselves, so they still glide. */
@media (prefers-reduced-motion: no-preference) {
  html:focus-within:not(:has(:focus-visible)) { scroll-behavior: smooth; }
}
/* Anything search can link to sits a further 2.5rem down (9rem in all): the
   24px at most that an entrance travels as it settles (--rise-card; text rises
   --rise-text), plus a little air. */
h1[id], h2[id], h3[id], section[id], .team-member[id] { scroll-margin-top: 2.5rem; }
body { font-family: 'Noto Sans', sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.6; overflow-x: hidden; }
img, svg { display: block; max-width: 100%; }
a { text-decoration: none; color: inherit; }
ul, ol { list-style: none; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }
input, textarea, select { font-family: inherit; }

/* ── 2. DESIGN TOKENS ────────────────────────────────────── */
:root {
  /* Brand: the Ardent brand guidelines, October 2026. Navy and white do
     most of the work; Orange marks the action; Teal and Sprout support. */
  --navy: #001D2D;        /* Text, the wordmark, dark bands */
  --teal: #69A6A6;        /* Shapes, icons, fills; text on Navy (6.3:1) and the dark card (5.3:1) */
  --teal-text: #3F6F76;   /* Teal when it has to be text on light grounds (5.6:1 on white) */
  --sprout: #9CC5AF;      /* Supporting: soft fills, never text */
  --orange: #E96512;      /* The action: primary buttons, the underline accent */
  --orange-text: #A34F1A; /* Orange when it has to be text on light grounds (5.7:1 on white) */
  --on-orange-shadow: 0 1px 2px rgba(110,40,0,0.55), 0 0 1px rgba(110,40,0,0.45); /* lifts white labels off Orange buttons */
  --teal-tint: #E8F2F2;   /* Info panels, icon tiles */
  --orange-tint: #FCEDE3;
  --sprout-tint: #E1EEE7;

  /* Backgrounds */
  --bg-primary: #FFFFFF;
  --bg-secondary: #F2F4F4;  /* Light grey: alternate bands */
  --bg-white: #FFFFFF;
  --bg-dark: #001D2D;
  --bg-dark-card: #0A2C3E;  /* the one lighter dark, for cards on Navy: Navy lifted with Teal */

  /* Text */
  --text-primary: #001D2D;
  --text-secondary: #4D616C;  /* Muted ink */
  --text-tertiary: #4D616C;
  --text-white: #ffffff;
  --text-white-70: rgba(255,255,255,0.7);
  --text-white-65: rgba(255,255,255,0.65);

  /* Lines: the guidelines separate things with lines and space */
  --line: rgba(0,29,45,0.12);
  --line-strong: rgba(0,29,45,0.24);

  /* Spacing */
  --section-py: 7rem;
  --container-max: 1280px;
  --container-pad: clamp(1.25rem, 4vw, 2.5rem);

  /* Radius */
  --radius-card: 1.25rem;
  --radius-inner: calc(1.25rem - 6px);
  --radius-pill: 9999px;
  --radius-md: 0.875rem;
  --radius-sm: 0.625rem;
  --radius-lg: 1.25rem;

  /* Elevation: four steps, all tinted midnight so shadows sit in the palette.
     Resting cards take 1, raised surfaces 2, hovered cards and menus 3, and
     the most raised surfaces 4. */
  --elev-1: 0 1px 2px rgba(0,29,45,0.04), 0 2px 8px rgba(0,29,45,0.04);
  --elev-2: 0 2px 4px rgba(0,29,45,0.04), 0 8px 24px rgba(0,29,45,0.07);
  --elev-3: 0 4px 8px rgba(0,29,45,0.05), 0 20px 48px rgba(0,29,45,0.10);
  --elev-4: 0 8px 16px rgba(0,29,45,0.08), 0 32px 80px rgba(0,29,45,0.18);

  /* Shadows (older names, kept as aliases of the elevation steps) */
  --shadow-card: var(--elev-2);
  --shadow-elevated: var(--elev-3);
  --shadow-glow-jade: 0 0 60px rgba(105,166,166,0.22);
  --shadow-glow-pumpkin: 0 0 60px rgba(233,101,18,0.25);
  --shadow-inset-shine: inset 0 1px 1px rgba(255,255,255,0.15);

  /* Easing */
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* Motion: durations and distances every entrance and state change draws on.
     Entrances are 0.5 to 1s and travel no further than --rise-card; hovers and
     presses stay under half a second. */
  --dur-press: 200ms;      /* hover, press */
  --dur-state: 450ms;      /* UI state changes: nav, menus, panels */
  --dur-enter: 700ms;      /* entrances */
  --dur-signature: 1000ms; /* hero and signature moments */
  --stagger: 70ms;         /* between siblings in a group */
  --rise-text: 12px;
  --rise-card: 24px;

  /* Layering: a dark section that rises over the one before it as a sheet */
  --sheet-radius: 2.5rem;
  --sheet-overlap: 2.5rem;

  /* Z-Index */
  --z-base: 1;
  --z-card: 10;
  --z-sticky: 100;
  --z-nav: 200;
  --z-overlay: 300;
  --z-modal: 400;
}
@media (max-width: 768px) {
  :root { --sheet-radius: 1.5rem; --sheet-overlap: 1.5rem; }
}

/* ── 2b. FOCUS, SKIP LINK, ICONS ─────────────────────────── */
:focus-visible { outline: 3px solid var(--teal-text); outline-offset: 3px; border-radius: 4px; }
.hero :focus-visible, .page-hero :focus-visible, .services-section :focus-visible, .cta-banner :focus-visible,
.section--sheet :focus-visible,
.site-footer :focus-visible, .nav-pill :focus-visible, .nav-overlay :focus-visible, .tcr-ice-section :focus-visible { outline-color: #fff; }
/* The mega menu's panels sit inside the dark pill but on a white card, so their
   links take the jade ring again (after the rule above, which they also match).
   On a menu item it is drawn inside the item, so it never spills into the 2px
   between rows; the foot links also darken, as they do on hover. */
.nav-dropdown :focus-visible { outline-color: var(--teal-text); }
.nav-dropdown-item:focus-visible { outline-width: 2px; outline-offset: -2px; }
.nav-dropdown-all:focus-visible { outline-offset: 2px; color: var(--text-primary); }
.skip-link {
  position: absolute; left: 1rem; top: -100px; z-index: 1000;
  background: var(--orange-text); color: #fff; font-weight: 600; font-size: 0.9375rem;
  padding: 0.75rem 1.25rem; border-radius: var(--radius-pill); transition: top 150ms;
}
.skip-link:focus { top: 1rem; }
/* It shows over the dark hero, and on a phone over the nav's white logo, so
   its ring is white with the midnight carried out under it as a halo, as the
   back-to-top button's is: the ring then reads on whatever it lands over. */
.skip-link:focus-visible { outline-color: #fff; box-shadow: 0 0 0 9px var(--navy); }
.icon { width: 1.25em; height: 1.25em; display: inline-block; vertical-align: middle; flex-shrink: 0; color: currentColor; }
.covered-icon { color: var(--teal-text); display: flex; align-items: center; }
.covered-icon .icon { width: 20px; height: 20px; }
.product-card-icon .icon { width: 26px; height: 26px; color: var(--navy); }
.contact-info-icon { color: var(--teal-text); }
.contact-info-icon .icon { width: 20px; height: 20px; }
.feature-icon { color: var(--teal-text); }
.feature-icon .icon { width: 24px; height: 24px; }
.trust-item-icon { color: var(--teal-text); }
.trust-item-icon .icon { width: 18px; height: 18px; }

/* ── 3. TYPOGRAPHY ────────────────────────────────────────── */
h1, h2, h3 { font-family: 'Montserrat', sans-serif; line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance; }
p, li, span { line-height: 1.7; }
/* 1.7 is running-text leading. A span inside a heading or a form label (an
   accent word, a split word, the landing question mark, the required star)
   keeps its parent's tighter leading instead, so it never opens up the line
   it sits on. At no extra weight, so a class on a span still wins. */
:where(h1, h2, h3, h4, h5, h6, label) span { line-height: inherit; }

.display-xl { font-size: clamp(2.25rem, 7vw, 5.5rem); font-family: 'Montserrat', sans-serif; line-height: 1.0; letter-spacing: -0.03em; }
.display-lg { font-size: clamp(2rem, 5vw, 4rem); font-family: 'Montserrat', sans-serif; line-height: 1.05; letter-spacing: -0.025em; }
.display-md { font-size: clamp(1.75rem, 3.5vw, 2.75rem); font-family: 'Montserrat', sans-serif; line-height: 1.1; letter-spacing: -0.02em; }
.display-sm { font-size: clamp(1.35rem, 2.5vw, 1.875rem); font-family: 'Montserrat', sans-serif; line-height: 1.2; }

.body-lg { font-size: 1.125rem; line-height: 1.75; color: var(--text-secondary); }
.body-md { font-size: 1rem; line-height: 1.7; color: var(--text-secondary); }

/* Eyebrow Tags */
.eyebrow {
  /* The guidelines' eyebrow: Montserrat ExtraBold capitals, echoing
     INSURANCE SOLUTIONS in the logo. A plain label, no chip. */
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: 'Montserrat', sans-serif;
  font-size: 0.75rem; line-height: 1.33; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--teal-text);
}
.eyebrow-dark { color: var(--teal); }
/* The underline accent (brand guidelines): a 4px Orange bar under the one
   word or phrase a heading turns on, once per screen, headings only. In the
   site editor it is the heading's **bold** words. Never a link style. */
.has-accent strong {
  font-weight: inherit;
  text-decoration: underline 4px var(--orange);
  text-underline-offset: 0.16em; text-decoration-skip-ink: none;
}
.eyebrow-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: 0.6; }
/* A heading that follows its eyebrow keeps one set gap. Kept at class weight
   so a heading's own margin (the page hero title's, say) still wins. */
.eyebrow + :where(h1, h2, h3) { margin-top: 0.875rem; }

/* ── 4. LAYOUT UTILITIES ─────────────────────────────────── */
.container {
  width: 100%; max-width: var(--container-max);
  margin: 0 auto; padding: 0 var(--container-pad);
}
.section { padding: var(--section-py) 0; }

/* ── 5. NAVIGATION ────────────────────────────────────────── */
/* The header stays fixed at the top of the screen the whole way down. The
   pill carries the header's view-transition name, so it holds still while the page beneath it changes. (The name sits on
   the pill, not the header: a named element becomes a backdrop root, and on
   the header that would stop the pill's glass blur.) */
.site-header {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  padding: 1.25rem var(--container-pad);
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.nav-pill {
  pointer-events: all;
  display: flex; align-items: center; gap: 0;
  /* Close to solid, so the logo never sits on a busy photo or video
     (brand guidelines) */
  background: rgba(0,29,45,0.9);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: var(--radius-pill);
  padding: 0.5rem 0.5rem 0.5rem 1.5rem;
  box-shadow: 0 4px 32px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.1);
  transition: background-color var(--dur-state) var(--ease-out), border-color var(--dur-state) var(--ease-out),
    box-shadow var(--dur-state) var(--ease-out), padding var(--dur-state) var(--ease-out);
  width: 100%; max-width: 1100px;
  view-transition-name: site-header;
}
/* Past the first few pixels of scroll the pill turns solid and draws in a little */
.nav-pill.scrolled {
  background: rgba(0,29,45,0.97);
  border-color: rgba(255,255,255,0.08);
  box-shadow: 0 8px 48px rgba(0,0,0,0.35), 0 1px 4px rgba(0,0,0,0.2);
  padding: 0.375rem 0.375rem 0.375rem 1.25rem;
}

/* Always use reverse (white) logo in nav */
.nav-logo .logo-reverse { display: block; }

.nav-logo { display: flex; align-items: center; margin-right: 2rem; flex-shrink: 0; }
/* 160px wide at rest, the guidelines' smallest screen size for the full logo,
   and 112px once the pill condenses (Stephen, October 2026) */
.nav-logo img { height: 54px; width: auto; display: block; transition: height var(--dur-state) var(--ease-out); }
.nav-pill.scrolled .nav-logo img { height: 38px; }

.nav-links { display: flex; align-items: center; gap: 0; flex: 1; }
.nav-link {
  font-size: 0.875rem; font-weight: 500; color: rgba(255,255,255,0.75);
  padding: 0.5rem 0.875rem; border-radius: var(--radius-pill);
  transition: color 300ms var(--ease-out), background-color 300ms var(--ease-out);
  position: relative; white-space: nowrap;
}
.nav-link:hover { color: white; background: rgba(255,255,255,0.08); }
.nav-link.active { color: var(--teal); }

/* Dropdown (desktop mega menu). Panels anchor to the left edge of the link row,
   so both menus share one edge and never overhang the logo. */
.nav-links { position: relative; }
.nav-item { position: static; }
.nav-item > .nav-link { display: inline-flex; align-items: center; gap: 0.3rem; }
.nav-chevron { width: 0.875em; height: 0.875em; opacity: 0.7; transition: transform 250ms var(--ease-out), opacity 250ms var(--ease-out); }
.nav-item:hover > .nav-link .nav-chevron,
.nav-item > .nav-link[aria-expanded="true"] .nav-chevron { transform: rotate(180deg); opacity: 1; }
.nav-dropdown {
  position: absolute; top: 100%; left: 0;
  transform: translateY(-8px);
  background: transparent; border-radius: 1.25rem;
  min-width: 240px; padding: 0.75rem;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), visibility 0s linear 200ms;
  z-index: var(--z-nav);
}
.nav-dropdown::before {
  content: ''; position: absolute; inset: 0.75rem 0 0;
  background: var(--bg-dark-card); border-radius: 1.25rem;
  border: 1px solid rgba(255,255,255,0.12);
  box-shadow: var(--elev-3);
  z-index: -1;
}
.nav-item:hover .nav-dropdown,
.nav-item:focus-within .nav-dropdown {
  opacity: 1; visibility: visible; pointer-events: all;
  transform: translateY(0);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), visibility 0s linear 0ms;
}
/* Escape closes the panel until the pointer or focus leaves the item */
.nav-item.nav-item--dismissed .nav-dropdown,
.nav-item.nav-item--dismissed:hover .nav-dropdown,
.nav-item.nav-item--dismissed:focus-within .nav-dropdown {
  opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(-8px);
}
/* Each entry is a tile on the midnight card: icon, name, and one line on what
   it covers or who it is for. */
.nav-dropdown-item {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.75rem; border-radius: 0.875rem;
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.66);
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.nav-dropdown-item:hover, .nav-dropdown-item:focus-visible { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.8); }
.nav-dropdown-text { display: flex; flex-direction: column; gap: 0.1875rem; min-width: 0; }
.nav-dropdown-label { font-family: 'Montserrat', sans-serif; font-weight: 600; font-size: 0.875rem; line-height: 1.3; color: #fff; }
.nav-dropdown-desc { font-size: 0.75rem; line-height: 1.4; }
.nav-dropdown-icon {
  width: 34px; height: 34px; border-radius: 10px; color: var(--teal);
  background: rgba(105,166,166,0.16); display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.nav-dropdown-glyph { width: 17px; height: 17px; }

/* One card for both menus. With a fine pointer, main.js adds .has-morph to the
   link row: the panels drop their own white card and a single .nav-morph layer
   sits behind whichever panel is open, placed from --morph-x/y/w/h. Moving from
   Products to Industries slides and resizes that one card instead of fading two.
   The card is display:none while shut, so the first open fades it in where it
   belongs (@starting-style) rather than growing it from the corner; a move
   between items inside the close debounce morphs it. The items settle in one
   after another (--i, set by the script). Without .has-morph none of this applies. */
.nav-morph { display: none; }
.nav-links.has-morph .nav-morph {
  position: absolute; top: 0; left: 0; z-index: calc(var(--z-nav) - 1);
  width: var(--morph-w, 0px); height: var(--morph-h, 0px);
  transform: translate(var(--morph-x, 0px), var(--morph-y, 0px));
  background: var(--bg-dark-card); border: 1px solid rgba(255,255,255,0.12); border-radius: 1.25rem;
  box-shadow: 0 24px 60px rgba(0,0,0,0.4), 0 2px 8px rgba(0,0,0,0.2);
  opacity: 0; pointer-events: none;
  transition: transform var(--dur-state) var(--ease-out), width var(--dur-state) var(--ease-out),
    height var(--dur-state) var(--ease-out), opacity var(--dur-press) var(--ease-out), display var(--dur-press);
  /* keeps it shown while it fades out; a browser without this simply cuts */
  transition-behavior: allow-discrete;
}
.nav-links.has-morph .nav-morph.is-open { display: block; opacity: 1; }
@starting-style { .nav-links.has-morph .nav-morph.is-open { opacity: 0; } }
/* On a close the card fades with the panel's contents, from the same frame. The
   script keeps it open a moment longer, so a move from one menu to the next
   morphs the card instead of blinking it; but once no open menu is under the
   pointer or focus, it is already on its way out, and never hangs on screen
   empty. */
.nav-links.has-morph:not(:has(> .nav-item:is(:hover, :focus-within):not(.nav-item--dismissed) > .nav-dropdown)) .nav-morph.is-open { opacity: 0; }
.nav-links.has-morph .nav-dropdown::before { opacity: 0; }
/* The shared card does the moving, so the panels themselves only fade */
.nav-links.has-morph .nav-dropdown,
.nav-links.has-morph .nav-item.nav-item--dismissed .nav-dropdown { transform: none; }
.nav-links.has-morph .nav-dropdown-item {
  opacity: 0; transform: translateY(6px);
  transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out),
    background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out);
}
.nav-links.has-morph .nav-item:is(:hover, :focus-within):not(.nav-item--dismissed) .nav-dropdown-item {
  opacity: 1; transform: none;
  transition-delay: calc(var(--i, 0) * 12ms), calc(var(--i, 0) * 12ms), 0s, 0s;
}
/* a group shown by its tab settles in the same way */
@starting-style {
  .nav-links.has-morph .nav-item:is(:hover, :focus-within):not(.nav-item--dismissed) .nav-dropdown-item { opacity: 0; transform: translateY(6px); }
}

.nav-cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--orange); color: #fff; text-shadow: var(--on-orange-shadow);
  font-family: 'Montserrat', sans-serif; font-size: 0.8125rem; font-weight: 800;
  padding: 0.625rem 1.25rem 0.625rem 1.25rem;
  border-radius: var(--radius-pill);
  transition: box-shadow 300ms var(--ease-spring);
  margin-left: auto; flex-shrink: 0;
  box-shadow: 0 4px 16px rgba(233,101,18,0.3);
}
/* No scale on hover or press: a scaled button inside the blurred pill is
   redrawn soft, so it answers with its shadow and arrow instead. */
.nav-cta:hover { box-shadow: 0 8px 24px rgba(233,101,18,0.4); }
.nav-cta:active { box-shadow: 0 2px 10px rgba(233,101,18,0.3); }
.nav-cta-arrow { display: inline-block; font-size: 0.75rem; opacity: 0.8; transition: transform 300ms var(--ease-spring); }
.nav-cta:hover .nav-cta-arrow { transform: translateX(2px); }

/* Hamburger (Mobile) */
.nav-hamburger {
  display: none; width: 40px; height: 40px; border-radius: 12px;
  background: rgba(255,255,255,0.08); align-items: center; justify-content: center;
  flex-direction: column; gap: 5px; margin-left: auto;
  transition: background-color 300ms var(--ease-out);
}
.nav-hamburger span {
  display: block; width: 18px; height: 1.5px; background: rgba(255,255,255,0.85);
  border-radius: 2px; transition: transform 400ms var(--ease-spring), opacity 400ms var(--ease-spring);
  transform-origin: center;
}
/* Tablets: the full link row does not fit beside the logo and the call to
   action, so it tightens a little up to 1100px, and below 1000px the nav folds
   into the menu button as it does on phones (the search button stays). */
@media (max-width: 1100px) {
  .nav-logo { margin-right: 1.25rem; }
  .nav-link { padding: 0.5rem 0.75rem; }
}
@media (max-width: 1000px) {
  .nav-links, .nav-cta { display: none; }
  .nav-hamburger { display: flex; }
}
@media (min-width: 768px) and (max-width: 1000px) {
  .nav-search-btn { margin-left: auto; margin-right: 0.5rem; }
  .nav-hamburger { margin-left: 0; }
}
.nav-hamburger.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-hamburger.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Mobile Nav Overlay */
.nav-overlay {
  position: fixed; inset: 0; z-index: calc(var(--z-nav) - 1);
  background: rgba(0,29,45,0.97);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 500ms var(--ease-spring), visibility 500ms var(--ease-spring);
  /* a group scrolled into view when it opens lands below the pill, where the
     first link sits when the menu opens, so its own toggle stays in reach */
  scroll-padding-top: 5.5rem;
}
.nav-overlay.open { opacity: 1; visibility: visible; pointer-events: all; }
/* Over the open menu the pill turns solid, so the links scrolling up under it
   do not show through the logo */
.site-header:has(~ .nav-overlay.open) .nav-pill { background-color: rgba(0,29,45,0.97); }
.nav-overlay-links {
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  width: 100%; max-width: 30rem; margin: auto; padding: 5.5rem 1.5rem 2.5rem;
}
.nav-overlay-links > * { opacity: 0; transform: translateY(2rem); transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out); }
.nav-overlay.open .nav-overlay-links > :nth-child(1) { opacity: 1; transform: none; transition-delay: 100ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(2) { opacity: 1; transform: none; transition-delay: 150ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(3) { opacity: 1; transform: none; transition-delay: 200ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(4) { opacity: 1; transform: none; transition-delay: 250ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(5) { opacity: 1; transform: none; transition-delay: 300ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(6) { opacity: 1; transform: none; transition-delay: 350ms; }
.nav-overlay.open .nav-overlay-links > :nth-child(7) { opacity: 1; transform: none; transition-delay: 400ms; }
.nav-overlay-link {
  font-family: 'Montserrat', sans-serif; font-size: clamp(1.625rem, 6vw, 2.25rem); color: white;
  padding: 0.5rem 0; text-align: center; width: 100%; display: block;
}
.nav-overlay-link:hover { color: var(--teal); }
.nav-overlay-group { width: 100%; }
.nav-overlay-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.nav-overlay-row .nav-overlay-link { grid-column: 2; width: auto; }
.nav-overlay-toggle {
  grid-column: 3; justify-self: start; margin-left: 0.25rem;
  width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.85);
  transition: background 250ms var(--ease-out), color 250ms var(--ease-out);
}
.nav-overlay-toggle:hover { background: rgba(255,255,255,0.14); color: white; }
.nav-overlay-toggle .nav-chevron { width: 1.125rem; height: 1.125rem; opacity: 1; }
.nav-overlay-toggle[aria-expanded="true"] { background: rgba(105,166,166,0.22); color: var(--teal); }
.nav-overlay-toggle[aria-expanded="true"] .nav-chevron { transform: rotate(180deg); }
.nav-overlay-sub {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.125rem 0.75rem;
  padding: 0.5rem 0 1rem; margin: 0.25rem 0 0.25rem;
  border-top: 1px solid rgba(255,255,255,0.1); border-bottom: 1px solid rgba(255,255,255,0.1);
}
.nav-overlay-sub[hidden] { display: none; }
.nav-overlay-sublink {
  display: block; font-size: 0.9375rem; font-weight: 500; line-height: 1.3;
  color: rgba(255,255,255,0.78); padding: 0.5rem 0.5rem; border-radius: 0.5rem;
  transition: color 200ms var(--ease-out), background 200ms var(--ease-out);
}
.nav-overlay-sublink:hover { color: white; background: rgba(255,255,255,0.06); }
.nav-overlay-sublink--all { grid-column: 1 / -1; color: var(--teal); font-weight: 600; }
@media (max-width: 480px) { .nav-overlay-sub { grid-template-columns: 1fr; } .nav-overlay-sublink { padding: 0.4375rem 0.5rem; } }
.nav-overlay-cta {
  margin-top: 2rem; opacity: 0; transform: translateY(1.5rem);
  transition: opacity 600ms var(--ease-out) 500ms, transform 600ms var(--ease-out) 500ms;
}
.nav-overlay.open .nav-overlay-cta { opacity: 1; transform: none; }

/* ── 6. BUTTONS ───────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 0.625rem;
  font-weight: 700; border-radius: var(--radius-pill);
  transition: transform 400ms var(--ease-spring), box-shadow 400ms var(--ease-spring),
    background-color 400ms var(--ease-spring), border-color 400ms var(--ease-spring), color 400ms var(--ease-spring);
  font-family: 'Montserrat', sans-serif;
  cursor: pointer; border: none; white-space: nowrap;
}
.btn:active { transform: scale(0.97); }

.btn-primary {
  background: var(--orange); color: #fff; text-shadow: var(--on-orange-shadow); font-weight: 800;
  padding: 0.875rem 1.75rem;
  box-shadow: 0 8px 24px rgba(233,101,18,0.35);
  font-size: 0.875rem;
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 32px rgba(233,101,18,0.45); }
.btn-primary .btn-icon {
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(0,29,45,0.18); display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; transition: transform 300ms var(--ease-spring);
}
.btn-primary:hover .btn-icon { transform: translate(2px, -1px) scale(1.1); }

.btn-secondary {
  background: transparent; color: var(--text-primary);
  padding: 0.875rem 1.75rem; font-size: 0.875rem;
  border: 1.5px solid var(--line-strong);
}
.btn-secondary:hover { background: rgba(0,0,0,0.04); border-color: rgba(0,0,0,0.2); }

.btn-ghost-white {
  background: rgba(255,255,255,0.1); color: white;
  padding: 0.875rem 1.75rem; font-size: 0.9375rem;
  border: 1.5px solid rgba(255,255,255,0.2);
  backdrop-filter: blur(8px);
}
.btn-ghost-white:hover { background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.35); }

.btn-sm { padding: 0.625rem 1.25rem; font-size: 0.8125rem; }
.btn-lg { padding: 1.125rem 2.25rem; font-size: 1.0625rem; }

/* ── 7. DOUBLE-BEZEL CARDS ────────────────────────────────── */
/* A light card rests just off the page (elevation 1) inside a pale rim, and
   lifts to elevation 3 on hover. The inner core keeps its inset highlight. */
.card-shell {
  background: rgba(0,29,45,0.028);
  border: 1px solid rgba(0,29,45,0.06);
  border-radius: var(--radius-card);
  padding: 6px;
  box-shadow: var(--elev-1);
  transition: transform 450ms var(--ease-spring), box-shadow 450ms var(--ease-spring), border-color 300ms var(--ease-out);
}
.card-shell:hover { transform: translateY(-3px); box-shadow: var(--elev-3); }
.card-core {
  background: var(--bg-white);
  border-radius: var(--radius-inner);
  box-shadow: var(--shadow-inset-shine);
  overflow: hidden;
  height: 100%;
}

/* Dark variant */
.card-shell-dark {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-card);
  padding: 6px;
  transition: transform 450ms var(--ease-spring), box-shadow 450ms var(--ease-spring), border-color 300ms var(--ease-out);
}
.card-core-dark {
  background: var(--bg-dark-card);
  border-radius: var(--radius-inner);
  box-shadow: inset 0 1px 1px rgba(255,255,255,0.06);
  overflow: hidden;
  height: 100%;
}

/* Pointer glow. With a fine pointer and motion allowed, main.js adds .has-glow
   to the cards of the story, product, caught-out, case study, partner, review
   and commitment grids, and sets --mx/--my (the pointer in the card, px) as the
   pointer moves. ::after is a full size layer masked down to the card's rim
   (the 1px border and the 6px bezel) and lit by a jade glow under the pointer.
   On hover the card lifts straight up and does not tilt: a card turned in 3D is
   drawn flat and then resampled, which blurs its text for as long as the
   pointer rests on it. Dark cards also take a faint wash across the core. */
.has-glow { position: relative; }
.has-glow::after {
  content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 7px;
  pointer-events: none; opacity: 0;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(105,166,166,0.7), rgba(105,166,166,0) 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  transition: opacity 350ms ease;
}
.has-glow:hover::after { opacity: 1; }
.card-shell.has-glow:hover, .card-shell-dark.has-glow:hover {
  transform: translateY(-4px);
  box-shadow: var(--elev-3);
}
.card-shell-dark.has-glow:hover {
  border-color: rgba(255,255,255,0.16);
  box-shadow: 0 20px 60px rgba(0,0,0,0.35), 0 4px 16px rgba(0,0,0,0.2);
}
.card-shell-dark.has-glow > .card-core-dark { position: relative; isolation: isolate; }
.card-shell-dark.has-glow > .card-core-dark::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  pointer-events: none; opacity: 0; transition: opacity 350ms ease;
  background: radial-gradient(420px circle at calc(var(--mx, 50%) - 7px) calc(var(--my, 50%) - 7px), rgba(105,166,166,0.2), rgba(105,166,166,0) 65%);
}
.card-shell-dark.has-glow:hover > .card-core-dark::before { opacity: 1; }
/* The shell does the lifting, so a product card's core stays in its bezel */
.has-glow .product-card:hover { transform: none; }

/* ── 8. HERO SECTION ──────────────────────────────────────── */
.hero {
  position: relative; min-height: 100dvh;
  background: var(--bg-dark);
  display: flex; align-items: center;
  overflow: hidden; padding-top: 6rem;
}
/* Tablets: a little less than the full screen, so the next section shows */
@media (min-width: 769px) and (max-width: 1024px) {
  .hero { min-height: 90vh; }
}

/* Hero video background */
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  z-index: 0;
  opacity: 0.38;
  pointer-events: none;
}
/* Dark overlay keeps text legible over any video content */
.hero-video-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(
    160deg,
    rgba(0,29,45,0.88) 0%,
    rgba(0,29,45,0.70) 50%,
    rgba(0,29,45,0.6) 100%
  );
  pointer-events: none;
}


/* Video play/pause control */
.hero-video-toggle {
  position: absolute; right: 1.25rem; bottom: 1.25rem; z-index: 4;
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: rgba(0,29,45,0.7); color: #fff; border: 1px solid rgba(255,255,255,0.25);
  border-radius: var(--radius-pill); padding: 0.5rem 0.875rem 0.5rem 0.625rem; font-size: 0.8125rem; font-weight: 500;
  backdrop-filter: blur(8px); min-height: 44px;
}
.hero-video-toggle .icon { width: 18px; height: 18px; }
.hero-video-toggle:hover { background: rgba(0,29,45,0.9); }

/* ── HERO: Full-width single column layout ── */
.hero-content { position: relative; z-index: 3; }

@media (max-width: 768px) {
  .hero-headline { margin-top: 2.5rem; }
}


/* ── HERO: Headline & copy ── */
.hero-headline { color: white; margin-bottom: 1.5rem; max-width: 13ch; text-wrap: balance; }
/* Upright: Montserrat is self-hosted upright only, so italic here was a browser-synthesised
   oblique. The jade still separates this half of the headline. */
.hero-headline em { font-style: normal; color: var(--teal); }
.hero-sub { color: rgba(255,255,255,0.6); max-width: 520px; margin-bottom: 2.5rem; font-size: 1.125rem; line-height: 1.8; }
.hero-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
/* Centred hero: the same content stacked on the page's centre line */
.hero--centered .hero-content { display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero--centered .hero-headline { max-width: none; }
.hero--centered .hero-sub { max-width: 640px; }
.hero--centered .hero-actions { justify-content: center; }
.hero--centered .hero-credentials { justify-content: center; }

/* ── INDUSTRIES STRIP ── */
.industries-strip {
  background: var(--bg-primary);
  border-top: 1px solid rgba(0,0,0,0.06);
  border-bottom: 1px solid rgba(0,0,0,0.06);
  padding: 1.125rem 0;
}
.industries-strip-inner {
  display: flex; overflow: hidden;
}
.industries-strip-label {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-tertiary);
  white-space: nowrap; flex-shrink: 0;
  padding: 0 1.5rem 0 0;
  border-right: 1px solid rgba(0,0,0,0.08);
}
.industries-marquee-outer {
  flex: 1; overflow: hidden; position: relative; min-width: 0;
}
.industries-marquee-track {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  padding: 0 0 0 1.25rem;
}
.ind-tag {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.3125rem 0.75rem;
  background: var(--bg-primary);
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: var(--radius-pill);
  font-size: 0.8125rem; font-weight: 500; color: var(--text-secondary);
  transition: border-color 200ms, color 200ms;
  text-decoration: none;
}
a.ind-tag { color: var(--teal-text); border-color: rgba(105,166,166,0.5); font-weight: 600; min-height: 36px; }
a.ind-tag:hover, a.ind-tag:focus-visible { background: var(--teal-text); color: #fff; border-color: var(--teal-text); }
.industries-strip-inner { align-items: flex-start; }
.industries-strip-label { padding-top: 0.45rem; }
/* Homepage strip: label above, icon pills centred in tidy rows, and a faint
   jade wash plus dot grid behind them so the strip reads as a deliberate band
   between the hero and the next section. The pills' entrance (one after
   another once the strip scrolls into view) lives with the homepage's own
   styles in index.html. */
.industries-strip--clean {
  position: relative; overflow: hidden; isolation: isolate;
  padding: 2.25rem 0 2.5rem;
}
.industries-strip--clean::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(ellipse 60% 120% at 50% 100%, rgba(105,166,166,0.12), transparent 70%),
    radial-gradient(circle, rgba(0,29,45,0.09) 1px, transparent 1.5px) 0 0 / 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 70% 100% at 50% 50%, #000 40%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 100% at 50% 50%, #000 40%, transparent 100%);
}
.industries-strip--clean .industries-strip-inner { flex-direction: column; align-items: center; gap: 1.25rem; overflow: visible; }
.industries-strip--clean .industries-strip-label {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 0; padding: 0; color: var(--teal-text); letter-spacing: 0.16em;
}
.industries-strip--clean .industries-strip-label::before,
.industries-strip--clean .industries-strip-label::after {
  content: ''; width: 2.5rem; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(105,166,166,0.55));
}
.industries-strip--clean .industries-strip-label::after { transform: scaleX(-1); }
.industries-strip-label-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--teal);
  box-shadow: 0 0 0 3px rgba(105,166,166,0.18);
}
.industries-strip--clean .industries-marquee-track { justify-content: center; padding: 0; gap: 0.625rem; max-width: 1120px; margin: 0 auto; }
/* The clean strip wraps its pills and never scrolls, so the marquee's clip has
   nothing left to do: it only sliced the focus ring and the hover lift and
   shadow off the first and last rows. The strip itself still clips, well
   clear of them. (On phones the track scrolls, and makes its own room.) */
.industries-strip--clean .industries-marquee-outer { overflow: visible; }
.industries-strip--clean a.ind-tag {
  gap: 0.5rem; padding: 0.4375rem 1rem 0.4375rem 0.75rem; min-height: 38px;
  font-weight: 500; font-size: 0.8125rem; color: var(--text-secondary);
  background: #fff; border: 1px solid rgba(0,29,45,0.1);
  box-shadow: 0 1px 2px rgba(0,29,45,0.04);
  transition: background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out),
    border-color var(--dur-press) var(--ease-out), box-shadow var(--dur-press) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
}
.industries-strip--clean a.ind-tag .icon {
  width: 16px; height: 16px; color: var(--teal);
  transition: color 220ms var(--ease-out), transform 320ms var(--ease-out);
}
.industries-strip--clean a.ind-tag:hover, .industries-strip--clean a.ind-tag:focus-visible {
  background: var(--teal-text); color: #fff; border-color: var(--teal-text);
  box-shadow: 0 8px 20px rgba(63,111,118,0.22), 0 2px 6px rgba(0,29,45,0.08);
  transform: translateY(-2px);
}
.industries-strip--clean a.ind-tag:hover .icon, .industries-strip--clean a.ind-tag:focus-visible .icon { color: #fff; transform: scale(1.12); }
/* The "All industries" pill: outlined in jade with an arrow that nudges on hover. */
.industries-strip--clean a.ind-tag--all {
  padding: 0.4375rem 0.875rem 0.4375rem 1rem; font-weight: 600;
  color: var(--teal-text); background: rgba(105,166,166,0.06); border-color: rgba(105,166,166,0.45);
}
.ind-tag-arrow { width: 14px; height: 14px; flex-shrink: 0; transition: transform 320ms var(--ease-out); }
.industries-strip--clean a.ind-tag--all:hover .ind-tag-arrow, .industries-strip--clean a.ind-tag--all:focus-visible .ind-tag-arrow { transform: translateX(3px); }

/* ── HERO: Google rating ──
   First item of the trust line. Sourced from content/reviews/google-reviews.json
   and linked to the profile, so the score can be checked. The count is left
   off while it is small; the stars carry the colour. */
.hero-rating {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.875rem; font-weight: 500; color: rgba(255,255,255,0.82);
  text-decoration: none; transition: color 200ms ease;
}
.hero-rating:hover { color: #fff; }
.hero-rating:hover .hero-rating-text { text-decoration: underline; text-underline-offset: 3px; }
.hero-rating-stars { color: #F5B544; font-size: 0.875rem; letter-spacing: 0.06em; line-height: 1; }

/* ── HERO: Trust line (rating, memberships, licence) ── */
.hero-credentials {
  position: relative; z-index: 3;
  display: flex; align-items: center; gap: 1.25rem;
  margin-top: 4rem; padding-top: 1.75rem;
  border-top: 1px solid rgba(255,255,255,0.07);
  flex-wrap: wrap;
}
.hero-credential {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.875rem; font-weight: 500; color: rgba(255,255,255,0.7);
}
.hero-credential svg { color: rgba(255,255,255,0.55); flex-shrink: 0; }
.hero-cred-dot {
  width: 3px; height: 3px; border-radius: 50%;
  background: rgba(255,255,255,0.18); flex-shrink: 0;
}

/* ── 10. SECTION HEADERS ──────────────────────────────────── */
.section-header { margin-bottom: 4rem; }
.section-header-center { text-align: center; }
.section-title { margin-top: 0.875rem; margin-bottom: 1rem; max-width: 22ch; }
.section-header-center .section-title, .text-center .section-title { margin-left: auto; margin-right: auto; }
.section-body-center { max-width: 560px; margin: 0 auto; }

/* Editorial header: eyebrow and heading on the left, the standfirst beside
   them on the right, both sitting on one baseline. One column under 900px.
   Markup: .section-header--split > .section-header-main (eyebrow, h2) +
   p.section-header-aside. */
.section-header--split {
  display: grid; grid-template-columns: 1.25fr 1fr; gap: 4rem; align-items: end;
  text-align: left;
}
.section-header--split .section-title { max-width: none; margin-left: 0; margin-right: 0; margin-bottom: 0; }
.section-header--split .section-header-aside { max-width: 34rem; margin: 0; }
@media (max-width: 899px) {
  .section-header--split { grid-template-columns: 1fr; gap: 1rem; }
}

/* ── 12. SERVICES / RISK CARDS ────────────────────────────── */
.services-section { background: var(--bg-dark); }
.risk-cards-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }

.risk-card {
  position: relative;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-card);
  padding: 2.25rem 2rem 2rem;
  overflow: hidden;
  transition: border-color 300ms, background 300ms, transform 350ms cubic-bezier(0.34,1.56,0.64,1);
}
/* Top accent sweep on hover */
.risk-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--teal), var(--sprout));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 400ms ease;
}
.risk-card:hover::before { transform: scaleX(1); }
.risk-card:hover {
  border-color: rgba(105,166,166,0.2);
  background: rgba(255,255,255,0.07);
  transform: translateY(-6px);
}

/* Cards share a row height; the link and its rule sit at the bottom of every card */
.risk-card { display: flex; flex-direction: column; }
.risk-card-body { position: relative; display: flex; flex-direction: column; flex: 1; }
.risk-card-body .risk-card-link { margin-top: auto; }
/* Each card opens on a photo run edge to edge across its top: its own home_
   photo, or the category page's cover (the same covers_ key) */
.risk-card { padding-top: 0; }
.risk-card-photo {
  display: block; width: calc(100% + 4rem); max-width: none; margin: 0 -2rem 1.75rem;
  aspect-ratio: 16 / 9; height: auto; object-fit: cover;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
/* Keep each subject in the crop: the warehouse worker stands low in the
   frame, the plumber's head sits near the top */
.risk-card-photo[data-cms-img="home_assets"] { object-position: center 80%; }
.risk-card-photo[data-cms-img="home_liabilities"] { object-position: center 0%; }
/* The question leads each card; the category name sits beneath it after a
   short jade rule. Montserrat stays upright: only its upright face is self-hosted. */
.risk-card-body { container-type: inline-size; }
/* One size for all three, set from the card's width so the longest question
   ("Who could hold you responsible?", 15.25em wide) stays on one line */
.risk-card-hook {
  font-family: 'Montserrat', sans-serif;
  font-size: 1.3rem;
  font-size: min(1.3rem, calc(100cqw / 15.6));
  font-weight: 700;
  line-height: 1.2;
  color: white;
  margin: 0 0 0.875rem;
}
.risk-card-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: 'Montserrat', sans-serif;
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--teal);
  margin: 0 0 1.125rem;
  line-height: 1.2;
}
.risk-card-title::before { content: ""; width: 22px; height: 2px; border-radius: 1px; background: var(--teal); flex: 0 0 auto; }
.risk-card-desc {
  font-size: 0.9375rem;
  color: rgba(255,255,255,0.72);
  line-height: 1.75;
  margin-bottom: 1.5rem;
}
.risk-card-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--teal);
  text-decoration: none;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255,255,255,0.07);
  width: 100%;
  transition: gap 200ms, color 200ms;
}
.risk-card-link:hover { gap: 0.625rem; color: white; }

/* ── 13. WHY ARDENT (FEATURE GRID) ───────────────────────── */
.features-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}
.feature-card { padding: 2.25rem; }
.feature-icon {
  width: 52px; height: 52px; border-radius: 15px;
  background: var(--teal-tint);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.375rem; margin-bottom: 1.25rem;
  border: 1px solid rgba(105,166,166,0.2);
}
.feature-title { font-family: 'Montserrat', sans-serif; font-size: 1.25rem; color: var(--text-primary); margin-bottom: 0.625rem; }
.feature-desc { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.7; }
/* Feature cards on a dark card surface */
.card-core-dark .feature-desc { color: rgba(255,255,255,0.78); }
.card-core-dark .feature-title { color: #fff; }
.card-core-dark .feature-icon { color: var(--teal); background: rgba(105,166,166,0.14); border-color: rgba(105,166,166,0.35); }
.card-core-dark.feature-card { display: flex; flex-direction: column; }

/* ── 14. TESTIMONIALS ─────────────────────────────────────── */
.testimonials-section { background: var(--bg-primary); overflow: hidden; }
/* The heading sits on the section's centre line, with the cards (or the quote)
   and the "read all" button below it, as every stacked section heading does */
.reviews-header { margin-bottom: 3rem; text-align: center; }

.reviews-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
/* Auto-scrolling carousel (homepage). Pauses on hover, keyboard focus, the pause button, and reduced motion. */
.reviews-carousel { position: relative; }
.reviews-track-wrap {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 8%, black 92%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 8%, black 92%, transparent 100%);
  padding: 0.25rem 0 0.5rem;
}
/* The script repeats the cards once and the strip slides by half its width.
   One set of cards repeats every (card + gap), so the end padding matches the
   gap: without it half the strip is half a gap short, and the strip jumped
   8px each time the loop came round. */
.reviews-track { display: flex; gap: 1rem; padding-right: 1rem; width: max-content; animation: reviews-scroll 150s linear infinite; }
.reviews-track-wrap:hover .reviews-track, .reviews-track-wrap:focus-within .reviews-track, .reviews-carousel.is-paused .reviews-track { animation-play-state: paused; }
.reviews-track .review-slide { flex: 0 0 340px; width: 340px; }
@keyframes reviews-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
.reviews-controls { display: flex; justify-content: center; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: 1.5rem; }
.reviews-pause { display: inline-flex; align-items: center; gap: 0.5rem; }
.reviews-pause .icon { width: 16px; height: 16px; }
/* The .btn display would otherwise override [hidden], which the script sets
   when there is no scrolling to pause */
.reviews-pause[hidden] { display: none; }
/* On a phone the two controls stack, both as wide as the wider, the pair
   centred, as the banner's buttons do. Side by side they wrap below about
   410px (the paused label, "Resume scrolling", is the longer one), and a
   wrapped row leaves a short button over a longer one. */
@media (max-width: 480px) {
  .reviews-controls { flex-direction: column; align-items: stretch; width: fit-content; max-width: 100%; margin-inline: auto; }
  .reviews-controls .btn { justify-content: center; }
}
@media (max-width: 640px) { .reviews-track .review-slide { flex-basis: 280px; width: 280px; } }
/* A still strip that the reader scrolls: nothing for the pause button to do */
@media (prefers-reduced-motion: reduce) {
  .reviews-track { animation: none; }
  .reviews-track-wrap { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .reviews-pause { display: none; }
}
.reviews-grid .review-slide[hidden] { display: none; }
/* Every card in a row of reviews is as tall as the tallest */
.reviews-track .review-slide > .card-shell, .reviews-grid .review-slide > .card-shell { height: 100%; display: flex; flex-direction: column; }
.reviews-track .card-shell > .card-core, .reviews-grid .card-shell > .card-core { flex: 1; }
.review-card { padding: 1.75rem; height: 100%; display: flex; flex-direction: column; }
.review-card .review-author { margin-top: auto; }
.reviews-more-row { display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap; margin-top: 2rem; }
@media (max-width: 1024px) { .reviews-grid { grid-template-columns: repeat(2, 1fr); } }
/* Two to a row on a tablet: an odd last card sits centred under the pair, at
   the same width, instead of alone at the left of an empty row */
@media (min-width: 641px) and (max-width: 1024px) {
  .reviews-grid > .review-slide:last-child:nth-child(odd),
  .testimonials-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 1.25rem) / 2);
  }
}
/* Three to a row: a lone card on the last row takes the middle column */
@media (min-width: 1025px) {
  .reviews-grid > .review-slide:last-child:nth-child(3n+1) { grid-column: 2; }
}
@media (max-width: 640px) {
  /* A strip that bleeds to the screen edges; the scroll padding holds each card,
     the first included, on the page gutter when it snaps */
  .reviews-grid {
    display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory;
    margin: 0 calc(-1 * var(--container-pad)); padding: 0.25rem var(--container-pad) 1rem;
    scroll-padding-inline: var(--container-pad);
    -webkit-overflow-scrolling: touch; scrollbar-width: thin;
  }
  .reviews-grid .review-slide { flex: 0 0 min(84vw, 320px); scroll-snap-align: start; }
}
.review-stars { display: flex; gap: 2px; color: #B8860B; font-size: 0.875rem; margin-bottom: 1rem; letter-spacing: 0.05em; }
.review-text { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.7; margin-bottom: 1.25rem; }
.review-author { display: flex; align-items: center; gap: 0.75rem; }
.review-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--navy); display: flex; align-items: center; justify-content: center;
  font-size: 0.875rem; font-weight: 700; color: white; flex-shrink: 0;
}
.review-name { font-size: 0.9375rem; font-weight: 600; color: var(--text-primary); }
.review-business { font-size: 0.8125rem; color: var(--text-tertiary); }
.review-verified { display: flex; align-items: center; gap: 0.375rem; font-size: 0.8125rem; color: var(--text-tertiary); margin-top: 0.25rem; }
/* A review on a dark card: light text, and the brighter gold for the stars
   (every pair here is 5.9:1 or better on the dark card) */
.card-core-dark .review-text { color: rgba(255,255,255,0.78); }
.card-core-dark .review-name { color: #fff; }
.card-core-dark .review-business, .card-core-dark .review-verified { color: rgba(255,255,255,0.62); }
.card-core-dark .review-stars { color: #F5B544; }
.g-badge { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: #1a73e8; color: #fff; font-weight: 800; font-size: 0.6875rem; font-family: 'Montserrat', sans-serif; line-height: 1; }
.review-text--clamp { display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 0.5rem; }
/* .review-more takes the body link style (BODY LINKS) */
.review-more { align-self: flex-start; font-size: 0.875rem; font-weight: 600; margin-bottom: 1.25rem; }
/* One client review, featured on each product, industry and category page
   (written by the stamp from content/reviews/featured.json): a midnight card on
   the light section, a jade quote mark, the words in Montserrat at a size set by
   their length, and the client under a short rule. A long review is cut to a
   few lines, fading out, with a link to the whole of it on Google. */
.review-feature {
  position: relative; max-width: 880px; margin: 0 auto; text-align: center;
  background: var(--bg-dark); border-radius: var(--radius-card); box-shadow: var(--elev-3);
  padding: clamp(2.75rem, 6vw, 4.5rem) clamp(1.5rem, 6vw, 4.5rem) clamp(2.25rem, 5vw, 3.5rem);
  overflow: hidden; isolation: isolate;
}
/* a soft jade light behind the quote mark, as the glows do on light sections */
.review-feature::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(60% 55% at 50% 0%, rgba(105,166,166,0.22), rgba(105,166,166,0) 70%);
}
.review-feature::before {
  content: '\201C'; display: block; margin: 0 auto 0.25rem; height: 0.5em;
  font-family: Georgia, 'Times New Roman', serif; font-weight: 700; font-size: clamp(5rem, 10vw, 7rem); line-height: 0.9;
  color: var(--teal);
}
.review-feature-stars { display: flex; justify-content: center; gap: 3px; color: #F5B544; font-size: 1rem; letter-spacing: 0.05em; margin-bottom: 1.5rem; }
.review-feature-quote {
  margin: 0; font-family: 'Montserrat', sans-serif; font-weight: 600; color: #fff;
  font-size: clamp(1.375rem, 2.6vw, 2rem); line-height: 1.35; letter-spacing: -0.01em; text-wrap: balance;
}
.review-feature-quote p + p { margin-top: 0.75em; }
.review-feature-quote--mid { font-size: clamp(1.1875rem, 2.1vw, 1.5rem); line-height: 1.45; }
.review-feature-quote--long {
  font-size: clamp(1.0625rem, 1.8vw, 1.3125rem); line-height: 1.55; text-wrap: pretty;
  max-height: 10.5lh; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3lh), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 3lh), transparent);
}
.review-feature .review-more { display: table; margin: 1rem auto 0; --link-rule: rgba(105,166,166,0.75); color: var(--teal); }
.review-feature-cite {
  display: inline-flex; align-items: center; gap: 0.875rem; text-align: left;
  margin-top: 2rem; padding-top: 1.75rem; position: relative;
}
.review-feature-cite::before {
  content: ''; position: absolute; top: 0; left: 50%; width: 48px; height: 2px; margin-left: -24px;
  background: var(--teal); border-radius: 1px;
}
.review-feature .review-more + .review-feature-cite { margin-top: 1.5rem; }
.review-feature .review-avatar { width: 48px; height: 48px; font-size: 1rem; }
/* The avatar is Navy on light cards; on a dark card it takes Teal, so it does not vanish into the ground */
.review-feature .review-avatar, .card-core-dark .review-avatar { background: var(--teal); color: var(--navy); }
.review-feature-who { display: flex; flex-direction: column; gap: 0.25rem; }
.review-feature-name { font-family: 'Montserrat', sans-serif; font-weight: 700; font-size: 1.0625rem; color: #fff; }
.review-feature-source { display: flex; align-items: center; gap: 0.375rem; font-size: 0.875rem; color: rgba(255,255,255,0.7); }
.review-feature-source a { color: rgba(255,255,255,0.85); text-decoration: underline; text-decoration-color: rgba(105,166,166,0.75); text-underline-offset: 3px; }
.review-feature-source a:is(:hover, :focus-visible) { color: #fff; text-decoration-color: var(--teal); }
@media (max-width: 600px) {
  .review-feature { border-radius: var(--radius-md); }
  .review-feature-quote--long { max-height: 12.5lh; }
}
@media print {
  .review-feature-quote--long { max-height: none; -webkit-mask-image: none; mask-image: none; }
}

/* ── 15. PROCESS ──────────────────────────────────────────── */
/* One photo of a client's people at work between the heading and the steps */
.process-photo { margin: 0 0 2.5rem; border-radius: var(--radius-card); overflow: hidden; aspect-ratio: 21 / 8; box-shadow: var(--elev-2); }
.process-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 55%; }
@media (max-width: 768px) { .process-photo { aspect-ratio: 4 / 3; margin-bottom: 2rem; } }
.process-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; position: relative; --step-gap: 120ms; }
/* The four steps land one after another, counted among the cards alone (a grid
   may or may not start with the connector). On a single row the step is two and
   a half stagger steps, enough to read as one, two, three, four while the last
   card still lands inside a second and a quarter; when the grid wraps, each
   card enters as it scrolls in, so the step is shorter. */
@media (min-width: 1025px) { .process-grid { --step-gap: calc(var(--stagger) * 2.5); } }
.process-grid > .card-shell { --step-delay: 0ms; }
.process-grid > .card-shell ~ .card-shell { --step-delay: var(--step-gap); }
.process-grid > .card-shell ~ .card-shell ~ .card-shell { --step-delay: calc(var(--step-gap) * 2); }
.process-grid > .card-shell ~ .card-shell ~ .card-shell ~ .card-shell { --step-delay: calc(var(--step-gap) * 3); }
.process-grid > .card-shell.reveal { --reveal-delay: var(--step-delay); }
/* The cards sit above the connector, so the line only shows in the gaps */
.process-grid > .card-shell { position: relative; z-index: 1; }
/* Connector sits at the vertical middle of the cards and shows in the gaps
   between them. It draws in at a steady rate as the cards land, its own
   keyframe, played by .visible like any reveal, and rests at a quarter
   strength. A reset that shows every .reveal at full opacity (print, reduced
   motion, and the homepage's no-script style) puts it back to that quarter. */
.process-connector {
  position: absolute; top: 50%; left: calc(12.5% + 26px); right: calc(12.5% + 26px);
  height: 1px; background: var(--teal-text);
  opacity: 0.25; pointer-events: none;
}
.process-connector.reveal { transform-origin: left center; animation: process-draw var(--dur-signature) linear 150ms backwards paused; }
.process-connector.reveal.visible { animation-play-state: running; }
@keyframes process-draw { from { opacity: 0; transform: scaleX(0); } }
.process-step { padding: 2rem 1.5rem; text-align: center; }

/* ── CLAIMS CASE STUDY ────────────────────────────────────
   Event, what we did, the outcome. Illustrative: see CLAUDE.md. */
.case-study { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; align-items: stretch; }
.case-study-step { position: relative; padding: 1.75rem; height: 100%; }
.case-study-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%; margin-bottom: 0.875rem;
  background: rgba(105,166,166,0.14); color: var(--teal-text);
  font-family: 'Montserrat', sans-serif; font-size: 0.8125rem;
}
.case-study-step--outcome .case-study-num { background: rgba(233,101,18,0.14); color: var(--orange-text); }
.case-study-label {
  display: block; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--teal-text); margin-bottom: 0.5rem;
}
.case-study-step--outcome .case-study-label { color: var(--orange-text); }
.case-study-step p { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.65; margin: 0; }
.case-study-cover {
  max-width: 880px; margin: 1.75rem auto 0; text-align: center;
  font-size: 0.8125rem; color: var(--text-tertiary);
}
.case-study-cover a { font-weight: 600; }
/* Ardent's compliance note: every case study is illustrative (October 2026) */
.case-study-note {
  max-width: 880px; margin: 1.25rem auto 0; text-align: center;
  font-size: 0.8125rem; line-height: 1.6; color: var(--text-secondary);
}
.case-study-cover + .case-study-note { margin-top: 0.5rem; }
@media (max-width: 900px) { .case-study { grid-template-columns: 1fr; gap: 1rem; } }

/* ── SITE SEARCH ──────────────────────────────────────────────
   One dialog, opened from the desktop nav button or the mobile overlay.
   Index is built from the nav partial by scripts/build.js. */
.nav-search-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: 0 0 auto; margin-right: 0.75rem;
  border: 1px solid rgba(255,255,255,0.18); border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.75);
  cursor: pointer; transition: background-color 250ms var(--ease-out), color 250ms var(--ease-out);
}
.nav-search-btn:hover { background: rgba(255,255,255,0.13); color: #fff; }
.nav-search-btn .icon { width: 17px; height: 17px; }

.nav-overlay-search {
  display: flex; align-items: center; gap: 0.625rem; width: 100%;
  padding: 0.875rem 1rem; margin-bottom: 0.5rem;
  border: 1px solid rgba(255,255,255,0.18); border-radius: var(--radius-md);
  background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.7);
  font-size: 0.9375rem; font-family: inherit; text-align: left; cursor: pointer;
}
.nav-overlay-search .icon { width: 18px; height: 18px; flex: 0 0 auto; }

.site-search { position: fixed; inset: 0; z-index: 2000; }
.site-search[hidden] { display: none; }
.site-search-backdrop { position: absolute; inset: 0; background: rgba(0,20,31,0.72); }
.site-search-panel {
  position: relative; width: min(640px, calc(100vw - 2rem));
  margin: clamp(3rem, 12vh, 8rem) auto 0;
  background: var(--bg-white); border-radius: var(--radius-card);
  box-shadow: 0 24px 64px rgba(0,29,45,0.35); overflow: hidden;
}
.site-search-field {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.875rem 1rem; border-bottom: 1px solid rgba(0,0,0,0.08);
}
.site-search-icon { width: 18px; height: 18px; color: var(--text-tertiary); flex: 0 0 auto; }
.site-search-input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  font-family: inherit; font-size: 1rem; color: var(--text-primary);
}
.site-search-input::placeholder { color: var(--text-tertiary); }
.site-search-close {
  flex: 0 0 auto; border: 1px solid rgba(0,0,0,0.12); border-radius: 0.375rem;
  background: transparent; padding: 0.1875rem 0.5rem; cursor: pointer;
  font-family: inherit; font-size: 0.6875rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-tertiary);
}
.site-search-results { list-style: none; margin: 0; padding: 0.375rem; max-height: min(58vh, 460px); overflow-y: auto; overflow-x: hidden; }
.site-search-results:empty { display: none; }
.site-search-result a {
  display: block; padding: 0.625rem 0.75rem; border-radius: 0.5rem;
  color: var(--text-primary); text-decoration: none;
}
.site-search-result[aria-selected="true"] a,
.site-search-result a:hover { background: rgba(105,166,166,0.12); }
.site-search-result-head { display: flex; align-items: baseline; gap: 0.5rem; }
/* A long title wraps at a word rather than running out of the panel; the kind
   label stays on its first line */
.site-search-result-title { flex: 0 1 auto; font-size: 0.9375rem; font-weight: 600; }
/* the heading the match sits under, so the result says where on the page it is.
   A zero basis gives it only the room the title and the kind label leave, so a
   long crumb never squeezes the title onto a second line */
.site-search-result-sub {
  flex: 1 1 0; min-width: 0; font-size: 0.8125rem; color: var(--text-tertiary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.site-search-result-sub::before { content: "› "; }
.site-search-result-kind {
  flex: 0 0 auto; margin-left: auto; font-size: 0.6875rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-tertiary);
}
.site-search-result-snippet {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; margin-top: 0.1875rem; font-size: 0.8125rem; line-height: 1.5;
  color: var(--text-secondary);
}
.site-search-result mark {
  background: rgba(105,166,166,0.22); color: inherit; border-radius: 2px; padding: 0 1px;
  font-weight: 600;
}
.site-search-note { margin: 0; padding: 0.875rem 1.125rem; font-size: 0.875rem; color: var(--text-tertiary); }
.site-search-note:empty { display: none; }
@media (max-width: 767px) {
  .nav-search-btn { display: none; }
  .site-search-panel { margin-top: 1rem; }
  .site-search-results { max-height: 60vh; }
}
/* On a phone the crumb takes its own line under the title, where it has room
   to be read, rather than an ellipsis stub beside it. The title fills what the
   kind label leaves, so the label stays on the first line. It holds while
   the panel is narrower than its full 640px (up to 671px): every portrait
   phone and the smaller landscape ones, where beside the site's longest
   title (the cyber article's) the crumb shrank to a few pixels. At full
   width the crumb keeps a readable start beside even that title. */
@media (max-width: 671px) {
  .site-search-result-head { flex-wrap: wrap; row-gap: 0; }
  .site-search-result-title { flex: 1 1 0; }
  .site-search-result-sub { order: 3; flex-basis: 100%; }
}

/* Partner callout: sends consumer enquiries to the right partner without
   adding anything to the top nav. */
.partner-callout { max-width: 880px; margin: 0 auto; }
.partner-callout-core {
  display: flex; align-items: center; gap: 1.5rem;
  padding: 1.75rem 2rem;
}
.partner-callout-icon {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 0.75rem;
  display: flex; align-items: center; justify-content: center;
  background: rgba(105,166,166,0.14); color: var(--teal-text);
}
.partner-callout-icon .icon { width: 22px; height: 22px; }
.partner-callout-body { flex: 1; min-width: 0; }
.partner-callout-label {
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--teal-text); margin: 0 0 0.25rem;
}
.partner-callout-title {
  font-family: 'Montserrat', sans-serif; font-size: 1.125rem;
  color: var(--text-primary); margin: 0 0 0.375rem;
}
.partner-callout-desc {
  font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.6; margin: 0;
}
.partner-callout-core .btn { flex: 0 0 auto; }
/* Ardent's referral disclosure (compliance wording, October 2026), under a
   partner callout and the partners grid */
.referral-note {
  max-width: 880px; margin: 1.25rem auto 0; text-align: center;
  font-size: 0.8125rem; line-height: 1.6; color: var(--text-secondary);
}
.partners-grid + .referral-note { margin-top: 2.5rem; }
@media (max-width: 720px) {
  .partner-callout-core { flex-direction: column; align-items: flex-start; gap: 1.125rem; padding: 1.5rem; }
  .partner-callout-core .btn { width: 100%; justify-content: center; }
}

.process-number {
  width: 52px; height: 52px; border-radius: 50%; position: relative;
  background: var(--navy); display: flex; align-items: center; justify-content: center;
  font-family: 'Montserrat', sans-serif; font-size: 1.25rem; color: white;
  margin: 0 auto 1.25rem; box-shadow: 0 8px 24px rgba(0,29,45,0.25);
}
/* As the cards come into view the numbers turn Orange one after another,
   1 to 4, each pulsing once as it lights (Stephen, October 2026). The text
   stays put; only the circle changes. On one column each card is revealed
   as it scrolls in, so there is no gap between them. process-ping is the
   ring the renewal runway's pill sends out on renewal day. */
.process-grid { --num-gap: 450ms; }
@media (max-width: 480px) { .process-grid { --num-gap: 0ms; } }
.process-grid > .card-shell { --num-delay: 300ms; }
.process-grid > .card-shell ~ .card-shell { --num-delay: calc(300ms + var(--num-gap)); }
.process-grid > .card-shell ~ .card-shell ~ .card-shell { --num-delay: calc(300ms + var(--num-gap) * 2); }
.process-grid > .card-shell ~ .card-shell ~ .card-shell ~ .card-shell { --num-delay: calc(300ms + var(--num-gap) * 3); }
.process-grid > .card-shell.visible .process-number {
  animation: process-pulse 700ms var(--ease-out) both, process-light 500ms var(--ease-out) both;
  animation-delay: var(--num-delay), var(--num-delay);
}
@keyframes process-pulse { 0% { transform: scale(1); } 40% { transform: scale(1.16); } 100% { transform: scale(1); } }
@keyframes process-light { to { background-color: var(--orange); box-shadow: 0 8px 24px rgba(233,101,18,0.32); text-shadow: var(--on-orange-shadow); } }
@keyframes process-ping { 0% { opacity: 0.7; transform: scale(0.9); } 100% { opacity: 0; transform: scale(1.9); } }
.process-title { font-family: 'Montserrat', sans-serif; font-size: 1.125rem; color: var(--text-primary); margin-bottom: 0.625rem; }
.process-desc { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.65; }

/* ── 16. ARTICLES PREVIEW ─────────────────────────────────── */
.article-card { display: flex; flex-direction: column; overflow: hidden; }
.article-card-img {
  aspect-ratio: 16/10; background: var(--teal-tint);
  position: relative; overflow: hidden;
  border-radius: var(--radius-inner) var(--radius-inner) 0 0;
}
.article-card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-state) var(--ease-out); }
.article-card:hover .article-card-img img { transform: scale(1.04); }
.article-card-body { padding: 1.75rem; flex: 1; display: flex; flex-direction: column; }
.article-category {
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--teal-text); margin-bottom: 0.75rem;
}
.article-title { font-family: 'Montserrat', sans-serif; font-size: 1.25rem; color: var(--text-primary); margin-bottom: 0.75rem; line-height: 1.3; }
.article-excerpt { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.65; flex: 1; margin-bottom: 1.25rem; }
.article-meta { display: flex; align-items: center; gap: 0.75rem; font-size: 0.8125rem; color: var(--text-tertiary); flex-wrap: wrap; }
.article-meta-dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; }
.article-read-more {
  display: inline-flex; align-items: center; gap: 0.375rem; min-height: 44px;
  font-size: 0.875rem; font-weight: 600; color: var(--teal-text);
  margin-top: 1rem; transition: gap 300ms var(--ease-out);
}
.article-read-more:hover { gap: 0.625rem; }

/* The whole card is the click target: the read-more link stretches over it.
   Keeps one link in the accessibility tree and stays keyboard focusable. */
.article-card { position: relative; }
.article-card .article-read-more::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  border-radius: var(--radius-card);
}
.article-card:focus-within { outline: 2px solid var(--teal-text); outline-offset: 3px; }
.article-card .article-read-more:focus-visible { outline: none; }
.article-card:hover .article-read-more { gap: 0.625rem; }

/* Featured article card: spans the grid, image beside text */
.article-card--featured { grid-column: 1 / -1; }
.article-card--featured .card-core { display: grid; grid-template-columns: 1.1fr 1fr; }
.article-card--featured .article-card-img { aspect-ratio: auto; min-height: 280px; height: 100%; border-radius: var(--radius-inner) 0 0 var(--radius-inner); }
.article-card--featured .article-card-body { padding: 2.5rem; justify-content: center; }
.article-card--featured .article-title { font-size: 1.75rem; }
.article-card--featured .article-excerpt { font-size: 0.9375rem; flex: 0 0 auto; }
@media (max-width: 768px) {
  .article-card--featured .card-core { grid-template-columns: 1fr; }
  .article-card--featured .article-card-img { aspect-ratio: 16/10; min-height: 0; height: auto; border-radius: var(--radius-inner) var(--radius-inner) 0 0; }
  .article-card--featured .article-card-body { padding: 1.75rem; }
  .article-card--featured .article-title { font-size: 1.375rem; }
}

/* ── 17. CTA BANNER ───────────────────────────────────────── */
.cta-banner {
  background: var(--bg-dark);
  position: relative; overflow: hidden;
}
.cta-banner-orb {
  position: absolute; border-radius: 50%; filter: blur(60px); pointer-events: none;
}
.cta-banner-orb-1 { width: 400px; height: 400px; background: rgba(105,166,166,0.2); left: -100px; top: -100px; }
.cta-banner-orb-2 { width: 400px; height: 400px; background: rgba(156,197,175,0.2); right: -100px; bottom: -100px; }
/* The banner ends every page directly on the footer, the same midnight, and
   the lower orb is brightest right on that line, where the banner's clip would
   cut it straight across. So the banner's foot fades back to midnight under
   the orbs and the glow runs out before the footer starts. The ramp eases in
   and out (smoothstep): a straight one starts falling at full slope inside
   the orb's bright middle and draws a faint line across it. A gradient is
   straight between its stops, so each stop is a small corner; sampled every
   6.25% (8px), no corner is sharp enough to read as a line. */
.cta-banner::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 8rem; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom, rgba(0,29,45,0) 0%, rgba(0,29,45,0.011) 6.25%, rgba(0,29,45,0.043) 12.5%,
    rgba(0,29,45,0.092) 18.75%, rgba(0,29,45,0.156) 25%, rgba(0,29,45,0.232) 31.25%, rgba(0,29,45,0.316) 37.5%,
    rgba(0,29,45,0.407) 43.75%, rgba(0,29,45,0.5) 50%, rgba(0,29,45,0.593) 56.25%, rgba(0,29,45,0.684) 62.5%,
    rgba(0,29,45,0.768) 68.75%, rgba(0,29,45,0.844) 75%, rgba(0,29,45,0.908) 81.25%, rgba(0,29,45,0.957) 87.5%,
    rgba(0,29,45,0.989) 93.75%, var(--bg-dark) 100%);
}
.cta-banner-content { position: relative; z-index: 2; text-align: center; }
.cta-banner-title { color: white; margin-bottom: 1.25rem; max-width: 22ch; margin-left: auto; margin-right: auto; }
.cta-banner-sub { color: rgba(255,255,255,0.6); max-width: 480px; margin: 0 auto 2.5rem; font-size: 1.0625rem; }
.cta-banner-actions { display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; }
/* Up to 799px the two buttons stack, each as wide as the wider, with the pair
   centred and each label centred on its pill. The longest pair (the "Also
   consider" pill for Public & Products Liability) needs about 780px side by
   side; left to wrap just above 768px, it fell into a short button over a
   long one. */
@media (max-width: 799px) {
  .cta-banner-actions { flex-direction: column; align-items: stretch; width: fit-content; max-width: 100%; margin-inline: auto; }
  .cta-banner-actions .btn { justify-content: center; }
}

/* ── 18. FOOTER ───────────────────────────────────────────── */
/* No rule on top: most pages end on a midnight banner, where a hairline drew a hard line between the two (Stephen, October 2026) */
.site-footer { background: var(--bg-dark); padding-top: 5rem; }
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 3rem; padding-bottom: 4rem;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.footer-brand { max-width: 280px; }
.footer-logo { display: flex; align-items: center; gap: 0.625rem; margin-bottom: 1.25rem; }
.footer-logo img { display: block; width: auto; }
.footer-brand-desc { font-size: 0.9375rem; color: rgba(255,255,255,0.7); line-height: 1.75; margin-bottom: 1.75rem; }
.footer-contact-item { display: flex; align-items: flex-start; gap: 0.625rem; font-size: 0.875rem; color: rgba(255,255,255,0.7); margin-bottom: 0.625rem; }
.footer-contact-item a { color: rgba(255,255,255,0.85); transition: color 200ms; padding: 0.2rem 0; display: inline-block; }
.footer-contact-item a:hover { color: var(--teal); }
.footer-contact-icon { opacity: 0.5; flex-shrink: 0; }

.footer-col-title { font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255,255,255,0.6); margin-bottom: 1.25rem; }
.footer-col-title--spaced { margin-top: 2rem; }
.footer-links { display: flex; flex-direction: column; gap: 0.625rem; }
.footer-link { font-size: 0.9375rem; color: rgba(255,255,255,0.7); transition: color 200ms; padding: 0.3rem 0; display: inline-block; }
.footer-link:hover { color: white; }
/* "View all" at the foot of a column: jade, with its arrow nudging on hover */
.footer-link--all { color: var(--teal); margin-top: 0.25rem; }
.footer-link--all:hover { color: var(--sprout); }
.footer-link--all span { display: inline-block; transition: transform 250ms var(--ease-out); }
.footer-link--all:hover span, .footer-link--all:focus-visible span { transform: translateX(3px); }

/* Licence lines first, one entity per line with its numbers set off by drawn
   dots (screen readers hear the numbers, not punctuation); then a hairline
   and a row with the copyright on the left and the links on the right. */
.footer-bottom { padding: 2rem 0; }
.footer-legal { display: grid; gap: 0.375rem; }
.footer-legal-line { margin: 0; font-size: 0.8125rem; line-height: 1.6; color: rgba(255,255,255,0.65); }
.footer-legal-name { color: rgba(255,255,255,0.9); font-weight: 600; }
/* The general advice warning (Ardent's compliance wording, October 2026) leads
   the licence lines, which finish it by naming the licensee */
.footer-legal-warning { max-width: 60rem; margin-bottom: 0.75rem; }
.footer-legal-id { white-space: nowrap; }
.footer-legal-id::before, .footer-bottom-link--credit::before {
  content: ""; display: inline-block; width: 3px; height: 3px; border-radius: 50%;
  background: var(--teal); vertical-align: middle; margin: 0 0.625rem 0.15em 0.375rem;
}
.footer-bottom-meta {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 2rem;
  margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid rgba(255,255,255,0.08);
  /* keep the links clear of the fixed back-to-top button (2rem in, 48px wide) */
  padding-right: max(0px, calc(5.5rem - (100vw - 100%) / 2));
}
.footer-bottom-links { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.footer-bottom-link { font-size: 0.875rem; color: rgba(255,255,255,0.65); transition: color 200ms; padding: 0.375rem 0; display: inline-block; }
.footer-bottom-link:hover { color: #fff; }
.footer-bottom-link--credit::before { margin: 0 1.5rem 0.15em 0; }
.footer-copyright { margin: 0; font-size: 0.875rem; color: rgba(255,255,255,0.65); }

/* Steadfast membership mark in the footer: no box, sized just under the Ardent logo */
.steadfast-badge { display: block; }
.steadfast-badge img { display: block; width: 130px; height: auto; opacity: 0.9; }

/* ── 19. PAGE HERO (INNER PAGES) ──────────────────────────── */
/* The grid and orbs sit in .page-hero-bg, which clips them the way the
   section itself used to. */
.page-hero {
  background: var(--bg-dark);
  padding: 10rem 0 6rem;
  position: relative; z-index: 2;
}
.page-hero-bg { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.page-hero-orb {
  position: absolute; border-radius: 50%; filter: blur(80px); pointer-events: none;
}
.page-hero-orb-1 { width: 400px; height: 400px; background: rgba(105,166,166,0.2); top: -50px; right: 10%; }
.page-hero-orb-2 { width: 300px; height: 300px; background: rgba(156,197,175,0.2); bottom: -50px; left: 5%; }
.page-hero-grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px);
  background-size: 60px 60px;
}
.page-hero-content { position: relative; z-index: 2; }
.page-hero-title { color: white; margin-top: 1rem; margin-bottom: 1.25rem; max-width: 18ch; }
.page-hero-desc { color: rgba(255,255,255,0.6); max-width: 560px; font-size: 1.125rem; line-height: 1.75; }
.page-hero-breadcrumb { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: rgba(255,255,255,0.65); margin-bottom: 1.5rem; flex-wrap: wrap; }
.page-hero-breadcrumb a { color: rgba(255,255,255,0.75); transition: color 200ms; padding: 0.375rem 0; }
.page-hero-breadcrumb a:hover { color: rgba(255,255,255,0.8); }
.page-hero-breadcrumb span { color: rgba(255,255,255,0.45); }
@media (max-width: 768px) {
  .page-hero { padding: 6.5rem 0 3.5rem; }
  .page-hero-desc { font-size: 1rem; }
}
/* Hero photo (product and industry pages, October 2026): a full-bleed photo
   behind the hero's words under a midnight fade. The stamp adds .page-hero--photo
   only when content/images.json gives the page a hero_ photo; without one the
   layer stays hidden and the hero keeps its grid and orbs. */
.page-hero-photo { display: none; }
/* A photo hero is as tall as the screen allows (up to 60% of its width), so
   a 3:2 photo loses little of its height to the crop on a wide screen. */
.page-hero--photo { padding: 12rem 0 9rem; min-height: min(100svh, 60vw); display: flex; flex-direction: column; justify-content: center; }
.page-hero--photo > .container { width: 100%; }
.page-hero--photo .page-hero-grid,
.page-hero--photo .page-hero-orb { display: none; }
.page-hero--photo .page-hero-photo { display: block; position: absolute; inset: 0; }
.page-hero--photo .page-hero-photo img { width: 100%; height: 100%; object-fit: cover; object-position: 70% 30%; filter: saturate(0.85); }
.page-hero--photo .page-hero-photo::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, var(--bg-dark) 0%, rgba(0,29,45,0.92) 32%, rgba(0,29,45,0.55) 58%, rgba(0,29,45,0.15) 100%);
}
/* The fade into the section below rides the hero itself, not the photo,
   because the photo is fixed to the screen and the hero's foot moves. */
.page-hero--photo .page-hero-bg::after {
  content: ""; position: absolute; inset: auto 0 0; height: 30%;
  background: linear-gradient(0deg, var(--bg-dark) 0%, rgba(0,29,45,0) 100%);
}
/* On screen the photo holds still while the page moves over it, as the
   homepage video does: fixed to the screen and clipped to the hero (a
   clip-path clips a fixed child, where overflow does not), so the hero's
   words and then the section after it rise over the picture like layers.
   Under reduced motion and in print it scrolls with the page. Nothing on the
   hero or above it may take a transform, filter, perspective, contain or
   will-change, or the fixed layer would scroll after all. */
@media screen and (prefers-reduced-motion: no-preference) {
  .page-hero--photo { clip-path: inset(0); }
  .page-hero--photo .page-hero-photo { position: fixed; inset: 0 0 auto; height: 100vh; height: 100lvh; }
}
/* As the hero leaves, the photo dims into the midnight behind it (opacity only). */
@supports (animation-timeline: view()) {
  @media screen and (prefers-reduced-motion: no-preference) {
    .page-hero--photo { view-timeline: --page-hero-photo block; view-timeline-inset: 0; }
    .page-hero--photo .page-hero-photo img { animation: page-hero-photo-dim linear both; animation-timeline: --page-hero-photo; animation-range: exit 0% exit 100%; }
  }
}
@keyframes page-hero-photo-dim { to { opacity: 0.3; } }
/* Wider screens: the photo starts 30% in from the left, over the midnight, so a
   centred subject sits right of the words instead of under the fade (Stephen,
   October 2026). The frame is narrower than the screen, so the photo crops less
   of its width and is drawn no larger than before. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo { left: 30%; }
  .page-hero--photo .page-hero-photo::after {
    background: linear-gradient(90deg, var(--bg-dark) 0%, rgba(0,29,45,0.8) 22%, rgba(0,29,45,0.4) 50%, rgba(0,29,45,0.1) 100%);
  }
}
/* Residential Strata's couple stand in the middle of their photo, so on wider
   screens the frame starts further right (by the screen's shape, so the woman
   is never cut off) and the photo hangs from its left edge, keeping both clear
   of the words (Stephen, November 2026). Keyed to the picture, so a new photo
   in the site editor still gets this; take it out if the new one does not need it.
   The shared navy fade and desaturation left their skin grey, so this photo
   keeps its own colour and the fade clears before it reaches them. The frame's
   edge is rounded to a whole pixel, or a faint line of photo shows along it. */
.page-hero--photo .page-hero-photo img[data-cms-img="hero_residential_strata"] { filter: none; }
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_residential_strata"]) { left: clamp(34%, calc(96% - 105vh), 44%); left: round(clamp(34%, calc(96% - 105vh), 44%), 1px); }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_residential_strata"])::after {
    background: linear-gradient(90deg, var(--bg-dark) 0%, rgba(0,29,45,0.75) 20%, rgba(0,29,45,0.2) 42%, rgba(0,29,45,0) 60%);
  }
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_residential_strata"] { object-position: 0% 30%; }
}
/* On phones the couple's heads sit at the very top of the photo, under the
   menu bar, so phones show a copy with plain wall added above them
   (images/uploads/hero-residential-strata-tall.webp), drawn as the frame's
   background so the stamped <img> stays as it is. It is the same photo, so if
   the top of page photo changes in the site editor, take this out (or make a
   new tall copy), or phones keep the old one. */
@media (max-width: 768px) {
  .page-hero--photo:has(img[data-cms-img="hero_residential_strata"]) { padding-top: 30rem; }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_residential_strata"]) {
    height: 36.75rem;
    background: url("/images/uploads/hero-residential-strata-tall.webp") 50% 0 / cover no-repeat;
  }
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_residential_strata"] { visibility: hidden; }
}
@supports (animation-timeline: view()) {
  @media screen and (max-width: 768px) and (prefers-reduced-motion: no-preference) {
    .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_residential_strata"]) { animation: page-hero-photo-dim linear both; animation-timeline: --page-hero-photo; animation-range: exit 0% exit 100%; }
  }
}
/* Prestige Home: the father and child sit right of centre in the photo, so the
   crop shows more of its left side to move them further right, clear of the
   words (Stephen, 1 November 2026). Take this out if the top of page photo
   changes in the site editor. */
.page-hero--photo .page-hero-photo img[data-cms-img="hero_prestige_home"] { object-position: 30% 30%; }
@media (max-width: 768px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_prestige_home"] { object-position: 40% 30%; }
}
/* Valuables: the jeweller's face and loupe sit left of centre in the photo, so
   on wider screens the crop shows its left edge to move them right, clear of
   the words; phones keep the default crop, which already centres the loupe
   (Stephen, 1 November 2026). Take this out if the top of page photo changes
   in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_valuables"] { object-position: 0% 30%; }
}
/* Business Interruption: the two workers stand right of centre, so on wider
   screens the crop shows a little more of the photo's left side to move them clear of
   the heading; phones keep the default crop (Stephen, 1 November 2026). Take
   this out if the top of page photo changes in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_business_interruption"] { object-position: 45% 30%; }
}
/* Professional Indemnity and Workers Compensation: the man at the laptop and
   the warehouse worker stand near the middle of their photos, so on wider
   screens the crop shows each photo's left edge to move them right, clear of
   the words; phones keep the default crop (Stephen, 1 November 2026). Take
   these out if the top of page photo changes in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_professional_indemnity"],
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_workers_compensation"] { object-position: 0% 30%; }
}
/* Corporate Travel's photo is portrait, so it already fills the frame's width
   and the crop cannot move him; on wider screens the frame itself starts
   further right instead (Stephen, 1 November 2026). Take this out if the top
   of page photo changes in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_corporate_travel"]) { left: 42%; }
}
/* Food and Beverage: in the mirrored photo the worker behind the cans sits mid
   frame, under the heading, so on wider screens the frame starts further right
   and shows the photo's left edge, putting her face right of the words; phones
   keep the default crop, which shows both workers above the words (Stephen,
   1 November 2026). Take this out if the top of page photo changes in the site
   editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_food_beverage"]) { left: 44%; }
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_food_beverage"] { object-position: 0% 30%; }
}
/* Manufacturing: the two workers at the box folding machine stand right of
   centre, with their helmets near the top of the photo. On wider screens the
   crop shows a little more of the photo's left side, moving the man's arm
   clear of the heading (all the way on laptops). On phones the frame starts below the menu bar, so
   their heads are not under it, and its top edge fades from the midnight
   (Stephen, 1 November 2026). Take this out if the top of page photo changes
   in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_manufacturing"] { object-position: 25% 30%; }
}
@media (min-width: 769px) and (max-width: 1360px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_manufacturing"] { object-position: 0% 30%; }
}
@media (max-width: 768px) {
  .page-hero--photo:has(img[data-cms-img="hero_manufacturing"]) { padding-top: 27rem; }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_manufacturing"]) { top: 5.5rem; }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_manufacturing"])::after {
    background: linear-gradient(180deg, var(--bg-dark) 0%, rgba(0,29,45,0.1) 22%, rgba(0,29,45,0.35) 60%, var(--bg-dark) 100%);
  }
}
/* Pharmaceuticals: in the mirrored lab photo the scientist sits right of
   centre, so on wider screens the crop shows a little more of the photo's left
   side, keeping his face clear of the heading; phones keep the default crop
   (Stephen, 1 November 2026). Take this out if the top of page photo changes
   in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_pharmaceuticals"] { object-position: 35% 30%; }
}
/* Transport and Fleet: the two workers beside the trailer stand right of
   centre, so on wider screens the crop shows a little more of the photo's left
   side, moving the bearded man clear of the heading (further on laptops). On phones the crop moves
   right to keep both men in frame, and the frame starts below the menu bar, so
   their helmets are not under it, with its top edge fading from the midnight
   (Stephen, 1 November 2026). Take this out if the top of page photo changes
   in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_transport_fleet"] { object-position: 40% 30%; }
}
@media (min-width: 769px) and (max-width: 1360px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_transport_fleet"] { object-position: 25% 30%; }
}
@media (max-width: 768px) {
  .page-hero--photo:has(img[data-cms-img="hero_transport_fleet"]) { padding-top: 27rem; }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_transport_fleet"]) { top: 5.5rem; }
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_transport_fleet"] { object-position: 92% 30%; }
  .page-hero--photo .page-hero-photo:has(img[data-cms-img="hero_transport_fleet"])::after {
    background: linear-gradient(180deg, var(--bg-dark) 0%, rgba(0,29,45,0.1) 22%, rgba(0,29,45,0.35) 60%, var(--bg-dark) 100%);
  }
}
/* Engineering: the engineer reading plans stands right of centre, so on wider
   screens the crop shows a little more of the photo's left side, moving his
   plans clear of the heading while keeping his right arm on screen (more so
   on laptops); phones keep the default crop, which puts his helmet below the
   menu bar (Stephen, 1 November 2026).
   Take this out if the top of page photo changes in the site editor. */
@media (min-width: 769px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_engineering"] { object-position: 45% 30%; }
}
@media (min-width: 769px) and (max-width: 1360px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_engineering"] { object-position: 30% 30%; }
}
/* Property and Real Estate: in the mirrored photo the agent and the couple
   stand right of centre, and the default phone crop cuts the man off at the
   right edge, so phones show the photo's right side, keeping all three in
   frame; wider screens keep the default crop (Stephen, 1 November 2026).
   Take this out if the top of page photo changes in the site editor. */
@media (max-width: 768px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_property_real_estate"] { object-position: 90% 30%; }
}
/* Technology: the man at the laptop in the data centre stands at the photo's
   right edge, so on wider screens the crop shows the photo's right side,
   keeping his back and shoulder on screen rather than cut off at the edge;
   tablets and phones keep the default crop (Stephen, 1 November 2026). Take
   this out if the top of page photo changes in the site editor. */
@media (min-width: 1025px) {
  .page-hero--photo .page-hero-photo img[data-cms-img="hero_technology"] { object-position: 100% 30%; }
}
.page-hero--photo .page-hero-desc { color: rgba(255,255,255,0.78); }
/* Phones: the photo fills the top of the hero and fades into the words below it. */
@media (max-width: 768px) {
  .page-hero--photo { padding: 22rem 0 3.5rem; min-height: 0; display: block; }
  .page-hero--photo .page-hero-photo { bottom: auto; height: 30rem; }
  .page-hero--photo .page-hero-bg::after { display: none; }
  .page-hero--photo .page-hero-photo img { object-position: 60% 30%; }
  .page-hero--photo .page-hero-photo::after {
    background: linear-gradient(180deg, rgba(0,29,45,0.5) 0%, rgba(0,29,45,0.1) 25%, rgba(0,29,45,0.35) 60%, var(--bg-dark) 100%);
  }
}
/* The orbs drift slowly on large screens, as the banner's do. Phones keep them
   still: they are big blurred layers. */
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
  .page-hero-orb { will-change: translate, scale; }
  .page-hero-orb-1 { animation: page-hero-orb-drift-1 30s ease-in-out infinite alternate; }
  .page-hero-orb-2 { animation: page-hero-orb-drift-2 36s ease-in-out infinite alternate; }
}
@keyframes page-hero-orb-drift-1 { to { translate: -140px 70px; scale: 1.15; } }
@keyframes page-hero-orb-drift-2 { to { translate: 160px -60px; scale: 1.1; } }

/* ── 20. PRODUCT GRID (ASSETS/LIABILITIES/PEOPLE) ─────────── */
.products-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}
.product-card { padding: 2rem; transition: transform var(--dur-state) var(--ease-spring); }
.product-card:hover { transform: translateY(-4px); }
.product-card-icon {
  width: 56px; height: 56px; border-radius: 16px;
  background: var(--teal-tint); display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; margin-bottom: 1.5rem;
}
/* Orange is kept for the action, so the icon is Navy on a Teal tint */
.product-card-icon > svg:not(.icon) { stroke: var(--navy); }
.product-card-title { font-family: 'Montserrat', sans-serif; font-size: 1.25rem; color: var(--text-primary); margin-bottom: 0.625rem; }
.product-card-desc { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.7; margin-bottom: 1.5rem; }
.product-card-link {
  display: inline-flex; align-items: center; gap: 0.375rem; min-height: 44px;
  font-size: 0.875rem; font-weight: 600; color: var(--teal-text);
  transition: gap 300ms var(--ease-out);
}
.product-card-link:hover { gap: 0.625rem; }

.split-image img.cover-art { object-fit: cover; }

/* ── 21. ABOUT PAGE ───────────────────────────────────────── */
.split-section { display: grid; grid-template-columns: 1fr 1fr; gap: 5rem; align-items: center; }
/* A half-width column takes its display heading one size down */
.split-section .display-lg { font-size: clamp(1.75rem, 3.5vw, 2.75rem); line-height: 1.1; letter-spacing: -0.02em; }
.split-image-wrap {
  background: rgba(0,0,0,0.03);
  border: 1px solid rgba(0,0,0,0.06);
  border-radius: var(--radius-card);
  padding: 6px;
}
.split-image {
  border-radius: var(--radius-inner);
  aspect-ratio: 4/3;
  background: var(--teal-tint);
  overflow: hidden;
}
.split-image img { width: 100%; height: 100%; object-fit: cover; }

/* Pinned split with layered media (product "What's covered", industry "Before
   renewal"). On a wide screen the cover art holds still beside the list as it
   scrolls, and two layers move against the section's own view timeline at
   different rates: a jade plate offset behind the frame (::before) and the art
   inside the frame (translate, with room above and below). The frosted ring
   that sat over the frame's corner was taken out in October 2026. The frame keeps its .reveal entrance.
   The frame stops 1.75rem short of the column's edge, so the plate's offset
   ends on the page's right margin and never runs into the gutter.
   Under 1025px it is a plain split: no sticky, no layers. */
@media (min-width: 1025px) {
  .split-section--pinned { align-items: start; }
  .split-section--pinned .split-image-wrap { position: sticky; top: 8rem; isolation: isolate; margin-right: 1.75rem; }
  .split-section--pinned .split-image-wrap::before {
    content: ''; position: absolute; z-index: -1; inset: 2.25rem -1.75rem -1.75rem 2.25rem;
    border-radius: var(--radius-card); pointer-events: none;
    background: linear-gradient(140deg, rgba(156,197,175,0.55) 0%, rgba(105,166,166,0.3) 100%);
  }
  .split-section--pinned .split-image img { height: calc(100% + 56px); margin-top: -28px; }
}
@supports (animation-timeline: view()) {
  @media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
    .split-section--pinned { view-timeline: --split-media block; view-timeline-inset: 0; }
    .split-section--pinned .split-image-wrap::before {
      animation: linear both; animation-timeline: --split-media; animation-range: cover 0% cover 100%;
    }
    .split-section--pinned .split-image-wrap::before { animation-name: split-media-plate; }
    .split-section--pinned .split-image-wrap img {
      animation: split-media-art linear both; animation-timeline: --split-media; animation-range: cover 0% cover 100%;
    }
  }
  /* With a script to start it, a revealed frame's art carries two animations:
     the entrance settle (paused until .visible, like any reveal) and the
     scroll drift on its own timeline */
  @media (min-width: 1025px) and (prefers-reduced-motion: no-preference) and (scripting: enabled) {
    .split-section--pinned .split-image-wrap.reveal--media img {
      animation-name: reveal-media, split-media-art;
      animation-duration: var(--dur-signature), auto;
      animation-timing-function: var(--ease-out), linear;
      animation-delay: var(--reveal-delay, 0ms), 0s;
      animation-fill-mode: backwards, both;
      animation-play-state: paused, running;
      animation-timeline: auto, --split-media;
      animation-range: normal, cover 0% cover 100%;
    }
    .split-section--pinned .split-image-wrap.reveal--media.visible img { animation-play-state: running, running; }
  }
}
@keyframes split-media-plate { from { translate: 0 -22px; } to { translate: 0 22px; } }
@keyframes split-media-art { from { translate: 0 -24px; } to { translate: 0 24px; } }
/* A partner or network logo in the image column: on the page background, centred and never cropped */
.split-logo { display: flex; align-items: center; justify-content: center; padding: 2rem; }
.split-logo img { width: 78%; max-width: 440px; height: auto; object-fit: contain; }

.value-list { display: flex; flex-direction: column; gap: 1.25rem; margin-top: 2rem; }
.value-item { display: flex; align-items: flex-start; gap: 1rem; }
/* The tick is the sprite's check-circle (an .icon inside), in the jade the
   industry checklists use: no disc, and no typed tick from a fallback font */
.value-check {
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  font-size: 0.875rem; color: var(--teal-text); flex-shrink: 0; margin-top: 1px;
}
.value-check .icon { width: 22px; height: 22px; }
.value-item-text { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.6; }
.value-item-text strong { color: var(--text-primary); font-weight: 600; }

/* Glow sections: every section on the plain light background, on every page,
   carries soft glows of jade, sprout and a touch of navy (Stephen, October
   2026). .section--glow-alt mirrors them, and sits on every second section of
   a run of glow sections, so a page of light sections does not repeat one
   pattern. Static: nothing moves and nothing waits for a script, and the glows
   are faint enough that text contrast is unchanged. */
.section--glow { position: relative; isolation: isolate; }
.section--glow::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  /* The layer fades to nothing over the top and bottom 160px, so a glow is
     never cut off at a section's edge, however short the section: light
     sections meet with no line between them */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 160px, #000 calc(100% - 160px), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 160px, #000 calc(100% - 160px), transparent);
  background:
    radial-gradient(640px 400px at 15% 380px, rgba(105,166,166,0.16), transparent 70%),
    radial-gradient(640px 400px at 85% 50%, rgba(156,197,175,0.22), transparent 70%),
    radial-gradient(720px 400px at 30% calc(100% - 380px), rgba(0,29,45,0.05), transparent 70%);
}
@media (max-width: 768px) {
  /* A phone's single column makes a section several screens tall, so the
     glows alternate sides down its length */
  .section--glow::before {
    background:
      radial-gradient(90vw 380px at 0% 300px, rgba(105,166,166,0.16), transparent 70%),
      radial-gradient(90vw 380px at 100% 40%, rgba(156,197,175,0.24), transparent 70%),
      radial-gradient(90vw 380px at 0% 70%, rgba(105,166,166,0.12), transparent 70%),
      radial-gradient(90vw 380px at 100% calc(100% - 300px), rgba(0,29,45,0.05), transparent 70%);
  }
}

.section--glow-alt::before {
  background:
    radial-gradient(640px 400px at 85% 380px, rgba(156,197,175,0.22), transparent 70%),
    radial-gradient(640px 400px at 12% 50%, rgba(105,166,166,0.14), transparent 70%),
    radial-gradient(720px 400px at 70% calc(100% - 380px), rgba(0,29,45,0.05), transparent 70%);
}
@media (max-width: 768px) {
  .section--glow-alt::before {
    background:
      radial-gradient(90vw 380px at 100% 300px, rgba(156,197,175,0.24), transparent 70%),
      radial-gradient(90vw 380px at 0% 45%, rgba(105,166,166,0.14), transparent 70%),
      radial-gradient(90vw 380px at 100% calc(100% - 300px), rgba(0,29,45,0.05), transparent 70%);
  }
}

/* Light sections of two shades (the cream page and the grey --bg-secondary)
   meet without a step: the lower one starts in the upper one's colour and
   eases into its own over 280px. --from-primary goes on a grey section under
   a cream one, --from-secondary on a cream section under a grey one. A
   section that sets its colour with the background shorthand in a page's own
   styles still takes the blend, since these two classes are more specific;
   an inline style must set background-color only. */
.section.section--from-primary { background-image: linear-gradient(var(--bg-primary), rgba(255,255,255,0) 280px); }
.section.section--from-secondary { background-image: linear-gradient(var(--bg-secondary), rgba(242,244,244,0) 280px); }

/* Team Grid */
/* People in a row share its height, and each contact row sits at the foot of
   its column (see .team-contact), so the rows line up whatever the bios' length */
.team-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3rem 2rem; align-items: stretch; }
/* Advisor panels on product and industry pages carry one or two people, not six.
   --pair was already in use on the jewellers page with no rule behind it. */
.team-grid--pair { grid-template-columns: repeat(2, minmax(0, 300px)); justify-content: center; }
.team-grid--solo { grid-template-columns: minmax(0, 300px); justify-content: center; }
@media (max-width: 720px) { .team-grid--pair { grid-template-columns: minmax(0, 300px); } }
.team-member { text-align: center; display: flex; flex-direction: column; }

/* Portrait ring container */
.team-portrait-wrap {
  position: relative;
  width: 188px; height: 188px;
  margin: 0 auto 1.5rem;
  border-radius: 50%;
  /* Static gradient ring */
  background: linear-gradient(135deg, var(--teal) 0%, var(--sprout) 100%);
  transition: transform 380ms cubic-bezier(0.34,1.56,0.64,1), box-shadow 380ms ease;
}

/* Inner portrait circle */
.team-portrait {
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-secondary);
}
.team-portrait img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
  transform: scale(1);
  transition: transform 400ms cubic-bezier(0.34,1.56,0.64,1);
}
.team-member:hover .team-portrait img { transform: scale(1.04); }

/* Text */
.team-member-body { padding: 0 0.5rem; flex: 1; display: flex; flex-direction: column; }
.team-name {
  font-family: 'Montserrat', sans-serif; font-size: 1.25rem; font-weight: 600;
  color: var(--text-primary); margin-bottom: 0.25rem;
  transition: color 250ms ease, transform 250ms ease;
  display: block;
}
.team-member:hover .team-name { color: var(--teal-text); transform: translateY(-2px); }
.team-role {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--teal-text); margin-bottom: 0.875rem;
}
/* Post-nominals under the role (October 2026), so the bio itself stays short. */
.team-quals { font-size: 0.8125rem; font-weight: 600; line-height: 1.5; color: var(--text-primary); margin: -0.375rem 0 0.625rem; }
.team-quals + .team-focus { margin-top: 0; }
.team-focus { font-size: 0.875rem; color: var(--text-secondary); margin: -0.375rem 0 0.75rem; }
.team-bio { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.7; margin-bottom: 1.125rem; }
/* Contact row under each person: the mobile number with a round icon, then round
   icon buttons for email and LinkedIn. The address stays out of the markup text;
   it is only the mailto target. Shared by the About page team cards and the
   advisor panels on product and industry pages. No boxes, just the icons. The
   auto top margin takes the row to the foot of the column, so every contact row
   in a row of people shares one line, however long each bio runs. */
.team-contact { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0.5rem 0.625rem; margin: auto 0 0.25rem; }
.team-contact-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  background: var(--teal-tint); border: 1px solid rgba(105,166,166,0.22);
  color: var(--teal-text); text-decoration: none;
  transition: background 250ms var(--ease-out), border-color 250ms var(--ease-out), color 250ms var(--ease-out), transform 250ms var(--ease-out);
}
.team-contact-btn .icon { width: 18px; height: 18px; }
.team-contact-btn:hover { background: var(--teal-text); border-color: var(--teal-text); color: #fff; transform: translateY(-2px); }
/* The phone link is the icon circle plus the number as plain text, so it stays readable on a desktop */
.team-contact-btn--phone {
  width: auto; border-radius: var(--radius-pill); gap: 0.625rem;
  padding: 0 0.875rem 0 0; background: none; border-color: transparent;
  color: var(--text-primary); font-size: 0.875rem; font-weight: 600; letter-spacing: 0.01em;
}
.team-contact-btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  background: var(--teal-tint); border: 1px solid rgba(105,166,166,0.22); color: var(--teal-text);
  transition: background 250ms var(--ease-out), border-color 250ms var(--ease-out), color 250ms var(--ease-out);
}
.team-contact-btn--phone:hover { background: none; border-color: transparent; color: var(--teal-text); }
.team-contact-btn--phone:hover .team-contact-btn-icon { background: var(--teal-text); border-color: var(--teal-text); color: #fff; }

/* Legal pages: the reset strips list markers, so their lists take back the
   disc an article's lists carry. */
.legal-list > li { list-style: disc; }

/* ── 22. ARTICLES / BLOG ──────────────────────────────────── */
.articles-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 3rem; flex-wrap: wrap; gap: 1.5rem; }
.filter-btn {
  font-size: 0.8125rem; font-weight: 500; padding: 0.5rem 1rem;
  border-radius: var(--radius-pill); border: 1.5px solid rgba(0,0,0,0.1);
  color: var(--text-tertiary); background: transparent;
  transition: background-color 250ms var(--ease-out), color 250ms var(--ease-out), border-color 250ms var(--ease-out); cursor: pointer;
}
.filter-btn:hover, .filter-btn.active { background: var(--navy); color: white; border-color: var(--navy); }

/* The category pill on an article page. The page's own style block draws the
   pill and loads before this file, which sets its small capitals in the jade
   for text on light surfaces (--teal on the pale pill is under 3:1). */
.article-tag { color: var(--teal-text); }

.articles-full-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
@media (max-width: 1024px) { .articles-full-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) { .articles-full-grid { grid-template-columns: 1fr; } }

/* ── 23. CONTACT PAGE ─────────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: 1fr 1.4fr; gap: 4rem; align-items: start; }
/* No sticky: the details column is about as tall as the form, so a pin held
   it for a few pixels and then let go, which read as a wobble on scroll */
.contact-info-item {
  display: flex; align-items: flex-start; gap: 1rem;
  padding: 1.25rem; border-radius: 1rem;
  background: var(--bg-white); border: 1px solid rgba(0,0,0,0.06);
  margin-bottom: 0.875rem; transition: box-shadow 300ms var(--ease-out);
}
.contact-info-item:hover { box-shadow: var(--shadow-card); }
.contact-info-icon {
  width: 44px; height: 44px; border-radius: 12px;
  background: var(--teal-tint); border: 1px solid rgba(105,166,166,0.15);
  display: flex; align-items: center; justify-content: center; font-size: 1.125rem; flex-shrink: 0;
}
.contact-info-label { font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-tertiary); margin-bottom: 0.25rem; }
.contact-info-value { font-size: 0.9375rem; font-weight: 500; color: var(--text-primary); }
.contact-info-value a { transition: color 200ms; display: inline-block; padding: 0.375rem 0; }
.contact-info-value a:hover { color: var(--teal-text); }

.contact-form-wrap {
  background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06);
  border-radius: var(--radius-card); padding: 6px;
}
.contact-form-inner { background: var(--bg-white); border-radius: var(--radius-inner); padding: 2.5rem; }
.form-group { margin-bottom: 1.25rem; }
/* The gap runs between the two fields only: stacked on a phone, each field's
   own margin is the whole space to the next, as everywhere else in the form */
.form-row { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1rem; }
.form-label { display: block; font-size: 0.8125rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 0.5rem; }
.form-input, .form-select, .form-textarea {
  width: 100%; padding: 0.875rem 1rem; border-radius: 0.875rem;
  border: 1.5px solid rgba(0,0,0,0.1); background: var(--bg-primary);
  font-size: 0.9375rem; font-family: 'Noto Sans', sans-serif;
  color: var(--text-primary);
  transition: border-color 250ms var(--ease-out), background-color 250ms var(--ease-out), box-shadow 250ms var(--ease-out);
  outline: none;
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
  border-color: var(--teal-text); background: white;
  box-shadow: 0 0 0 4px rgba(105,166,166,0.1);
}
/* A block, so it does not sit on a text line: inline, the line below its
   baseline added 8px under it that no other field has */
.form-textarea { display: block; resize: vertical; min-height: 140px; }
/* Full width, with the label centred on it like every stretched button */
.form-submit { width: 100%; padding: 1rem; font-size: 1rem; justify-content: center; }
/* Honeypot field: off screen for people, visible to bots */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
/* Read out, not shown: a label or heading that sighted readers get from the layout */
.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;
}
/* The newsletter sign-up (articles page): on a narrow card the button takes
   its own line under the field, so the field keeps the full width */
@media (max-width: 560px) {
  form[name="newsletter"] .btn { flex: 1 1 100%; justify-content: center; }
}
/* A failed sign-up's message (main.js puts it before the button) takes a line
   of its own under the field and the button, where a success message goes,
   so the field keeps its width and the button stays beside it */
form[name="newsletter"] .form-error { flex: 1 1 100%; order: 1; margin: 1rem 0 0; }
.form-success { font-size: 0.9375rem; color: #1F6E3E; background: rgba(31,110,62,0.08); border: 1px solid rgba(31,110,62,0.25); border-radius: var(--radius-sm); padding: 0.75rem 1rem; margin-top: 1rem; width: 100%; }
.form-error {
  font-size: 0.875rem; color: #b3261e; line-height: 1.5;
  background: rgba(179,38,30,0.06); border: 1px solid rgba(179,38,30,0.25);
  border-radius: var(--radius-sm); padding: 0.75rem 1rem; margin-bottom: 1rem;
}

/* ── 24. SCROLL REVEAL ANIMATIONS ─────────────────────────── */
/* An element waits at the first frame of a paused animation, hidden, and
   plays it once main.js marks it .visible. The entrance is an animation, not
   a transition, so it leaves the element's own transition alone: a card still
   lifts on hover with its spring, and its shadow eases with it. The stagger
   is --reveal-delay (set by the delay classes, or by a grid on its children),
   which delays the entrance and never a hover. The end frame is left implicit
   so the animation settles on the element's own styles and nothing snaps when
   it finishes.
   Two entrances share the one keyframe, which starts from --reveal-from: text
   rises --rise-text, and a card (a .card-shell, or anything marked
   .reveal--card) rises --rise-card while it grows from 98%. An image frame
   marked .reveal--media lands as a card while the image inside settles from
   106% to rest over the longer signature duration, started by the same
   .visible. Nothing travels further than 24px, which the scroll margin at the
   top of this file allows for. The no-JS fallback is a <noscript> style in
   each page head that shows every .reveal; a .reveal--media image only waits
   zoomed when scripting is on. Print and reduced motion share one reset, at
   the end of this file. */
.reveal {
  --reveal-from: translateY(var(--rise-text));
  animation: reveal-in var(--dur-enter) var(--ease-out) var(--reveal-delay, 0ms) backwards paused;
}
.reveal.visible { animation-play-state: running; }
@keyframes reveal-in { from { opacity: 0; transform: var(--reveal-from); } }
/* Text stays put: since October 2026 (the team's call) headings, eyebrows,
   paragraphs, lists, buttons and the people and value blocks are on the page
   before the reader scrolls to them. Only cards, image frames and the process
   connector keep an entrance. The observer still marks text .visible, so
   anything keyed to that (the portrait rings, the drawn ticks) still plays. */
.reveal:not(.card-shell, .card-shell-dark, .reveal--card, .reveal--media, .process-connector) { animation: none; }
.card-shell.reveal, .card-shell-dark.reveal, .reveal--card, .reveal--media {
  --reveal-from: translateY(var(--rise-card)) scale(0.98);
}
/* The image waits zoomed only where a script is there to start it; with
   scripting off (or a browser that cannot tell) it is simply at rest */
@media (scripting: enabled) {
  .reveal--media img { animation: reveal-media var(--dur-signature) var(--ease-out) var(--reveal-delay, 0ms) backwards paused; }
  .reveal--media.visible img { animation-play-state: running; }
}
@keyframes reveal-media { from { transform: scale(1.06); } }
.reveal-delay-1 { --reveal-delay: 100ms; }
.reveal-delay-2 { --reveal-delay: 200ms; }
.reveal-delay-3 { --reveal-delay: 300ms; }
.reveal-delay-4 { --reveal-delay: 400ms; }
/* A grid marked data-reveal-group steps its children by --stagger, in reading
   order. These sit at class weight and after the delay classes, so they win
   over those; a grid with its own rhythm (the process steps, the homepage
   story grids) keeps it. A grid that has fallen to one column reveals card by
   card as each scrolls in, so there the step is dropped. The steps run to the
   fourteenth child (the products page's full grid) and hold there, so no later
   card ever lands before an earlier one. */
[data-reveal-group] > :where(.reveal:nth-child(2)) { --reveal-delay: var(--stagger); }
[data-reveal-group] > :where(.reveal:nth-child(3)) { --reveal-delay: calc(var(--stagger) * 2); }
[data-reveal-group] > :where(.reveal:nth-child(4)) { --reveal-delay: calc(var(--stagger) * 3); }
[data-reveal-group] > :where(.reveal:nth-child(5)) { --reveal-delay: calc(var(--stagger) * 4); }
[data-reveal-group] > :where(.reveal:nth-child(6)) { --reveal-delay: calc(var(--stagger) * 5); }
[data-reveal-group] > :where(.reveal:nth-child(7)) { --reveal-delay: calc(var(--stagger) * 6); }
[data-reveal-group] > :where(.reveal:nth-child(8)) { --reveal-delay: calc(var(--stagger) * 7); }
[data-reveal-group] > :where(.reveal:nth-child(9)) { --reveal-delay: calc(var(--stagger) * 8); }
[data-reveal-group] > :where(.reveal:nth-child(10)) { --reveal-delay: calc(var(--stagger) * 9); }
[data-reveal-group] > :where(.reveal:nth-child(11)) { --reveal-delay: calc(var(--stagger) * 10); }
[data-reveal-group] > :where(.reveal:nth-child(12)) { --reveal-delay: calc(var(--stagger) * 11); }
[data-reveal-group] > :where(.reveal:nth-child(13)) { --reveal-delay: calc(var(--stagger) * 12); }
[data-reveal-group] > :where(.reveal:nth-child(n+14)) { --reveal-delay: calc(var(--stagger) * 13); }
@media (max-width: 900px) { .caught-grid, .case-study { --stagger: 0ms; } }
@media (max-width: 768px) { .products-grid, .team-grid, .features-grid, .linkedin-grid { --stagger: 0ms; } }
@media (max-width: 640px) { .partners-grid, .reviews-grid, .stats-grid-alt { --stagger: 0ms; } }

/* ── 25. UTILITY CLASSES ──────────────────────────────────── */
/* main.js sets this on an ambient loop (an orb's drift, the hero light, the
   review marquee) while it is off screen, so the page goes idle; the loop
   picks up where it stopped when it comes back */
.is-offscreen { animation-play-state: paused !important; }
.text-center { text-align: center; }
.mt-3 { margin-top: 1.5rem; }
.mt-4 { margin-top: 2rem; }

/* ── 26. NOISE OVERLAY ────────────────────────────────────── */
.noise-overlay {
  position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: 0.022;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
  background-repeat: repeat; background-size: 128px 128px;
}

/* ── 27. LINKEDIN SECTION ─────────────────────────────────── */
.linkedin-section { background: var(--bg-primary); }

.linkedin-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin-bottom: 3rem; flex-wrap: wrap; gap: 1.5rem;
}

.linkedin-follow-btn {
  display: inline-flex; align-items: center; gap: 0.625rem;
}
.linkedin-icon { flex-shrink: 0; }

.linkedin-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem;
}

.linkedin-post { height: 100%; }
.linkedin-post-inner {
  padding: 1.75rem; display: flex; flex-direction: column; gap: 1.125rem; height: 100%;
}

.linkedin-post-header {
  display: flex; align-items: center; gap: 0.875rem;
}
.linkedin-avatar {
  width: 44px; height: 44px; border-radius: 10px; flex-shrink: 0;
  background: var(--bg-primary); border: 1px solid rgba(0,0,0,0.06);
  overflow: hidden; display: flex; align-items: center; justify-content: center;
}
.linkedin-post-name {
  font-weight: 700; font-size: 0.8125rem; color: var(--text-primary); line-height: 1.2;
}
.linkedin-post-meta {
  font-size: 0.75rem; color: var(--text-tertiary); margin-top: 0.125rem;
}
.linkedin-logo-link {
  margin-left: auto; flex-shrink: 0; opacity: 0.7;
  transition: opacity 200ms var(--ease-out);
}
.linkedin-logo-link:hover { opacity: 1; }

.linkedin-post-text {
  font-size: 0.9rem; color: var(--text-secondary); line-height: 1.75;
  flex: 1;
  display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical;
  overflow: hidden;
}
.linkedin-post-text em { font-style: italic; color: var(--text-primary); }

.linkedin-post-tags {
  display: flex; flex-wrap: wrap; gap: 0.375rem;
}
.linkedin-tag {
  font-size: 0.6875rem; font-weight: 500;
  color: var(--teal-text); background: rgba(105,166,166,0.1);
  padding: 0.25rem 0.625rem; border-radius: var(--radius-pill);
}

.linkedin-post-cta {
  display: inline-flex; align-items: center; gap: 0.375rem; min-height: 44px;
  font-size: 0.875rem; font-weight: 600; color: var(--teal-text);
  transition: gap 250ms var(--ease-out), color 200ms;
  margin-top: auto; padding-top: 0.25rem;
  border-top: 1px solid rgba(0,0,0,0.06);
}
.linkedin-post-cta:hover { gap: 0.625rem; color: var(--navy); }


/* ── 29. BACK TO TOP ──────────────────────────────────────── */
.back-to-top {
  position: fixed; bottom: 2rem; right: 2rem; z-index: 90;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--navy); border: 1.5px solid rgba(105,166,166,0.35);
  color: var(--teal); font-size: 1.125rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0; pointer-events: none;
  transform: translateY(12px);
  /* Hidden, it is out of the tab order too, so focus never lands on it unseen;
     visibility holds while it fades either way. After it takes the reader to
     the top, the next Tab starts from the top of the page. */
  visibility: hidden;
  transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out), visibility 300ms, background 200ms, border-color 200ms;
  box-shadow: 0 4px 20px rgba(0,29,45,0.25);
}
.back-to-top.visible {
  opacity: 1; pointer-events: auto; transform: translateY(0); visibility: visible;
}
.back-to-top:hover {
  background: var(--teal); border-color: var(--teal); color: white;
}
/* The button floats over cream sections as well as the dark footer, so its ring
   brings its own ground: white, with the button's midnight carried out under
   it as a halo, so the ring reads the same on any section behind it. */
.back-to-top:focus-visible { outline-color: #fff; box-shadow: 0 0 0 9px var(--navy), 0 4px 20px rgba(0,29,45,0.25); }

/* ── TCR EXPLAINER ────────────────────────────────────────── */
/* The explainer sits on midnight directly above the iceberg so the two read as one block */
.tcr-explainer-section { background: var(--bg-dark); color: white; }
.tcr-explainer-section.section { padding-bottom: 1rem; }
.tcr-explainer-section .display-md { color: white; }
.tcr-explainer-section .body-lg, .tcr-explainer-section .body-md { color: rgba(255,255,255,0.78); }
.tcr-explainer-grid {
  display: grid;
  grid-template-columns: 1fr 0.8fr;
  gap: 5rem;
  align-items: start;
  margin-top: 2rem;
}
.tcr-explainer-intro .body-md { margin-top: 1.25rem; }
.tcr-compare {
  background: var(--bg-dark-card);
  border-radius: var(--radius-card);
  padding: 2rem 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.tcr-compare-separator {
  height: 1px;
  background: rgba(255,255,255,0.1);
  margin: 1.5rem 0;
}
.tcr-compare-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255,255,255,0.55);
  margin-bottom: 0.75rem;
}
.tcr-compare-label--ardent { color: var(--teal); }
.tcr-compare-list {
  list-style: none;
  padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 0.5rem;
}
.tcr-compare-list li {
  font-size: 0.875rem;
  color: rgba(255,255,255,0.72);
  padding-left: 1.75rem;
  position: relative;
  line-height: 1.5;
}
/* The marks are drawn, never typed: a text hyphen reads as a dash (and is
   read out as one), and no site font has a tick, so a typed one came from
   whatever the device had. The standard list takes a short muted rule; the
   Ardent list takes the sprite's check-circle (an .icon in each item, as in
   the banner's offer list), centred on the same 18px column, with the text
   of both lists starting on one edge. */
.tcr-compare-list li::before {
  content: ''; position: absolute; left: 4px; top: calc(0.75em - 0.75px);
  width: 10px; height: 1.5px; border-radius: 1px;
  background: rgba(255,255,255,0.4);
}
/* Forced colours turn that fill into the page colour, keeping its
   transparency, which leaves the rule invisible; there it takes the text
   colour instead, as the typed hyphen it replaced did */
@media (forced-colors: active) {
  .tcr-compare-list:not(.tcr-compare-list--ardent) li::before { background: CanvasText; }
}
.tcr-compare-list li .icon {
  position: absolute; left: 0; top: calc(0.75em - 9px);
  width: 18px; height: 18px; color: var(--teal);
}
.tcr-compare-list--ardent li { color: white; font-weight: 500; }
/* an Ardent item without its icon still gets a tick, drawn */
.tcr-compare-list--ardent li::before {
  left: 5px; top: calc(0.75em - 6.5px); width: 5px; height: 9px; border-radius: 0;
  background: none; border: solid var(--teal); border-width: 0 1.75px 1.75px 0; rotate: 45deg;
}
.tcr-compare-list li:has(.icon)::before { content: none; }

/* Recognition row (about page): one column on a phone; two to a row up to
   899px, with the third card centred under the pair at the same width, as
   the other grids' short last rows are; three across from 900px, where each
   card is wide enough to keep "AFS Licence 550275" on one line. */
.stats-grid-alt { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
@media (min-width: 641px) and (max-width: 899px) {
  .stats-grid-alt { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats-grid-alt > :last-child:nth-child(odd) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 1.25rem) / 2);
  }
}
@media (min-width: 900px) { .stats-grid-alt { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* The sub line wraps in balanced lines, so "Pty Ltd" or "Association" is
   never left alone on a line of its own */
.stats-grid-alt .card-core > :last-child { text-wrap: balance; }
/* About page memberships: each body's logo from images/memberships/<slug>.svg */
.membership-logo { height: 48px; display: flex; align-items: center; justify-content: center; margin-bottom: 0.875rem; }
.membership-logo img { height: 100%; width: auto; max-width: 100%; object-fit: contain; }

/* Tighter split used inside product category cards */
.split-section--tight { gap: 3rem; }

/* ── 30. RESPONSIVE ───────────────────────────────────────── */
@media (max-width: 1280px) {
  .linkedin-grid { grid-template-columns: repeat(2, 1fr); }
  .hero-content { max-width: 100%; }
}

@media (max-width: 1024px) {
  .risk-cards-grid { grid-template-columns: 1fr 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .products-grid { grid-template-columns: repeat(2, 1fr); }
  .split-section { grid-template-columns: 1fr; gap: 3rem; }
  /* A split with its columns set inline still stacks: !important here beats
     an inline style that is not itself !important */
  .split-section[style] { grid-template-columns: 1fr !important; gap: 3rem !important; }
  .tcr-explainer-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .contact-grid { grid-template-columns: 1fr; }
  /* a one or two person advisor panel keeps its own centred 300px columns */
  .team-grid:not(.team-grid--solo):not(.team-grid--pair) { grid-template-columns: repeat(2, 1fr); }
  .industries-strip:not(.industries-strip--clean) .industries-strip-label { display: none; }
}

/* A short last row sits centred under the row above, each card at the same
   width as the rest, not at the left of an empty row (the review grids do the
   same in section 14). Two to a row, the width allows for the grid's own gap. */
@media (min-width: 769px) and (max-width: 1024px) {
  .risk-cards-grid > :last-child:nth-child(odd),
  .products-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 1.25rem) / 2);
  }
  .team-grid:not(.team-grid--solo):not(.team-grid--pair) > :last-child:nth-child(odd) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 2rem) / 2);
  }
}
@media (min-width: 769px) and (max-width: 1280px) {
  .linkedin-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1; justify-self: center; width: calc((100% - 1.25rem) / 2);
  }
}
/* Three to a row. The team's lone seventh takes the middle column. Product
   cards sit on six tracks, two each, so a last row of one or two can centre. */
@media (min-width: 1025px) {
  .team-grid:not(.team-grid--solo):not(.team-grid--pair) > :last-child:nth-child(3n+4) { grid-column: 2; }
  .products-grid { grid-template-columns: repeat(6, 1fr); }
  .products-grid > * { grid-column: span 2; }
  .products-grid > :last-child:nth-child(3n+1) { grid-column: 3 / span 2; }
  .products-grid > :nth-last-child(2):nth-child(3n+1) { grid-column: 2 / span 2; }
}

@media (max-width: 640px) {
  /* Phones: two rows that scroll sideways instead of eighteen pills stacked
     down the page. The row bleeds to the screen edges, the ends fade out so
     it is obvious there is more, and the scrollbar is hidden. */
  .industries-strip--clean { padding: 1.5rem 0 1.5rem; }
  .industries-strip--clean .industries-strip-inner { gap: 1rem; }
  .industries-strip--clean .industries-strip-label::before,
  .industries-strip--clean .industries-strip-label::after { width: 1.5rem; }
  .industries-strip--clean .industries-marquee-outer {
    width: calc(100% + 2 * var(--container-pad)); margin: 0 calc(-1 * var(--container-pad));
  }
  .industries-strip--clean .industries-marquee-track {
    display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto);
    justify-content: start; gap: 0.5rem; max-width: none; width: auto;
    overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
    /* The right-hand padding and scroll padding are wider than the 2.5rem fade,
       so the last pill clears it at the end of the row, and a pill brought into
       view (a tabbed-to one, say) stops short of it */
    scroll-snap-type: x proximity; scroll-padding-inline: var(--container-pad) 3rem;
    /* A scroller clips on both axes: the top padding holds the first row's
       focus ring and lift (8px), and the pull-up keeps the pills in place.
       The bottom padding holds the second row's hover and focus shadow, which
       reaches about 28px below a lifted pill, so it fades out instead of
       stopping on a line; the negative margin gives that room back, so the
       strip is the same height. */
    padding: 0.5rem 3rem 1.75rem var(--container-pad); margin: -0.25rem 0 -1.25rem;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--container-pad), #000 calc(100% - 2.5rem), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 var(--container-pad), #000 calc(100% - 2.5rem), transparent);
  }
  .industries-strip--clean .industries-marquee-track::-webkit-scrollbar { display: none; }
  .industries-strip--clean a.ind-tag {
    scroll-snap-align: start; white-space: nowrap;
    min-height: 36px; padding: 0.375rem 0.875rem 0.375rem 0.625rem; font-size: 0.78rem;
  }
  /* The last pill keeps the whole row in view, so it sits in both rows' column and stays reachable. */
  .industries-strip--clean a.ind-tag--all { grid-row: 1 / -1; align-self: center; }
}

@media (max-width: 768px) {
  :root { --section-py: 4rem; }

  .nav-links, .nav-cta { display: none; }
  .nav-hamburger { display: flex; }
  .nav-pill { padding: 0.625rem 0.625rem 0.625rem 1.25rem; }
  .nav-pill.scrolled { padding: 0.5rem 0.5rem 0.5rem 1.125rem; }

  .risk-cards-grid { grid-template-columns: 1fr; }
  .features-grid { grid-template-columns: 1fr; }
  .process-grid { grid-template-columns: repeat(2, 1fr); }
  .process-connector { display: none; }
  .products-grid { grid-template-columns: 1fr; }
  .linkedin-grid { grid-template-columns: 1fr; }
  .linkedin-header { flex-direction: column; align-items: flex-start; }
  .team-grid { grid-template-columns: 1fr !important; gap: 2rem !important; }
  .team-portrait-wrap { width: 148px; height: 148px; }
  /* The link groups sit two to a row under the brand: Assets beside Liabilities
     and People, then Company beside Legal (the last column's two groups, laid
     side by side on the same two tracks), so no block is left half a row */
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.5rem 1.5rem; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-grid > :last-child:not(.footer-brand) {
    grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto 1fr; grid-auto-flow: column; column-gap: 1.5rem;
  }
  .footer-grid > :last-child > .footer-col-title--spaced { margin-top: 0; }
  /* the bottom links wrap as whole labels, on centred rows */
  .footer-bottom-links { flex-wrap: wrap; justify-content: center; column-gap: 1.5rem; row-gap: 0; }
  .footer-bottom-link { white-space: nowrap; }
  .form-row { grid-template-columns: 1fr; }
  /* The form card steps its padding down, as the featured article card does,
     so its fields line up with the cards above and below and have room */
  .contact-form-inner { padding: 1.75rem; }

  .hero-actions { flex-direction: column; align-items: flex-start; }
  /* A stacked pair of buttons shares one width, the wider label's (the centred
     column already shrinks to it), with each label centred on its pill */
  .hero--centered .hero-actions { align-items: stretch; }
  .hero--centered .hero-actions .btn { justify-content: center; }
  /* Room for the pause button, which sits in the bottom right corner over the credentials */
  .hero { padding-bottom: 5.5rem; }
  .hero-video-toggle { right: 1rem; bottom: 1rem; }
  .footer-bottom { text-align: center; }
  .footer-legal-name, .footer-legal-ids { display: block; }
  .footer-legal-ids .footer-legal-id:first-child::before { display: none; }
  .footer-legal-line + .footer-legal-line { margin-top: 0.5rem; }
  .footer-bottom-meta { flex-direction: column-reverse; padding-right: 0; }
  .footer-bottom-link--credit { flex-basis: 100%; }
  .footer-bottom-link--credit::before { display: none; }
  .hero-credentials { gap: 0.875rem; }
  /* the strip wraps at this width, which strands the separator */
  .hero-cred-dot { display: none; }

  .back-to-top { display: none; }
}

/* Two footer columns on a small phone: the links take the 14px of the rest of
   the footer, so the longer product names still fit on one line at 390 */
@media (max-width: 399px) {
  .footer-link { font-size: 0.875rem; line-height: 1.4; }
}

@media (max-width: 480px) {
  /* Long CTA labels wrap instead of pushing past the viewport */
  .btn-lg { white-space: normal; text-align: center; justify-content: center; max-width: 100%; }
  /* A long "Also consider" label wraps here. In the button's flex row the
     wrapped text centred in the room left of its arrow, which stayed at the
     pill's edge; set as one run of text, the arrow follows the last word and
     every line is centred on the pill. (These pills hold text only.) */
  .cta-banner-actions .btn-ghost-white { display: block; text-wrap: balance; }
  .cta-banner-actions .btn-ghost-white .btn-icon { margin-left: 0.25em; }
  .process-grid { grid-template-columns: 1fr; }
  /* Small phones: the hero copy and the banner title step down a size */
  .hero-sub { font-size: 1rem; margin-bottom: 1.75rem; }
  .hero-actions { gap: 0.75rem; }
  .cta-banner-title { font-size: clamp(2rem, 6vw, 3rem); }
}
/* The smallest screens (a folding phone's cover screen): beside the arrow
   circle a label wraps with its lines pushed left of the pill's centre, or
   runs past the screen. Without the circle, which is decoration, every
   primary label fits on one line, centred, and any label still too long for
   the screen wraps onto a second. */
@media (max-width: 319px) {
  .btn-primary, .reviews-more-row .btn { white-space: normal; text-align: center; justify-content: center; max-width: 100%; text-wrap: balance; }
  .btn-primary .btn-icon { display: none; }
}

/* ── FAQ ACCORDION ───────────────────────────────────────────── */
.faq-section { background: var(--bg-primary); }
.faq-list { display: flex; flex-direction: column; gap: 0.625rem; max-width: 860px; margin: 0 auto; }
.faq-item {
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-primary);
  transition: border-color 300ms var(--ease-out);
}
.faq-item.open { border-color: rgba(105,166,166,0.3); background: var(--bg-white); }
.faq-question {
  width: 100%; text-align: left;
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  padding: 1.25rem 1.5rem;
  font-family: 'Montserrat', sans-serif; font-size: 1.0625rem; font-weight: 600;
  color: var(--text-primary); background: none; border: none; cursor: pointer;
  transition: color 200ms;
}
.faq-question:hover { color: var(--teal-text); }
.faq-item.open .faq-question { color: var(--teal-text); }
/* The item clips what it holds (overflow: hidden keeps an opening answer inside
   its rounded corners), and that would cut the question's own focus ring off
   entirely, so the ring goes round the whole item instead. The question's own
   ring is turned off with it: on an open item it would show as a stray rule
   between the question and the answer. A browser without :has() keeps the
   question's ring. */
@supports selector(:has(*)) {
  .faq-item:has(> .faq-question:focus-visible) { outline: 3px solid var(--teal-text); outline-offset: 3px; }
  .faq-item > .faq-question:focus-visible { outline: none; }
}
.faq-icon {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  background: rgba(105,166,166,0.1); display: flex; align-items: center; justify-content: center;
  font-size: 1rem; line-height: 1; color: var(--teal-text);
  transition: transform 350ms var(--ease-spring), background 200ms;
}
.faq-item.open .faq-icon { transform: rotate(45deg); background: var(--teal-text); color: white; }
.faq-answer {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 350ms var(--ease-out);
}
.faq-item.open .faq-answer { grid-template-rows: 1fr; }
.faq-answer-inner {
  overflow: hidden;
  padding: 0 1.5rem;
  font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.75;
}
.faq-item.open .faq-answer-inner { padding-bottom: 1.25rem; }

/* Split FAQ: the heading (and any intro) holds still on the left while the
   questions scroll past on the right. Stacked under 1025px.
   Markup: .container.faq-layout > .faq-layout-head + .faq-list */
.faq-layout-head { margin-bottom: 2.5rem; }
.faq-layout-head .section-title { margin-top: 0; }
/* Stacked, the list keeps its 860px measure but starts on the heading's edge */
.faq-layout .faq-list { margin-left: 0; margin-right: 0; }
/* The fixed back-to-top button (shown above 768px) only has the page margin to
   itself on a wide screen. Narrower, a list stops short of it, so the button
   never sits on a question's + as the row passes under it: by the button's
   width plus a little, less the page gutter. A centred list gives up that much
   on both sides; the split layout's list only on the right, and eases it to
   nothing once the margin beside a 1280px container can take the button. */
@media (min-width: 769px) {
  .faq-list { max-width: min(860px, 100% - 2 * (5.5rem - var(--container-pad))); }
  .faq-layout .faq-list { max-width: 860px; margin-right: clamp(0px, 700px - 50vw, 5.5rem - var(--container-pad)); }
}
@media (min-width: 1025px) {
  /* the narrow column takes its display heading one size down, as a split does */
  .faq-layout-head .display-lg { font-size: clamp(1.75rem, 3.5vw, 2.75rem); line-height: 1.1; letter-spacing: -0.02em; }
}
.faq-layout-head .eyebrow + .section-title { margin-top: 0.875rem; }
.faq-layout-head .body-lg, .faq-layout-head .body-md { margin-top: 1rem; }
@media (min-width: 1025px) {
  .faq-layout { display: grid; grid-template-columns: 0.85fr 1.4fr; gap: 4rem; align-items: start; }
  .faq-layout-head { position: sticky; top: 8rem; margin-bottom: 0; }
  .faq-layout .faq-list { max-width: none; }
}

/* ── PARTNER CARDS ───────────────────────────────────────────── */
.partners-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.25rem;
}
.partner-card {
  display: flex; flex-direction: column; gap: 0.875rem;
  padding: 1.75rem; height: 100%;
}
.partner-card-logo {
  height: 48px; display: flex; align-items: center;
}
.partner-card-logo img { height: 100%; width: auto; max-width: 100%; object-fit: contain; object-position: left; }
.partner-card-link .btn-icon { font-size: 1rem; }
.partner-card-link { min-height: 44px; font-size: 0.875rem; font-weight: 600; color: var(--teal-text); display: inline-flex; align-items: center; gap: 0.375rem; transition: gap 200ms; }
.partner-card-link:hover { gap: 0.625rem; }

@media (max-width: 1024px) { .partners-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .partners-grid { grid-template-columns: 1fr; } }

/* ── WIDE NAV DROPDOWNS (Products, Industries) ─────────────── */
/* A panel never runs past the foot of the screen. The header is fixed, so
   the page cannot bring a low link up; on a short screen the panel scrolls
   inside its card instead, and focus scrolls it to each link in turn. The
   0.75rem gap above the card, which holds the menu open while the pointer
   crosses from the link, is a transparent border here rather than padding,
   so the list scrolls under the card's top edge and never shows in the gap
   (the ::before still reports that gap to main.js, which places the shared
   card from it). The taller top radii leave the card's own 1.25rem corners
   inside the border. */
.nav-dropdown-wide {
  display: grid; gap: 0 0.5rem; align-items: start;
  padding: 0 1rem 1rem; border-top: 0.75rem solid transparent;
  border-radius: 1.25rem 1.25rem 1.25rem 1.25rem / 2rem 2rem 1.25rem 1.25rem;
  max-width: calc(100vw - 2 * var(--container-pad) - 2rem);
  max-height: calc(100vh - 5.5rem); max-height: calc(100dvh - 5.5rem);
  overflow-y: auto; overscroll-behavior: contain;
}
/* Where a scrollbar shows, it is a slim thumb whose track stops short of the
   card's round corners (a plain one ran square past them) */
.nav-dropdown-wide::-webkit-scrollbar { width: 10px; }
.nav-dropdown-wide::-webkit-scrollbar-track { background: transparent; margin-block: 1.25rem; }
.nav-dropdown-wide::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.22) padding-box; border: 3px solid transparent; border-radius: 999px; }
@supports not selector(::-webkit-scrollbar) {
  .nav-dropdown-wide { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.22) transparent; }
}
/* Without the shared card (no mouse, or no script) the panel draws its own
   card: a layer inside a scroller would scroll away with the list, and lose
   its shadow to the clip */
.nav-links:not(.has-morph) .nav-dropdown-wide {
  background: var(--bg-dark-card) padding-box;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12), 0 24px 60px rgba(0,0,0,0.4);
}
.nav-links:not(.has-morph) .nav-dropdown-wide::before { content: none; }
/* Forced colours paint every border in the text colour, which would turn the
   transparent gap into a solid bar. So the panel keeps its own colours there
   (everything in it still takes the forced ones), and a card it draws itself
   uses the system colours. */
@media (forced-colors: active) {
  .nav-dropdown-wide { forced-color-adjust: none; }
  .nav-dropdown-wide > * { forced-color-adjust: auto; }
  .nav-links:not(.has-morph) .nav-dropdown-wide { background: Canvas padding-box; box-shadow: inset 0 0 0 1px CanvasText; }
  .nav-dropdown-wide::-webkit-scrollbar-thumb { background-color: CanvasText; }
}
/* Both menus share one layout (October 2026): a row of group tabs with the
   "All ..." link, the chosen group's tiles three across, then a midnight strip
   with Let's chat. main.js adds .is-tabbed and hides the other groups; without
   the script every group shows under its label and the tabs stay hidden. The
   width stops short of the screen edge, measured from where the link row
   starts, and the tiles drop to two across when that is narrow. */
.nav-dropdown-products, .nav-dropdown-industries {
  display: block;
  width: min(54rem, calc(100vw - 2 * var(--container-pad) - 16rem));
}
.nav-dropdown-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: 1rem 0.25rem 0.875rem;
}
.nav-dropdown:not(.is-tabbed) .nav-dropdown-head { justify-content: flex-end; padding-bottom: 0; }
.nav-dropdown:not(.is-tabbed) .nav-dropdown-tabs { display: none; }
.nav-dropdown-tabs {
  display: inline-flex; gap: 0.25rem; padding: 0.25rem;
  background: rgba(255,255,255,0.06); border-radius: var(--radius-pill);
}
.nav-dropdown-tab {
  border: 0; background: transparent; cursor: pointer;
  font-family: 'Montserrat', sans-serif; font-size: 0.8125rem; font-weight: 600; line-height: 1.2;
  color: rgba(255,255,255,0.75); padding: 0.5625rem 1rem; border-radius: var(--radius-pill);
  white-space: nowrap;
  transition: background-color var(--dur-press) var(--ease-out), color var(--dur-press) var(--ease-out);
}
.nav-dropdown-tab:hover { color: #fff; background: rgba(255,255,255,0.06); }
.nav-dropdown-tab[aria-selected="true"] { background: #fff; color: var(--navy); }
.nav-dropdown-tab:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.nav-dropdown-group { min-width: 0; }
.nav-dropdown-group[hidden] { display: none; }
.is-tabbed .nav-dropdown-col-label { display: none; }
.nav-dropdown-col {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr)); gap: 0.5rem;
}
.nav-dropdown-col-label {
  font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--teal);
  padding: 1rem 0.25rem 0.5rem;
}
.nav-dropdown-all { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.8125rem; font-weight: 600; color: #fff; border-radius: 4px; padding: 0.375rem 0.25rem; }
.nav-dropdown-all [aria-hidden] { color: var(--teal); transition: transform var(--dur-press) var(--ease-out); }
.nav-dropdown-all:hover { color: var(--teal); }
.nav-dropdown-all:hover [aria-hidden] { transform: translateX(2px); }
.nav-dropdown-strip {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem 1.25rem; flex-wrap: wrap;
  margin-top: 0.75rem; padding: 0.75rem 0.75rem 0.75rem 1.25rem;
  background: var(--navy); border-radius: 0.875rem;
}
.nav-dropdown-strip-text { margin: 0; font-size: 0.8125rem; line-height: 1.45; color: rgba(255,255,255,0.8); }
.nav-dropdown-strip-cta {
  display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0;
  background: var(--orange); color: #fff; text-shadow: var(--on-orange-shadow);
  font-size: 0.8125rem; font-weight: 800; white-space: nowrap;
  padding: 0.5625rem 1.125rem; border-radius: var(--radius-pill);
  box-shadow: 0 4px 16px rgba(233,101,18,0.3);
  transition: box-shadow var(--dur-press) var(--ease-out);
}
.nav-dropdown-strip-cta:hover { box-shadow: 0 8px 24px rgba(233,101,18,0.4); }

/* ── PRODUCTS PAGE CATEGORY TABS ─────────────────────────────── */
.products-filter { display: flex; gap: 0.625rem; flex-wrap: wrap; margin-bottom: 3rem; }
.products-filter-btn {
  padding: 0.5rem 1.25rem; border-radius: var(--radius-pill);
  font-size: 0.875rem; font-weight: 600; cursor: pointer; border: 1.5px solid rgba(0,0,0,0.1);
  background: transparent; color: var(--text-secondary);
  transition: background-color 250ms var(--ease-out), color 250ms var(--ease-out), border-color 250ms var(--ease-out);
}
.products-filter-btn.active, .products-filter-btn:hover {
  background: var(--navy); color: white; border-color: var(--navy);
}
/* Phones: an even two by two block on the cards' edge, never one chip left
   alone on a second row (the break allows for Noto Sans's wider chips) */
@media (max-width: 560px) {
  .products-filter { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .products-filter-btn { text-align: center; }
}

/* ── PRODUCT DETAIL PAGE ─────────────────────────────────────── */
.covered-list { display: flex; flex-direction: column; gap: 0.625rem; margin-top: 1.25rem; }
.covered-item {
  display: flex; align-items: flex-start; gap: 0.875rem;
  padding: 0.875rem 1rem; border-radius: var(--radius-sm);
  background: var(--bg-primary); border: 1px solid rgba(0,0,0,0.06);
}
.covered-icon { flex-shrink: 0; font-size: 1.125rem; margin-top: 0.1rem; }
.covered-title { font-weight: 600; font-size: 0.9375rem; color: var(--text-primary); }
.covered-desc { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.6; margin-top: 0.125rem; }
/* Small phones: tighter items so long titles never push past the edge */
@media (max-width: 480px) {
  .covered-item { gap: 0.625rem; padding: 0.75rem; }
  .covered-title { font-size: 0.875rem; }
  .covered-desc { font-size: 0.8125rem; }
}
/* Scroll focus: as an item crosses the middle of the screen a white card
   with a jade rule rises behind it and fades again once it has passed. The
   layer is ::before under the content; only its opacity moves. The item's
   timeline watches a 40px band on the screen's centre line (the inset), so
   the focus is sized by the item itself, not the screen: it holds while the
   item covers the line and hands over to the next item in the gap between
   them, and one item is lit at a time. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .covered-item {
      position: relative; isolation: isolate;
      view-timeline: --covered-item block; view-timeline-inset: calc(50% - 20px);
    }
    .covered-item::before {
      content: ''; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; pointer-events: none;
      background: var(--bg-white);
      box-shadow: inset 3px 0 0 var(--teal), var(--elev-2);
      opacity: 0;
      animation: covered-focus linear both; animation-timeline: --covered-item; animation-range: cover 0% cover 100%;
    }
  }
}
@keyframes covered-focus { 0% { opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } }

/* ── STATIC TESTIMONIALS GRID (contact page) ────────────────── */
.testimonials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
  gap: 1.25rem;
}
/* Tablets: always two across, with an odd last card centred under the pair
   (see TESTIMONIALS), since auto-fit would leave it alone on its row */
@media (min-width: 641px) and (max-width: 1024px) {
  .testimonials-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── PARTNER CARD EXTRAS ──────────────────────────────────────── */
.partner-category { font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--teal-text); }
.partner-desc { font-size: 0.9rem; color: var(--text-secondary); line-height: 1.65; flex: 1; }
.partner-tag { display: inline-block; padding: 0.25rem 0.75rem; border-radius: var(--radius-pill); font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; background: rgba(49,121,126,0.1); color: var(--teal-text); margin-top: auto; }

/* ── PLAIN TESTIMONIAL (product pages, single quote) ─────────── */

/* ── INDUSTRY PAGES ─────────────────────────────────────────── */
/* Shared by the industry pages: the "where they get caught out" grid and the
   renewal checklist. Each page used to carry its own copy of these rules. */
.caught-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.caught-item { padding: 1.75rem; }
.caught-item .covered-icon { margin-bottom: 1rem; }
.caught-item h3 { font-family: 'Montserrat', sans-serif; font-size: 1.25rem; color: var(--text-primary); margin-bottom: 0.5rem; }
.caught-item p { font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.65; }
.check-list { list-style: none; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem 2rem; margin-top: 1.5rem; }
.check-list li { display: flex; gap: 0.75rem; align-items: flex-start; font-size: 0.9375rem; color: var(--text-secondary); line-height: 1.6; }
.check-list .icon { width: 20px; height: 20px; color: var(--teal-text); margin-top: 0.15rem; }
@media (max-width: 900px) { .caught-grid { grid-template-columns: 1fr; } .check-list { grid-template-columns: 1fr; } }

/* ── SHEETS ─────────────────────────────────────────────────── */
/* A dark section marked .section--sheet rises over the section before it: it
   overlaps that section's foot by --sheet-overlap, with rounded top corners
   and a soft shadow cast upward. As it comes up the screen, the section
   beneath recedes under a midnight veil (::after, opacity only), driven by
   that section's own view timeline, from the moment its foot meets the bottom
   of the screen to when the foot is a fifth of the way from the top. Never
   used on the first section after a page hero.
   The section beneath is never scaled or moved: an animated transform is
   drawn once and then resampled, which softens its text for as long as the
   reader is on its last screen (the reason the cards do not tilt either). */
.section--sheet {
  position: relative; z-index: 1;
  margin-top: calc(-1 * var(--sheet-overlap));
  border-radius: var(--sheet-radius) var(--sheet-radius) 0 0;
  box-shadow: 0 -20px 48px -16px rgba(0,29,45,0.28), inset 0 1px 0 rgba(255,255,255,0.08);
}
/* A sheet straight after another sheet rises over midnight, where its edge
   highlight and shadow drew a hard line across the page: the two meet flush */
.section--sheet + .section--sheet { box-shadow: none; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    main > :has(+ .section--sheet) {
      position: relative; z-index: 0;
      view-timeline: --sheet-under block; view-timeline-inset: 0;
    }
    main > :has(+ .section--sheet)::after {
      content: ''; position: absolute; inset: 0; z-index: 20; pointer-events: none;
      background: linear-gradient(to top, var(--navy) 0%, rgba(0,29,45,0.55) 30%, rgba(0,29,45,0) 75%);
      opacity: 0;
      animation: sheet-dim linear both;
      animation-timeline: --sheet-under;
      animation-range: cover calc(100% - 100vh) cover calc(100% - 20vh);
    }
  }
}
@keyframes sheet-dim { from { opacity: 0; } to { opacity: 0.14; } }

/* ── BODY LINKS ─────────────────────────────────────────────── */
/* A link in running copy (a paragraph, a list item, a form label or an FAQ
   answer, with no class of its own) reads as a link without its colour: jade
   text over a permanent 1px rule, and a 2px full-strength rule that draws in
   from the left on hover and focus. The resting rule is 3:1 or better against
   the page, so it marks the link for a reader who cannot tell the colour. On
   dark sections the jade is the lighter one (lighter again on a dark card). A
   link that sets its own underline inline is left to it. */
main :is(p, li, label, .faq-answer-inner) a:not([class]):not([style*="text-decoration"]),
.review-more {
  --link-rule: rgba(63,111,118,0.75);
  color: var(--teal-text);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--link-rule), var(--link-rule));
  background-repeat: no-repeat;
  background-size: 0% 2px, 100% 1px;
  background-position: 0 100%, 0 100%;
  transition: background-size 350ms var(--ease-out), color var(--dur-press) var(--ease-out);
}
main :is(p, li, label, .faq-answer-inner) a:not([class]):not([style*="text-decoration"]):is(:hover, :focus-visible),
.review-more:is(:hover, :focus-visible) {
  background-size: 100% 2px, 100% 1px;
}
:is(.page-hero, .cta-banner, .services-section, .tcr-explainer-section, .commit-section, .section--sheet, .card-core-dark, [style*="--bg-dark"])
  :is(p, li, label, .faq-answer-inner) a:not([class]):not([style*="text-decoration"]) {
  --link-rule: rgba(105,166,166,0.75);
  color: var(--teal);
}
.card-core-dark :is(:is(p, li, label, .faq-answer-inner) a:not([class]):not([style*="text-decoration"]), .review-more) {
  --link-rule: rgba(105,166,166,0.75);
  color: var(--teal);
}
@media (forced-colors: active) {
  main :is(p, li, label, .faq-answer-inner) a:not([class]), .review-more { text-decoration: underline; }
}

/* ── PAGE TRANSITIONS ───────────────────────────────────────── */
/* Moving between pages cross-fades, with the new page rising 12px into place.
   The header keeps its own name (see NAVIGATION), so it holds still. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-old(root) { animation: vt-page-out 250ms var(--ease-in-out) both; }
::view-transition-new(root) { animation: vt-page-in 350ms var(--ease-out) both; }
@keyframes vt-page-out { to { opacity: 0; } }
@keyframes vt-page-in { from { opacity: 0; transform: translateY(12px); } }

/* ── 30b. PHONES (October 2026 phone review) ──────────────── */
/* Product and industry heroes carry the homepage's pair of buttons under the
   paragraph, so a reader can get in touch without scrolling eight screens */
.page-hero-actions { margin-top: 2rem; }

/* Sticky Let's chat bar: phones and tablets only, on the homepage, product
   pages and industry pages (main.js shows it). It sits on the page's own
   layer step (--z-sticky), so the open menu, the search dialog and the
   iceberg's detail sheet all cover it. It is hidden (not just moved) while
   away, so it leaves the tab order too, and while it shows the page keeps
   its height clear when scrolling a focused link into view. */
.sticky-mobile-cta { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: #001D2D; border-top: 1px solid rgba(255,255,255,0.08); padding: 0.5rem 0.5rem calc(0.5rem + env(safe-area-inset-bottom, 0px)) 1rem; z-index: var(--z-sticky, 100); align-items: center; gap: 0.5rem; }
.sticky-mobile-cta__text { font-size: 0.875rem; color: rgba(255,255,255,0.7); flex: 1; line-height: 1.3; }
.sticky-mobile-cta__btn { display: inline-flex; align-items: center; min-height: 44px; background: var(--orange); color: #fff; text-shadow: var(--on-orange-shadow); border: none; border-radius: 999px; padding: 0 1.125rem; font-family: 'Montserrat', sans-serif; font-size: 0.875rem; font-weight: 800; text-decoration: none; white-space: nowrap; cursor: pointer; }
.sticky-mobile-cta__close { background: none; border: none; color: rgba(255,255,255,0.6); font-size: 1.375rem; line-height: 1; cursor: pointer; min-width: 2.75rem; min-height: 2.75rem; padding: 0; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sticky-mobile-cta__close:hover { color: #fff; }
.sticky-mobile-cta :focus-visible { outline-color: #fff; }
.sticky-mobile-cta__close:focus-visible { color: #fff; }
@media (max-width: 768px) {
  .sticky-mobile-cta { display: flex; transform: translateY(100%); visibility: hidden; transition: transform var(--dur-state) var(--ease-out), visibility 0s linear var(--dur-state); }
  .sticky-mobile-cta.visible:not(.is-held):not(.is-away) { transform: none; visibility: visible; transition: transform var(--dur-state) var(--ease-out), visibility 0s; }
  body:has(.nav-overlay.open) .sticky-mobile-cta, body:has(#site-search:not([hidden])) .sticky-mobile-cta,
  body:has(.tcr-ice-detail-panel.on) .sticky-mobile-cta { transform: translateY(100%); visibility: hidden; transition: transform var(--dur-state) var(--ease-out), visibility 0s linear var(--dur-state); }
  /* the room to scroll the footer's foot clear of the bar is the footer's own
     midnight, so no page colour shows between the two whatever the bar's height */
  body.has-sticky-cta .site-footer { padding-bottom: 4.5rem; }
  html.has-sticky-cta { scroll-padding-bottom: 5rem; }
}
@media (prefers-reduced-motion: reduce) { .sticky-mobile-cta { transition: none !important; } }

/* Form fields at 16px: iPhones zoom the page in on a field set smaller */
@media (max-width: 1024px) {
  .form-input, .form-select, .form-textarea { font-size: 1rem; }
}
/* The consent box at a size that matches the fields, beside its label */
.form-check { width: 1.25rem; height: 1.25rem; flex-shrink: 0; margin: 0.0625rem 0 0; accent-color: var(--teal-text); }

/* Contact page, one column: the heading and intro, then the form, then the
   contact details and credentials, so the form is on the first screen
   after the hero instead of two screens down */
@media (max-width: 1024px) {
  .contact-grid { display: flex; flex-direction: column; gap: 0; }
  .contact-grid > .contact-info { display: contents; }
  .contact-info > * { order: 2; }
  .contact-info > .eyebrow, .contact-info > .section-title, .contact-info > .body-md { order: 0; }
  .contact-grid > :not(.contact-info) { order: 1; margin-bottom: 3rem; }
}

/* Advisor and team cards on phones: the portrait beside the name and role,
   with the bio and the contact row under them at full width, so three
   people fit in about a screen instead of two */
@media (max-width: 600px) {
  .team-grid .team-member { display: grid; grid-template-columns: 88px minmax(0, 1fr); column-gap: 1rem; text-align: left; align-items: center; }
  .team-grid .team-member-body { display: contents; }
  .team-grid .team-portrait-wrap { width: 88px; height: 88px; margin: 0; grid-row: 1 / span 3; align-self: center; }
  .team-grid .team-name, .team-grid .team-role, .team-grid .team-quals, .team-grid .team-focus { grid-column: 2; padding: 0; }
  .team-grid .team-quals { margin: 0 0 0.25rem; }
  .team-grid .team-role { margin-bottom: 0.25rem; }
  .team-grid .team-focus { margin: 0; }
  .team-grid .team-bio, .team-grid .team-contact { grid-column: 1 / -1; }
  .team-grid .team-bio { margin: 1rem 0 0.875rem; }
  .team-grid .team-contact { justify-content: flex-start; margin: 0; }
  .team-grid .team-member:hover .team-name { transform: none; }
}

/* Phones: no text under 12px, descriptions and form labels at 14px, and
   links and buttons at least 40 to 44px tall to tap */
@media (max-width: 768px) {
  .footer-col-title, .industries-strip-label, .tcr-compare-label, .linkedin-tag { font-size: 0.75rem; }
  .covered-desc, .form-label, .contact-info-label { font-size: 0.875rem; }
  .nav-hamburger { width: 44px; height: 44px; }
  /* Footer rows: the same spacing as before, with the gap moved into each
     link so the whole row takes the tap */
  .footer-links { gap: 0; }
  .footer-link { padding: 0.5625rem 0; }
  .footer-link--all { margin-top: 0; }
  .footer-contact-item { margin-bottom: 0.25rem; align-items: center; }
  .footer-contact-item a { padding: 0.625rem 0; }
  .footer-bottom-link { padding: 0.75rem 0.25rem; min-width: 44px; text-align: center; }
  .review-more { padding: 0.6875rem 0; margin: -0.6875rem 0 0.5625rem; }
  .contact-info-value a { display: inline-block; padding: 0.25rem 0; }
  .linkedin-logo-link { padding: 12px; margin: -12px -12px -12px auto; }
}

/* ── 31. REDUCED MOTION (WCAG 2.3.3) AND PRINT ───────────────
   Readers who opt out of motion at OS level get a static site: no marquees,
   orbs, pulses, reveals or glides. So does a printed page, or one saved as a
   PDF: the snapshot is a single frame, so an entrance that has not played yet
   (anything below the part of the page the reader reached) would print as
   blank space. The two share the list of entrances below, so a hidden state
   added for one reaches the other. Its animation goes at full weight, since
   the homepage runs some of these from its own later styles; the homepage's
   other hidden states are reset with its styles in index.html.
   Everything scroll-driven (sheets receding, the pinned art drifting,
   the covered-item focus) and the page transition are only ever
   switched on under prefers-reduced-motion: no-preference, so reduced motion
   has nothing to undo for them; print stills them with everything else. */
@media print, (prefers-reduced-motion: reduce) {
  /* Every entrance off, and every state that waits hidden for one shown at rest */
  .reveal, .reveal--media img,
  .risk-card :is(.type-word, .risk-card-title, .risk-card-desc, .risk-card-link) {
    animation: none !important;
  }
  .reveal { opacity: 1; transform: none; }
  .process-connector.reveal { opacity: 0.25; }
  /* The process numbers are simply Orange */
  .process-number { background-color: var(--orange); box-shadow: 0 8px 24px rgba(233,101,18,0.32); text-shadow: var(--on-orange-shadow); }
  /* The orbs hold still */
  .page-hero-orb, .industries-marquee-track { animation: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0s !important;
    transition-delay: 0ms !important;
  }
  /* The header still gets out of the way on scroll, without the slide */
  .site-header { transition: none; }
  /* No pointer glow; cards still lift */
  .has-glow::after, .card-shell-dark.has-glow > .card-core-dark::before { display: none; }
  .nav-links.has-morph .nav-dropdown-item { transform: none; }
}
@media print {
  /* One frame: every animation, scroll-driven or not, and every transition at rest */
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* Fixed and floating pieces would repeat on every sheet or cover the copy:
     the header prints once, at the top, and the rest stays off the page. A
     header that had slid away as the reader scrolled down comes back for it. */
  .site-header { position: absolute; transform: none; }
  .back-to-top, .sticky-mobile-cta, .noise-overlay, .nav-overlay, .skip-link { display: none !important; }
}
