/* ==========================================================================
   Veritís Lux Consulting
   Navy + gold. Cream ground. Serif display over sans body.

   Palette sampled from the logo artwork (brand-assets/BRAND.md), not eyeballed.
   🔴 --gold FAILS AA as body text on light grounds (3.47:1 on white,
      3.25:1 on cream). It is structure and accent only: rules, icons, large
      display accents, or a BACKGROUND beneath navy text. Never small text.
   ========================================================================== */

/* Self-hosted fonts. Previously loaded from Google Fonts, which Lighthouse
   measured as 820ms of render-blocking time and the single largest contributor
   to a 2363ms LCP render delay. Self-hosting removes the third-party origin
   entirely (also drops a processor from the privacy policy).
   Latin subset only, U+00ED for "Veritís" is inside U+0000-00FF. Both are
   variable fonts, so two files cover every weight used. */

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url("../assets/fonts/fraunces-latin-var.woff2") format("woff2");
  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: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../assets/fonts/inter-latin-var.woff2") format("woff2");
  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;
}

:root {
  /* brand */
  --navy:        #05193c;
  --navy-soft:   #0d2a55;
  --navy-deep:   #030f26;
  --gold:        #ae8237;   /* structure only: rules, icons, LARGE display accents */
  --gold-text:   #8a672c;   /* the only gold allowed on small text over a light ground.
                               4.84:1 on cream, 4.52:1 on warm, 5.18:1 on white, all AA.
                               --gold itself is 3.25:1 / 3.03:1 and FAILS. */
  --gold-light:  #f1cf88;
  --cream:       #faf7f2;
  --cream-warm:  #f4efe6;
  --white:       #ffffff;
  --muted:       #5a6472;
  --border:      #e3ded4;

  /* type */
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;

  /* scale */
  --radius:    0.75rem;
  --radius-sm: 0.375rem;
  --maxw:      1180px;
  --maxw-prose: 68ch;
  --header-h:  76px;

  --shadow-sm: 0 1px 2px rgba(5, 25, 60, .06), 0 2px 8px rgba(5, 25, 60, .04);
  --shadow-md: 0 4px 12px rgba(5, 25, 60, .08), 0 12px 32px rgba(5, 25, 60, .06);
  --shadow-lg: 0 8px 24px rgba(5, 25, 60, .10), 0 24px 64px rgba(5, 25, 60, .08);

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

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--navy);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0;
  font-variation-settings: "SOFT" 0, "WONK" 0;
}

h1 { font-size: clamp(2.4rem, 5.6vw, 4rem); letter-spacing: -0.025em; }
h2 { font-size: clamp(1.9rem, 3.8vw, 2.85rem); }
h3 { font-size: clamp(1.15rem, 1.7vw, 1.35rem); line-height: 1.25; }

p { margin: 0 0 1.15rem; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: clamp(1.1rem, 1.7vw, 1.28rem);
  line-height: 1.6;
  color: var(--muted);
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Caught by the G2 contrast gate: this was --gold (3.25:1 on cream, 3.03:1 on
     warm) with a comment claiming a short uppercase label made it acceptable.
     That reasoning was wrong, WCAG "large text" means >=18.66px bold, and this
     is 12px. Uses --gold-text, which clears AA on every ground we paint. */
  color: var(--gold-text);
  margin: 0 0 1rem;
  display: block;
}
.eyebrow.on-dark { color: var(--gold-light); }  /* 11.6:1 on navy */

.muted { color: var(--muted); }
.prose { max-width: var(--maxw-prose); }

/* Page titles. Sized per page rather than off one h1 rule because the headline
   lengths differ enough that one clamp leaves either /pricing cramped or /404
   oversized. .legal h1 is in the legal-prose section. */
.page-title  { font-size: clamp(2.1rem, 4.4vw, 3.1rem); }
.error-title { font-size: clamp(2rem, 5vw, 2.9rem); }

/* ---------- layout -------------------------------------------------------- */

.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 1.5rem; }
.container.narrow { max-width: 780px; }

.section { padding: clamp(4rem, 9vw, 7.5rem) 0; }
.section.tight { padding: clamp(3rem, 6vw, 5rem) 0; }
.section.alt  { background: var(--cream-warm); }

/* First section on a page that opens with a section head instead of a hero:
   the header is fixed, so the section has to clear it by hand. Hero pages do
   not need this, the hero is full-height and sits under the header on purpose. */
.section.page-top      { padding-top: calc(var(--header-h) + 3.5rem); }
.section.page-top-wide { padding-top: calc(var(--header-h) + 4rem); }
.section.dark {
  background: var(--navy);
  color: rgba(255, 255, 255, .88);
}
.section.dark h1, .section.dark h2, .section.dark h3 { color: #fff; }
.section.dark .lede, .section.dark .muted { color: rgba(255, 255, 255, .70); }

.section-head { max-width: 62ch; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }

/* The logo's divider, a gold hairline broken by a small rotated square.
   Recurring section motif so the brand carries past the header. */
.rule {
  display: flex;
  align-items: center;
  gap: .85rem;
  margin: 1.35rem 0;
}
.rule::before, .rule::after {
  content: "";
  height: 1px;
  flex: 1;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: .55;
}
.rule span {
  width: 6px; height: 6px;
  background: var(--gold);
  transform: rotate(45deg);
  flex: none;
}
.rule.left::before { display: none; }
.rule.left { justify-content: flex-start; }
.rule.left::after { flex: 0 0 4.5rem; background: linear-gradient(90deg, var(--gold), transparent); }
.section.dark .rule::before,
.section.dark .rule::after { background: linear-gradient(90deg, transparent, var(--gold-light), transparent); opacity: .4; }
.section.dark .rule.left::after { background: linear-gradient(90deg, var(--gold-light), transparent); }
.section.dark .rule span { background: var(--gold-light); }

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

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--header-h);
  z-index: 100;
  display: flex;
  align-items: center;
  /* 🔴 The header is a DARK surface in every state. It used to be transparent
     at rest and cream when scrolled, which meant two opposite text treatments
     and a whole override block below. One ground, one treatment. Everything in
     here is therefore light-on-navy BY DEFAULT, see the enumeration at
     .brand-name onwards. The only exception is a dark hero, where the header
     goes transparent because the photo behind it is already dark. */
  background: var(--navy);
  transition: background .28s var(--ease), box-shadow .28s var(--ease), border-color .28s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header.solid {
  background: rgba(5, 25, 60, .90);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: rgba(241, 207, 136, .20);
  box-shadow: var(--shadow-md);
}
/* Dark-hero pages only: let the hero photo run to the top edge until scroll. */
body.hero-page .site-header:not(.solid) {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

/* Mark + live wordmark. The supplied lockup is square (929x995) and its
   tagline renders ~3px tall at header height, see brand-assets/BRAND.md. */
.brand { display: flex; align-items: center; gap: .7rem; flex: none; }
/* The header mark is an inline SVG, not the raster master. The master is a
   30-ray hairline sunburst: at 40px the gold rays came out as a pale smudge
   with almost no contrast. Fewer, heavier rays, and the mark reads in two
   tones: the bright light-gold rays carry legibility, the deeper gold arc
   carries the brand.
   Both are gold because the ground is now navy in every state, on cream the
   rays had to be navy (gold is only 3.25:1 there), which is exactly why the
   header was darkened. On #05193c: --gold-light 11.6:1, --gold 5.0:1, both
   well over the 3:1 a graphic needs. */
/* The header mark is an <img> of the footer lockup cropped to the sunburst, not
   an inline SVG, so there is nothing here to recolour. The .bm-rays / .bm-arc
   stroke rules that lived here were deleted on 2026-08-10 with the swap. */
/* 68px, up 70% from 40px (Kyle, 2026-08-10). At aspect 1.667 that is ~41px
   tall inside a 76px header, so it still clears the bar. */
.brand-mark { width: 68px; height: auto; flex: none; display: block; }
.brand-text {
  display: flex; flex-direction: column; line-height: 1;
}
.brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: .01em;
  color: #fff;                                          /* 15.1:1 on --navy */
}
.brand-sub {
  font-size: .58rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .62);                      /* 7.4:1 on --navy */
  margin-top: .22rem;
}

.nav { display: flex; align-items: center; gap: 2rem; }
.nav-links { display: flex; align-items: center; gap: 1.75rem; list-style: none; margin: 0; padding: 0; }
.nav-links a {
  font-size: .925rem;
  font-weight: 500;
  color: #fff;                                          /* 15.1:1 on --navy */
  position: relative;
  padding: .35rem 0;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--gold-light);                        /* 11.6:1 on --navy */
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .26s var(--ease);
}
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }
.nav-links a[aria-current="page"] { color: #fff; font-weight: 600; }

/* 🔴 Everything below is the rest of what lands on the dark header. This project's
   recurring bug is a navy default on a dark surface, so the list is kept explicit
   rather than discovered one screenshot at a time: .brand-name, .brand-sub,
   .nav-links a, the current-page underline (all above), and these three.
   The previous body.hero-page override block lived here and is GONE, with one
   ground there is nothing left for it to override. */

/* .btn-primary is navy-on-white everywhere else, which is navy-on-navy here. */
.site-header .btn-primary {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(255, 255, 255, .34);
  box-shadow: none;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.site-header .btn-primary:hover {
  background: var(--gold-light); color: var(--navy); border-color: var(--gold-light);
}
/* .nav-toggle's base border is --border, a cream hairline: invisible on navy. */
.site-header .nav-toggle { border-color: rgba(255, 255, 255, .34); }
.site-header .nav-toggle-bars::before,
.site-header .nav-toggle-bars::after,
.site-header .nav-toggle-bars i { background: #fff; }

/* ---------- buttons ------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .82rem 1.5rem;
  border-radius: var(--radius-sm);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .005em;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: transform .18s var(--ease), background .2s var(--ease),
              box-shadow .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.btn:active { transform: translateY(1px); }

/* navy on white = 17.34:1 */
.btn-primary { background: var(--navy); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--navy-soft); box-shadow: var(--shadow-md); }

/* navy on gold-light = 11.58:1 */
.btn-accent { background: var(--gold-light); color: var(--navy); }
.btn-accent:hover { background: #f7dda6; box-shadow: var(--shadow-md); }

.btn-ghost { background: transparent; color: var(--navy); border-color: var(--border); }
.btn-ghost:hover { border-color: var(--gold); background: rgba(174, 130, 55, .06); }
/* .hero is its own dark surface and is NOT .section.dark, without it listed
   here the ghost button renders navy-on-navy and disappears. Caught in visual
   verification, not by any automated gate. */
.section.dark .btn-ghost,
.hero .btn-ghost { color: #fff; border-color: rgba(255,255,255,.34); }
.section.dark .btn-ghost:hover,
.hero .btn-ghost:hover { border-color: var(--gold-light); background: rgba(241, 207, 136, .12); }

.btn-sm { padding: .6rem 1.1rem; font-size: .875rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; margin-top: 2rem; }
/* .center on a container was INERT until 2026-08-10: four blocks carried the
   class and all four rendered left-aligned (both homepage feature blocks, the
   /pricing CTA and the /404 body). The markup always declared the intent, the
   rule was simply never written. Defining it here fixes all four at once.
   A button row still needs .btn-row.center below, because centring text does
   not centre a flex line. */
.container.center { text-align: center; }
.btn-row.center { justify-content: center; }

/* ---------- mobile nav ---------------------------------------------------- */

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  flex: none;
}
.nav-toggle-bars { display: block; width: 18px; height: 12px; position: relative; }
.nav-toggle-bars::before,
.nav-toggle-bars::after,
.nav-toggle-bars i {
  content: ""; position: absolute; left: 0; right: 0;
  height: 1.5px; background: var(--navy);
  transition: transform .26s var(--ease), opacity .18s var(--ease);
}
.nav-toggle-bars::before { top: 0; }
.nav-toggle-bars i { top: 5.25px; }
.nav-toggle-bars::after { bottom: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { transform: translateY(5.25px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after { transform: translateY(-5.25px) rotate(-45deg); }

.mobile-nav {
  position: fixed;
  inset: var(--header-h) 0 auto 0;
  background: var(--cream);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  padding: 1.25rem 1.5rem 2rem;
  z-index: 99;
  display: none;
}
.mobile-nav.open { display: block; }
.mobile-nav ul { list-style: none; margin: 0 0 1.25rem; padding: 0; }
.mobile-nav li + li { border-top: 1px solid var(--border); }
.mobile-nav a { display: block; padding: .95rem 0; font-size: 1.05rem; font-weight: 500; }
.mobile-nav a[aria-current="page"] { color: var(--gold-text); font-weight: 600; }
.mobile-nav .btn { width: 100%; }
body.nav-open { overflow: hidden; }

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

.hero {
  position: relative;
  padding: calc(var(--header-h) + clamp(3.5rem, 9vw, 7rem)) 0 clamp(3.5rem, 8vw, 6.5rem);
  overflow: hidden;
  background: var(--navy);
  color: #fff;
  isolation: isolate;
}
.hero::after {
  /* faint radiating band under the content, echoes the mark's rays */
  content: "";
  position: absolute;
  inset: auto 0 -40% 0;
  height: 90%;
  background: radial-gradient(60% 100% at 50% 100%, rgba(241, 207, 136, .16), transparent 70%);
  z-index: -1;
  pointer-events: none;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(3, 15, 38, .90), rgba(3, 15, 38, .78) 45%, rgba(3, 15, 38, .93));
}
.hero h1 { color: #fff; max-width: 17ch; }
.hero .lede { color: rgba(255, 255, 255, .78); max-width: 56ch; margin-top: 1.5rem; }
.hero-grid { display: grid; gap: 2rem; }
/* Hero content right-aligned, Kyle 2026-08-16. justify-items moves the single
   child to the right edge; h1 and lede keep their own max-widths, so the
   measure is unchanged and only the position moves. .btn-row is flex, so it
   needs its own end alignment rather than inheriting text-align. */
.hero-grid.align-right { justify-items: end; text-align: right; }
.hero-grid.align-right .btn-row { justify-content: flex-end; }

/* ---------- cards --------------------------------------------------------- */

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

/* Two-column layouts that need a wider gutter or a different cross-axis
   alignment than the 1.25rem card default. */
.grid.audience-grid { gap: 3rem;    align-items: center; }
.grid.tier-grid     { gap: 1.75rem; align-items: stretch; }
.grid.contact-grid  { gap: 2.5rem;  align-items: start; }

/* Free-standing photography, as opposed to an image inside a .card. */
.img-framed { border-radius: var(--radius); box-shadow: var(--shadow-md); }

.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.75rem;
  position: relative;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: #d8d0c0; }
.card h3 { margin-bottom: .6rem; }
.card p { font-size: .975rem; color: var(--muted); }
.section.dark .card {
  background: rgba(255, 255, 255, .045);
  border-color: rgba(255, 255, 255, .12);
}
.section.dark .card:hover { border-color: rgba(241, 207, 136, .4); }
.section.dark .card p { color: rgba(255, 255, 255, .70); }

.card-icon {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 1px solid var(--gold);
  border-radius: 50%;
  color: var(--gold);
  margin-bottom: 1.1rem;
  flex: none;
}
.card-icon svg { width: 19px; height: 19px; }
.section.dark .card-icon { border-color: var(--gold-light); color: var(--gold-light); }

/* numbered step */
.step { counter-increment: step; }
.step .step-num {
  font-family: var(--font-display);
  font-size: 2.15rem;
  font-weight: 500;
  color: var(--gold);          /* large display accent, permitted */
  line-height: 1;
  margin-bottom: .85rem;
  display: block;
}
.section.dark .step .step-num { color: var(--gold-light); }

/* ---------- pricing ------------------------------------------------------- */

.tier {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
  display: flex;
  flex-direction: column;
}
.tier.featured {
  border-color: var(--gold);
  box-shadow: var(--shadow-md);
  position: relative;
}
/* A badge WITHOUT the gold border and shadow, so a second tier can carry a
   label without competing with the featured card. Added 2026-08-16 for
   "Most popular" on The Full System, which sits beside the featured
   Chief of Staff card. */
.tier.badged { position: relative; }
.tier.featured::before,
.tier.badged::before {
  content: attr(data-badge);
  position: absolute;
  top: -.72rem; left: 2rem;
  background: var(--gold-light);
  color: var(--navy);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  padding: .3rem .7rem;
  border-radius: 999px;
}
/* Navy on the secondary badge so the gold one stays the eye's first stop.
   White on --navy is 15.8:1, well clear of AA at this size. */
.tier.badged::before { background: var(--navy); color: #fff; }
.tier-price {
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 600;
  line-height: 1;
  margin: .35rem 0 .2rem;
}
.tier-price small { font-family: var(--font-body); font-size: .95rem; font-weight: 500; color: var(--muted); }
.tier-setup { font-size: .9rem; color: var(--muted); margin-bottom: 1.4rem; }
.tier ul { list-style: none; margin: 1.4rem 0 2rem; padding: 0; flex: 1; }
.tier li {
  position: relative;
  padding: .42rem 0 .42rem 1.6rem;
  font-size: .95rem;
  border-top: 1px solid var(--border);
}
.tier li:first-child { border-top: 0; }
.tier li::before {
  content: "";
  position: absolute;
  left: 0; top: .95rem;
  width: 6px; height: 6px;
  background: var(--gold);
  transform: rotate(45deg);
}
.tier .eyebrow { margin-bottom: .4rem; }
.tier h2       { font-size: 1.5rem; }
.tier .muted   { font-size: .95rem; }

/* The "prices are indicative" line under the /pricing head, and the usage-billing
   note under the tiers. Both are deliberately quiet next to the figures. */
.section-note { font-size: .92rem; margin-top: .9rem; }

/* The stack of qualifiers under the two tiers: how upgrading works, that we fit
   around what you already have, and how usage is billed. Quiet next to the
   figures on purpose, they qualify the price, they don't compete with it. */
.pricing-notes { max-width: 75ch; margin-top: 1.75rem; }
.pricing-notes p { font-size: .9rem; margin-bottom: .85rem; }
.pricing-notes p:last-child { margin-bottom: 0; }
.pricing-notes strong { color: var(--navy); }


/* ---------- accordion ----------------------------------------------------- */

.accordion { border-top: 1px solid var(--border); }
.accordion-item { border-bottom: 1px solid var(--border); }
.accordion-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: 1.08rem;
  font-weight: 600;
  color: var(--navy);
}
.accordion-trigger:hover { color: var(--navy-soft); }
.accordion-icon { position: relative; width: 14px; height: 14px; flex: none; }
.accordion-icon::before,
.accordion-icon::after {
  content: ""; position: absolute; background: var(--gold-text);
  transition: transform .28s var(--ease), opacity .2s var(--ease);
}
.accordion-icon::before { top: 6.25px; left: 0; right: 0; height: 1.5px; }
.accordion-icon::after  { left: 6.25px; top: 0; bottom: 0; width: 1.5px; }
.accordion-item.open .accordion-icon::after { transform: scaleY(0); opacity: 0; }
.accordion-panel {
  overflow: hidden;
  height: 0;
  transition: height .3s var(--ease);
}
.accordion-panel > div { padding: 0 0 1.4rem; color: var(--muted); max-width: 72ch; }

/* ---------- form / embed -------------------------------------------------- */

.embed-frame {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem;
  box-shadow: var(--shadow-sm);
  min-height: 420px;
}
.embed-frame iframe {
  width: 100%; min-height: 400px; border: 0;
  border-radius: var(--radius-sm); display: block;
  /* The vendor snippet asks for overflow:hidden via an inline style attribute,
     which style-src-attr 'none' blocks. It belongs here instead. */
  overflow: hidden;
}


/* /contact column headings and the trailing "email and phone always work" note. */
.col-title      { font-size: 1.4rem; margin-bottom: 1rem; }
.contact-direct { margin-top: 2.5rem; }
.contact-note   { font-size: .9rem; margin-top: 1.25rem; }

/* .consent-note lived here: page-level SMS consent copy sitting under the
   /contact form. Both are gone. The chat widget is the declared opt-in method
   and carries its own consent text, and consent language attached to a visible
   form reads as a second, undeclared opt-in flow. Do not reintroduce it without
   re-reading docs/2026-08-08-a2p-website-compliance.md, requirements B and C. */

/* ---------- contact form -------------------------------------------------
   🔴 THIS FORM COLLECTS NO PHONE NUMBER AND NO SMS CONSENT, AND MUST NOT START.
   The A2P campaign declares the chat widget as the ONE opt-in method on this
   site (requirement B), and the widget setup attestation names lead-capture
   forms explicitly. A phone field here contradicts the filing. Same rule that
   stripped the phone field out of /intake.

   Controls deliberately mirror css/intake.css so the two forms feel like one
   system; they cannot share rules because intake.css is only loaded on
   /intake. Keep them in step by eye, not by import. */

.cf-form { display: grid; gap: 1.15rem; }
.cf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.15rem; }
.cf-field > label {
  display: block;
  font-size: .875rem; font-weight: 600;
  margin-bottom: .4rem;
  color: var(--navy);
}
.cf-optional { font-weight: 400; color: var(--muted); }

.cf-field input[type="text"],
.cf-field input[type="email"],
.cf-field select,
.cf-field textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .7rem .85rem;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.cf-field textarea { min-height: 8rem; resize: vertical; }
.cf-field input:focus,
.cf-field select:focus,
.cf-field textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(174, 130, 55, .18);
}
.cf-field input[aria-invalid="true"],
.cf-field textarea[aria-invalid="true"] { border-color: #a3312a; }

/* --gold-text, not --gold: this is small text on a light ground. */
.cf-error { display: block; font-size: .82rem; color: #a3312a; margin-top: .3rem; }
.cf-error:empty { display: none; }

/* Honeypot. Off-screen rather than display:none, some bots skip hidden
   fields but fill positioned ones. aria-hidden + tabindex=-1 keep it away
   from assistive tech and the tab order. */
.cf-hp {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

.cf-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.cf-form button[disabled] { opacity: .6; cursor: progress; }

.cf-status { font-size: .9rem; line-height: 1.5; }
.cf-status:empty { display: none; }
.cf-status.err { color: #a3312a; }
.cf-status.ok {
  border-left: 2px solid var(--gold);
  background: var(--cream-warm);
  padding: 1rem 1.25rem;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--navy);
}

/* Pointer to the unlisted discovery wizard. Not in the nav, not in the
   footer, not in the sitemap, see CLAUDE.md. This is the only site-wide
   surface it is linked from besides the pricing CTA. */
.cf-alt {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: .925rem;
}
.cf-alt a { color: var(--gold-text); text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 560px) {
  .cf-row { grid-template-columns: 1fr; }
}

/* ---------- cookie consent -----------------------------------------------
   🔴 BOTTOM LEFT. The bottom right belongs to the A2P chat widget, which is
   the site's declared SMS opt-in surface and the thing a carrier reviewer
   looks for. Do not move this across, and do not let it grow wide enough to
   reach the widget on a small screen.

   Everything here sits on navy, so it is the dark-surface rule again: the
   defaults elsewhere in this file are navy and would vanish. */

.ck-fab {
  position: fixed;
  left: 20px; bottom: 20px;
  z-index: 9998;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--gold-light);                 /* 11.6:1 on --navy */
  border: 1px solid rgba(241, 207, 136, .28);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: transform .18s var(--ease), background .2s var(--ease);
}
.ck-fab:hover { transform: translateY(-2px); background: var(--navy-soft); }
.ck-fab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.ck-panel {
  position: fixed;
  left: 20px; bottom: 78px;
  z-index: 9999;
  width: 340px;
  max-width: calc(100vw - 40px);
  background: var(--white);
  color: var(--navy);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 1.35rem;
  opacity: 0;
  transform: translateY(10px) scale(.98);
  pointer-events: none;
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}
.ck-panel.open { opacity: 1; transform: none; pointer-events: auto; }

.ck-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.ck-title { font-family: var(--font-display); font-size: 1.05rem; margin: 0; color: var(--navy); }
.ck-close {
  background: none; border: 0; font-size: 1.4rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 2px 4px;
}
.ck-close:hover { color: var(--navy); }
.ck-text { font-size: .875rem; line-height: 1.6; color: var(--muted); margin: 0 0 1rem; }

.ck-row { display: flex; align-items: flex-start; gap: 1rem; justify-content: space-between; }
.ck-row-copy { display: block; }
.ck-row-label { display: block; font-size: .9rem; font-weight: 600; color: var(--navy); }
.ck-row-sub { display: block; font-size: .8rem; color: var(--muted); margin-top: .15rem; }

/* Visually hidden label text, still read aloud. */
.ck-sr {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.ck-switch { position: relative; flex: none; width: 42px; height: 24px; cursor: pointer; }
.ck-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.ck-slider {
  position: absolute; inset: 0;
  background: #c9c2b4;                      /* off state reads as off, not as a pale gold */
  border-radius: 999px;
  transition: background .2s var(--ease);
  pointer-events: none;
}
.ck-slider::before {
  content: "";
  position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px;
  background: var(--white);
  border-radius: 50%;
  transition: transform .2s var(--ease);
}
.ck-switch input:checked + .ck-slider { background: var(--gold-text); }
.ck-switch input:checked + .ck-slider::before { transform: translateX(18px); }
.ck-switch input:focus-visible + .ck-slider { outline: 2px solid var(--gold); outline-offset: 2px; }

.ck-actions { margin-top: 1.15rem; }
.ck-btn {
  font: inherit; font-size: .875rem; font-weight: 600;
  background: var(--navy); color: #fff;     /* 17.3:1 */
  border: 1px solid var(--navy);
  border-radius: var(--radius-sm);
  padding: .6rem 1.1rem;
  cursor: pointer;
  transition: background .2s var(--ease);
}
.ck-btn:hover { background: var(--navy-soft); }
.ck-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.ck-panel-link {
  display: inline-block; margin-top: .9rem;
  font-size: .8rem; color: var(--gold-text);
  text-decoration: underline; text-underline-offset: 3px;
}

/* First-visit notice, above the icon so the icon stays reachable. */
.ck-notice {
  position: fixed;
  left: 20px; bottom: 78px;
  z-index: 9997;
  width: 330px; max-width: calc(100vw - 40px);
  background: var(--navy);
  color: #fff;
  border: 1px solid rgba(241, 207, 136, .22);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 1.1rem 1.2rem;
  opacity: 0; transform: translateY(10px);
  transition: opacity .24s var(--ease), transform .24s var(--ease);
}
.ck-notice.show { opacity: 1; transform: none; }
.ck-notice p { margin: 0 0 .85rem; font-size: .875rem; line-height: 1.55; color: rgba(255,255,255,.88); }
.ck-notice-actions { display: flex; align-items: center; gap: .9rem; }
/* On navy: the ghost option is light, the primary is gold with navy text. */
.ck-notice .ck-link-btn {
  font: inherit; font-size: .85rem; font-weight: 500;
  background: none; border: 0; padding: 0;
  color: rgba(255,255,255,.82); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.ck-notice .ck-link-btn:hover { color: var(--gold-light); }
.ck-notice .ck-btn {
  background: var(--gold-light); color: var(--navy);   /* 11.6:1 */
  border-color: var(--gold-light);
  padding: .5rem 1rem;
}
.ck-notice .ck-btn:hover { background: #f7dda6; }

.ck-footer-link {
  font: inherit; background: none; border: 0; padding: 0;
  color: inherit; cursor: pointer; text-align: left;
}
.ck-footer-link:hover { color: var(--gold-light); }

@media (max-width: 480px) {
  /* Keep clear of the chat widget's launcher on a narrow screen. */
  .ck-panel, .ck-notice { width: calc(100vw - 40px); }
  .ck-fab { width: 42px; height: 42px; bottom: 16px; left: 16px; }
}

@media print { .ck-fab, .ck-panel, .ck-notice { display: none !important; } }

.contact-list { list-style: none; margin: 1.5rem 0 0; padding: 0; }
.contact-list li { padding: .6rem 0; border-top: 1px solid var(--border); font-size: .975rem; }
.contact-list li:first-child { border-top: 0; }
.contact-list a:hover { color: var(--gold-text); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- legal prose --------------------------------------------------- */

.legal { max-width: var(--maxw-prose); }
.legal h2 { font-size: 1.5rem; margin: 2.75rem 0 .85rem; }
.legal h3 { font-size: 1.08rem; margin: 1.75rem 0 .6rem; }
.legal ul, .legal ol { padding-left: 1.25rem; margin: 0 0 1.15rem; }
.legal li { margin-bottom: .45rem; }
.legal .updated { font-size: .875rem; color: var(--muted); }
.legal h1 { font-size: clamp(2rem, 4vw, 2.8rem); }
/* Every link in policy prose is underlined, a bare colour change is not a
   sufficient affordance in a document a carrier reviewer reads. Scoped to
   .legal so new policy links inherit it without anyone remembering to. */
.legal a { text-decoration: underline; text-underline-offset: 2px; }

/* The /404 lede, which is centred in a narrow container. */
.lede.center-block { margin-left: auto; margin-right: auto; }

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

.site-footer { background: var(--navy-deep); color: rgba(255, 255, 255, .72); padding: 4rem 0 2rem; }
.site-footer a:hover { color: var(--gold-light); }
/* Four children, so four tracks. It was 1.6fr 1fr 1fr, which wrapped Legal onto
   a second row, tolerable when that column held four items, conspicuous once
   the duplicate phone and email moved into the <address> block. */
.footer-grid { display: grid; grid-template-columns: 1.7fr .8fr 1.5fr .8fr; gap: 2.5rem; }
/* Uses the REVERSED lockup. The light master's wordmark is navy and disappears
   on this ground, see brand-assets/BRAND.md, which also explains why it can't
   simply be composited (its alpha is background-removal residue, so it halos).
   The header still uses mark + live text, because the lockup is square and
   illegible at header height; that's a separate constraint. */
.footer-logo { width: 148px; height: auto; margin-bottom: 1.25rem; }
.footer-brand p { font-size: .925rem; max-width: 34ch; }
.site-footer h3 {
  font-family: var(--font-body);
  font-size: .72rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold-light);
  margin: 0 0 1rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .55rem; font-size: .925rem; }
.footer-bottom {
  margin-top: 3rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .1);
  display: flex; flex-wrap: wrap; gap: 1rem;
  justify-content: space-between;
  font-size: .85rem;
  color: rgba(255, 255, 255, .55);
}

/* ---------- fixed-background CTA ------------------------------------------
   The image stays locked to the viewport while the section scrolls over it.

   Uses clip-path + position:fixed rather than `background-attachment: fixed`,
   which is broken on iOS Safari. Verified empirically in Chromium (2026-08-08):
   clip-path CLIPS the fixed child to this section without becoming its
   containing block, so the child stays viewport-anchored. That distinction is
   the whole trick, transform/filter/will-change on the parent WOULD trap it
   and kill the effect, so don't add any of those here. */

.cta-fixed {
  position: relative;
  isolation: isolate;
  clip-path: inset(0);
  background: var(--navy-deep);   /* fallback + edge colour while the image decodes */
  color: #fff;
}
.cta-fixed__media {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.cta-fixed__media img { width: 100%; height: 100%; object-fit: cover; }
.cta-fixed__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(3, 15, 38, .93), rgba(3, 15, 38, .86) 50%, rgba(3, 15, 38, .94));
}
.cta-fixed > .container { position: relative; z-index: 1; }
.cta-fixed h2 { color: #fff; }
.cta-fixed .lede { color: rgba(255, 255, 255, .78); }
.cta-fixed .rule::before,
.cta-fixed .rule::after { background: linear-gradient(90deg, transparent, var(--gold-light), transparent); opacity: .45; }
.cta-fixed .rule span { background: var(--gold-light); }
.cta-fixed .btn-ghost { color: #fff; border-color: rgba(255, 255, 255, .34); }
.cta-fixed .btn-ghost:hover { border-color: var(--gold-light); background: rgba(241, 207, 136, .12); }

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

.reveal { opacity: 0; transform: translateY(14px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

/* ---------- responsive ---------------------------------------------------- */

/* Breakpoints are deliberately split by CONCERN, not by device.
   Originally the 780px query switched the nav AND collapsed every grid to one
   column, which made a 768px iPad render like a phone: four-up cards became a
   single stack with ~700px-wide cards. Nav and grid density are separate
   problems and now have separate breakpoints. */

/* four-up is too dense below a small laptop */
@media (max-width: 1080px) {
  .grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 940px) {
  .grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
  /* Three tier cards would leave one orphaned on a second row at two-up, and a
     pricing ladder reads badly broken across rows. Stack them instead. Added
     2026-08-16 with the Chief of Staff tier. */
  .grid.tier-grid.cols-3 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}

/* nav loses room here, independent of card density */
@media (max-width: 780px) {
  .nav-links, .nav .btn { display: none; }
  .nav-toggle { display: flex; }
  /* two-up pairs are text+image or form+calendar; they need full width sooner */
  .grid.cols-2 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; gap: 2rem; }
  .brand-sub { display: none; }
  .section { padding: 3.5rem 0; }
}

/* genuine phone width: only now do the card grids go single-column */
@media (max-width: 640px) {
  .grid.cols-3, .grid.cols-4 { grid-template-columns: 1fr; }
}

@media (max-width: 420px) {
  body { font-size: 1rem; }
  .btn-row .btn { width: 100%; }
  .container { padding: 0 1.15rem; }
  .card { padding: 1.4rem; }
  .tier { padding: 1.5rem; }
}

/* ---------- reduced motion ------------------------------------------------ */

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

/* ---------- print --------------------------------------------------------- */

@media print {
  .site-header, .mobile-nav, .nav-toggle, .embed-frame { display: none !important; }
  body { background: #fff; color: #000; }
}

/* A2P requirement H: business address, support email and phone on the site,
   matching Brand registration. Sits in the footer beside the legal column. */
.footer-contact address { font-style: normal; display: grid; gap: .3rem; }
.footer-contact .addr { color: rgba(255, 255, 255, .70); font-size: .92rem; }
.footer-contact a { color: rgba(255, 255, 255, .82); }
.footer-contact a:hover { color: var(--gold-light); }

/* The registered legal name, as submitted to Brand registration. Small caps
   treatment so it reads as a legal line rather than shouting. */

/* The registered address moved out of the footer contact block into the bottom
   bar (Kyle, 2026-08-10). It is an A2P requirement that it stay publicly
   visible, so it is styled to read, not to hide. */
.footer-addr { color: rgba(255, 255, 255, .55); }
