/* site-owned tokens — the names the kernel does NOT emit. tokens.css is otherwise
   EXCLUDED: it mirrors Brand::css_variables(), and a body-side :root lands later
   than the host's <head> block, so shipping it would cancel the tenant brand while
   the page still looked correct. */
:root {
  --pad: clamp(16px, 5vw, 48px);
  --col: min(1200px, calc(100vw - 2 * var(--pad)));
  --col-narrow: min(760px, calc(100vw - 2 * var(--pad)));
  --z-header: 50;
  --z-mobilenav: 70;
}

/* base.css — resets + element defaults + typography. Every value is a token. No hex, no raw px.
   Self-host a brand display font here (NOT in tokens.css) if the design calls for one:
   @font-face { font-family:"Brand"; src:url("/vendor/<site>/fonts/brand.woff2") format("woff2");
                font-weight:400; font-display:swap; }
   ...then set --font-display:"Brand", <fallbacks> in tokens.css.

   The src MUST be absolute. This comment used to read `../assets/fonts/brand.woff2`, and SCV
   Dental's converter copied it verbatim: the sheet is served at `/vendor/scv.css`, so `../` had
   already left `/vendor/` and every one of its five faces 404'd at `/assets/fonts/` for the life
   of the site. `./fonts/` is wrong for the same reason in the other direction — it resolves to
   `/vendor/fonts/`. The files live at `/vendor/<site>/fonts/`, which is what the preloads in
   `main.rs` already point at, so only the stylesheet was ever wrong.

   It went unnoticed for months because the platform injects its own @font-face for six families
   into every published page, one of which (Instrument Serif) is the same face SCV asked for.
   Chrome kept the working copy and the site looked right. A site whose display face does NOT
   collide with a platform one gets no such rescue. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: rgb(var(--bg));
  color: rgb(var(--fg));
  font: var(--weight-base) var(--text-base) / var(--leading-base) var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}

h1, h2, h3, h4, p, figure, ul, ol { margin: 0; }
h1 { font: var(--weight-xl) clamp(var(--text-xl), 5.4vw, calc(var(--text-xl) * 1.9)) / 1.08 var(--font-display); letter-spacing: var(--tracking-tight); }
h2 { font: var(--weight-xl) clamp(var(--text-lg), 3.2vw, var(--text-xl)) / 1.15 var(--font-display); letter-spacing: var(--tracking-tight); }
h3 { font: var(--weight-lg) var(--text-lg) / var(--leading-lg) var(--font-display); }
h4 { font: var(--weight-lg) var(--text-base) / var(--leading-base) var(--font-sans); }

a {
  color: rgb(var(--color-primary));
  text-decoration: none;
  transition: opacity var(--dur-fast) var(--ease-standard);
}
a:hover { opacity: .8; }

/* Inline links within flowing prose must be distinguishable without relying on color alone
   (WCAG 1.4.1) — axe-core flagged bare color-only links inside body paragraphs AND inside
   bullet-list content (e.g. a "further reading" item that's a whole <li>, sitting next to
   plain-text <li> siblings). Buttons, card titles, and nav/footer/dropdown/breadcrumb lists
   are already distinguishable by shape/position, so those are explicitly excluded below. */
p a, li a { text-decoration: underline; text-underline-offset: 0.15em; }
.primary-nav a, .dropdown a, .mobile-nav a, .site-footer a, .breadcrumbs a,
.insurers a, .modalities a, .faq a { text-decoration: none; }

img { max-width: 100%; height: auto; display: block; }
code, pre { font-family: var(--font-mono); font-size: var(--text-sm); }

:focus-visible {
  outline: var(--focus-ring-width) solid rgb(var(--focus-ring));
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

/* Skip link (accessibility) — visible on focus. */
.skip-link {
  position: absolute; left: var(--space-2); top: -4rem;
  background: rgb(var(--color-primary)); color: rgb(var(--on-primary));
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-md);
  transition: top var(--dur-fast) var(--ease-standard); z-index: var(--z-toast);
}
.skip-link:focus { top: var(--space-2); }

/* Visually-hidden utility for screen-reader-only labels. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* layout.css — layout primitives only, tokens only. Flexbox/Grid/clamp; no deep nesting. */

/* Centered content column (uses the site-owned --pad/--col structural tokens). */
.container { width: var(--col); margin-inline: auto; }
.container--narrow { width: var(--col-narrow); margin-inline: auto; }

/* Vertical rhythm between page bands. */
.section { padding-block: clamp(var(--space-10), 8vw, calc(var(--space-10) * 2)); }
.section--tight { padding-block: clamp(var(--space-8), 5vw, var(--space-10)); }

/* Simple stacks. */
.stack    { display: flex; flex-direction: column; gap: var(--space-4); }
.stack-lg { display: flex; flex-direction: column; gap: var(--space-6); }

/* Rows. */
.row { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.row--between { justify-content: space-between; }

/* Auto-fit responsive grid for homogeneous item lists (R5 in the brief). */
.grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr)); }
.grid--tight { gap: var(--space-4); }

/* Two-column split (media + text); collapses to one column on small screens. */
.split {
  display: grid;
  gap: clamp(var(--space-6), 5vw, calc(var(--space-10) * 1.4));
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; } }


/* sections.css — per-section + component styles. Tokens only; flat, section-scoped rules.
   No hex, no token-owned px, no !important. Structural px (hairlines, breakpoints) only. */

/* ─────────────────────────  Buttons / CTAs  ───────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  font: var(--weight-lg) var(--text-sm) / 1 var(--font-sans);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  min-height: var(--space-10); border: var(--stroke-hairline) solid transparent;
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard),
              background var(--dur-fast) var(--ease-standard);
}
.btn:hover { opacity: .92; }
.btn:active { transform: translateY(1px); }
.btn--primary { background: rgb(var(--color-primary)); color: rgb(var(--on-primary)); }
.btn--ghost   { background: transparent; color: rgb(var(--fg)); border-color: var(--line); }
.btn--onprimary { background: rgb(var(--on-primary)); color: rgb(var(--color-primary)); }
.btn--sm { min-height: auto; padding: var(--space-2) var(--space-4); }

/* Text link with arrow — used as card "Learn More" affordances. */
.link-more {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font: var(--weight-lg) var(--text-sm) / 1 var(--font-sans);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: rgb(var(--color-primary));
}

/* ─────────────────────────  Header / nav  ───────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  background: rgb(var(--bg) / .88);
  backdrop-filter: saturate(1.2) blur(var(--blur-card));
  border-bottom: var(--stroke-hairline) solid var(--line);
}
.site-header__inner { padding-block: var(--space-3); gap: var(--space-5); }
.brand-mark {
  color: rgb(var(--fg)); font: var(--weight-xl) var(--text-lg) / 1 var(--font-display);
  letter-spacing: var(--tracking-tight); white-space: nowrap;
}
.brand-mark strong { color: rgb(var(--color-primary)); font-weight: inherit; }

.primary-nav { display: none; }
@media (min-width: 1040px) { .primary-nav { display: flex; align-items: center; gap: var(--space-5); } }
.primary-nav > li { position: relative; list-style: none; }
.primary-nav a, .navlink {
  color: rgb(var(--fg)); font: var(--weight-base) var(--text-sm) / 1 var(--font-sans);
  padding-block: var(--space-2); display: inline-flex; align-items: center; gap: var(--space-1);
}
.navlink[aria-expanded] { background: none; border: 0; cursor: pointer; font-family: inherit; }
.navlink svg { width: .7em; height: .7em; transition: transform var(--dur-fast) var(--ease-standard); }
.navlink[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Dropdown menus — CSS-hover open, JS toggles aria-expanded for keyboard/touch. */
.dropdown {
  position: absolute; top: 100%; left: 0; min-width: 15rem;
  background: rgb(var(--bg)); border: var(--stroke-hairline) solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: var(--space-2); margin: 0; list-style: none; z-index: var(--z-dropdown);
  display: none;
}
.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown,
.dropdown[data-open="true"] { display: block; }
.dropdown a { display: block; padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); }
.dropdown a:hover { background: rgb(var(--primary-surface)); color: rgb(var(--primary-on-surface)); opacity: 1; }

.header-actions { display: flex; align-items: center; gap: var(--space-3); }
.header-phone {
  display: none; font: var(--weight-lg) var(--text-sm) / 1 var(--font-sans);
  color: rgb(var(--color-primary)); white-space: nowrap;
}
@media (min-width: 680px) { .header-phone { display: inline-flex; } }

/* Mobile nav toggle + panel */
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-10); height: var(--space-10);
  background: transparent; border: var(--stroke-hairline) solid var(--line);
  border-radius: var(--radius-md); color: rgb(var(--fg)); cursor: pointer;
}
@media (min-width: 1040px) { .nav-toggle { display: none; } }
.mobile-nav {
  display: none; position: fixed; inset: 0; z-index: var(--z-mobilenav);
  background: rgb(var(--bg)); padding: var(--space-6) var(--pad);
  overflow-y: auto;
}
.mobile-nav[data-open="true"] { display: block; }
.mobile-nav ul { list-style: none; margin: 0; padding: 0; }
.mobile-nav > ul > li { border-bottom: var(--stroke-hairline) solid var(--line); }
.mobile-nav a, .mobile-nav summary {
  display: block; padding: var(--space-4) 0; color: rgb(var(--fg));
  font: var(--weight-lg) var(--text-lg) / 1.2 var(--font-display); cursor: pointer;
}
.mobile-nav details ul a { font: var(--weight-base) var(--text-base) / 1.4 var(--font-sans); padding: var(--space-2) 0 var(--space-2) var(--space-4); }
.mobile-nav__close { position: absolute; top: var(--space-5); right: var(--pad); }

/* ─────────────────────────  Breadcrumbs  ───────────────────────── */
.breadcrumbs { padding-block: var(--space-4); }
.breadcrumbs ol { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; margin: 0; padding: 0; font-size: var(--text-sm); color: rgb(var(--muted)); }
.breadcrumbs li::after { content: "/"; margin-left: var(--space-2); color: rgb(var(--muted) / .6); }
.breadcrumbs li:last-child::after { content: ""; }
.breadcrumbs a { color: rgb(var(--muted)); }
.breadcrumbs [aria-current="page"] { color: rgb(var(--fg)); }

/* ─────────────────────────  Eyebrow / section head / lede  ───────────────────────── */
.eyebrow { color: rgb(var(--color-primary)); text-transform: uppercase; letter-spacing: var(--tracking-wide); font: var(--weight-lg) var(--text-sm) / 1 var(--font-sans); }
.sec-head { max-width: 60ch; margin-bottom: var(--space-8); }
.sec-head__title { margin-top: var(--space-3); }
.sec-head__lede { color: rgb(var(--fg-2)); margin-top: var(--space-4); font-size: var(--text-lg); line-height: var(--leading-lg); }
.lede { color: rgb(var(--fg-2)); font-size: var(--text-lg); line-height: var(--leading-lg); }

/* ─────────────────────────  Hero  ───────────────────────── */
.hero { padding-block: clamp(var(--space-10), 9vw, calc(var(--space-10) * 2.4)); position: relative; }
.hero__eyebrow { margin-bottom: var(--space-4); }
.hero__title { max-width: 18ch; }
.hero__subtitle { color: rgb(var(--fg-2)); font-size: var(--text-lg); line-height: var(--leading-lg); max-width: 54ch; margin-top: var(--space-5); }
.hero__cta { margin-top: var(--space-8); gap: var(--space-3); }
.hero--split .hero__media { display: grid; gap: var(--space-4); }

/* ─────────────────────────  Placeholder image (ALL source imagery is a placeholder) ─────────────────────────
   Every live image is a grey SVG data-URI. We render an honest, neutral, on-token block
   carrying the real alt as an accessible name, and flag it for the client. Nothing invented. */
.ph {
  display: grid; place-items: center;
  background:
    linear-gradient(135deg, rgb(var(--primary-surface)), rgb(var(--bg-3)));
  border: var(--stroke-hairline) solid var(--line);
  border-radius: var(--radius-xl);
  color: rgb(var(--muted));
  aspect-ratio: 4 / 3; width: 100%; overflow: hidden;
}
.ph::after {
  content: "Photo pending"; font: var(--weight-base) var(--text-xs) / 1 var(--font-sans);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; opacity: .7;
}
.ph--portrait { aspect-ratio: 3 / 4; }
.ph--square { aspect-ratio: 1 / 1; }
.ph--wide { aspect-ratio: 16 / 9; }
.ph--avatar { aspect-ratio: 1 / 1; border-radius: var(--radius-full); width: var(--space-10); height: var(--space-10); }
.ph--avatar::after { content: ""; }
.ph--logo { aspect-ratio: 5 / 2; background: rgb(var(--bg-2)); border-radius: var(--radius-md); }
.ph--logo::after { content: attr(aria-label); padding: var(--space-2); text-align: center; text-transform: none; letter-spacing: 0; }

/* ─────────────────────────  Cards  ───────────────────────── */
.card {
  background: rgb(var(--bg-2));
  border: var(--stroke-hairline) solid var(--line);
  border-radius: var(--radius-2xl);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-3);
  transition: transform var(--dur-base) var(--ease-standard), box-shadow var(--dur-base) var(--ease-standard);
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.card__eyebrow { color: rgb(var(--muted)); text-transform: uppercase; letter-spacing: var(--tracking-wide); font-size: var(--text-xs); }
.card__title { font: var(--weight-lg) var(--text-lg) / var(--leading-lg) var(--font-display); }
.card__body { color: rgb(var(--fg-2)); }
.card__media { margin: calc(var(--space-6) * -1) calc(var(--space-6) * -1) 0; }
.card__media .ph { border-radius: var(--radius-2xl) var(--radius-2xl) 0 0; border: 0; }
.card > .link-more { margin-top: auto; }

/* Program card — numbered, editorial */
.card--program .card__num { font: var(--weight-xl) var(--text-xl) / 1 var(--font-display); color: rgb(var(--color-primary) / .7); }

/* Team card */
.card--team { align-items: flex-start; text-align: left; }
.card--team .ph { margin-bottom: var(--space-2); }
.card--team .card__role { color: rgb(var(--muted)); font-size: var(--text-sm); }

/* Post card */
.card--post .card__meta { display: flex; align-items: center; gap: var(--space-3); color: rgb(var(--muted)); font-size: var(--text-sm); margin-top: auto; }
.card--post .card__title a { color: rgb(var(--fg)); }
.card--post .card__title a:hover { color: rgb(var(--color-primary)); opacity: 1; }

/* ─────────────────────────  Stats band  ───────────────────────── */
.stats { background: rgb(var(--primary-surface)); border-radius: var(--radius-2xl); padding: clamp(var(--space-6), 5vw, var(--space-10)); }
.stats__grid { display: grid; gap: var(--space-6); grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); text-align: center; }
.stat__num { font: var(--weight-xl) clamp(var(--text-xl), 6vw, calc(var(--text-xl) * 1.8)) / 1 var(--font-display); color: rgb(var(--primary-on-surface)); }
.stat__label { color: rgb(var(--fg-2)); font-size: var(--text-sm); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-top: var(--space-2); }

/* ─────────────────────────  Modalities list  ───────────────────────── */
.modalities { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.modalities li { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: rgb(var(--bg-2)); border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-lg); }
.modalities li::before { content: ""; width: var(--space-2); height: var(--space-2); border-radius: var(--radius-full); background: rgb(var(--color-primary)); flex: none; }

/* ─────────────────────────  Insurance logo grid  ───────────────────────── */
.insurers { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); }

/* ─────────────────────────  Forms  ───────────────────────── */
.form { display: grid; gap: var(--space-5); }
.field { display: grid; gap: var(--space-2); }
.field > label { font: var(--weight-lg) var(--text-sm) / 1.2 var(--font-sans); }
.field .req { color: rgb(var(--color-negative)); }
.field input, .field select, .field textarea {
  font: var(--weight-base) var(--text-base) / var(--leading-base) var(--font-sans);
  color: rgb(var(--fg)); background: rgb(var(--bg));
  border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4); width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: rgb(var(--color-primary)); }
.field .hint { color: rgb(var(--muted)); font-size: var(--text-sm); }
.field .error { color: rgb(var(--color-negative)); font-size: var(--text-sm); }
.field--invalid input, .field--invalid select, .field--invalid textarea { border-color: rgb(var(--color-negative)); }
.consent { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--text-sm); color: rgb(var(--fg-2)); }
.consent input { width: auto; margin-top: .2em; }
.form__status { border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); font-size: var(--text-sm); }
.form__status[data-kind="error"] { background: rgb(var(--color-negative) / .1); color: rgb(var(--color-negative)); }
.form__status[data-kind="ok"] { background: rgb(var(--positive-surface, var(--primary-surface))); color: rgb(var(--primary-on-surface)); }
.form-embed-note { color: rgb(var(--muted)); font-size: var(--text-sm); border-left: var(--stroke-thick) solid var(--line); padding-left: var(--space-4); }

/* ─────────────────────────  CTA bands  ───────────────────────── */
.band { background: rgb(var(--bg-2)); border-block: var(--stroke-hairline) solid var(--line); }
.bigcta { background: rgb(var(--color-primary)); color: rgb(var(--on-primary)); border-radius: var(--radius-2xl); padding: clamp(var(--space-8), 6vw, calc(var(--space-10) * 1.4)); text-align: center; }
.bigcta h2 { color: rgb(var(--on-primary)); }
.bigcta p { color: rgb(var(--on-primary) / .85); margin-top: var(--space-3); }
.bigcta .btn { margin-top: var(--space-6); }

/* ─────────────────────────  Prose (R10 subset — articles, legal, bios)  ───────────────────────── */
.prose { max-width: 68ch; }
.prose > * + * { margin-top: var(--space-5); }
.prose h2 { margin-top: var(--space-10); }
.prose h3 { margin-top: var(--space-8); }
.prose ul, .prose ol { padding-left: var(--space-6); display: grid; gap: var(--space-2); }
.prose blockquote { border-left: var(--stroke-heavy) solid rgb(var(--color-primary)); padding-left: var(--space-5); color: rgb(var(--fg-2)); font-style: italic; }
.prose figure { margin: 0; }
.prose figcaption { color: rgb(var(--muted)); font-size: var(--text-sm); margin-top: var(--space-2); }
.callout { background: rgb(var(--primary-surface)); border-radius: var(--radius-lg); padding: var(--space-5); color: rgb(var(--primary-on-surface)); }

/* ─────────────────────────  FAQ accordion (native <details>)  ───────────────────────── */
.faq { display: grid; gap: var(--space-3); }
.faq details { border: var(--stroke-hairline) solid var(--line); border-radius: var(--radius-lg); background: rgb(var(--bg-2)); }
.faq summary { cursor: pointer; padding: var(--space-4) var(--space-5); font: var(--weight-lg) var(--text-lg) / 1.3 var(--font-display); display: flex; justify-content: space-between; gap: var(--space-4); align-items: center; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: rgb(var(--color-primary)); font-size: var(--text-xl); flex: none; }
.faq details[open] summary::after { content: "\2013"; }
.faq__body { padding: 0 var(--space-5) var(--space-5); color: rgb(var(--fg-2)); }

/* ─────────────────────────  Footer  ───────────────────────── */
.site-footer { border-top: var(--stroke-hairline) solid var(--line); background: rgb(var(--bg-2)); color: rgb(var(--fg-2)); }
.site-footer__inner { padding-block: clamp(var(--space-8), 6vw, calc(var(--space-10) * 1.4)); display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 640px) { .site-footer__inner { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .site-footer__inner { grid-template-columns: 2fr 1fr 1fr 1.4fr; } }
.site-footer__inner > div { min-width: 0; }
.site-footer h2 { font: var(--weight-lg) var(--text-sm) / 1 var(--font-sans); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: rgb(var(--muted)); margin-bottom: var(--space-4); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-footer a { color: rgb(var(--fg-2)); }
.site-footer a:hover { color: rgb(var(--color-primary)); opacity: 1; }
.footer-social { display: flex; gap: var(--space-3); margin-top: var(--space-4); }
.footer-hours { display: grid; grid-template-columns: minmax(0, auto) minmax(0, auto); gap: var(--space-1) var(--space-4); font-size: var(--text-sm); }
.footer-legal { border-top: var(--stroke-hairline) solid var(--line); padding-block: var(--space-4); color: rgb(var(--muted)); font-size: var(--text-sm); }

/* ─────────────────────────  Sticky mobile call bar  ───────────────────────── */
.callbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-header);
  display: flex; gap: var(--space-2); padding: var(--space-2) var(--space-3);
  background: rgb(var(--bg) / .95); backdrop-filter: blur(var(--blur-card));
  border-top: var(--stroke-hairline) solid var(--line);
}
.callbar .btn { flex: 1; }
@media (min-width: 680px) { .callbar { display: none; } }
body { padding-bottom: calc(var(--space-10) + var(--space-6)); }
@media (min-width: 680px) { body { padding-bottom: 0; } }

/* Section tint helper for alternating bands */
.tint { background: rgb(var(--bg-2)); }

/* ─────────────────────────  Small layout affordances (replace inline styles) ─────────────────────────
   Named, context-scoped rules — every value is a token; nothing hardcoded to re-skin cleanly. */
.stack > .btn:not(.cta-center), .stack-lg > .btn:not(.cta-center) { align-self: flex-start; }
.stack > .btn.cta-center, .stack-lg > .btn.cta-center { align-self: center; }
.eyebrow-head h2 { margin-top: var(--space-3); }
.sec-head p + p { margin-top: var(--space-4); }
.sec-head--split { max-width: none; align-items: flex-end; }
.sec-head--split h2 { margin: 0; }
.stats h2 { text-align: center; }
.rating-band { gap: var(--space-6); }
.rating-band__mark { gap: var(--space-4); }
.ph--reviews { width: 10rem; aspect-ratio: 164 / 40; }
.footer-about { margin-top: var(--space-4); max-width: 42ch; }


/* Northeast Wellness Collective — corrections layer.
   convert.py appends this LAST to nwc.css. Never edit the generated bundle, and never edit
   ~/Downloads/Northeast Wellness/build: that build is the client's reference and stays as
   it is. */

/* ── 1. Restored photography ──────────────────────────────────────────────────
   `repair.py` replaces the rebuild's `<div class="ph …">` boxes with real `<img>`s. These
   rules carry each `.ph` modifier's geometry across ONE FOR ONE — same aspect ratio, same
   radius, same width — so putting the photographs back does not move a single element on
   the page. The differences are only the ones a replaced element needs:

     - `object-fit: cover`, because `.ph` was an empty grid box and an <img> is not;
     - no `::after`, because the "Photo pending" label was the placeholder saying so, and a
       replaced element cannot render one anyway;
     - a `--bg-3` fill rather than the `.ph` gradient, so a slow connection shows a neutral
       plate instead of a teal wash that reads like part of the design.                     */
.photo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;                                  /* mirrors `.ph` */
  object-fit: cover;
  background: rgb(var(--bg-3));
  border: var(--stroke-hairline) solid var(--line);
  border-radius: var(--radius-xl);
  overflow: hidden;
}
.photo--portrait { aspect-ratio: 3 / 4; }
.photo--square   { aspect-ratio: 1 / 1; }
.photo--wide     { aspect-ratio: 16 / 9; }
.photo--avatar {
  aspect-ratio: 1 / 1;
  width: var(--space-10);
  height: var(--space-10);
  border-radius: var(--radius-full);
}
/* An insurer's logo is artwork on a plate, not a photograph: contain it, never crop it. */
.photo--logo {
  aspect-ratio: 5 / 2;
  object-fit: contain;
  background: rgb(var(--bg-2));
  border-radius: var(--radius-md);
  padding: var(--space-2);
}

/* ── 2. Placeholders that survived ────────────────────────────────────────────
   A handful of `.ph` boxes have no counterpart on the live site (the contact page's map is
   an <iframe> there, not an image). They keep the build's honest "Photo pending" treatment
   — see the residue reported by repair.py. Nothing to override; this note is here so the
   next person does not think the restoration silently missed them. */

/* ── 3. The one `.ph` modifier §1 did not mirror ──────────────────────────────
   `sections.css` narrows the review badge with `.ph--reviews { width: 10rem; aspect-ratio:
   164/40 }`. `repair.py` swaps the placeholder for `<img class="photo photo--logo">` and the
   `--reviews` part is not carried across, so the badge inherited `.photo--logo`'s full-width
   5:2 plate: a 1600x391 strip of five faces rendered a metre wide, with a grey mat behind it.
   Scoped to its only container rather than inventing a `.photo--reviews` that the converter
   would then have to learn to emit. */
.rating-band__mark > .photo--logo {
  width: 10rem;
  aspect-ratio: 164 / 40;
  padding: 0;
  background: none;
  border: 0;
}

/* ── 4. A rule the shipped bundle had and the reference build does not ────────
   `.card--post .card__cat` — the category pill on the three blog cards — exists only in
   `nwc.css`, which means it was written straight into the generated file. Rebuilding the
   bundle from `sections.css` therefore DELETED it and the pills lost their treatment, and
   nothing would have said so. Moved here, where the corrections layer belongs, so the
   stylesheet can be regenerated without silently losing it again. */
.card--post .card__cat {
  align-self: flex-start;
  font-size: var(--text-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgb(var(--muted));
  border: var(--stroke-hairline) solid rgb(var(--line));
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-3);
  margin-bottom: var(--space-2);
}


/* Self-hosted typefaces — GENERATED from faces.json by convert.py. */
@font-face {
  font-family: "Instrument Sans";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-sans-italic-latin.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: "Instrument Sans";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-sans-italic-latin-ext.woff2") format("woff2");
  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;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-sans-normal-latin.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: "Instrument Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-sans-normal-latin-ext.woff2") format("woff2");
  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;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-serif-italic-latin.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: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-serif-italic-latin-ext.woff2") format("woff2");
  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;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-serif-normal-latin.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: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/nwc/fonts/instrument-serif-normal-latin-ext.woff2") format("woff2");
  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;
}

/* Northeast Wellness Collective — the Claude Design direction, expressed on the site that
   already exists.

   WHAT THIS FILE IS
   `convert.py` appends it LAST, after base/layout/sections/polish. It is a LOOK layer: it
   restyles the class vocabulary the rebuild already ships and changes no markup at all. That
   is deliberate and it is the whole safety argument — copy, media, page order and page count
   cannot regress if not one byte of page HTML is touched. `parity.py` still proves it.

   WHERE THE DESIGN LIVES
   Not here. The palette, the typefaces, the radii and the spacing rhythm are in
   `northeast_wellness_brand()` (server/src/main.rs), because the brand is the source of truth
   for every medium — iOS and Android realize the same `Tokens` and would never see a value
   written into a stylesheet. This file only says HOW those tokens are arranged: what is large,
   what is quiet, what has an arch cut into it. Two gates keep that honest —
   `no_design_literals_in_the_shipped_css` (no hex, no rgba, no numeric rgb anywhere in the
   bundle) and `shipped_css_declares_no_kernel_token`.

   THE ONE ESCAPE HATCH
   `Brand` has no type-scale slot: it hardcodes a 12/13/14/18/20px UI ramp. This design is
   drawn on an editorial one (17px body at 1.65, display type up to ~6rem). So the ramp below
   is SITE-OWNED — every name is `--nw-*`, which the kernel never emits, so it cannot cancel
   the tenant brand the way shipping `--text-*` would. Same precedent as SCV's `--lh-*`.

   The design's own reference: `Northeast Wellness Collective.dc.html`. Where it and this file
   diverge, the divergence is noted inline with the reason. */

/* TYPEFACES: the `@font-face` block above this comment is GENERATED from `faces.json` by
   convert.py and prepended at build time, so a face can never reference a woff2 that is not
   in the embedded asset table. The files are self-hosted under /vendor/nwc/fonts/ because the
   published-site CSP is `font-src 'self' data:` — a Google Fonts <link> is blocked on the
   exact surface this design is for. */

/* ── Site-owned tokens ────────────────────────────────────────────────────────────────────
   Names the kernel does not emit. Anything here that COULD be a brand token is a brand token
   instead; what remains is type scale (no `Brand` slot), geometry the design invents (the
   band arc, the arch cut), and one theme-flipping alias. */
:root {
  /* Editorial type ramp. Sizes are fluid so a 1560px design and a 380px phone both read. */
  --nw-fs-body: 17px;            --nw-lh-body: 1.65;
  --nw-fs-lede: clamp(1.06rem, 1.5vw, 1.32rem);   --nw-lh-lede: 1.58;
  --nw-fs-small: 15px;
  --nw-fs-meta: 13px;
  --nw-fs-micro: 11px;           /* eyebrows, band labels */
  /* Display steps. d1 is a page's one big serif statement; d2 a section head; d3 a card or
     accordion row; d4 a small title. Line-heights tighten as the size grows, which is what
     makes a 400-weight serif read as deliberate rather than accidental. */
  /* The reference headline is three words and runs to 7.4rem. Real page titles here go to
     ~70 characters ("Understanding Inpatient vs Outpatient Mental Health Treatment"), and at
     7.4rem that is a six-line wall on every blog post. 4.6rem keeps the editorial scale and
     keeps the longest title in this site to three lines. */
  --nw-fs-d1: clamp(2.4rem, 5.6vw, 4.6rem);   --nw-lh-d1: 1.0;
  --nw-fs-d2: clamp(1.95rem, 4.6vw, 3.8rem);  --nw-lh-d2: 1.04;
  --nw-fs-d3: clamp(1.5rem, 3vw, 2.35rem);    --nw-lh-d3: 1.12;
  --nw-fs-d4: clamp(1.2rem, 1.9vw, 1.55rem);  --nw-lh-d4: 1.2;
  --nw-track-eyebrow: 0.3em;
  --nw-track-meta: 0.14em;
  --nw-track-btn: 0.015em;
  --nw-fw-medium: 500;           /* Instrument Sans is variable; the kernel ramp is all 400 */

  /* Geometry the design invents. The arc is the shallow curve cut into the top of a dark
     band; the arch is the lozenge cut into hero and gallery photography. */
  --nw-arc: clamp(var(--space-8), 6vw, calc(var(--space-10) * 2.5));
  --nw-band-pad: clamp(var(--space-10), 11vw, calc(var(--space-10) * 3));
  --nw-rule: calc(var(--space-8) - var(--space-2));   /* the 34px hairline before an eyebrow */

  /* The dark band. In light mode it is the design's navy — which IS `--fg`, because this
     design treats navy as ink rather than as a hue (see the brand's note). Flipping it below
     rather than hardcoding `--fg` is what keeps dark mode from ending up with a near-white
     footer on a near-black page. */
  --nw-band: var(--fg);
  --nw-band-ink: var(--bg);

  /* Motion. The design's signature curve is a long ease-out; the kernel's `--ease-emphasized`
     is the same shape. Durations are the kernel's `--dur-*` everywhere except the two places
     a 260ms move reads as a twitch (see `--nw-dur-rise`). */
  --nw-dur-rise: 900ms;
  --nw-rise-shift: var(--space-6);
}

/* Dark mode is the design's OWN dark band taken deeper (see the brand). The band token has to
   invert or the footer becomes the brightest thing on the page. Only `--nw-*` names are
   declared here — the kernel's `.dark` block in <head> is untouched. */
.dark {
  --nw-band: var(--bg-3);
  --nw-band-ink: var(--fg);
}

/* ── Foundations ──────────────────────────────────────────────────────────────────────────*/
body {
  font-size: var(--nw-fs-body);
  line-height: var(--nw-lh-body);
  text-wrap: pretty;
}

/* Instrument Serif at 400, tight, large. `base.css` sizes h1/h2 off the kernel's UI ramp;
   these replace those values wholesale rather than nudging them. */
h1, .hero__title {
  font: var(--weight-xl) var(--nw-fs-d1) / var(--nw-lh-d1) var(--font-display);
  letter-spacing: -0.022em;
  color: rgb(var(--fg));
}
h2, .sec-head__title {
  font: var(--weight-xl) var(--nw-fs-d2) / var(--nw-lh-d2) var(--font-display);
  letter-spacing: -0.018em;
  color: rgb(var(--fg));
}
h3 {
  font: var(--weight-lg) var(--nw-fs-d4) / var(--nw-lh-d4) var(--font-display);
  letter-spacing: -0.01em;
}
h4 { font: var(--nw-fw-medium) var(--nw-fs-small) / 1.4 var(--font-sans); }

/* The design's emphasis mark: a serif italic in sage, inside a navy heading or a grey
   paragraph. The rebuild has no <em> in its headings — that would be a copy edit — but blog
   prose carries plenty, and this is where they land. */
h1 em, h2 em, h3 em, .hero__title em, .sec-head__title em {
  font-family: var(--font-display);
  font-style: italic;
  color: rgb(var(--color-primary));
}

/* Links: ink, not accent. `base.css` paints every <a> with `--color-primary`, which in dark
   mode is sage on a deep ground at 3.20:1 — legal for a focus ring, short of AA for text. The
   design's own rule is `a { color: navy } a:hover { color: sage }`, which is both prettier and
   correct in both modes, so the accent stops being used as text anywhere on the site. */
a { color: rgb(var(--fg)); }
a:hover { color: rgb(var(--color-primary)); opacity: 1; }
p a, li a { text-underline-offset: 0.18em; text-decoration-color: rgb(var(--fg) / 0.35); }
p a:hover, li a:hover { text-decoration-color: rgb(var(--color-primary)); }
::selection { background: rgb(var(--accent-meadow)); color: rgb(var(--fg)); }

/* ── Header ───────────────────────────────────────────────────────────────────────────────
   Transparent over the top of the page, frosting in on scroll. `redesign.js` toggles
   `.is-scrolled`; with JS off the header simply stays in its at-rest state, which is legible
   because the page ground and the header ground are the same paper. */
.site-header {
  background: rgb(var(--bg) / 0);
  backdrop-filter: none;
  border-bottom-color: rgb(var(--fg) / 0);
  transition: background var(--dur-slow) var(--ease-standard),
              backdrop-filter var(--dur-slow) var(--ease-standard),
              border-color var(--dur-slow) var(--ease-standard),
              padding var(--dur-slow) var(--ease-emphasized);
}
.site-header.is-scrolled {
  background: rgb(var(--bg) / var(--fill-frost));
  backdrop-filter: saturate(1.7) blur(var(--blur-frost));
  border-bottom-color: rgb(var(--fg) / var(--o-muted));
}
.site-header__inner { padding-block: var(--space-4); }
.site-header.is-scrolled .site-header__inner { padding-block: var(--space-2); }

.brand-mark {
  font: var(--weight-xl) var(--nw-fs-d4) / 1.05 var(--font-display);
  letter-spacing: 0.005em;
}
/* "Collective" is the tracked, uppercase second line of the design's wordmark. It is a
   <strong> in the markup, so the treatment goes there rather than into new elements. */
.brand-mark strong {
  display: block;
  font: var(--weight-base) var(--nw-fs-micro) / 1.4 var(--font-sans);
  letter-spacing: var(--nw-track-eyebrow);
  text-transform: uppercase;
  color: rgb(var(--muted));
}

.primary-nav a, .navlink {
  font: var(--weight-base) var(--nw-fs-small) / 1 var(--font-sans);
  color: rgb(var(--fg) / 0.72);
  padding-block: var(--space-2);
  border-bottom: var(--stroke-hairline) solid transparent;
  transition: color var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.primary-nav a:hover, .navlink:hover,
.has-dropdown:hover > .navlink, .has-dropdown:focus-within > .navlink {
  color: rgb(var(--fg));
  border-bottom-color: rgb(var(--accent-stone));
}
.dropdown {
  border-radius: var(--radius-xl);
  border-color: rgb(var(--fg) / var(--o-muted));
  box-shadow: var(--shadow-xl);
  padding: var(--space-3);
}
.dropdown a { font-size: var(--nw-fs-small); border-radius: var(--radius-lg); }

.header-phone {
  font: var(--weight-base) var(--nw-fs-small) / 1 var(--font-sans);
  color: rgb(var(--fg));
}
/* The theme toggle reads as chrome, not as a call to action: a quiet round icon button. */
[data-theme-toggle] {
  border-radius: var(--radius-full);
  width: var(--space-8); height: var(--space-8);
  min-height: 0; padding: 0;
  font-size: var(--nw-fs-small);
  color: rgb(var(--muted));
  border-color: rgb(var(--fg) / var(--o-muted));
}
[data-theme-toggle]:hover { color: rgb(var(--fg)); }
.nav-toggle { border-radius: var(--radius-full); border-color: rgb(var(--fg) / var(--o-strong)); }

.mobile-nav a, .mobile-nav summary {
  font: var(--weight-xl) var(--nw-fs-d3) / 1.15 var(--font-display);
  letter-spacing: -0.014em;
}
.mobile-nav details ul a { font: var(--weight-base) var(--nw-fs-small) / 1.5 var(--font-sans); }

/* ── Breadcrumbs ──────────────────────────────────────────────────────────────────────────*/
.breadcrumbs ol {
  font-size: var(--nw-fs-meta);
  letter-spacing: 0.04em;
}
.breadcrumbs [aria-current="page"] { color: rgb(var(--fg)); }

/* ── Hero ─────────────────────────────────────────────────────────────────────────────────
   Every one of the 71 pages opens with `.hero`; only the home page has `.hero__media`, so the
   treatment has to carry a text-only hero too. The blobs are the design's drifting organic
   gradients, drawn as pseudo-elements so no markup is added and nothing is focusable. */
.hero {
  padding-block: clamp(calc(var(--space-10) * 1.6), 13vw, calc(var(--space-10) * 3.2))
                 clamp(var(--space-10), 9vw, calc(var(--space-10) * 2));
  overflow: hidden;
  isolation: isolate;
}
/* ONE layer, not two. The obvious shape — a pseudo-element per blob, sized in `vw` and hung
   off the hero's corners — works on the reference's `100svh` hero and fails on this site's:
   71 of these heroes are a breadcrumb, a title and a lede, ~500px tall, and a 62vw blob
   overhangs them by hundreds of pixels. `overflow: hidden` then cuts the gradient while it
   still has ~15% alpha left, drawing a hard horizontal edge across the page at the hero's top
   AND bottom. Sizing both gradients INSIDE a hero-sized box and fading that box at both ends
   makes the treatment independent of how tall the hero happens to be. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58% 86% at 84% 6%,
      rgb(var(--accent-meadow) / 0.85),
      rgb(var(--accent-stone) / 0.4) 46%,
      rgb(var(--bg) / 0) 72%),
    radial-gradient(46% 72% at 4% 98%,
      rgb(var(--accent-stone) / 0.5),
      rgb(var(--accent-meadow) / 0.22) 50%,
      rgb(var(--bg) / 0) 76%);
  background-repeat: no-repeat;
  mask-image: linear-gradient(to bottom,
    rgb(var(--fg) / 0), rgb(var(--fg)) 16%, rgb(var(--fg)) 68%, rgb(var(--fg) / 0));
  -webkit-mask-image: linear-gradient(to bottom,
    rgb(var(--fg) / 0), rgb(var(--fg)) 16%, rgb(var(--fg)) 68%, rgb(var(--fg) / 0));
  animation: nw-drift 24s var(--ease-standard) infinite;
}

/* On the deep ground the same wash would read as fog. Dimmed, not removed — the shapes are
   what stop a full-bleed dark hero from looking like a blank slab. */
.dark .hero::before { opacity: 0.34; }

.hero__title { max-width: 16ch; }
.hero__subtitle {
  font-size: var(--nw-fs-lede);
  line-height: var(--nw-lh-lede);
  color: rgb(var(--muted));
  max-width: 53ch;
  margin-top: clamp(var(--space-5), 3vh, var(--space-8));
}
.hero__cta { margin-top: clamp(var(--space-8), 4vh, var(--space-10)); }

@keyframes nw-drift {
  0%, 100% { background-position: 0 0, 0 0; }
  50%      { background-position: 2.2% -3.4%, -2.6% 2.2%; }
}

/* ── Section rhythm, eyebrow, section head ────────────────────────────────────────────────*/
.section { padding-block: var(--nw-band-pad); }
.section--tight { padding-block: clamp(var(--space-8), 6vw, calc(var(--space-10) * 1.3)); }

/* The design's eyebrow is a short hairline, then 11px uppercase at wide tracking — quiet, not
   accent-coloured. The rule is a pseudo-element so it stays out of the accessible name. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font: var(--weight-base) var(--nw-fs-micro) / 1 var(--font-sans);
  letter-spacing: var(--nw-track-eyebrow);
  text-transform: uppercase;
  color: rgb(var(--muted));
}
.eyebrow::before {
  content: "";
  width: var(--nw-rule);
  height: var(--stroke-hairline);
  background: rgb(var(--accent-stone));
  flex: none;
}
.eyebrow-head h2, .sec-head__title { margin-top: var(--space-5); max-width: 20ch; }
.sec-head--split .sec-head__title { max-width: none; }
.sec-head__lede, .lede {
  font-size: var(--nw-fs-lede);
  line-height: var(--nw-lh-lede);
  color: rgb(var(--muted));
  max-width: 46ch;
}

/* ── Buttons ──────────────────────────────────────────────────────────────────────────────
   Pills, sentence case. The rebuild's uppercase micro-caps belong to a different design; the
   reference sets 15.5px at 0.015em with the label left as written. */
.btn {
  font: var(--weight-base) var(--nw-fs-small) / 1 var(--font-sans);
  letter-spacing: var(--nw-track-btn);
  text-transform: none;
  padding: var(--space-4) var(--space-6);
  min-height: var(--hit-min);
  transition: transform var(--dur-slow) var(--ease-emphasized),
              box-shadow var(--dur-slow) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.btn:hover { opacity: 1; transform: translateY(calc(var(--space-1) * -0.5)); }
.btn:active { transform: translateY(0); }
.btn--sm { padding: var(--space-2) var(--space-4); min-height: var(--space-8); }

/* Solid = ink. Navy in light mode, paper in dark — the inversion the design already performs
   by hand inside its own dark band. */
.btn--primary {
  background: rgb(var(--fg));
  color: rgb(var(--bg));
  box-shadow: var(--shadow-md);
}
.btn--primary:hover { box-shadow: var(--shadow-lg); color: rgb(var(--bg)); }
.btn--ghost {
  background: rgb(var(--bg) / 0.5);
  color: rgb(var(--fg));
  border-color: rgb(var(--fg) / var(--o-strong));
  backdrop-filter: blur(var(--blur-card));
}
.btn--ghost:hover { background: rgb(var(--bg)); border-color: rgb(var(--fg) / 0.42); }
/* Used inside a dark band: paper fill, ink label. */
.btn--onprimary { background: rgb(var(--nw-band-ink)); color: rgb(var(--nw-band)); }
.btn--onprimary:hover { color: rgb(var(--nw-band)); }

/* The design's inline affordance: a label on a hairline that lengthens its gap on hover. */
.link-more {
  font: var(--weight-base) var(--nw-fs-small) / 1 var(--font-sans);
  letter-spacing: 0.04em;
  text-transform: none;
  color: rgb(var(--fg));
  border-bottom: var(--stroke-hairline) solid rgb(var(--fg) / 0.28);
  padding-bottom: var(--space-1);
  transition: gap var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}
.card > .link-more, .stack > .link-more, .stack-lg > .link-more { align-self: flex-start; }
.link-more:hover {
  gap: var(--space-4);
  color: rgb(var(--color-primary));
  border-bottom-color: rgb(var(--color-primary));
}

/* ── Photography ──────────────────────────────────────────────────────────────────────────
   `polish.css` gave every restored photo the placeholder's geometry so nothing moved when the
   imagery went back in. The shapes change here — and the surviving `.ph` placeholders change
   with them, so a page that still has one does not read as a different design. */
.photo, .ph { border-radius: var(--radius-2xl); }
.photo--avatar, .ph--avatar { border-radius: var(--radius-full); }
.photo--logo, .ph--logo {
  border-radius: var(--radius-lg);
  border: var(--stroke-hairline) solid rgb(var(--fg) / var(--o-subtle));
}
/* The arch: the design's signature cut, a full radius on top and a soft corner below. Kept to
   the two places it reads as intentional — the hero portrait and standalone portraits — rather
   than applied to every image on the site, which turns a motif into a tic. */
.hero__media .photo--portrait,
.hero__media .ph--portrait,
.split > .photo--portrait {
  border-radius: var(--radius-full) var(--radius-full) var(--radius-2xl) var(--radius-2xl);
}
.hero__media .photo { box-shadow: var(--shadow-xl); }

/* ── Cards ────────────────────────────────────────────────────────────────────────────────*/
.card {
  background: rgb(var(--bg) / var(--fill-card));
  border-color: rgb(var(--fg) / var(--o-muted));
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-5), 2.6vw, var(--space-8));
  gap: var(--space-4);
  transition: transform var(--dur-slow) var(--ease-emphasized),
              box-shadow var(--dur-slow) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard);
}
.card:hover {
  transform: translateY(calc(var(--space-1) * -1));
  box-shadow: var(--shadow-lg);
  border-color: rgb(var(--fg) / var(--o-strong));
}
.card__title { font: var(--weight-lg) var(--nw-fs-d4) / var(--nw-lh-d4) var(--font-display); }
.card__eyebrow {
  font-size: var(--nw-fs-micro);
  letter-spacing: var(--nw-track-meta);
  color: rgb(var(--muted));
}
.card__body { color: rgb(var(--muted)); }
.card__media {
  /* Must be the exact negation of `.card`'s padding above. `clamp()` of three negatives is
     not that: clamp() returns its MIN when min > max, so the bleed would pin to -space-5. */
  margin: calc(-1 * clamp(var(--space-5), 2.6vw, var(--space-8)))
          calc(-1 * clamp(var(--space-5), 2.6vw, var(--space-8))) 0;
}
.card__media .photo, .card__media .ph {
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  border: 0;
}

/* The four levels of care. The design gives these a full-width editorial stack — a rule, an
   index, a large serif title — instead of a grid of boxes. `:has()` scopes it to the grids
   that actually hold them; a browser without `:has()` keeps the card grid, which is the
   rebuild's own layout and perfectly serviceable. */
.grid:has(> .card--program) {
  grid-template-columns: 1fr;
  gap: 0;
  border-top: var(--stroke-hairline) solid rgb(var(--fg) / 0.14);
}
.grid:has(> .card--program) > .card--program {
  flex-direction: row;
  align-items: baseline;
  gap: clamp(var(--space-4), 3vw, var(--space-10));
  background: none;
  border: 0;
  border-bottom: var(--stroke-hairline) solid rgb(var(--fg) / 0.14);
  border-radius: 0;
  padding: clamp(var(--space-5), 3.2vh, var(--space-10)) clamp(var(--space-1), 1.4vw, var(--space-6));
  flex-wrap: wrap;
  transition: background var(--dur-slow) var(--ease-standard),
              padding-left var(--dur-slow) var(--ease-emphasized);
}
.grid:has(> .card--program) > .card--program:hover {
  transform: none;
  box-shadow: none;
  background: rgb(var(--accent-meadow) / 0.26);
  padding-left: clamp(var(--space-2), 1.6vw, var(--space-6));
}
.dark .grid:has(> .card--program) > .card--program:hover {
  background: rgb(var(--accent-meadow) / 0.1);
}
.card--program .card__num {
  font: var(--weight-base) var(--nw-fs-meta) / 1 var(--font-sans);
  letter-spacing: var(--nw-track-meta);
  color: rgb(var(--fg) / 0.34);
  flex: none;
}
.grid:has(> .card--program) > .card--program:hover .card__num { color: rgb(var(--color-primary)); }
.grid:has(> .card--program) .card__title {
  flex: 1 1 14ch;
  font: var(--weight-xl) var(--nw-fs-d3) / var(--nw-lh-d3) var(--font-display);
  letter-spacing: -0.014em;
}
.grid:has(> .card--program) .link-more {
  margin: 0 0 0 auto;
  align-self: center;
  white-space: nowrap;
}

/* Post cards keep the box, but the picture leads and the title carries the serif. */
.card--post .card__meta {
  font-size: var(--nw-fs-meta);
  letter-spacing: 0.03em;
  color: rgb(var(--muted));
}
.card--team .card__role { font-size: var(--nw-fs-meta); letter-spacing: 0.03em; }

/* ── Modalities, insurers, callout ────────────────────────────────────────────────────────*/
.modalities li {
  background: none;
  border: 0;
  border-bottom: var(--stroke-hairline) solid rgb(var(--fg) / 0.12);
  border-radius: 0;
  padding: var(--space-4) 0;
  font-size: var(--nw-fs-small);
}
.modalities li::before { background: rgb(var(--accent-stone)); }
.insurers { gap: var(--space-5); }
.callout {
  background: rgb(var(--accent-meadow) / 0.34);
  color: rgb(var(--fg));
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-5), 3vw, var(--space-8));
}
.dark .callout { background: rgb(var(--accent-meadow) / 0.1); }

/* ── Stats ────────────────────────────────────────────────────────────────────────────────*/
.stats {
  background: rgb(var(--accent-meadow) / 0.3);
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-8), 6vw, calc(var(--space-10) * 1.6));
}
.dark .stats { background: rgb(var(--accent-meadow) / 0.08); }
.stats h2 { text-align: center; }
.stat__num {
  font: var(--weight-xl) clamp(2.4rem, 5vw, 3.6rem) / 1 var(--font-display);
  color: rgb(var(--fg));
}
.stat__label {
  font-size: var(--nw-fs-micro);
  letter-spacing: var(--nw-track-meta);
  color: rgb(var(--muted));
}

/* ── FAQ ──────────────────────────────────────────────────────────────────────────────────
   Hairline rows rather than stacked boxes, and a drawn chevron rather than a `+` glyph — the
   glyph is a pseudo-element either way, so it stays out of the summary's accessible name. */
.faq { gap: 0; border-top: var(--stroke-hairline) solid rgb(var(--fg) / 0.14); }
.faq details {
  background: none;
  border: 0;
  border-bottom: var(--stroke-hairline) solid rgb(var(--fg) / 0.14);
  border-radius: 0;
}
.faq summary {
  font: var(--weight-lg) var(--nw-fs-d4) / var(--nw-lh-d4) var(--font-display);
  padding: var(--space-5) 0;
  color: rgb(var(--fg));
}
.faq summary::after {
  content: "";
  width: var(--icon-sm); height: var(--icon-sm);
  border-right: var(--stroke-thick) solid rgb(var(--muted));
  border-bottom: var(--stroke-thick) solid rgb(var(--muted));
  transform: rotate(45deg) translate(-0.15em, -0.15em);
  transition: transform var(--dur-base) var(--ease-standard);
}
.faq details[open] summary::after {
  transform: rotate(225deg) translate(-0.15em, -0.15em);
}
.faq__body { padding: 0 0 var(--space-6); color: rgb(var(--muted)); max-width: 68ch; }

/* ── Forms ────────────────────────────────────────────────────────────────────────────────*/
.form.card { padding: clamp(var(--space-6), 3.4vw, var(--space-10)); }
.field > label {
  font: var(--nw-fw-medium) var(--nw-fs-meta) / 1.2 var(--font-sans);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgb(var(--muted));
}
.field input, .field select, .field textarea {
  font-size: var(--nw-fs-small);
  border-radius: var(--radius-lg);
  border-color: rgb(var(--fg) / var(--o-strong));
  padding: var(--space-4) var(--space-5);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: rgb(var(--color-primary));
}
.consent, .form-embed-note, .field .hint { font-size: var(--nw-fs-meta); }

/* ── Prose ────────────────────────────────────────────────────────────────────────────────
   43 of the 71 pages are articles or policies. This is where the type ramp earns its keep. */
.prose { max-width: 68ch; font-size: var(--nw-fs-body); line-height: var(--nw-lh-body); }
.prose h2 {
  font-size: var(--nw-fs-d3);
  line-height: var(--nw-lh-d3);
  margin-top: calc(var(--space-10) * 1.2);
}
.prose h3 { font-size: var(--nw-fs-d4); margin-top: var(--space-10); }
.prose > p { color: rgb(var(--fg) / 0.86); }
.prose blockquote {
  border-left: var(--stroke-thick) solid rgb(var(--accent-stone));
  padding-left: var(--space-6);
  font: var(--weight-lg) var(--nw-fs-d4) / 1.42 var(--font-display);
  font-style: italic;
  color: rgb(var(--fg));
}
.prose figcaption {
  font-size: var(--nw-fs-meta);
  letter-spacing: var(--nw-track-meta);
  text-transform: uppercase;
  color: rgb(var(--muted));
}

/* ── Tinted band ──────────────────────────────────────────────────────────────────────────*/
.tint { background: rgb(var(--accent-stone) / 0.13); }
.dark .tint { background: rgb(var(--bg-2)); }

/* ── Footer: the design's dark band ───────────────────────────────────────────────────────
   The reference folds admissions and the footer into one navy section with a shallow arc cut
   into its top edge. The rebuild's footer is the only full-width band on every page, so it is
   the one that carries the treatment. */
.site-footer {
  background: rgb(var(--nw-band));
  color: rgb(var(--nw-band-ink) / 0.68);
  border-top: 0;
  border-radius: 50% 50% 0 0 / var(--nw-arc) var(--nw-arc) 0 0;
  margin-top: calc(var(--space-10) * 1.4);
  overflow: hidden;
}
.site-footer__inner { padding-block: var(--nw-band-pad) var(--space-10); }
.site-footer .brand-mark { color: rgb(var(--nw-band-ink)); }
.site-footer .brand-mark strong { color: rgb(var(--nw-band-ink) / 0.5); }
.site-footer h2 {
  font: var(--weight-base) var(--nw-fs-micro) / 1 var(--font-sans);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgb(var(--nw-band-ink) / 0.46);
  margin-bottom: var(--space-5);
}
.site-footer a { color: rgb(var(--nw-band-ink) / 0.76); }
.site-footer a:hover { color: rgb(var(--accent-meadow)); }
.footer-about { color: rgb(var(--nw-band-ink) / 0.6); font-size: var(--nw-fs-small); }
.footer-social { gap: var(--space-2); }
.footer-social a {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  border: var(--stroke-hairline) solid rgb(var(--nw-band-ink) / 0.22);
  font-size: var(--nw-fs-meta);
  letter-spacing: 0.06em;
}
.footer-social a:hover {
  background: rgb(var(--nw-band-ink) / 0.12);
  color: rgb(var(--nw-band-ink));
}
.footer-hours { font-size: var(--nw-fs-meta); color: rgb(var(--nw-band-ink) / 0.66); }
.footer-legal {
  border-top-color: rgb(var(--nw-band-ink) / 0.12);
  color: rgb(var(--nw-band-ink) / 0.5);
  font-size: var(--nw-fs-meta);
}
.footer-legal a { color: rgb(var(--nw-band-ink) / 0.5); }
/* The focus ring is sage, which is drawn for paper. On the band it would sit at 1.9:1, so
   inside the footer the ring becomes the band's own ink — 13:1, and the same shape. */
.site-footer :focus-visible, .footer-legal :focus-visible {
  outline-color: rgb(var(--nw-band-ink));
}

/* ── Sticky call bar ──────────────────────────────────────────────────────────────────────
   A floating frosted pill rather than a full-width tray. */
.callbar {
  left: var(--space-3); right: var(--space-3); bottom: var(--space-3);
  padding: var(--space-2);
  gap: var(--space-2);
  border: var(--stroke-hairline) solid rgb(var(--fg) / var(--o-muted));
  border-radius: var(--radius-full);
  background: rgb(var(--bg) / var(--fill-frost));
  backdrop-filter: saturate(1.5) blur(var(--blur-frost));
  box-shadow: var(--shadow-lg);
}
.callbar .btn { min-height: var(--space-10); }

/* ── Motion ───────────────────────────────────────────────────────────────────────────────
   `redesign.js` marks elements with `data-nw-rise` and unsets the transform when they enter
   the viewport. Everything here is scoped to that attribute, so with JS off — or with reduced
   motion, where the script does not mark anything — the page renders at rest and fully
   visible. Nothing is hidden by CSS alone. */
[data-nw-rise] {
  opacity: 0;
  transform: translate3d(0, var(--nw-rise-shift), 0);
  transition: opacity var(--nw-dur-rise) var(--ease-emphasized),
              transform var(--nw-dur-rise) var(--ease-emphasized);
  will-change: opacity, transform;
}
[data-nw-rise="in"] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hero::before, .hero::after { animation: none; }
  [data-nw-rise] { opacity: 1; transform: none; transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   DENSITY PASS — "think HIMS"

   The brief was to improve the UI with HIMS as reference while keeping NE's colours.
   What HIMS actually does that this page did not: it commits to colour FIELDS, it keeps
   the vertical rhythm tight enough that a section boundary reads as a beat rather than a
   pause, and it makes the primary action the loudest object on the screen.

   This page was doing the opposite of all three — 11vw of band padding (≈316px between
   sections at desktop), `.tint` set to stone at 13% (invisible against #FAFAF8, so every
   band read as the same paper), and a small uppercase pill for a CTA on a page whose whole
   job is to get an anxious person to make contact.

   Still a LOOK layer: no markup is touched, so parity cannot regress. Colours come from
   the brand (`cream`, `clay`, `moss` were added there for this), never as literals here —
   `no_design_literals_in_the_shipped_css` enforces that.
   ═══════════════════════════════════════════════════════════════════════════════ */

:root {
  /* 11vw → 7vw. The old value put a third of a screen between every section; the page read
     as a slideshow of unrelated cards rather than one argument. */
  --nw-band-pad: clamp(var(--space-8), 7vw, calc(var(--space-10) * 1.9));
  --nw-band-pad-tight: clamp(var(--space-8), 4.5vw, var(--space-10));
}

/* ── Bands actually read as bands ──────────────────────────────────────────────
   `cream` is a second paper rather than a colour: enough separation from #FAFAF8 to mark
   a boundary, not enough to become decoration on a healthcare page. */
.tint { background: rgb(var(--accent-cream)); }
.dark .tint { background: rgb(var(--bg-2)); }

/* ── The primary action ────────────────────────────────────────────────────────
   Bigger, warmer, and no longer uppercase-micro. Clay is the only saturated colour on the
   page and it is reserved for this, so "the orange thing" and "the thing to press" are the
   same object. Sentence case because SHOUTING AT SOMEONE seeking mental health care is the
   wrong register — the uppercase ramp stays on eyebrows and meta, where it is a label. */
.btn--primary {
  background: rgb(var(--accent-clay));
  color: rgb(var(--bg));
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--nw-fs-body);
  padding: var(--space-4) var(--space-6);
  min-height: var(--hit-min);
}
.btn--primary:hover { background: rgb(var(--accent-clay) / .9); opacity: 1; }
.dark .btn--primary { color: rgb(var(--bg-2)); }

/* The secondary keeps the quiet treatment but matches the new scale, so a button pair does
   not look like two different components. */
.btn--ghost {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--nw-fs-body);
  padding: var(--space-4) var(--space-6);
  min-height: var(--hit-min);
  border-color: rgb(var(--fg) / .22);
}
.btn--ghost:hover { background: rgb(var(--fg) / .05); }

/* ── The rating band: was a tiny avatar strip floating in a void ───────────────
   It carries the only social proof above the fold. Given a field and a real height so it
   reads as a credential rather than an orphaned row. */
.rating-band {
  background: rgb(var(--accent-meadow) / .5);
  border-radius: var(--radius-2xl);
  padding: var(--space-6) var(--space-8);
  align-items: center;
  gap: var(--space-6);
}
.rating-band .lede { color: rgb(var(--accent-moss)); font-weight: var(--nw-fw-medium); }
.section--tight { padding-block: var(--nw-band-pad-tight); }

/* ── Condition / service cards ─────────────────────────────────────────────────
   HIMS's grid reads as a set of choices. These were flat images with a caption; giving them
   a surface, a hairline and a lift on hover makes them legible as things you can pick. */
.card {
  background: rgb(var(--bg));
  border: var(--stroke-hairline) solid rgb(var(--fg) / .10);
  border-radius: var(--radius-xl);
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-fast) var(--ease-standard);
}
.tint .card { background: rgb(var(--bg)); }
.card:hover { transform: translateY(calc(var(--space-1) * -1)); box-shadow: 0 var(--space-3) var(--space-8) rgb(var(--fg) / .09); }
.card__title { color: rgb(var(--fg)); }
.card__eyebrow { color: rgb(var(--accent-moss)); }

/* ── Stats band: the credibility moment ───────────────────────────────────────
   Was navy-on-paper like everything else. Sage field + oversized numerals so the figures
   carry the section instead of the heading above them. */
.stats { background: rgb(var(--color-primary)); border-radius: var(--radius-2xl); padding: clamp(var(--space-8), 5vw, var(--space-10)); }
.stats, .stats .sec-head__title, .stats .stat__num, .stats .stat__label { color: rgb(var(--bg)); }
.stats__grid { gap: var(--space-8); }
/* `var(--nw-fs-d)` — no such token; the ramp is `--nw-fs-d1`…`d4`. An undefined custom property
   makes the whole declaration invalid at computed-value time, so `font-size` fell back to
   INHERITED and every stat figure outside the sage band rendered at body size — smaller than its
   own uppercase label, on the 13 pages that carry this grid beside prose rather than in the band.
   `d3` is the size the half-width column wants; `.stats .stat__num` below takes the band's. */
.stat__num { font-family: var(--font-display); font-size: var(--nw-fs-d3); line-height: 1; }
.stat__label { color: rgb(var(--bg) / .78); }
.stats .btn--primary { background: rgb(var(--bg)); color: rgb(var(--color-primary)); }
.stats .btn--primary:hover { background: rgb(var(--bg) / .9); }

/* ── A single-column section should not leave half the grid empty ─────────────
   `.sec-head` holds the heading AND its prose as one block, so a full-width section rendered
   everything down the left and left the right half void — the most obviously unfinished thing
   on the page. Split it: heading in one column, copy in the other. This is the move HIMS makes
   on every section header, and it costs no markup.

   Scoped OUT of `--narrow` containers and `--center` heads, which are deliberately one column
   and would be wrecked by a split. Desktop only — below 60rem a two-column header is worse
   than a stacked one. */
@media (min-width: 60rem) {
  .section > .container.stack-lg:not(.container--narrow) > .sec-head:not(.sec-head--center) {
    /* `.sec-head` is capped at 60ch for single-column reading; a two-column header needs the
       whole container or the split just moves the void rather than filling it. */
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    column-gap: clamp(var(--space-8), 6vw, var(--space-10));
    row-gap: var(--space-4);
    align-items: start;
  }
  .section > .container.stack-lg:not(.container--narrow) > .sec-head:not(.sec-head--center) > .sec-head__title {
    grid-column: 1; grid-row: 1 / -1; margin: 0;
    max-width: 14ch;   /* a display heading wants to break early; 20ch made it one long line */
  }
  .section > .container.stack-lg:not(.container--narrow) > .sec-head:not(.sec-head--center) > :not(.sec-head__title) {
    grid-column: 2; max-width: 60ch;
  }
  /* A button is not prose: grid stretches it to the column and a 600px "View All Conditions"
     pill reads as a banner rather than a control. */
  .section > .container.stack-lg:not(.container--narrow) > .sec-head:not(.sec-head--center) > .btn {
    justify-self: start; max-width: none;
  }
}

/* ============================================================================
   MATERIAL PASS — texture, glass, accent shapes
   ----------------------------------------------------------------------------
   Three rules govern everything below, and each one is a scar:

   1. No colour literal may appear in the bundle. `no_design_literals_in_the_shipped_css`
      scans the comment-stripped file for `#`+3 hex chars, the substring `rgba(`, and
      `rgb(` followed by a digit. That last one is why every colour here is
      `rgb(var(--token) / <alpha>)` — the `v` is what keeps it legal. It also rules out
      SVG data-URIs, which cannot carry a token-derived colour at all.

   2. The brand accents do NOT flip between schemes. --accent-cream stays 242 238 228
      on a #0E1524 page. Only --bg and --fg flip. So anything tinted with an accent
      needs an explicit `.dark` counterpart, exactly as `.dark .tint` already does.

   3. backdrop-filter and box-shadow re-rasterize on this codebase when they change,
      which is the flicker bug. Everything here declares them statically and never
      lists them in a `transition`.
   ========================================================================= */

/* The light/shadow polarity pair. In light, the lit side is the paper and the shadow
   side is the ink; in dark those swap. One pair, declared once, so a highlight stays a
   highlight in both schemes instead of becoming a smudge. */
:root {
  --nw-spec: var(--bg);
  --nw-shade: var(--fg);
  /* Texture ink. Warm on light — the palette is sage/cream/clay and slate-navy --fg
     pulls the whole page cool. In dark the band IS dark, so a dark tooth is invisible
     and the ink has to invert. */
  --nw-tooth: var(--accent-moss);
  --nw-tooth-a: 0.055;
}
.dark {
  --nw-spec: var(--fg);
  --nw-shade: var(--bg);
  --nw-tooth: var(--fg);
  --nw-tooth-a: 0.03;
}

/* --- TEXTURE ---------------------------------------------------------------
   A tooth, not a pattern. Two dot fields at 23px and 31px — deliberately coprime, so
   they never align into a visible grid and read as stock instead. 1.1px dots at ~5%
   move cream about 9 levels, which is perceptible as surface and invisible as ornament.
   Applied ONLY to coloured bands: on white it is not texture, it is dirt behind text.
   z-index:-1 under `isolation:isolate` puts the layer above the band's own background
   but below every child, without the -1 escaping to the page canvas. */
.tint, .stats, .rating-band, .callout, .site-footer { position: relative; isolation: isolate; }
.tint::before, .stats::before, .rating-band::before, .callout::before, .site-footer::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(circle at 50% 50%, rgb(var(--nw-tooth) / var(--nw-tooth-a)) 0.55px, transparent 0.6px),
    radial-gradient(circle at 50% 50%, rgb(var(--nw-tooth) / var(--nw-tooth-a)) 0.55px, transparent 0.6px);
  background-size: 23px 23px, 31px 31px;
  background-position: 0 0, 11px 7px;
}
/* The tint bands carry the longest prose on the site. Weight the tooth to the seams and
   let it fall away through the middle, so it defines where a band starts and stops
   without printing under a paragraph about seeking help. */
.tint::before {
  -webkit-mask-image: linear-gradient(to bottom, rgb(var(--fg)) 0 8%, transparent 40%, transparent 60%, rgb(var(--fg)) 92% 100%);
          mask-image: linear-gradient(to bottom, rgb(var(--fg)) 0 8%, transparent 40%, transparent 60%, rgb(var(--fg)) 92% 100%);
}
/* Rounded bands clip their own tooth. */
.stats::before, .rating-band::before, .callout::before { border-radius: inherit; }
/* On a saturated field the tooth has to invert or it does not exist: moss on sage, and
   moss on the navy footer, are the same value twice. These are the two dark grounds in
   light mode — in dark mode the ink is already the lit side, so this changes nothing. */
.stats::before, .site-footer::before { --nw-tooth: var(--nw-spec); --nw-tooth-a: 0.05; }

/* --- GLASS BUTTONS ---------------------------------------------------------
   The site already had glass and it was failing: `rgb(var(--bg) / .5)` with a blur, on
   319 controls of which all but a handful sit on a flat band. With nothing behind it the
   blur does nothing and a 50% fill just reads as a disabled control.

   So glass is rebuilt as a MATERIAL rather than an effect — a high translucent fill that
   lets the band tint through, a lit top edge, a hairline, and a micro shadow. That reads
   as a pane resting on the surface everywhere. The actual backdrop blur is then added
   back only where there is genuinely something behind to refract. */
.btn--ghost {
  background: rgb(var(--bg) / 0.82);
  border-color: rgb(var(--fg) / 0.16);
  backdrop-filter: none;
  box-shadow:
    inset 0 var(--stroke-hairline) 0 rgb(var(--nw-spec) / 0.75),
    0 1px 2px rgb(var(--nw-shade) / 0.05);
}
.btn--ghost:hover { background: rgb(var(--bg)); border-color: rgb(var(--fg) / 0.32); }

/* Here the blur earns its cost: the hero sits on an animated wash and a photograph, and
   the call bar has the whole page scrolling beneath it. Declared static — never
   transitioned, never changed on hover — because a changing backdrop-filter is the
   documented flash on this codebase. */
.hero .btn--ghost, .callbar .btn--ghost {
  background: rgb(var(--bg) / var(--fill-glass));
  backdrop-filter: saturate(1.3) blur(var(--blur-glass));
  border-color: rgb(var(--nw-spec) / 0.5);
}
.hero .btn--ghost:hover, .callbar .btn--ghost:hover { background: rgb(var(--bg) / 0.86); }
/* --fill-glass collapses from .62 to .035 in dark — an 18x drop — so the fill stops
   carrying the shape and the edge has to. */
.dark .hero .btn--ghost, .dark .callbar .btn--ghost { border-color: rgb(var(--nw-spec) / 0.26); }

/* The one CTA gets a lit top edge, not a bevel. 0.16 and not 0.4: this rule multiplies
   across 241 buttons, and at bevel strength clay reads as glossy plastic. */
.btn--primary { box-shadow: inset 0 var(--stroke-hairline) 0 rgb(var(--nw-spec) / 0.16); }

/* box-shadow was in the transition list, which is the flicker class this codebase has
   already been bitten by. Shadows are now static; only transform/background/border/colour move. */
.btn {
  transition: transform var(--dur-slow) var(--ease-emphasized),
              background var(--dur-base) var(--ease-standard),
              border-color var(--dur-base) var(--ease-standard),
              color var(--dur-base) var(--ease-standard);
}

/* --- ACCENT SHAPES ---------------------------------------------------------
   One move, used three times. The hero photograph is masked into an arch, so the shape
   language is that arch continued at architectural scale: a single hairline circle far
   larger than its band, cropped by the band's own edges so only an arc survives. Three
   placements site-wide, all off to one side of the content column. A border-radius
   circle costs nothing to paint and never animates. */
.stats { overflow: hidden; }
.stats::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  aspect-ratio: 1; border-radius: var(--radius-full);
  border: var(--stroke-hairline) solid rgb(var(--nw-spec) / 0.22);
  width: 34rem; right: -9rem; bottom: -19rem;
}
/* Deliberately ONE placement. Two others were built and cut:
   - .rating-band is ~120px tall, so any circle large enough to read as architecture shows
     only a near-vertical slice. It rendered as a crease across the band, not an arc.
   - .site-footer already curves: its top edge is a full-width arch, which is where this
     shape language came from. A second arc inside it is the same idea said twice. */

@media (prefers-reduced-motion: reduce) {
  .btn:hover { transform: none; }
}

/* --- BRAND MARK -------------------------------------------------------------
   new-well.svg has been embedded in the binary and served at /vendor/nwc/ since the
   migration, and referenced by exactly zero pages — the site shipped a text wordmark while
   the real logo sat in the bundle unused.

   The mark is drawn white-on-transparent with a pale green emblem, i.e. built for a dark
   ground. On the light header it is invisible, so it ships as two files: new-well-ink.svg
   recolours the same paths to the site's ink and sage. Which one shows is a display swap,
   not a filter — filters re-rasterize on this codebase.

   The paths deliberately are NOT referenced from CSS: `the_self_hosted_typefaces_are_actually_shipped`
   asserts that the only /vendor/nwc/ URLs in the stylesheet are the eight woff2 subsets, and
   that invariant is worth more than saving two <img> tags. */
:root { --nw-logo-h: 58px; }
.brand-mark { display: inline-flex; align-items: center; }
.brand-mark img { display: block; width: auto; height: var(--nw-logo-h); }
/* Specificity, not order: `.brand-mark img` is (0,1,1) and a bare `.brand-mark__light` is
   (0,1,0), so the display:block above wins and BOTH marks paint side by side. Every toggle
   below therefore carries the parent class too. */
.brand-mark img.brand-mark__light { display: none; }
.dark .brand-mark img.brand-mark__ink   { display: none; }
.dark .brand-mark img.brand-mark__light { display: block; }
/* The footer is a fixed navy field in BOTH schemes — it is not --bg — so it always takes the
   light mark regardless of the active theme, and can carry a larger one. */
.site-footer .brand-mark { --nw-logo-h: 76px; }
.site-footer .brand-mark img.brand-mark__ink   { display: none; }
.site-footer .brand-mark img.brand-mark__light { display: block; }

/* ============================================================================
   FIXES — three defects found by rendering interior pages
   ========================================================================= */

/* 1. STAT COLOURS WERE UNSCOPED. `.stat__label { color: rgb(var(--bg) / .78) }` was written for
   the sage stats band, where --bg is the light ink on a dark field. But `.stats__grid` is used on
   14 pages OUTSIDE any `.stats` band — on `.tint`, where --bg is the paper — so the labels were
   near-white on cream and effectively invisible. The band-specific colours belong to the band. */
.stat__num   { color: rgb(var(--color-primary)); }
.stat__label { color: rgb(var(--muted)); font-size: var(--nw-fs-small); }
.stats .stat__num   { color: rgb(var(--bg)); }
.stats .stat__label { color: rgb(var(--bg) / 0.78); }

/* 2. THE SPLIT SECTIONS READ AS EMPTY. `.split` is a 1fr 1fr grid; its media cell holds TWO
   stacked portraits (~1600x2000 each), so the media column runs roughly twice the height of the
   prose beside it and the text floats in the middle of a tall void. Seven sections, and on the
   ones whose text is just a heading and a link it is most of the screen.
   Side by side halves the column height; the drop on the second keeps the pair from reading as a
   contact sheet. Wide screens only — stacked is correct when the grid is one column. */
@media (min-width: 56.25rem) {
  /* `:has(> .photo + .photo)` and not a bare `.split > .stack`: `.stack` is a generic vertical
     rhythm class, and the insurance section uses one to hold a heading, a paragraph, the 15-logo
     grid and a button. Two-columning THAT dealt its contents alternately down two tracks. Only a
     stack that is literally a pair of adjacent photographs gets the side-by-side treatment. */
  .split > .stack:has(> .photo + .photo) {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: var(--space-3); align-self: center;
  }
  .split > .stack:has(> .photo + .photo) > .photo { width: 100%; height: auto; }
  .split > .stack:has(> .photo + .photo) > .photo:nth-child(2) { margin-block-start: var(--space-8); }
}

/* 3. THE TWO HEADER CONTROLS WERE DIFFERENT HEIGHTS ON MOBILE. `.nav-toggle` is
   var(--space-10) square (52px); the theme toggle is a `.btn--sm` at var(--space-8) (40px), so
   they sat side by side visibly mismatched. Matched only below the breakpoint where the
   hamburger exists — above it the theme toggle is alone and a 52px pill is oversized. */
@media (max-width: 64.9375rem) {
  [data-theme-toggle] { width: var(--space-10); height: var(--space-10); }
}

/* 1b. The same grid, outside the sage band, is a fact row sitting beside prose — not a centred
   hero block. In a half-width column the 12rem track floor forced a 2+1 wrap, and centred figures
   against left-aligned body copy read as a stray widget. Three narrow tracks fit; the band keeps
   its own centred treatment. */
.stats__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 7rem), 1fr)); text-align: left; gap: var(--space-5); }
.stats .stats__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); text-align: center; gap: var(--space-8); }

/* Interior heroes. 73 of the 74 routes opened with a title, a line of copy and a button in a
   single column, leaving the right half of the first screen empty on every page but home — the
   "empty feeling" the site owner reported. They now use the same two-column hero the home page
   has always used; no new layout primitive, the CSS below just handles the landscape crop.
   Deliberately NOT the arch mask: that treatment is the home hero's signature and repeating it
   74 times turns a motif into a tic. */
.hero--split .hero__media .photo--wide {
  width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-2xl);
}

/* 3b. The theme toggle was still WIDER than the hamburger even after matching their heights:
   52x52 vs 66x52. `[data-theme-toggle]` sets `padding: 0`, but it and `.btn` are both (0,1,0),
   so the `.btn` padding written later in this file won the cascade and the glyph plus 32px of
   side padding forced the flex item past its declared width. Squared off explicitly.
   (`.header-phone` is already display:none below 680px, so it never competed for this row.) */
@media (max-width: 64.9375rem) {
  :root { --nw-logo-h: 48px; }
  [data-theme-toggle] { padding: 0; min-width: var(--space-10); }
}
@media (max-width: 30rem) { :root { --nw-logo-h: 40px; } }

/* THE INSURER LOGOS ARE DARK INK ON TRANSPARENT. They were sitting directly on the page ground,
   which is fine on cream and invisible on a #0E1524 one — 15 logos on 23 pages, gone in dark mode.
   They need a card that stays light in BOTH schemes, and almost every token flips. --on-primary
   does not: it is the ink colour for the sage primary, white in both, which is exactly a sheet of
   paper to print a vendor mark on. Padding so the artwork is not flush to the edge. */
.photo--logo, .ph--logo {
  background: rgb(var(--on-primary));
  padding: var(--space-3) var(--space-4);
  border-color: rgb(var(--fg) / var(--o-muted));
  object-fit: contain;
}
.dark .photo--logo, .dark .ph--logo { border-color: rgb(var(--on-primary) / 0.16); }

/* THE CLINICIAN BIO BAND. Its text column holds one thing — an <h2> repeating the H1 directly
   above it — beside a full-height square portrait, so a 1fr/1fr split left roughly 700x600 of
   empty cream on every staff page. Now that the hero carries the portrait too, this band is a
   name and a photograph and should be sized like one: a capped photo column, centred, on tighter
   band padding. Markup untouched — the heading is on the live site and removing it would read as
   lost copy. */
#profile .split { align-items: center; }
@media (min-width: 56.25rem) {
  #profile .split { grid-template-columns: minmax(0, 1fr) minmax(0, 20rem); }
}
#profile .split > .photo { width: 100%; height: auto; }
#profile.section { padding-block: var(--nw-band-pad-tight); }

/* ─────────────────────────────────────────────────────────────────────────────
   CLIENT CHANGE LIST V1 (NE Website Changes_V1.pdf)
   Every value below is a token or derived from one — this sheet is gated against
   raw hex, `rgba(` and kernel-token redeclaration by `nwc_import_tests`.
   ───────────────────────────────────────────────────────────────────────────── */

/* Copy sits over video here, so it is light in BOTH schemes rather than flipping
   with the page: the scrim is dark either way, and a token that inverted would put
   dark text on dark footage in one of them. */
:root {
  --nw-scrim: 14 18 22;
  --nw-scrim-a: 0.58;
  --nw-on-media: 255 255 255;
  --nw-mark-a: 0.05;
}

/* ── Hero: centred over a muted, looping background video ─────────────────── */
.hero--video { position: relative; isolation: isolate; overflow: hidden; }
.hero--video .hero__video {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.hero--video .hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background: rgb(var(--nw-scrim) / var(--nw-scrim-a));
}
.hero__center { text-align: center; max-width: 60rem; margin-inline: auto; }
.hero--video .hero__title,
.hero--video .hero__subtitle { color: rgb(var(--nw-on-media)); }
.hero--video .hero__subtitle { opacity: 0.92; margin-inline: auto; }
/* `text-align: center` centres the TEXT INSIDE each box; it does not centre the boxes. Both of
   these carry a measure cap — 16ch on the title, 53ch on the lede — so each is a narrow block
   sitting at the START of the 60rem column, and centred text inside a left-hung box reads as
   very slightly off, which is exactly how it looked: the headline hanging ~130px left of the
   paragraph under it. The lede was already given `margin-inline: auto` above and the title was
   not, which is why only one of the two was wrong. */
.hero__center .hero__title { margin-inline: auto; }
.row--center { justify-content: center; }
/* The hero has to be tall enough for the footage to read as footage rather than as a band of
   colour behind the words. `svh` and not `vh`: on iOS `vh` is the address-bar-collapsed height,
   so a `100vh` hero is taller than the screen on first paint and the CTAs start below the fold. */
.hero--video { min-height: min(38rem, 78svh); display: grid; align-content: center; }
/* The video is decoration, so a reduced-motion visitor gets the still poster frame. It is
   PAUSED rather than hidden: `display:none` on the <video> takes the poster with it and leaves
   a flat scrim, and CSS cannot put the poster back — `the_self_hosted_typefaces_are_actually_shipped`
   asserts that the only /vendor/nwc/ URLs in the bundle are the eight woff2 subsets. `motion.js`
   does the pausing, because a media query cannot stop `autoplay`. */

/* ── Brand mark as a faint section watermark ──────────────────────────────── */
.brandmark { position: relative; isolation: isolate; overflow: hidden; }
.brandmark > .brandmark__mark {
  position: absolute; z-index: -1; pointer-events: none;
  inset-inline-end: calc(var(--nw-band-pad-tight) * -0.35);
  inset-block-start: 50%; translate: 0 -50%;
  width: min(38rem, 55%); height: auto;
  opacity: var(--nw-mark-a);
}
@media (max-width: 56.25rem) { .brandmark > .brandmark__mark { display: none; } }

/* ── "Get a 100% Confidential Callback" band ──────────────────────────────── */
/* "the same color as the footer background" — so it uses the footer's OWN tokens
   (`--nw-band` / `--nw-band-ink`, set beside `.site-footer`) rather than a second
   name meaning the same thing. Re-skin the band once and this follows. */
.callback { background: rgb(var(--nw-band)); }
.callback .sec-head__title,
.callback .sec-head__lede,
.callback .callback__note { color: rgb(var(--nw-band-ink)); }
.callback .callback__note { opacity: 0.78; text-align: center; }
.sec-head--center { text-align: center; margin-inline: auto; }
.callback__form {
  display: grid; gap: var(--space-4); align-items: end;
  grid-template-columns: 1fr;
  max-width: 56rem; margin-inline: auto;
}
@media (min-width: 48rem) {
  .callback__form { grid-template-columns: 1fr 1fr auto; }
}
.callback__form .field { display: grid; gap: var(--space-2); }
.callback__form label { color: rgb(var(--nw-band-ink)); opacity: 0.86; }

/* ── Testimonials: one horizontal rail you drag, looping ──────────────────────
   `overflow-x: auto` with `overflow-y` left at `visible` does NOT mean "scroll sideways
   only": the spec computes a `visible` axis to `auto` when the other axis is not visible,
   so the row had a vertical scrollbar as well, for a card set that never overflows
   vertically. Both axes are now stated, and the horizontal bar is hidden too — this is a
   drag rail, so a scrollbar is the wrong affordance for it.

   The scroll POSITION is still native `scrollLeft`, not a transform. That keeps trackpad
   and touch momentum working for free, and `motion.js` only has to add the mouse drag and
   move the position by one set when it reaches the seam. Without JS it stays a plain
   horizontal scroller with three copies of the set in it — odd, but not broken. */
.reviews__scroll {
  overflow-x: auto;
  overflow-y: hidden;              /* the whole point — see above */
  overscroll-behavior-x: contain;  /* no rubber-band, no back-swipe out of the page */
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  cursor: grab;
}
.reviews__scroll::-webkit-scrollbar { display: none; }
.reviews__scroll.is-dragging { cursor: grabbing; scroll-behavior: auto; user-select: none; }
.reviews__track {
  display: flex; align-items: stretch;
  gap: var(--space-6);
  width: max-content;
  padding-block-end: var(--space-4);
}
.review {
  flex: 0 0 min(22rem, 78vw);
  margin: 0;
  display: grid; gap: var(--space-4); align-content: start;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: rgb(var(--bg));
  border: var(--stroke-hairline) solid rgb(var(--fg) / 0.10);
}
/* A card is being dragged past, not pointed at — the lift would fire on every pass. */
.reviews__scroll.is-dragging .review { pointer-events: none; }
.review blockquote { margin: 0; }
.review figcaption { color: rgb(var(--fg) / 0.62); font-size: var(--text-sm); }
.stars { letter-spacing: 0.12em; color: rgb(var(--color-primary)); }

/* ── Stats: bigger, bolder, and legible on the sage field in BOTH schemes ───
   Two defects the brief caught, and one it did not:

   1. The previous pass sized these with `clamp(var(--text-2xl), 5vw, var(--text-4xl))`. The
      kernel ramp stops at `--text-xl`; `--text-2xl` and `--text-4xl` do not exist, so the
      declaration was invalid at computed-value time and the numerals fell back to INHERITED
      body size. "Increase the numbers" had made them smaller.
   2. "Bolden" cannot be done in the display face — Instrument Serif ships one weight (400) and
      `font-weight: 700` on it is a synthesised faux-bold. The numerals move to Instrument Sans,
      which is variable 400–700, so the weight is real type rather than a smeared outline.
   3. "Audit this section in dark mode" — the whole band was failing, in both schemes. `.stats`
      paints `--color-primary` (sage) in light AND dark, but the ink was `--bg`: near-white on
      sage is 5.7:1, near-black on sage is 3.3:1, and the heading took `h2 { color: --fg }`
      over the band entirely — navy on sage, 2.4:1. `--on-primary` is the kernel's ink FOR this
      fill and is white in both schemes, which is the only value that clears AA on both sides. */
.stats,
.stats h2,
.stats .sec-head__title,
.stats .stat__num { color: rgb(var(--on-primary)); }
.stats .stat__label { color: rgb(var(--on-primary) / 0.88); }
.stats .btn--primary { background: rgb(var(--on-primary)); color: rgb(var(--color-primary)); }
.stats .btn--primary:hover { background: rgb(var(--on-primary) / 0.9); color: rgb(var(--color-primary)); }
/* One treatment for the figure, two sizes. "Have Questions? Let Our Expert Team Help." is the
   sage band on the home page and a fact row beside a photograph on the 12 condition pages; a
   serif figure in one place and a bold grotesque in the other would read as two components. */
.stat__num {
  font-family: var(--font-sans);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.02;
}
.stats .stat__num { font-size: clamp(2.9rem, 6.5vw, 4.6rem); }

/* A split section head puts its CTA at the far edge; a measure cap would stop it
   short of the container and read as "nearly right-aligned". */
.sec-head--split { max-width: none; width: 100%; }

/* ── "Let's Work Together": a tighter band over imagery ───────────────────── */
.band--media { position: relative; isolation: isolate; overflow: hidden; }
.band--media > .band__bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.band--media > .band__scrim {
  position: absolute; inset: 0; z-index: -1;
  background: rgb(var(--nw-scrim) / var(--nw-scrim-a));
}
.band--media, .band--media h2, .band--media p { color: rgb(var(--nw-on-media)); }
.band--media .sec-head__lede { opacity: 0.92; }

/* ── Insurance logos as one moving line, with arrows ──────────────────────────
   The scroll container and the animated element MUST be two different boxes. The
   previous pass made `.marquee__track` both: `overflow-x: auto` sizes an element to
   its column and `translateX(-50%)` then slides that whole viewport half its own
   width off to the left — the logos march out from under the heading and over the
   prev arrow, and the arrows' `scrollBy` fights the transform for the same pixels.
   A viewport that clips, holding a `max-content` track that translates, is the shape
   where both work: the animation moves content inside the window, the arrows move
   the window, and neither knows about the other.

   The track carries the fifteen logos TWICE, so -50% lands exactly one copy along and
   the loop is seamless. The duplicate is `aria-hidden` in the markup. */
.marquee { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; }
.marquee__viewport { overflow-x: auto; scroll-behavior: smooth; scrollbar-width: none; }
.marquee__viewport::-webkit-scrollbar { display: none; }
.marquee__track {
  display: flex; gap: var(--space-8); align-items: center;
  width: max-content;
  animation: nw-marquee 60s linear infinite;
}
/* Pausing on hover/focus is what makes the arrows usable at all — otherwise the
   thing you reached for has already moved. */
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }
/* `--nw-logo-h` is the BRAND MARK's height (58px) and was being read here as a logo
   width, which is why the insurers came out as 58px chips. This row owns its own size. */
/* The plate's own padding is drawn for a 3-across grid; in a single moving row it eats
   most of a 5:2 insurer mark and "United Healthcare" arrives as a smudge. Wider card,
   tighter inset — the artwork, not the plate, is what has to be readable at a glance. */
.marquee__track > .photo--logo {
  flex: 0 0 auto;
  width: var(--nw-marquee-logo); height: auto;
  padding: var(--space-2) var(--space-3);
}
:root { --nw-marquee-logo: 11.5rem; }
@media (max-width: 30rem) { :root { --nw-marquee-logo: 8.5rem; } }
.marquee__nav {
  display: grid; place-items: center;
  inline-size: var(--hit-min); block-size: var(--hit-min);
  border: var(--stroke-hairline) solid rgb(var(--fg) / 0.16);
  border-radius: var(--radius-full);
  background: rgb(var(--bg)); color: rgb(var(--fg));
  cursor: pointer; font-size: var(--nw-fs-d4); line-height: 1;
}
.marquee__nav:hover { background: rgb(var(--bg-2)); }
@keyframes nw-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; } }

/* ── Sources: one accordion card instead of a long visible list ───────────── */
.sources-accordion {
  border: var(--stroke-hairline) solid rgb(var(--fg) / 0.14);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  background: rgb(var(--bg-2));
}
.sources-accordion > summary {
  cursor: pointer; font-weight: var(--nw-fw-medium);
  list-style: none; display: flex; justify-content: space-between; align-items: center;
  min-block-size: var(--hit-min);
}
.sources-accordion > summary::-webkit-details-marker { display: none; }
.sources-accordion > summary::after { content: "+"; font-size: var(--text-lg); }
.sources-accordion[open] > summary::after { content: "\2212"; }
.sources-accordion > ul { margin-block-start: var(--space-4); word-break: break-word; }

/* Copy column beside its list. */
.services--split { align-items: start; }

/* ═══════════════════════════════════════════════════════════════════════════════
   CLIENT CHANGE LIST V1 — the markup pass
   `changes_v1.py` introduces the elements below; this is what they need to look
   like. Same two gates as everything above: no colour literal, no kernel token.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── The watermark is a pale emblem, not ink ────────────────────────────────
   The asset the brief links is already drawn as a watermark — line art at roughly
   6% ink on transparent. The 0.05 opacity written for a solid mark made it
   invisible on paper, so the alpha is per-scheme instead: near-full on the light
   ground, well down on the dark one where a pale green is the brightest thing in
   the band. */
:root { --nw-mark-a: 0.9; }
.dark { --nw-mark-a: 0.1; }
.brandmark > .brandmark__mark { width: min(34rem, 46%); }

/* ── The callback band ──────────────────────────────────────────────────────
   "This should feel like it's a part of the footer and should carry over the
   rounded border on top." So the band above the footer takes the arc and the gap
   that the footer used to own, and the footer directly beneath it goes flat — two
   stacked arcs would read as a mistake, and the seam between them as a crack. */
.callback--footer {
  border-radius: 50% 50% 0 0 / var(--nw-arc) var(--nw-arc) 0 0;
  margin-top: calc(var(--space-10) * 1.4);
  padding-block: calc(var(--nw-band-pad) + var(--nw-arc)) var(--nw-band-pad-tight);
}
.callback--footer + .site-footer { border-radius: 0; margin-top: 0; }
.callback--footer + .site-footer .site-footer__inner { padding-block-start: var(--nw-band-pad-tight); }
/* The band is a dark field in both schemes, exactly like the footer, so the sage
   focus ring (1.9:1 on it) becomes the band's own ink — same shape, 13:1. */
.callback :focus-visible { outline-color: rgb(var(--nw-band-ink)); }
.callback a { color: rgb(var(--nw-band-ink)); }
.callback a:hover { color: rgb(var(--accent-meadow)); }
.callback .sec-head { max-width: 46rem; }
/* The status line is a grid item like the fields; without this it takes the first
   track and shoves the name input onto its own row the moment a send fails. */
.callback__form .form__status { grid-column: 1 / -1; margin: 0; }
.callback__form > noscript { grid-column: 1 / -1; }
.callback__form .form-embed-note { color: rgb(var(--nw-band-ink) / 0.72); border-left-color: rgb(var(--nw-band-ink) / 0.3); }
/* `align-items: end` lines the button's baseline up with the inputs, but only once
   the row actually is a row — stacked, it should be full width like the fields. */
.callback__form > .btn { width: 100%; }
@media (min-width: 48rem) { .callback__form > .btn { width: auto; } }

/* ── "Let's Work Together" over its photograph ──────────────────────────────
   `.tint` came off these sections in the markup: it paints a ground AND a dot
   texture at the same depth the photograph wants, so the two fought. */
.band--media .container { position: relative; }
.band--media .btn--ghost {
  background: rgb(var(--nw-on-media) / 0.12);
  border-color: rgb(var(--nw-on-media) / 0.5);
  color: rgb(var(--nw-on-media));
  box-shadow: none;
}
.band--media .btn--ghost:hover { background: rgb(var(--nw-on-media) / 0.2); color: rgb(var(--nw-on-media)); }
.band--media :focus-visible { outline-color: rgb(var(--nw-on-media)); }
.band--media .row--center { justify-content: center; }

/* ── "Evidence-Based": the photograph leads, the copy sits beside it ────────
   A 1194x1600 portrait in a 1fr column is otherwise painted at its intrinsic size. */
.approach--split > .photo { width: 100%; height: auto; }
@media (min-width: 900px) {
  .approach--split { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); align-items: center; }
}

/* ── "What We Treat": the CTA at the far right ──────────────────────────────
   The head is already `.sec-head--split`, but the desktop rule up in the density
   pass grids every `.sec-head` and pins a `.btn` to `justify-self: start` — which
   put "View All Conditions" in the middle of the page, reading as neither left- nor
   right-aligned. This is the one head that wants the far edge.

   The selector deliberately MIRRORS that rule's shape rather than being the short
   thing that expresses the intent. `:not()` takes the specificity of its argument,
   so the density rule is (0,7,0); the obvious
   `.container.stack-lg > .sec-head--split > .btn` is (0,5,0) and loses in silence —
   the button simply stays where it was and the CSS reads as if it should have moved.
   Same count, later in the file, so this one wins. */
@media (min-width: 60rem) {
  .section > .container.stack-lg:not(.container--narrow) > .sec-head--split:not(.sec-head--center) > .btn {
    justify-self: end;
  }
}

/* ── Testimonials ──────────────────────────────────────────────────────────
   The scroller is focusable (it is a scroll region with no other keyboard path in),
   so it needs a visible ring; `.review` sits on `.tint`, hence the paper fill. */
.reviews__scroll:focus-visible { outline: var(--stroke-thick) solid rgb(var(--color-primary)); outline-offset: var(--space-2); }
.review blockquote p { margin: 0; color: rgb(var(--fg) / 0.86); }
.review figcaption { font-size: var(--nw-fs-meta); letter-spacing: var(--nw-track-meta); text-transform: uppercase; }
.stars { font-size: var(--nw-fs-lede); line-height: 1; }

/* ── Sources accordion ─────────────────────────────────────────────────────
   The summary is a hit target, and its `+`/`−` is a pseudo-element so it stays out
   of the accessible name. `word-break` because these are bare URLs. */
.sources-accordion > summary { font: var(--weight-lg) var(--nw-fs-d4) / var(--nw-lh-d4) var(--font-display); }
.sources-accordion > summary:focus-visible { outline: var(--stroke-thick) solid rgb(var(--color-primary)); outline-offset: var(--space-1); }
.sources-accordion > ul { padding-left: var(--space-5); }
.sources-accordion > ul li { font-size: var(--nw-fs-small); }

/* ═══════════════════════════════════════════════════════════════════════════════
   CLIENT CHANGE LIST V2 (NE Wellness Website_V2.pdf)
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── The callback band's heading fits on one line ───────────────────────────
   Two caps were fighting it, and only one is obvious: `.callback .sec-head` was
   capped at 46rem, and `.sec-head__title` carries `max-width: 20ch` from the
   editorial scale — 20 characters, on a 34-character heading. Both are lifted for
   this band, and the display size is stepped down so the longer of the two
   headings ("A Transformative Experience In Healing", 38 characters) also lands on
   one line inside the container rather than merely being allowed to try. */
/* ── The home hero breaks where the brief asks ─────────────────────────────
   The break itself is a tag in the markup; these two caps are what let the first
   line hold. `.hero__title` is capped at 16ch for the 73 interior heroes, where a
   long page title should break early — on the one hero that is a short statement
   over video, the cap is what was forcing "Outpatient Mental Health Care" onto two
   lines no matter where the break went. */
.hero--video .hero__center { max-width: min(72rem, 100%); }
.hero--video .hero__title { max-width: none; }

.sec-head--wide { max-width: none; }
.sec-head--wide .sec-head__title {
  max-width: none;
  font-size: clamp(1.7rem, 3.1vw, 2.85rem);
}
.sec-head--wide .sec-head__lede { max-width: 52rem; margin-inline: auto; }

/* ── The practice's own forms, framed ──────────────────────────────────────
   The vendor's companion script is blocked by policy (`embed_origins` widens
   frame-src only), so nothing resizes these to their content: the height comes
   from the brief's own `data-height` and is set inline per form. The wrapper is
   what carries the rounded corner, because clipping an iframe by its own
   `border-radius` is unreliable across engines. */
.embed-form {
  max-width: 44rem; margin-inline: auto; width: 100%;
  border-radius: var(--radius-lg); overflow: hidden;
  background: rgb(var(--bg));
}
.callback .embed-form { max-width: 40rem; }
.embed-form > iframe { display: block; width: 100%; border: 0; }

/* Measured, not guessed — see `form_embed()` for the numbers and how they were taken. A little
   headroom on each, because too tall is dead space and too short cuts off a submit button. */
/* Measured at rest, then given HEADROOM. V3 reports the insurance form scrolling inside its
   frame, and a form at rest is not the tall case: a select, a date picker or a validation
   message grows it after the measurement, and with the vendor's resize script blocked nothing
   tracks that. Dead space is cosmetic; a scrollbar over a submit button is not, so each of
   these sits ~12% above what the form actually needs. */
.embed-form--callback       > iframe { height: 320px; }   /* measures 274 */
.embed-form--transformative > iframe { height: 340px; }   /* measures 294 */
.embed-form--contact        > iframe { height: 1080px; }  /* measures 973 desktop, 994 phone */
/* The insurance form is the one that reflows, and it does so exactly at the 44rem this layout
   gives it: 616px at that width, 1086px at anything narrower. Below the viewport where the
   frame stops being 44rem wide, it needs the taller box or the submit button is 450px past the
   bottom edge. */
/* MEASURED BY SCROLLBAR, not by ink. The first measurement of this form found where its visible
   content ends — 616px — and set the box just above that, and the form still scrolled, which is
   what the client reported twice. The vendor's DOCUMENT is taller than the content drawn on it,
   so "where the pixels stop" is the wrong question; "at what height does the frame stop showing
   a scrollbar" is the right one. It scrolls at 760 and is clean at 800. */
.embed-form--verify         > iframe { height: 830px; }   /* scrollbar clears at 800 */
/* 49rem, not 50: the frame is 44rem until `100vw - 2*--pad` drops below it, and with `--pad` at
   5vw that is 782px — so the boundary IS 48.9rem, and rounding it the other way leaves a sliver
   of viewports where the frame has already narrowed (form 1086px) but the short height is still
   applied. Rounding up costs dead space in a 2px-wide band; rounding down costs a scrollbar. */
@media (max-width: 49rem) { .embed-form--verify > iframe { height: 1340px; } }  /* clears at 1300 */

/* ── Review cards: clamped, with the whole review one click away ───────────
   The quote is rendered in full and CLAMPED, never truncated in the build — the
   complete review stays in the page for the popout, for search and for a screen
   reader, and the ellipsis is the browser's own. `motion.js` reveals the button
   only on the cards that are actually overflowing. */
.review { grid-template-rows: auto 1fr auto auto; }
.review__quote {
  margin: 0;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6;
  overflow: hidden;
}
.review__quote p { margin: 0; color: rgb(var(--fg) / 0.86); }
.review__quote p + p { margin-top: var(--space-3); }
.review__more {
  justify-self: start; align-self: start;
  background: none; border: 0; padding: 0;
  font: var(--weight-base) var(--nw-fs-small) / 1 var(--font-sans);
  color: rgb(var(--color-primary));
  border-bottom: var(--stroke-hairline) solid rgb(var(--color-primary) / 0.5);
  cursor: pointer;
}
.review__more:hover { border-bottom-color: rgb(var(--color-primary)); }
.review__more::after { content: " \2192"; }

.review-dialog {
  max-width: min(40rem, 92vw); width: 100%;
  border: var(--stroke-hairline) solid rgb(var(--fg) / 0.14);
  border-radius: var(--radius-xl);
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  background: rgb(var(--bg)); color: rgb(var(--fg));
  box-shadow: var(--shadow-xl);
}
.review-dialog::backdrop { background: rgb(var(--nw-scrim) / 0.55); }
.review-dialog__body p { margin: 0 0 var(--space-4); color: rgb(var(--fg) / 0.86); }
.review-dialog__who {
  margin: 0; font-size: var(--nw-fs-meta);
  letter-spacing: var(--nw-track-meta); text-transform: uppercase;
  color: rgb(var(--fg) / 0.62);
}
.review-dialog__close {
  position: absolute; inset-block-start: var(--space-4); inset-inline-end: var(--space-4);
  inline-size: var(--hit-min); block-size: var(--hit-min);
  display: grid; place-items: center;
  background: none; border: 0; cursor: pointer;
  font-size: var(--nw-fs-d4); line-height: 1; color: rgb(var(--muted));
}
.review-dialog__close:hover { color: rgb(var(--fg)); }

/* ═══════════════════════════════════════════════════════════════════════════════
   CLIENT CHANGE LIST V3 (NE Wellness Website_V3.pdf)
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── Arrows on the testimonial rail ────────────────────────────────────────
   The rail was draggable but gave no sign of it — nothing on screen said there
   were more reviews to the right. Same control the insurer marquee uses, so the
   two rows read as the same kind of thing. */
.reviews__rail { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; }
.reviews__nav { flex: none; }
@media (max-width: 40rem) { .reviews__nav { display: none; } }

/* ── An image left, the copy and CTA right ─────────────────────────────────
   The sections this applies to were `container--narrow` single columns, so the
   measure is already right; the split just gives the picture the other half.
   `align-items: center` because these run to three or four paragraphs and a
   top-aligned photograph beside them leaves a hole under the image. */
.media-split { align-items: center; }
.media-split > .photo {
  width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-2xl);
}
@media (min-width: 900px) {
  .media-split { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}

/* ── About: the mission section, one photograph instead of two ─────────────
   The brief removes one of the pair and asks for the other larger. With the pair
   gone the `:has(> .photo + .photo)` side-by-side rule no longer applies, so the
   remaining image simply fills its half — which is the "larger" being asked for. */
.mission--single > .photo { width: 100%; height: auto; }

/* ── About: the award, whole ───────────────────────────────────────────────
   It was cropped to a 4:3 plate, which cut the top and bottom off the badge.
   `contain` shows the whole thing; the plate goes because a badge on a tinted
   card reads as a sticker. */
.awards--split { align-items: center; }
.awards--split > .photo {
  width: 100%; height: auto;
  aspect-ratio: auto; object-fit: contain;
  background: none; border: 0; border-radius: 0;
  max-height: 26rem;
}

/* ── Contact: details over a photograph, hours beside them ─────────────────
   The scrim is the same one the media bands use, so "legible over an image" is
   solved once for the site rather than per section. */
.contact-split { align-items: stretch; }
.contact-split__panel {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: var(--radius-2xl);
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  display: grid; align-content: center;
}
.contact-split__bg { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
.contact-split__scrim { position: absolute; inset: 0; z-index: -1; background: rgb(var(--nw-scrim) / 0.66); }
.contact-split__panel,
.contact-split__panel h2,
.contact-split__panel p,
.contact-split__panel a { color: rgb(var(--nw-on-media)); }
.contact-split__panel a { text-decoration-color: rgb(var(--nw-on-media) / 0.5); }
.contact-split__panel :focus-visible { outline-color: rgb(var(--nw-on-media)); }
/* The site's ONE surviving placeholder — the map, which is an <iframe> on the live site and so
   has no image to restore — now sits inside this dark panel, where a grey plate reads as a
   broken image rather than as "not supplied yet". Same honesty, dressed for the ground it is
   on. */
.contact-split__panel .ph {
  background: rgb(var(--nw-on-media) / 0.07);
  border: var(--stroke-hairline) dashed rgb(var(--nw-on-media) / 0.34);
  color: rgb(var(--nw-on-media) / 0.62);
}
.contact-split__panel .ph::after { color: rgb(var(--nw-on-media) / 0.62); }

/* ── A pair of CTAs side by side ───────────────────────────────────────────
   `.stack-lg > .btn` pins each button to its own row; these two belong together. */
.cta-pair { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.stack-lg > .cta-pair, .stack > .cta-pair { align-self: flex-start; }

/* ═══════════════════════════════════════════════════════════════════════════════
   CLIENT CHANGE LIST V4 (NE WELLNESS_WEBSITE_V4.pdf)
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── The watermark, larger ─────────────────────────────────────────────────
   "the same but larger, taking a majority of the section". The default mark is
   sized to sit beside content; this one is sized to sit BEHIND it, so it also
   drops its opacity — the same artwork at the same alpha across four times the
   area reads as a second background rather than as a watermark. */
.brandmark--lg > .brandmark__mark {
  width: min(58rem, 82%);
  inset-inline-end: calc(var(--nw-band-pad-tight) * -0.6);
  opacity: calc(var(--nw-mark-a) * 0.62);
}
@media (max-width: 56.25rem) { .brandmark--lg > .brandmark__mark { display: none; } }

/* ── Opening hours: day left, time right, ruled between ────────────────────
   Not a table. It is three rows of one fact, and a table would be announced as
   one to a screen reader for nothing in return. */
.hours { gap: 0; }
.hours-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-bottom: var(--stroke-hairline) solid rgb(var(--fg) / 0.12);
}
.hours-row:last-child { border-bottom: 0; }
.hours-row > h3 { margin: 0; }
.hours-row > p { margin: 0; color: rgb(var(--muted)); text-align: right; white-space: nowrap; }

