/* ============================================
   proservices-static template
   Professional-services vertical (lawyers + accountants). A trust-forward,
   authoritative LIGHT-NAVY theme: cool near-white body + a real brand navy
   + a DARKENED brand-strong for AA text/CTAs + a confident brand accent
   (brass/gold for accountants OR a bright confident blue for litigators, per
   prospect). Re-hued per prospect via deriveProPalette (template.json
   paletteMode="pro").

   BOLD RESULTS-FORWARD direction (malmanlaw-inspired): the confident,
   results-first energy of a top personal-injury / litigation firm applied to the
   whole vertical. SHARP 0-radius corners, HIGH contrast, bold uppercase CTAs
   ("CALL NOW" energy), oversized serif result numbers, and deep brand-navy
   section bands carry authority. Keeps the two-family type system (Playfair
   Display for display/numbers, Plus Jakarta Sans for UI + body — NEVER
   Fraunces/Lora/Cormorant/Inter), disciplined photo slots with graceful
   gradient fallbacks, and considered motion. The bold-but-tokenized treatment
   reads confident, not generic: every result number, stat and CTA is
   content-driven and real-data-gated.
   ============================================ */

/* --- Reset & Base --- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  /* Brand (real, verbatim) + derived AA-safe strong + refined accent */
  --color-brand:        #783506;        /* real brand navy: eyebrows, icons, headings, accents */
  --color-brand-strong: #642C05;  /* darkened navy (AA on light): button fills, links, small text */
  --color-accent:       #B12532;       /* brass/gold, DECORATIVE: rules, stars, hero CTA, underlines */
  --color-brand-fg:     #FFFFFF;       /* text on brand/brand-strong fills (white) */
  --color-accent-soft:  rgba(120, 53, 6, 0.07);    /* faint brand tint for icon chips + hovers */

  /* Cool neutral surfaces (a restrained brand cast, corporate not warm) */
  --color-bg:        #F9F8F8;        /* page base, cool near-white */
  --color-surface:   #F5F4F3;   /* alt bands, cards */
  --color-surface-2: #F1EFEE;  /* monogram bg, nested cards */
  --color-muted:     #ECE9E7;     /* subtle fills */
  --color-border:    #E4E0DE;    /* hairline borders */

  /* Text */
  --color-ink:     #261C15;     /* deep navy-ink */
  --color-ink-dim: #7A6552;  /* secondary / captions (AA on the light base) */

  /* Deep brand-navy for hero panels, the consult CTA band + footer */
  --color-hero-ink:   #4B260B;
  --color-hero-ink-2: #2B1404;
  --color-hero-overlay: rgba(75, 38, 11, 0.82); /* navy wash over a hero photo */
  --color-hero-scrim:   rgba(24, 14, 6, 0.62);   /* bottom-up scrim for legibility */
  --color-footer:       #2E1707;      /* deep brand-navy footer */

  /* Shadows: soft, diffuse, premium (one shadow OR a hairline — never both at rest) */
  --color-border-accent: color-mix(in srgb, var(--color-brand) 13%, transparent);
  --color-border-accent-hover: color-mix(in srgb, var(--color-brand) 30%, transparent);
  --shadow-sm: 0 1px 2px rgba(12,20,38,0.05);
  --shadow-md: 0 20px 48px -30px rgba(12,20,38,0.34);
  --shadow-lg: 0 40px 90px -44px rgba(12,20,38,0.42);
  --shadow-hover: 0 28px 60px -34px rgba(12,20,38,0.36);

  /* Typography — two families, disciplined weight budget (Playfair Display
     700 roman + 600 italic; Plus Jakarta Sans 400/600/700 = 5 loaded variants
     total, down from 12 across four families previously). Playfair Display
     (elegant high-contrast serif, matches the darkhorse.cpa inspiration's own
     headline face) carries every display/number moment: h1-h4, hero result
     figure, stat numbers, step medallions, monogram initials, review quotes.
     Plus Jakarta Sans is the ONE sans, doing double duty as both the crisp UI
     layer (eyebrows/nav/buttons/labels) AND body copy — a single family, two
     optical roles, per the pack's font-wave brief. Metric-compatible fallback
     stacks below prevent layout shift while fonts swap in. No Fraunces/Lora/
     Cormorant/Inter, ever. */
  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-sans: 'Plus Jakarta Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* Spacing — a consistent scale with a generous editorial top end */
  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 3rem;
  --space-xl: 6rem;
  --space-2xl: 7.5rem;

  /* Layout — SHARP, malmanlaw-style. Corners drive to 0 for a bold,
     results-forward, high-authority read. A hair of radius (2px) survives only
     where a pure-square edge would look like a rendering bug on the smallest
     interactive chips; everything structural is a crisp rectangle. */
  --max-width: 1200px;
  --radius: 0;
  --radius-lg: 0;
  --radius-xl: 0;
  --radius-chip: 2px;
}

html {
  scroll-behavior: smooth;
  font-size: 16px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--font-sans);
  background: var(--color-bg);
  color: var(--color-ink);
  font-size: 1.05rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--color-brand-strong); text-decoration: none; transition: color 0.2s; }
a:hover { color: var(--color-brand); }
button { cursor: pointer; font-family: var(--font-sans); }

:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
  border-radius: 3px;
}

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  /* Min raised to an on-grid 24px (was 1.25rem/20px) (improve loop Arc S). */
  padding: 0 clamp(1.5rem, 4vw, 2.5rem);
}

/* --- Typography --- */
/* One serif family carries the whole heading hierarchy at a single confident
   weight (700); size + tracking do the differentiating, not weight-hopping
   between families (the old h1/h2-vs-h3/h4 split rendered on two different
   fonts, one of which — Playfair — was never actually loaded). Tracking
   tightens as size grows, per the type-system brief. */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; color: var(--color-ink); text-wrap: balance; }
h1 { font-size: clamp(2.75rem, 6.4vw, 5.25rem); line-height: 1.01; letter-spacing: -0.025em; }
h2 { font-size: clamp(2.1rem, 4.4vw, 3.4rem); line-height: 1.05; letter-spacing: -0.02em; }
h3 { font-size: clamp(1.2rem, 2vw, 1.45rem); line-height: 1.25; letter-spacing: -0.01em; }
h4 { font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.3; letter-spacing: -0.008em; }

.section-label {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-brand-strong);
  margin-bottom: 1.1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
}
.section-label::before {
  content: '';
  width: 28px; height: 1.5px;
  background: var(--color-accent);
}

.section-title {
  color: var(--color-ink);
  margin-bottom: var(--space-md);
  text-wrap: balance;
}

.section-desc {
  color: var(--color-ink-dim);
  font-size: 1.08rem;
  max-width: 640px;
  line-height: 1.75;
}

.section-head-center {
  text-align: center;
  max-width: 720px;
  margin: 0 auto var(--space-xl);
}
.section-head-center .section-label { justify-content: center; }
.section-head-center .section-desc { margin-left: auto; margin-right: auto; }

/* --- Buttons — bold, uppercase, confident (malmanlaw "CALL NOW" energy) --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1.05rem 2rem;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border: 2px solid transparent;
  border-radius: var(--radius);
  transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease, filter 0.2s ease;
  white-space: nowrap;
}

.btn-primary {
  background: var(--color-brand-strong);
  color: var(--color-brand-fg);
}
.btn-primary:hover {
  filter: brightness(1.1);
  color: var(--color-brand-fg);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

/* Gold accent CTA — the marquee action (hero + consult band + close bands) */
.btn-accent {
  background: var(--color-accent);
  color: var(--color-hero-ink-2);
  border-color: var(--color-accent);
  font-weight: 700;
}
.btn-accent:hover {
  filter: brightness(1.06);
  color: var(--color-hero-ink-2);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.btn-outline {
  background: transparent;
  color: var(--color-brand-strong);
  border-color: var(--color-border);
}
.btn-outline:hover {
  background: var(--color-surface);
  border-color: var(--color-brand);
  color: var(--color-brand-strong);
  transform: translateY(-2px);
}

/* Hero/band outline: white on the deep navy */
.btn-hero-outline {
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(4px);
  color: #fff;
  border-color: rgba(255,255,255,0.5);
}
.btn-hero-outline:hover {
  background: rgba(255,255,255,0.16);
  border-color: #fff;
  color: #fff;
  transform: translateY(-2px);
}

/* Skip link (SEO/metadata wave, 2026-08): first focusable element in the
   body, hidden off-screen until keyboard focus, jumps straight to <main>.
   z-index 1000 clears the fixed .nav (200) and the modal overlay (250). */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  transform: translateY(-120%);
  background: var(--color-ink, #0f1720);
  color: #fff;
  padding: 0.85rem 1.5rem;
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  border-radius: 0 0 8px 0;
  transition: transform 0.15s ease;
}
.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid #fff;
  outline-offset: -2px;
}

/* --- Navigation --- */
/* Solid light bar at ALL scroll positions. A dark-ink logo we don't recolour reads
   cleanly on light (matching how premium firms ship an "on-light" logo), so there is
   no transparent-over-hero state and no logo pill to clash with the bar. */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  /* Above the mobile sticky call bar (150) so the open drawer is never partly
     covered by it, below the modal (250). */
  z-index: 200;
  padding: 1.05rem 0;
  /* OPAQUE white — matches the logo's baked-in white plate exactly, so the mark
     blends into the bar with no visible box. (A translucent bar let the dark hero
     bleed through and read darker than the opaque-white plate.) */
  background: #ffffff;
  border-bottom: 1px solid var(--color-border);
  transition: background 0.25s ease, box-shadow 0.25s ease, padding 0.25s ease;
}
.nav.scrolled {
  padding: 0.6rem 0;
  background: #ffffff;
  box-shadow: 0 1px 0 var(--color-border), var(--shadow-sm);
}

.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 2.5rem);
}

/* Real logo lockup, or a clean wordmark when no logo asset exists. The bar is
   always light, so the real (un-recoloured) mark reads directly on it — no pill. */
.nav-logo { display: inline-flex; align-items: center; }
.nav-logo-img { height: 58px; width: auto; display: block; max-width: 250px; object-fit: contain; }
.nav.scrolled .nav-logo-img { height: 50px; }
/* Always show the primary (dark-ink) logo on the light bar; a light knockout would
   vanish on light, so it is never used here. */
.nav-logo-dark { display: none; }
.nav-logo-light { display: block; }
.nav-wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.32rem;
  letter-spacing: -0.015em;
  color: var(--color-ink);
  line-height: 1.1;
  white-space: nowrap;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  list-style: none;
}
.nav-links a {
  display: inline-block;
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  white-space: nowrap;
  position: relative;
  padding: 0.25rem 0;
}
.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -3px; left: 0;
  width: 0; height: 1.5px;
  background: var(--color-accent);
  transition: width 0.3s;
}
.nav-links a:hover::after,
.nav-links a.active::after { width: 100%; }

.nav-actions { display: flex; align-items: center; gap: 1.1rem; }
.nav-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.nav-phone svg {
  width: 16px; height: 16px;
  color: var(--color-brand-strong);
  flex-shrink: 0;
}
.nav-phone:hover { color: var(--color-brand); }

.nav-cta {
  padding: 0.7rem 1.5rem;
  background: var(--color-accent);
  color: var(--color-hero-ink-2) !important;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: filter 0.2s, transform 0.2s, box-shadow 0.2s;
}
.nav-cta:hover { filter: brightness(1.06); transform: translateY(-1px); box-shadow: var(--shadow-sm); color: var(--color-hero-ink-2) !important; }
.nav-cta::after { display: none !important; }

/* Mobile menu toggle. Explicit 44x44 hit area (WCAG/Apple HIG touch-target
   minimum) around the visual 22px glyph, centered rather than padded, so the
   whole button — not just the three bars — is tappable. */
.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  background: none;
  border: none;
  padding: 0;
}
.nav-toggle span {
  display: block;
  width: 22px; height: 2px;
  border-radius: 1px;
  background: var(--color-ink);
  transition: all 0.3s;
}
.nav-toggle.open span { background: var(--color-ink); }
.nav-toggle.open span:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }

/* --- Hero --- */
.hero {
  position: relative;
  min-height: 92vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  /* Deep brand-navy gradient fallback when no hero photo is staged */
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
}
/* A faint architectural grid over the gradient hero fallback — quiet texture so
   the no-photo hero never reads flat/empty. */
.hero::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.028) 1px, transparent 1px);
  background-size: 68px 68px;
  mask-image: radial-gradient(120% 120% at 15% 0%, #000 20%, transparent 78%);
  pointer-events: none;
}
.hero-media { position: absolute; inset: 0; z-index: 0; }
/* Art-directed crop for the sample's hero (two colleagues just right of centre,
   heads roughly a third of the way down): on the very tall mobile hero
   (min-height:100svh, cover crops left/right, keeps full height) this keeps
   them inside the visible slice instead of the browser's blind 50/50 default;
   on the wide desktop hero (cover crops top/bottom) it keeps their heads clear
   of the crop line too. Per-prospect real hero photos should tune this slot. */
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 56% 38%; }
.hero-media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-video-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-media video { display: none; }
  .hero-video-poster { display: block; }
}
.hero-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: var(--color-hero-overlay);
  background:
    linear-gradient(0deg, var(--color-hero-scrim) 0%, transparent 58%),
    linear-gradient(97deg,
      color-mix(in srgb, var(--color-hero-ink) 92%, transparent) 0%,
      color-mix(in srgb, var(--color-hero-ink) 80%, transparent) 34%,
      color-mix(in srgb, var(--color-hero-ink) 54%, transparent) 66%,
      color-mix(in srgb, var(--color-hero-ink) 40%, transparent) 100%);
}
.hero-inner { position: relative; z-index: 2; width: 100%; }
.hero-content { max-width: 700px; padding: 4rem 0 4rem; }

/* Bold "RECORD-SETTING RESULTS" pill — a confident accent-bordered chip that
   sets the results-forward tone the moment the page loads. */
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 1rem;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 700;
  /* 0.2em: this badge plays the same eyebrow-before-headline role as
     .section-label (same size class, 0.72-0.75rem) which already carries
     0.2em pack-wide — was a 0.18em one-off outlier from that established
     eyebrow convention (distinct from the pack's OTHER, smaller-size
     0.14em mid-tier caption family; this matches the larger eyebrow tier
     instead, improve loop corrections 94-96). */
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--color-accent) 55%, transparent);
  border-radius: var(--radius-chip);
  margin-bottom: var(--space-md);
}
.hero-badge::before { content: ''; width: 8px; height: 8px; background: var(--color-accent); }

/* Oversized hero result number — the malmanlaw signature. Content-gated
   (hero.resultStat), so a firm without a headline number drops it cleanly. */
.hero-result {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-bottom: var(--space-lg);
  padding-left: 1.15rem;
  border-left: 4px solid var(--color-accent);
}
.hero-result-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: clamp(3rem, 7vw, 5.25rem);
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: #fff;
}
.hero-result-label {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  max-width: 15ch;
  line-height: 1.35;
}

.hero h1 {
  color: #fff;
  font-size: clamp(2.85rem, 6.6vw, 5.5rem);
  line-height: 1.0;
  letter-spacing: -0.025em;
  text-wrap: balance;
  text-shadow: 0 1px 30px rgba(0, 0, 0, 0.3);
  margin-bottom: var(--space-md);
}
/* The accent is the ONE phrase that carries the eye — set in Playfair ITALIC,
   in brass. A coloured italic key phrase reads editorial + premium and never
   collides with descenders. Keep it short at authoring time (2-4 words). */
.hero h1 em {
  font-style: italic;
  font-weight: 600;
  color: var(--color-accent);
}

.hero-sub {
  font-size: 1.18rem;
  color: rgba(255,255,255,0.94);
  /* Same legibility treatment as .hero h1 (a soft shadow, not a hard outline)
     so body copy over a busy hero photo reads with the same contrast the
     headline already gets. */
  text-shadow: 0 1px 20px rgba(0, 0, 0, 0.25);
  margin-bottom: var(--space-lg);
  max-width: 590px;
  line-height: 1.6;
}

.hero-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: var(--space-lg);
}
/* In the hero, the primary action reads as the gold marquee CTA */
.hero .btn-primary {
  background: var(--color-accent);
  color: var(--color-hero-ink-2);
  border-color: var(--color-accent);
  font-weight: 700;
  filter: saturate(1.14);
  box-shadow: 0 10px 26px -10px color-mix(in srgb, var(--color-accent) 60%, transparent);
}
.hero .btn-primary:hover {
  filter: saturate(1.14) brightness(1.06);
  color: var(--color-hero-ink-2);
  box-shadow: 0 18px 36px -12px color-mix(in srgb, var(--color-accent) 65%, transparent);
}

.hero-trust {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}
.hero-rating {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: #fff;
  font-size: 0.95rem;
}
.hero-rating strong { font-family: var(--font-display); font-size: 1.2rem; }
.hero-stars { color: var(--color-accent); letter-spacing: 0.06em; }
/* Honest star fill: --stars-fill (from hero.starsPercent) clips the gold to the
   real rating (4.6 -> 92%), so no full extra star is claimed. Falls back to 100%. */
.hero-stars[style*="--stars-fill"] {
  background: linear-gradient(90deg, currentColor var(--stars-fill, 100%), rgba(255,255,255,0.30) var(--stars-fill, 100%));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1rem;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: var(--radius);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 600;
}
.hero-chip svg { width: 18px; height: 18px; color: var(--color-accent); flex-shrink: 0; }

/* Scroll cue on the gradient (no-media) hero — a quiet considered detail */
.hero-scrollcue {
  position: absolute; z-index: 2;
  left: 50%; bottom: 1.75rem;
  transform: translateX(-50%);
  width: 24px; height: 38px;
  border: 1.5px solid rgba(255,255,255,0.4);
  border-radius: 14px;
  display: flex; justify-content: center;
}
.hero-scrollcue span {
  width: 3px; height: 8px; margin-top: 7px;
  border-radius: 2px;
  background: var(--color-accent);
  animation: scrollcue 1.8s ease-in-out infinite;
}
@keyframes scrollcue { 0%,100% { opacity: 0.4; transform: translateY(0); } 50% { opacity: 1; transform: translateY(7px); } }
@media (prefers-reduced-motion: reduce) { .hero-scrollcue span { animation: none; } }

/* --- Hero archetypes: split + bandoverlay (fullbleed = the base above) --- */
.hero-split { min-height: auto; }
.hero-split .hero-inner {
  max-width: 100%;
  padding: 0;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  align-items: stretch;
  min-height: 90vh;
}
.hero-split .hero-content {
  max-width: none;
  padding: clamp(7.5rem, 9vw, 9rem) clamp(1.5rem, 5vw, 4.5rem) clamp(3rem, 6vw, 4.5rem);
  background: linear-gradient(160deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.hero-figure {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-accent) 175%);
}
.hero-figure::after {
  content: '';
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 3px; background: var(--color-accent); opacity: 0.85;
}
/* Split archetype's side panel is narrower than the fullbleed background, so it
   crops more aggressively than .hero-media — same subject-protecting bias. */
.hero-figure img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 56% 34%; display: block; }

/* Bandoverlay: full-bleed photo + a solid brand CTA band low on the hero. */
.hero-bandoverlay .hero-inner {
  display: flex;
  align-items: flex-end;
  min-height: 92vh;
  padding: 7rem 0 clamp(2rem, 5vw, 3.5rem);
}
.hero-bandoverlay .hero-overlay { background: linear-gradient(0deg, var(--color-hero-scrim) 0%, transparent 68%); }
.hero-bandoverlay .hero-content {
  max-width: 920px;
  padding: clamp(2rem, 3.5vw, 3rem) clamp(2rem, 4vw, 3.25rem);
  background: linear-gradient(140deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

/* --- Hero lead-capture form (solid card on the dark hero) --- */
.hero-inner:has(.hero-lead) {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(320px, 0.9fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.hero-inner:has(.hero-lead) .hero-content { max-width: none; }
/* Align the consult form's top with the H1 (drop it past the eyebrow: content
   padding + eyebrow height). Scales down cleanly toward the stacked layout. */
.hero-inner:has(.hero-lead) .hero-lead { margin-top: clamp(0rem, 10vw, 8rem); }
.hero-split .hero-inner:has(.hero-lead) { grid-template-columns: 1.05fr 1fr; }
.hero-split .hero-inner:has(.hero-lead) .hero-figure { grid-column: 2; grid-row: 1; }
.hero-split .hero-inner:has(.hero-lead) .hero-lead {
  grid-column: 2; grid-row: 1;
  align-self: center; justify-self: center;
  max-width: 420px;
  margin: clamp(1.5rem, 3vw, 2.5rem);
}
.hero-bandoverlay .hero-inner:has(.hero-lead) {
  align-items: end;
  grid-template-columns: minmax(0, 1.05fr) minmax(320px, 0.86fr);
}

/* True frosted-glass card: translucent over the dark hero (photo or gradient),
   not a solid navy panel, so it reads as a distinct floating surface rather
   than blending into the hero band behind it. */
.consult-form.hero-lead {
  position: relative;
  z-index: 3;
  width: 100%;
  padding: clamp(1.75rem, 2.6vw, 2.35rem);
  background: linear-gradient(158deg, color-mix(in srgb, var(--color-hero-ink) 62%, transparent) 0%, color-mix(in srgb, var(--color-hero-ink-2) 62%, transparent) 100%);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.16);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.hero-lead-head { margin-bottom: var(--space-md); }
.hero-lead h2 { color: #fff; font-family: var(--font-display); font-size: clamp(1.4rem, 2.2vw, 1.8rem); line-height: 1.15; margin: 0; }
.hero-lead-sub { color: rgba(255,255,255,0.82); font-size: 0.9rem; margin-top: 0.4rem; line-height: 1.5; }
.hero-lead .form-group { margin-bottom: 0.85rem; }
.hero-lead .form-row { gap: 0.85rem; }
.consult-form.hero-lead label { color: rgba(255,255,255,0.88); }
.consult-form.hero-lead input,
.consult-form.hero-lead select {
  background: #fff;
  border-color: rgba(255,255,255,0.42);
  color: var(--color-ink);
}
.consult-form.hero-lead input::placeholder { color: color-mix(in srgb, var(--color-ink-dim) 72%, transparent); }
.consult-form.hero-lead input:focus,
.consult-form.hero-lead select:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 40%, transparent);
}
.hero-lead-submit { width: 100%; margin-top: 0.35rem; }
.hero-lead-privacy { color: rgba(255,255,255,0.72); font-size: 0.72rem; margin-top: 0.7rem; text-align: center; }

/* --- Trust strip --- */
.trust-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
.trust-bar-inner {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  row-gap: 0.75rem;
  padding: 1.2rem clamp(1.25rem, 4vw, 2.5rem);
}
/* Typography-first: a thin divider between items stands in for the old icon,
   an editorial ticker rather than an icon-led value-prop row. */
.trust-item {
  display: inline-flex;
  align-items: center;
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0 1.4rem;
  border-left: 1px solid var(--color-border);
}
.trust-item:first-child { padding-left: 0; border-left: none; }
/* Structured rating chip — rendered ONCE, here in the trust bar; the stats band
   never repeats the rating. Gold stars + value; the count shows only when strong
   (>=500) via the showReviewCount gate, else it reads "on Google". */
.trust-item-rating .trust-stars {
  color: #e8a33d;
  letter-spacing: 1.5px;
  font-size: 0.95rem;
  line-height: 1;
}
/* Honest star fill (unify with the hero's gradient-clip system): a partial
   rating clips to its real percent instead of always drawing five full stars. */
.trust-item-rating .trust-stars[style*="--stars-fill"] {
  background: linear-gradient(90deg, currentColor var(--stars-fill, 100%), var(--color-border) var(--stars-fill, 100%));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.trust-item-rating strong { font-weight: 700; }

/* --- Trust-stats band (REAL DATA ONLY; collapses gracefully to 2-5, centered) --- */
.stats-band {
  position: relative;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  color: #fff;
  padding: clamp(1.6rem, 3vw, 2.5rem) 0;
  border-bottom: 1px solid var(--color-border);
}
.stats-band::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: min(180px, 46%); height: 4px;
  background: var(--color-accent);
}
.stats-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: clamp(2rem, 4.5vw, 4rem); /* min 32px, on-grid (was 1.75rem/28px) */
}
.stat {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 140px;
  padding: 0 clamp(0.75rem, 2vw, 1.5rem);
}
.stat + .stat::before {
  content: '';
  position: absolute;
  left: calc(clamp(1.5rem, 4vw, 3.5rem) / -2);
  top: 10%; bottom: 10%;
  width: 1px;
  background: rgba(255,255,255,0.18);
}
.stat-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: clamp(3.4rem, 6.8vw, 5rem);
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: #fff;
}
.stat-label {
  margin-top: 0.85rem;
  font-family: var(--font-sans);
  font-size: clamp(0.72rem, 1.5vw, 0.82rem);
  font-weight: 700;
  /* Mid-tier caption tracking converges on 0.14em pack-wide (matches
     .about-badge-label/.footer-col h3) — was an 0.12em outlier. */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--color-accent);
}
.stat-sub {
  margin-top: 0.45rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.45;
  color: rgba(255,255,255,0.7);
  max-width: 190px;
}

/* --- Sections --- */
section {
  /* Bounds tightened to the 8px rhythm scale (32px/56px) so the fluid clamp lands on-grid
     at both the mobile (390) and desktop (1440) reference widths (improve loop Arc S). */
  padding: clamp(2rem, 4vw, 3.5rem) 0;
  position: relative;
  scroll-margin-top: 72px;
}
.about-section { background: var(--color-bg); }
.practice-section { background: var(--color-surface); border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.approach-section { background: var(--color-bg); }
.team-section { background: var(--color-surface); border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.credentials-section { background: var(--color-bg); }
.results-section { background: var(--color-surface); border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.faq-section { background: var(--color-bg); }
.contact-section { background: var(--color-bg); border-top: 1px solid var(--color-border); }

/* --- Sub-niche variant structural hooks (fillStatic `variantEmphasis`/
   `variantCompact`, driven by templates/variants/lawyer.json + accountant.json
   emphasize/deemphasize lists). Section-key -> DOM mapping for this pack:
     about       -> #about         (About / why us)
     practice    -> #practice      (Practice areas / services)
     approach    -> #approach      (Approach / how we work)
     trustStats  -> .stats-band    (Trust-stats band)
     reviews     -> #results       (Results / testimonials)
   [data-emph="1"] = a real featured treatment: promoted heading scale, an
   accent-derived band tint, and more vertical rhythm, structurally distinct
   from a plain section, not a recolor. [data-compact="1"] = condensed: tighter
   rhythm, a smaller heading, description dropped. Both are additive/no-op when
   a section carries neither attribute. */
/* Arc S note: the calc(clamp() * multiplier) idiom below compounds a shared inner clamp
   through per-variant multipliers, which is how the previous values (86.4px/74px/34.6px/
   20.4px/28px …) drifted off the 8px grid — fixing the shared inner clamp shifts multiple
   variants' multiplied outputs at once and doesn't land all of them on-grid together. Each
   variant now carries its own clamp with bounds picked to pin to an on-grid value at the two
   reference widths (1440 desktop / 390 mobile), same outcome (a real featured/condensed
   rhythm difference) without the multiplier chain. */
[data-emph="1"]:not(.stats-band) {
  padding-block: clamp(2.5rem, 8vw, 5.5rem);
  background-image: linear-gradient(180deg, color-mix(in srgb, var(--color-accent) 7%, transparent) 0%, transparent 55%);
}
[data-emph="1"] .section-title { font-size: clamp(2.6rem, 4.6vw, 3.9rem); }
[data-emph="1"] .section-label { font-size: 0.8rem; letter-spacing: 0.24em; }
[data-emph="1"] .section-label::before { width: 44px; height: 2px; }
.stats-band[data-emph="1"] { padding-block: clamp(2.5rem, 8vw, 4.5rem); }
.stats-band[data-emph="1"] .stat-value { font-size: clamp(3.9rem, 7.6vw, 5.8rem); }
.stats-band[data-emph="1"]::before { width: min(260px, 60%); height: 5px; }

[data-compact="1"]:not(.stats-band) {
  padding-block: clamp(1.5rem, 4vw, 2rem);
}
[data-compact="1"] .section-title { font-size: clamp(1.7rem, 2.6vw, 2.3rem); }
[data-compact="1"] .section-desc { display: none; }
.stats-band[data-compact="1"] { padding-block: calc(clamp(1.6rem, 3vw, 2.5rem) * 0.6); }
.stats-band[data-compact="1"] .stat-value { font-size: clamp(2.6rem, 5vw, 3.6rem); }
@media (max-width: 620px) {
  [data-emph="1"]:not(.stats-band) { padding-block: 2.5rem; }
  .stats-band[data-emph="1"] { padding-block: 2rem; }
}

/* --- About --- */
.about-grid {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}
.about-grid.no-media { grid-template-columns: 1.15fr 1fr; }
/* Editorial framed photo: the image sits on a soft shadow with a thin brass
   frame offset behind it toward the lower-right (a considered magazine detail). */
.about-media { position: relative; }
.about-media::before {
  content: '';
  position: absolute;
  inset: 20px -20px -20px 20px;
  border: 1px solid color-mix(in srgb, var(--color-accent) 55%, transparent);
  border-radius: var(--radius-lg);
  z-index: 0;
}
.about-media img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  min-height: 440px;
  object-fit: cover;
  /* Office/interior about photos tend to carry their interest (furniture, desks,
     people) in the lower two-thirds; a plain 50% centre crop wastes room on
     blank ceiling. Nudged down, not to an extreme. */
  object-position: center 62%;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
/* Real-data credential badge overlapping the image corner (optional). */
.about-badge {
  position: absolute;
  z-index: 2;
  left: -14px; bottom: 26px;
  padding: 0.9rem 1.25rem;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.about-badge-value { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 1.7rem; color: #fff; }
.about-badge-label { font-family: var(--font-sans); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-accent); margin-top: 0.2rem; max-width: 150px; }
.about-text p { color: var(--color-ink-dim); margin-bottom: var(--space-sm); line-height: 1.8; }

.proof-points {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: var(--space-md);
}
.proof-point {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
  padding: 1rem 1.1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition: border-color 0.2s, transform 0.2s;
}
.proof-point:hover { border-color: color-mix(in srgb, var(--color-brand) 40%, var(--color-border)); transform: translateY(-2px); }
.about-section .proof-point { background: var(--color-surface); }
/* Typography-first index number stands in for the old icon-in-a-box. */
.proof-index {
  flex-shrink: 0;
  min-width: 1.6rem;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 1rem;
  color: var(--color-accent);
  line-height: 1.4;
}
.proof-point strong { display: block; color: var(--color-ink); font-family: var(--font-display); font-size: 0.95rem; margin-bottom: 0.15rem; }
.proof-point span { color: var(--color-ink-dim); font-size: 0.84rem; line-height: 1.5; }

.about-signature {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-md);
  padding-left: 1rem;
  border-left: 2px solid var(--color-accent);
}
.about-signature-name { font-family: var(--font-display); font-style: italic; font-weight: 600; font-size: 1.15rem; color: var(--color-ink); }
/* 0.14em: same mid-tier caption tracking as .about-badge-label/.footer-col h3
   (was 0.06em, an outlier against the pack's own convention). */
.about-signature-role { font-family: var(--font-sans); font-size: 0.78rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-ink-dim); margin-top: 0.2rem; }

/* --- Practice areas / services (NO prices — quoted per matter) --- */
.practice-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}
/* Refined card: a hairline border at rest (no resting shadow), a soft shadow +
   lift + an accent hairline that slides across the top on hover. */
.practice-card {
  position: relative;
  padding: 2rem 1.85rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.practice-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}
.practice-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 34px 74px -30px rgba(12,20,38,0.44);
  border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border));
}
.practice-card:hover::before { transform: scaleX(1); }
/* Typography-first index number stands in for the old icon-in-a-box (this
   niche's stock library carries no service-tagged photography, so cards lead
   with an editorial numeral rather than a forced photo or an SVG glyph). */
.practice-index {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 1.4rem;
  color: var(--color-accent);
  margin-bottom: 0.9rem;
  line-height: 1;
}
.practice-card h3 { margin-bottom: var(--space-xs); } /* 8px, on-grid (was 0.55rem/8.8px) */
.practice-card p { color: var(--color-ink-dim); font-size: 0.96rem; line-height: 1.65; }
/* Soft background-image variant: a per-item `practice.items[].image` or the shared
   `practice.image` fallback turns a card photographic — the photo sits behind a
   brand scrim so the heading + copy stay legible. Icon-only cards are unaffected. */
.practice-card-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transition: transform 0.4s ease;
}
.practice-card:hover .practice-card-bg { transform: scale(1.045); }
.practice-card-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    165deg,
    color-mix(in srgb, var(--color-brand) 60%, transparent) 0%,
    color-mix(in srgb, var(--color-brand) 88%, transparent) 100%
  );
}
.practice-card:has(.practice-card-bg) { border-color: transparent; }
.practice-card:has(.practice-card-bg) > :not(.practice-card-bg):not(.practice-card-scrim) {
  position: relative;
  z-index: 2;
}
.practice-card::before { z-index: 3; }
.practice-card:has(.practice-card-bg) .practice-index { color: #fff; }
.practice-card:has(.practice-card-bg) h3 { color: #fff; }
.practice-card:has(.practice-card-bg) p { color: rgba(255, 255, 255, 0.9); }
.practice-meta {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--color-border);
  font-family: var(--font-sans);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--color-brand-strong);
}
.practice-cta {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: var(--space-xl);
}

/* --- Approach / how we work (steps) --- */
.steps-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}
/* Quiet connector line linking the numbered medallions (desktop only). */
@media (min-width: 901px) {
  .steps-grid::before {
    content: '';
    position: absolute;
    top: calc(2.85rem + 44px);
    left: 18%; right: 18%;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--color-border) 15%, var(--color-border) 85%, transparent);
    z-index: 0;
  }
}
.step-card {
  padding: 2.85rem 1.9rem 2.35rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  position: relative;
  z-index: 1;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px; height: 88px;
  border-radius: 50%;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: 2.3rem;
  letter-spacing: 0.01em;
  margin-bottom: 1.4rem;
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08), 0 16px 34px -16px rgba(12,20,38,0.6);
}
.step-num::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid var(--color-accent);
  opacity: 0.6;
}
.step-card h3 { margin-bottom: 0.5rem; }
.step-card p { color: var(--color-ink-dim); font-size: 0.96rem; line-height: 1.6; max-width: 34ch; }

/* --- Credibility / office statement band (deep-navy editorial moment) --- */
.credibility {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  color: #fff;
}
.credibility-media { position: absolute; inset: 0; z-index: 0; }
.credibility-media img { width: 100%; height: 100%; object-fit: cover; }
/* Spatially-graduated overlay (matches .hero-overlay's recipe, same tokens):
   was a FLAT single-opacity wash (0.85) that crushed the photo to a barely-
   visible grey texture everywhere, even on the side with no text over it —
   the opposite of the hero band's considered, direction-aware treatment
   right above it on the same page. Reuses .hero-overlay's exact stops (own
   existing --color-hero-ink token, no new color) so the office photo now
   reads clearly on the right (text sits left, per .credibility-inner's
   max-width), matching the hero's "strategic use of imagery" rather than
   flattening every band to the same solid wash (improve loop corrections
   94-96, color-cohesion). */
.credibility-overlay {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(0deg, var(--color-hero-scrim) 0%, transparent 58%),
    linear-gradient(97deg,
      color-mix(in srgb, var(--color-hero-ink) 92%, transparent) 0%,
      color-mix(in srgb, var(--color-hero-ink) 80%, transparent) 34%,
      color-mix(in srgb, var(--color-hero-ink) 54%, transparent) 66%,
      color-mix(in srgb, var(--color-hero-ink) 40%, transparent) 100%);
}
.credibility::after {
  content: '';
  position: absolute; top: 0; left: 0; width: min(160px, 34%); height: 3px;
  background: var(--color-accent); z-index: 2;
}
.credibility .container { position: relative; z-index: 2; }
.credibility-inner { max-width: 940px; }
.credibility .section-label { color: var(--color-accent); }
.credibility-statement {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.7rem, 3.6vw, 2.85rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: #fff;
  text-wrap: balance;
}
.credibility-statement em, .credibility-statement i { font-style: italic; color: var(--color-accent); }
.credibility-text {
  margin-top: var(--space-md);
  max-width: 640px;
  color: rgba(255,255,255,0.82);
  font-size: 1.05rem;
  line-height: 1.75;
}
.credibility-markers {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 2.25rem;
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid rgba(255,255,255,0.16);
}
/* Typography-first: a short accent rule stands in for the old icon. */
.credibility-markers li {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: 600;
  color: #fff;
}
.credibility-markers li::before {
  content: '';
  width: 14px;
  height: 1px;
  background: var(--color-accent);
  flex-shrink: 0;
}
.credibility .btn-accent { margin-top: var(--space-lg); }

/* --- Areas we serve (service-area / locations — malmanlaw "Other Areas We
   Serve"). Fully content-gated on the serviceAreas key; a firm without a
   service-area footprint drops the whole band. Bold, sharp location cards with
   a left accent edge and an address/note line. No image slots (never an empty
   image). --- */
.areas-section { background: var(--color-bg); border-top: 1px solid var(--color-border); }
.areas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--space-md);
  max-width: 1040px;
  margin: 0 auto;
}
.area-card {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.6rem 1.7rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.area-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
  border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
}
.area-card svg { width: 24px; height: 24px; color: var(--color-accent); flex-shrink: 0; margin-top: 0.15rem; }
.area-card-body { display: flex; flex-direction: column; }
.area-name { font-family: var(--font-display); font-weight: 700; font-size: 1.12rem; color: var(--color-ink); letter-spacing: -0.012em; }
.area-note { color: var(--color-ink-dim); font-size: 0.88rem; line-height: 1.5; margin-top: 0.15rem; }
.areas-note { text-align: center; color: var(--color-ink-dim); font-size: 0.9rem; margin-top: var(--space-lg); }

/* --- Team --- */
.team-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-lg);
  max-width: 1040px;
  margin: 0 auto;
  /* align-items:start (was the grid default, stretch): bios vary in length
     (measured 153-223 chars in the sample) and CSS Grid's default row-stretch
     forced every card to the tallest sibling's height, leaving a dead gap
     below the shorter bios' text before the card border (measured: 29px on
     the longest bio's card vs 78px on the two shorter ones — a real,
     photographable "spacing... uneven" defect, not a token problem — same
     grid-stretch defect class the trades-static wave found in
     .service-card-body). Each card now sizes to its own content, giving every
     card the same clean bottom padding regardless of its neighbour's bio
     length (improve loop, corrections 94-96). */
  align-items: start;
}
/* Editorial portrait cards: a tall photo (or navy monogram panel) above the body. */
.team-card {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.team-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
  border-color: color-mix(in srgb, var(--color-accent) 30%, var(--color-border));
}
.team-photo { margin: 0; position: relative; overflow: hidden; }
.team-photo img {
  width: 100%;
  aspect-ratio: 4 / 4.4;
  object-fit: cover;
  /* Headshots/portraits carry the face in the upper portion of the frame; a
     centred crop tends to cut off the top of the head on a tall 4:4.4 card. */
  object-position: center 22%;
  display: block;
  transition: transform 0.4s ease;
}
.team-card:hover .team-photo img { transform: scale(1.04); }
/* Accent underline echoes the monogram's own bottom accent, so a real headshot
   and the initials fallback read as the same considered treatment. */
.team-photo::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--color-accent);
}
.team-monogram {
  width: 100%;
  aspect-ratio: 4 / 4.4;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  color: var(--color-brand-fg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 3.4rem;
  letter-spacing: 0.02em;
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
}
.team-monogram::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--color-accent);
}
.team-body { padding: 1.65rem 1.6rem 1.75rem; text-align: left; }
.team-body h3 { margin-bottom: var(--space-xs); } /* 8px, on-grid + unifies card-heading spacing with .practice-card/.step-card h3 (was 0.2rem/3.2px) */
.team-credentials {
  color: var(--color-brand-strong);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  margin-bottom: 0.3rem;
}
.team-role {
  color: var(--color-ink-dim);
  font-family: var(--font-sans);
  font-size: 0.74rem;
  text-transform: uppercase;
  /* 0.14em: aligns to the pack's mid-tier caption tracking (was 0.1em). */
  letter-spacing: 0.14em;
  font-weight: 600;
  margin-bottom: 0.95rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--color-border);
}
.team-body p { color: var(--color-ink-dim); font-size: 0.92rem; line-height: 1.65; }

/* --- Credentials / associations --- */
.credentials-wrap { max-width: 980px; margin: 0 auto; }
.credentials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--space-md);
}
/* Typography-first: a thin accent rule stands in for the old icon chip so every
   card reads as an editorial label/detail pair, not a value-prop icon grid. */
.credential-card {
  padding: 1.4rem 1.6rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius);
  transition: border-color 0.2s, transform 0.2s;
}
.credential-card:hover { border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border)); border-left-color: var(--color-accent); transform: translateY(-2px); }
.credential-card strong { display: block; color: var(--color-ink); font-family: var(--font-display); font-size: 1rem; margin-bottom: 0.2rem; }
.credential-card span { color: var(--color-ink-dim); font-size: 0.88rem; line-height: 1.55; }
.credentials-note { text-align: center; color: var(--color-ink-dim); font-size: 0.92rem; margin-top: var(--space-lg); }

/* --- Results / testimonials --- */
.results-section .section-head-center { margin-bottom: var(--space-lg); }
.rating-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: var(--space-md);
  padding: 0.75rem 1.5rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  color: var(--color-ink-dim);
  box-shadow: var(--shadow-sm);
}
.rating-score { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--color-ink); font-size: 1.8rem; line-height: 1; }
.rating-stars { color: var(--color-accent); letter-spacing: 0.14em; font-size: 1.15rem; }
/* Honest star fill (unify with the hero's gradient-clip system): a partial
   rating clips to its real percent instead of always drawing five full stars. */
.rating-stars[style*="--stars-fill"] {
  background: linear-gradient(90deg, currentColor var(--stars-fill, 100%), var(--color-border) var(--stars-fill, 100%));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.rating-meta { font-weight: 600; }

/* Confident lead pull-quote with an oversized brass quote mark */
.review-lead {
  position: relative;
  max-width: 860px;
  margin: 0 auto var(--space-xl);
  padding: 2.75rem 3rem 2.5rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  text-align: center;
}
.review-lead-mark {
  position: absolute;
  top: -0.3rem; left: 1.5rem;
  font-family: var(--font-display);
  font-size: 6rem;
  line-height: 1;
  color: color-mix(in srgb, var(--color-accent) 32%, transparent);
  pointer-events: none;
}
.review-lead .review-stars { justify-content: center; }
.review-lead p {
  position: relative;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.25rem, 2.3vw, 1.65rem);
  font-weight: 600;
  line-height: 1.5;
  color: var(--color-ink);
  margin: 0.5rem 0 1.1rem;
  text-wrap: balance;
}
.review-lead footer { font-size: 0.92rem; }
.reviews-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}
.review-card {
  padding: 1.9rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-align: left;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.review-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); border-color: color-mix(in srgb, var(--color-accent) 30%, var(--color-border)); }
.review-stars { color: var(--color-accent); font-size: 0.9rem; letter-spacing: 0.1em; margin-bottom: 0.85rem; display: flex; }
.review-card blockquote { color: var(--color-ink); font-size: 0.98rem; line-height: 1.7; margin-bottom: var(--space-sm); }
.review-author { font-family: var(--font-display); font-weight: 700; color: var(--color-ink); font-size: 0.95rem; }
.review-source { color: var(--color-ink-dim); font-family: var(--font-sans); font-size: 0.8rem; }

/* Representative matters / engagements (real-shaped, illustrative) */
.matters {
  margin-top: var(--space-2xl);
  padding-top: var(--space-xl);
  border-top: 1px solid var(--color-border);
}
.matters-head { text-align: center; max-width: 660px; margin: 0 auto var(--space-lg); }
.matters-head .section-label { justify-content: center; }
.matters-head .section-desc { margin: 0 auto; }
.matters-title { margin-bottom: var(--space-sm); }
.matters-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}
.matter-card {
  padding: 1.75rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius);
}
.matter-label {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  /* 0.14em: aligns to the pack's mid-tier caption tracking (was 0.1em). */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-brand-strong);
  margin-bottom: 0.6rem;
}
.matter-card p { color: var(--color-ink-dim); font-size: 0.95rem; line-height: 1.65; }
.matters-note { text-align: center; color: var(--color-ink-dim); font-size: 0.85rem; font-style: italic; margin-top: var(--space-lg); }

/* --- FAQ (native <details> accordion) --- */
.faq-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.faq-intro { position: sticky; top: 100px; }
.faq-intro .section-desc { margin-bottom: var(--space-md); }
.faq-aside {
  margin-top: var(--space-md);
  padding: 1.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.faq-aside p { color: var(--color-ink-dim); font-size: 0.95rem; margin-bottom: 1rem; }
.faq-list { display: flex; flex-direction: column; }
.faq-item {
  border-bottom: 1px solid var(--color-border);
}
.faq-item:first-child { border-top: 1px solid var(--color-border); }
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  /* var(--space-md) = 1.5rem, matching .faq-answer's 1.5rem bottom padding
     below (was 1.4rem, a one-off that made the closed-question rhythm and
     the open-answer rhythm inconsistent). */
  padding: var(--space-md) 0.25rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.02rem, 1.6vw, 1.15rem);
  color: var(--color-ink);
  transition: color 0.2s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--color-brand-strong); }
/* +/- indicator built from two accent bars. Sized up slightly (was 20px/14px)
   for more visual prominence against the question text. */
.faq-icon {
  position: relative;
  flex-shrink: 0;
  width: 22px; height: 22px;
}
.faq-icon::before, .faq-icon::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--color-accent);
  transition: transform 0.28s ease, opacity 0.28s ease;
}
.faq-icon::before { width: 16px; height: 2.5px; }
.faq-icon::after { width: 2.5px; height: 16px; }
.faq-item[open] .faq-icon::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }
.faq-answer {
  padding: 0 0.25rem var(--space-md);
  max-width: 60ch;
}
.faq-answer p { color: var(--color-ink-dim); font-size: 1rem; line-height: 1.75; }

/* --- Consult / CTA band --- */
.consult-section {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  color: #fff;
}
.consult-media { position: absolute; inset: 0; z-index: 0; }
.consult-media img { width: 100%; height: 100%; object-fit: cover; }
/* Spatially-graduated overlay (matches .hero-overlay's recipe, same tokens
   — see the .credibility-overlay comment above for the full rationale):
   was a flat 0.86-opacity wash, crushing the consult-band photo to a
   near-invisible grey texture across the whole band. .consult-grid puts the
   text (.consult-intro) on the left and the opaque white form card on the
   right, the same left-text/right-open layout as the hero, so the hero's
   own left-strong/right-open gradient direction is a direct, evidenced
   reuse, not a new pattern. The form card is fully opaque regardless, so
   its own legibility is unaffected; only the photo now actually reads in
   the margins around it. */
.consult-overlay {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(0deg, var(--color-hero-scrim) 0%, transparent 58%),
    linear-gradient(97deg,
      color-mix(in srgb, var(--color-hero-ink) 92%, transparent) 0%,
      color-mix(in srgb, var(--color-hero-ink) 80%, transparent) 34%,
      color-mix(in srgb, var(--color-hero-ink) 54%, transparent) 66%,
      color-mix(in srgb, var(--color-hero-ink) 40%, transparent) 100%);
}
.consult-section .container { position: relative; z-index: 2; }
.consult-grid {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.consult-intro .section-label { color: var(--color-accent); }
.consult-intro .section-title { color: #fff; }
.consult-intro .section-desc { color: rgba(255,255,255,0.9); }
.consult-call {
  margin-top: var(--space-lg);
  padding: 1.5rem;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-lg);
}
.consult-call p { color: rgba(255,255,255,0.9); margin-bottom: 1rem; font-size: 0.95rem; }

.consult-form {
  padding: 2.35rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.consult-form .btn-primary { background: var(--color-accent); color: var(--color-hero-ink-2); border-color: var(--color-accent); font-weight: 700; }
.consult-form .btn-primary:hover { filter: brightness(1.06); color: var(--color-hero-ink-2); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
.form-group { margin-bottom: var(--space-sm); }
.form-group label {
  display: block;
  font-size: 0.7rem;
  font-family: var(--font-sans);
  font-weight: 700;
  text-transform: uppercase;
  /* 0.14em: aligns to the pack's mid-tier caption tracking (was 0.1em),
     sharpening the label-vs-input typographic contrast in the consult forms. */
  letter-spacing: 0.14em;
  color: var(--color-ink-dim);
  margin-bottom: 0.5rem;
}
.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 0.8rem 0.95rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  color: var(--color-ink);
  font-family: var(--font-sans);
  /* 1rem (16px), not 0.95rem: below 16px, iOS Safari auto-zooms the viewport
     on focus, which is jarring on the highest-intent element in the pack (the
     hero + #consult intake forms). 16px is the documented no-zoom floor. */
  font-size: 1rem;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px var(--color-accent-soft);
  outline: none;
}
.form-group textarea { resize: vertical; min-height: 104px; }
.form-group select { cursor: pointer; }
/* One trust moment at the actual decision point (the submit button): the firm's
   own frozen guarantee copy (hero.credentialChip), typography-first, no icon. */
.consult-guarantee {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: fit-content;
  /* var(--space-sm) = 1rem, matching the form's own field rhythm (was a
     hand-tuned 0.85rem, off the form's tokenized spacing scale). */
  margin: 0 auto var(--space-sm);
  padding: 0.5rem 1.1rem;
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-accent) 32%, transparent);
  border-radius: var(--radius);
  color: var(--color-brand-strong);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.82rem;
  text-align: center;
}
.consult-submit { width: 100%; margin-top: 0.25rem; }
/* margin-top: var(--space-sm) (1rem), matching the form's own field rhythm
   (was a hand-tuned 0.8rem, off the form's tokenized spacing scale). */
.consult-privacy { color: var(--color-ink-dim); font-size: 0.78rem; margin-top: var(--space-sm); text-align: center; }

/* --- Contact / Map --- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: stretch;
}
.contact-details { display: flex; flex-direction: column; gap: 0.75rem; }
.contact-detail {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.1rem 1.25rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius);
}
.contact-detail svg {
  width: 18px; height: 18px;
  padding: 0.55rem;
  box-sizing: content-box;
  background: var(--color-accent-soft);
  border-radius: var(--radius);
  color: var(--color-brand);
  flex-shrink: 0;
}
.contact-detail strong { display: block; color: var(--color-ink); font-family: var(--font-display); font-size: 0.98rem; margin-bottom: 0.15rem; }
.contact-detail span { color: var(--color-ink-dim); font-size: 0.9rem; line-height: 1.55; }
.contact-detail a { color: var(--color-brand-strong); font-weight: 600; }
.contact-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: var(--space-md); }
.contact-note { color: var(--color-ink-dim); font-size: 0.88rem; margin-top: var(--space-sm); }
.map-container {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-accent);
  box-shadow: var(--shadow-md);
  min-height: 400px;
}
.map-container iframe { width: 100%; height: 100%; min-height: 400px; border: 0; display: block; }

/* --- Page hero (practice-areas.html) --- */
.page-hero {
  position: relative;
  overflow: hidden;
  padding: calc(5rem + var(--space-lg)) 0 var(--space-xl);
  text-align: center;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
}
.page-hero-media { position: absolute; inset: 0; z-index: 0; }
.page-hero-media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  opacity: 0.86;
}
.page-hero .container { position: relative; z-index: 2; }
.page-hero .section-label { color: var(--color-accent); justify-content: center; }
.page-hero .section-title,
.page-hero h1 { color: #fff; font-size: clamp(2.2rem, 4.5vw, 3.5rem); }
.page-hero .section-desc { color: rgba(255,255,255,0.9); margin: 0 auto; max-width: 640px; }
.page-hero-actions { display: flex; gap: 0.75rem; justify-content: center; flex-wrap: wrap; margin-top: var(--space-lg); }

/* --- Practice overview intro (practice-areas.html) --- */
.practice-overview { background: var(--color-bg); padding: clamp(1.75rem, 3vw, 2.75rem) 0; border-bottom: 1px solid var(--color-border); }
.practice-overview-inner { max-width: 820px; margin: 0 auto; text-align: center; }
.practice-overview-inner .section-label { justify-content: center; }
.practice-overview-lead {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.6vw, 1.9rem);
  font-weight: 700;
  line-height: 1.42;
  color: var(--color-ink);
  text-wrap: balance;
}

/* --- Full practice-areas page --- */
.full-practice-section { padding: clamp(2.125rem, 4vw, 3.75rem) 0; background: var(--color-bg); }
.full-practice-category { margin-bottom: var(--space-2xl); }
.category-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}
.category-index {
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: 1.05rem;
  color: var(--color-accent);
  letter-spacing: 0.02em;
}
.category-header h2 { font-size: clamp(1.5rem, 2.8vw, 2.1rem); white-space: nowrap; }
.category-header .line { flex: 1; height: 1px; background: var(--color-border); }
.category-desc { color: var(--color-ink-dim); font-size: 1.02rem; max-width: 720px; margin-bottom: var(--space-lg); line-height: 1.7; }
.full-practice-section .practice-card { background: var(--color-surface); }

/* Closing CTA band on the practice-areas page */
.practice-close {
  margin-top: var(--space-xl);
  padding: clamp(2.75rem, 5vw, 4.5rem) clamp(1.75rem, 4vw, 3.5rem);
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  border-radius: var(--radius-xl);
  border-top: 3px solid var(--color-accent);
  text-align: center;
  box-shadow: var(--shadow-lg);
}
.practice-close-inner { max-width: 680px; margin: 0 auto; }
.practice-close h2 { color: #fff; margin-bottom: var(--space-sm); }
.practice-close .section-desc { color: rgba(255,255,255,0.85); margin: 0 auto 0.5rem; }
.practice-cta-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; justify-content: center; margin-top: var(--space-md); }
/* One trust moment before this page's own decision point (the closing CTA):
   reuses .hero-chip's glass-chip treatment, real data only, typography-first. */
.practice-close-trust { display: flex; gap: 0.6rem; flex-wrap: wrap; justify-content: center; margin-top: var(--space-md); }

/* --- Footer --- */
.footer {
  background: var(--color-footer);
  padding: calc(var(--space-xl) / 2) 0 var(--space-md);
  color: rgba(255,255,255,0.75);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.8fr 1fr 1.3fr 1.3fr;
  gap: var(--space-lg);
  margin-bottom: var(--space-lg);
  align-items: start;
}
/* Nudge the brand column down to match the baseline of the "Explore/Contact/
   Hours" h4 row in the other three columns (the logo/wordmark has no heading
   sitting above it, so without this the row starts noticeably higher). */
.footer-brand { padding-top: 0.35rem; }
.footer-logo { height: 40px; width: auto; max-width: 240px; object-fit: contain; margin-bottom: var(--space-sm); display: block; }
.footer-wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.4rem;
  letter-spacing: -0.02em;
  color: #fff;
  display: inline-block;
  margin-bottom: var(--space-sm);
}
.footer-brand p { color: rgba(255,255,255,0.72); font-size: 0.88rem; max-width: 320px; line-height: 1.65; }
.footer-tag { margin-top: 0.75rem; color: var(--color-accent) !important; font-weight: 600; font-size: 0.85rem !important; }
.footer-col h3 {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--space-sm);
}
.footer-col ul { list-style: none; }
.footer-col li { margin-bottom: 0.5rem; font-size: 0.88rem; color: rgba(255,255,255,0.72); }
.footer-col a { color: rgba(255,255,255,0.72); font-size: 0.88rem; }
.footer-col a:hover { color: #fff; }
.footer-contact li { display: flex; align-items: flex-start; gap: 0.5rem; }
.footer-contact li svg { width: 15px; height: 15px; flex: none; margin-top: 0.2rem; color: rgba(255,255,255,0.85); }
.footer-hours { display: flex; flex-direction: column; gap: 0.4rem; }
.footer-hours-row { display: flex; justify-content: space-between; gap: var(--space-sm); font-size: 0.85rem; color: rgba(255,255,255,0.72); }
.footer-hours-row span:first-child { color: #fff; font-weight: 600; }
.footer-hours-row span:last-child { text-align: right; white-space: nowrap; }
.footer-bottom {
  padding-top: var(--space-md);
  border-top: 1px solid rgba(255,255,255,0.14);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-sm);
  font-size: 0.78rem;
  color: rgba(255,255,255,0.65);
}

/* --- Modal --- */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(10,18,34,0.55);
  z-index: 250;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: all 0.3s;
  padding: var(--space-md);
}
.modal-overlay.open { opacity: 1; visibility: visible; }
.modal {
  background: var(--color-bg);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  max-width: 440px;
  width: 100%;
  text-align: center;
  box-shadow: var(--shadow-lg);
  transform: scale(0.95);
  transition: transform 0.3s;
}
.modal-overlay.open .modal { transform: scale(1); }
.modal-icon {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--color-accent-soft);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto var(--space-sm);
}
.modal-icon svg { width: 28px; height: 28px; color: var(--color-brand); }
.modal h3 { margin-bottom: var(--space-xs); }
.modal p { color: var(--color-ink-dim); margin-bottom: var(--space-md); font-size: 0.92rem; line-height: 1.6; }

/* --- Back to top --- */
.back-to-top {
  position: fixed;
  bottom: 2rem; right: 2rem;
  width: 44px; height: 44px;
  border-radius: var(--radius);
  background: var(--color-brand-strong);
  color: #fff;
  border: none;
  display: flex; align-items: center; justify-content: center;
  z-index: 90;
  opacity: 0; visibility: hidden;
  transform: translateY(10px);
  transition: all 0.3s ease;
  box-shadow: var(--shadow-md);
}
.back-to-top.visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { filter: brightness(1.1); transform: translateY(-2px); }
.back-to-top svg { width: 20px; height: 20px; }

/* --- Animations (scroll reveal) --- */
/* Proservices flavor: authoritative and composed, not retail-playful (this
   pack serves injury law / accounting firms). Smaller rise, slightly slower
   settle than a punchier retail pack, transform+opacity only throughout. */
html.js-anim .fade-up {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
html.js-anim .fade-up.visible { opacity: 1; transform: translateY(0); }

/* Card-grid stagger (motion wave): the grid stays one cheap
   IntersectionObserver target (.fade-up, no JS change), but with the
   .fade-up-stagger modifier its own reveal is neutralized and each direct
   child (practice/step/area/team/credential/review/matter card) rises
   individually on a slight cascade instead of the whole grid moving as one
   rigid block. Delay caps so a long grid still settles quickly. */
html.js-anim .fade-up.fade-up-stagger {
  opacity: 1;
  transform: none;
  transition: none;
}
html.js-anim .fade-up.fade-up-stagger > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.45s ease-out, transform 0.45s ease-out;
}
html.js-anim .fade-up.fade-up-stagger.visible > * { opacity: 1; transform: translateY(0); }
html.js-anim .fade-up.fade-up-stagger > *:nth-child(2) { transition-delay: 0.07s; }
html.js-anim .fade-up.fade-up-stagger > *:nth-child(3) { transition-delay: 0.14s; }
html.js-anim .fade-up.fade-up-stagger > *:nth-child(4) { transition-delay: 0.21s; }
html.js-anim .fade-up.fade-up-stagger > *:nth-child(5) { transition-delay: 0.28s; }
html.js-anim .fade-up.fade-up-stagger > *:nth-child(n+6) { transition-delay: 0.32s; }

/* Results/stats band: the pack's one real signature-numbers moment ($50M+
   recovered etc.) earns a touch more ceremony than the other card grids —
   a slightly slower settle plus a small scale-in on the number itself, still
   nothing playful, still transform+opacity only, still well inside the
   harness's settle window. */
html.js-anim .stats-grid.fade-up-stagger > * { transition-duration: 0.55s; }
html.js-anim .stats-grid .stat-value {
  display: inline-block;
  transform: scale(0.94);
  transition: transform 0.55s ease-out;
}
html.js-anim .stats-grid.fade-up-stagger.visible .stat-value { transform: scale(1); }

/* Hero entrance (composed load-in): badge, heading, subhead, result figure,
   actions and trust chips stagger in ~80ms apart, fully settled well under
   800ms. Pure CSS animation (no JS/observer dependency) so it plays
   identically with JS on or off and never depends on scroll or the vision
   gate's screenshot settle window. */
@keyframes hero-in {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
.hero-content > * { animation: hero-in 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.hero-content > *:nth-child(1) { animation-delay: 0s; }
.hero-content > *:nth-child(2) { animation-delay: 0.08s; }
.hero-content > *:nth-child(3) { animation-delay: 0.16s; }
.hero-content > *:nth-child(4) { animation-delay: 0.24s; }
.hero-content > *:nth-child(n+5) { animation-delay: 0.24s; }

/* Pressed states (transform-only, compositor-safe): buttons settle to a
   subtle scale on press rather than just releasing the hover lift. */
.btn:active { transform: scale(0.97); }
.btn-primary:active { transform: scale(0.97); filter: brightness(0.96); box-shadow: none; }
.btn-accent:active { transform: scale(0.97); filter: brightness(0.96); box-shadow: none; }
.btn-outline:active, .btn-hero-outline:active { transform: scale(0.97); }
.nav-cta:active { transform: scale(0.96); box-shadow: none; }

/* Card lift on hover (motion-wave stagger fix, ported from trades-static's
   proven pattern): practice/area/team/credential/review cards each sit
   directly inside a `.grid.fade-up.fade-up-stagger` container (motion wave),
   so once revealed every card permanently matches `html.js-anim .fade-up
   .fade-up-stagger.visible > *` (html + 3 classes + .visible = 4 selector
   components) which outguns each card's own plain `.card:hover` (2
   components) and silently pins it at translateY(0) forever -- a real,
   confirmed regression (isolated Playwright before/after getComputedStyle()
   .transform hover test, no diff without this fix). Fix: match the
   `html.js-anim` prefix plus the parent grid class (equal/higher
   specificity, tie broken by this block coming later in the file than the
   stagger rule above), same declarations as the original rules already in
   place (which stay -- now redundant but harmless where they still apply). A
   plain, unprefixed fallback (same parent-grid scoping) covers the no-JS /
   stagger-inert case. Descendant zoom rules (`.practice-card:hover
   .practice-card-bg`, `.team-card:hover .team-photo img`) are untouched:
   they target a grandchild, not the grid's direct child, so the stagger
   rule's `> *` never contests them. */
html.js-anim .practice-grid .practice-card:hover,
.practice-grid .practice-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 34px 74px -30px rgba(12,20,38,0.44);
  border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border));
}
html.js-anim .areas-grid .area-card:hover,
.areas-grid .area-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
  border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
}
html.js-anim .team-grid .team-card:hover,
.team-grid .team-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
  border-color: color-mix(in srgb, var(--color-accent) 30%, var(--color-border));
}
html.js-anim .credentials-grid .credential-card:hover,
.credentials-grid .credential-card:hover {
  border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border));
  border-left-color: var(--color-accent);
  transform: translateY(-2px);
}
html.js-anim .reviews-grid .review-card:hover,
.reviews-grid .review-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
  border-color: color-mix(in srgb, var(--color-accent) 30%, var(--color-border));
}

@media (prefers-reduced-motion: reduce) {
  .fade-up,
  html.js-anim .fade-up.fade-up-stagger > *,
  html.js-anim .stats-grid .stat-value { opacity: 1; transform: none; transition: none; }
  .hero-content > * { animation: none; opacity: 1; transform: none; }
  .btn:hover, .btn:active, .btn-primary:active, .btn-accent:active,
  .btn-outline:active, .btn-hero-outline:active, .nav-cta:active,
  .back-to-top:hover,
  html.js-anim .practice-grid .practice-card:hover, .practice-grid .practice-card:hover,
  .practice-card:hover .practice-card-bg,
  html.js-anim .team-grid .team-card:hover, .team-grid .team-card:hover,
  .team-card:hover .team-photo img,
  html.js-anim .reviews-grid .review-card:hover, .reviews-grid .review-card:hover,
  html.js-anim .credentials-grid .credential-card:hover, .credentials-grid .credential-card:hover,
  .proof-point:hover,
  html.js-anim .areas-grid .area-card:hover, .areas-grid .area-card:hover { transform: none; }
}

/* ==========================================================================
   Layout-variety wave (2026-08-01, wave 7/7): CSS-only structural alternates
   for hero / practice (services) / about, keyed purely off the existing
   sub-niche variant engine's `body[data-variant="<key>"]` attribute (see
   fillStatic.ts + orchestrator/src/lib/variants.ts's resolveVariant) -- no
   new fillStatic logic, no new content.json fields, no new attribute. Groups
   are drawn from the real emphasize/accentMood axis already authored in
   templates/variants/lawyer.json + accountant.json: law's litigation-forward,
   urgent variants (bold accentMood, several of which deliberately do NOT
   emphasize About) vs. the calm/warm, reassurance-forward variants shared by
   family law, estate planning and most of accounting's own practice areas --
   "law's urgency vs accounting's calm" is the layout axis. Every other
   resolved key (classic accentMood: corporate-business, real-estate-notary,
   employment-labour, tax-law, tax, audit-assurance, forensic,
   enterprise-corporate, both niches' shared "general" default) plus any
   prospect with NO variant resolved at all render the UNCHANGED base layout
   -- guaranteed byte-identical for that bucket because every rule below keys
   off an explicit, enumerated data-variant value, never an absence/negation
   (the About alternate is the one exception, and it is gated the same
   defensive way dental-static's wave learned to require: on data-emph being
   absent from a section AND body[data-variant] being present, never on
   data-emph's absence alone -- see that section below). */

/* --- Hero: alternate 1 of 2, "urgent band" (bold/litigation-forward group:
   personal-injury, criminal-defense, civil-litigation, intellectual-property
   from lawyer.json; advisory is accountant.json's one bold-mood entry, its
   own "CFO/growth partner" variant reads with the same forward energy). A
   full-width, square-cornered content band with a left accent rule replaces
   the default centered/rounded treatment -- an immediate, no-nonsense read.
   Composes with all three hero archetypes and with/without a staged
   hero.image (only .hero-content is touched; .hero-media/.hero-overlay and
   the gradient fallback on .hero itself are never touched). */
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .hero-content {
  max-width: none;
  border-radius: 0;
  border-left: 4px solid var(--color-accent);
  padding-left: clamp(1.5rem, 4vw, 2.5rem);
}
/* fullbleed's content sits transparent over the photo/gradient by default;
   turn it into a solid band so the band reads immediately at a glance. */
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .hero-fullbleed .hero-content {
  background: linear-gradient(140deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  padding-top: clamp(2rem, 4vw, 3rem);
  padding-bottom: clamp(2rem, 4vw, 3rem);
  padding-right: clamp(1.5rem, 4vw, 3rem);
  box-shadow: var(--shadow-lg);
}
/* bandoverlay already carries its own solid card (identical background
   gradient + shadow); square it off and drop its top accent so the left
   accent above reads as the one accent line, not two competing ones. */
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .hero-bandoverlay .hero-content {
  border-top: none;
}

/* --- Practice areas: alternate 1 of 2, "bento" (same group as the hero
   alternate above). A 4-column asymmetric grid with the first practice area
   spanning 2x2 as a scannable, featured tile -- an action-first read that
   matches the urgent hero. Purely structural (:first-child), no new content
   field; composes with both photo-backed cards (.practice-card-bg stays
   position:absolute so it fills whatever size the tile becomes) and the
   plain numbered cards this pack's stock library mostly produces. Collapses
   to 2-col at <=900px, 1-col at <=620px (new rules alongside the existing
   breakpoints, same as the hero group's byte-identical default elsewhere). */
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid {
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-sm);
}
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid .practice-card:first-child {
  grid-column: span 2;
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid .practice-card:first-child .practice-index {
  font-size: 2.1rem;
}
body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid .practice-card:first-child h3 {
  font-size: 1.3rem;
}
@media (max-width: 900px) {
  body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid .practice-card:first-child {
    grid-column: span 2;
    grid-row: span 1;
  }
}
@media (max-width: 620px) {
  body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid {
    grid-template-columns: 1fr;
  }
  body:is([data-variant="personal-injury"], [data-variant="criminal-defense"], [data-variant="civil-litigation"], [data-variant="intellectual-property"], [data-variant="advisory"]) .practice-grid .practice-card:first-child {
    grid-column: span 1;
    grid-row: span 1;
  }
}

/* --- Hero: alternate 2 of 2, "calm card" (calm/warm, reassurance-forward
   group: family-divorce, estate-wills, immigration, bankruptcy-debt from
   lawyer.json; bookkeeping, payroll, wealth-planning, small-business-startup,
   non-profit from accountant.json -- the pack's steadiest, most personal
   practice areas). A softer, more deeply rounded floating card, anchored
   toward the lower third on the fullbleed archetype instead of centered, so
   it reads as an unhurried, considered composition rather than the urgent
   band above. Composes with all three archetypes and with/without a staged
   hero.image (same reasoning as the urgent-band alternate: only
   .hero-content/.hero-fullbleed are touched). */
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .hero-fullbleed .hero-content {
  max-width: 640px;
  border-radius: 28px;
  background: linear-gradient(150deg, var(--color-hero-ink) 0%, var(--color-hero-ink-2) 100%);
  box-shadow: var(--shadow-lg);
  padding: clamp(2.25rem, 4vw, 3.25rem) clamp(2rem, 4vw, 3rem);
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .hero-fullbleed {
  align-items: flex-end;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
/* bandoverlay's default card gets deeper corners and loses its top accent
   (the calm mood carries no hard line); split keeps its edge-to-edge panel
   but softens the one corner that meets the photo. */
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .hero-bandoverlay .hero-content {
  border-top: none;
  border-radius: 28px;
  padding: clamp(2.25rem, 4vw, 3.25rem) clamp(2rem, 4vw, 3rem);
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .hero-split .hero-content {
  border-radius: 0 28px 28px 0;
}
@media (max-width: 900px) {
  /* split collapses to a single, full-width stacked column below this
     breakpoint (existing rule); a one-sided rounded corner looks accidental
     on a full-width block, so even it out once stacked. */
  body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .hero-split .hero-content {
    border-radius: 28px;
  }
}

/* --- Practice areas: alternate 2 of 2, "editorial list" (same group as the
   calm hero alternate above). A single-column, borderless divided row list
   instead of a card grid -- a calmer, magazine read. Built with CSS Grid
   rather than flex so the existing sibling elements (.practice-index, h3, p,
   optional .practice-meta -- there is no wrapper div to flex, by design, per
   the copy-freeze/no-new-markup rule) can still compose into a "number left,
   copy stacked right" row purely through grid placement: the index is
   pinned to column 1 spanning several rows, the text elements are pinned to
   column 2 and auto-place into successive rows via the grid's normal sparse
   auto-placement. A photo-backed card (.practice-card-bg/.practice-card-scrim,
   both position:absolute) is unaffected by this and simply fills the now
   short, wide row instead of a tall tile -- still a legible thumbnail-style
   photo row, no markup change needed. */
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-grid {
  display: block;
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-card {
  display: grid;
  grid-template-columns: 3rem 1fr;
  column-gap: 1.1rem;
  align-items: start;
  padding: 1.5rem 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-border);
  border-radius: 0;
  box-shadow: none;
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-card:first-child {
  border-top: 1px solid var(--color-border);
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-card::before {
  display: none;
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-index {
  grid-column: 1;
  grid-row: 1 / span 3;
  margin-bottom: 0;
}
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-card h3,
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-card p,
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-meta {
  grid-column: 2;
}
/* Calmer hover: keep the lift (motion wave), drop the heavy card shadow that
   reads mismatched against a borderless row. Same specificity family as the
   hover-restoration fix above (attr + 2 classes + pseudo-class); this block
   comes later in the file so it wins the tie on the properties it redeclares
   (box-shadow/border-color) while leaving `transform` alone -- the fix
   rule's lift keeps applying untouched. */
body:is([data-variant="family-divorce"], [data-variant="estate-wills"], [data-variant="immigration"], [data-variant="bankruptcy-debt"], [data-variant="bookkeeping"], [data-variant="payroll"], [data-variant="wealth-planning"], [data-variant="small-business-startup"], [data-variant="non-profit"]) .practice-grid .practice-card:hover {
  box-shadow: none;
  border-color: var(--color-accent);
}

/* --- About: 1 alternate, "stacked editorial" (full-width banner image with
   text + proof-points stacked below, instead of the media-left/text-right
   grid). Triggers only when a variant resolved AND that variant's profile
   does not list "about" in its emphasize[] -- today: personal-injury,
   criminal-defense, real-estate-notary, civil-litigation (lawyer.json; every
   accountant.json variant emphasizes About, so this alternate is a
   lawyer-only read in practice today). Gated on body[data-variant] being
   present, not just data-emph's absence: data-emph is ALSO simply absent
   whenever no variant resolves at all, and an unqualified
   `.about-section:not([data-emph="1"])` would make this the silent fallback
   for any prospect whose niche/variant fails to resolve -- dental-static's
   wave hit exactly this and fixed it the same way; ported the fix in from
   the start rather than re-discovering it. Degrades cleanly with no
   about.image too: `.about-grid.no-media` already collapses to one column,
   which is already "stacked". */
body[data-variant] .about-section:not([data-emph="1"]) .about-grid,
body[data-variant] .about-section:not([data-emph="1"]) .about-grid.no-media {
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}
body[data-variant] .about-section:not([data-emph="1"]) .about-media {
  max-width: none;
}
body[data-variant] .about-section:not([data-emph="1"]) .about-media img {
  width: 100%;
  aspect-ratio: 21 / 9;
  min-height: 0;
}
body[data-variant] .about-section:not([data-emph="1"]) .about-media::before {
  inset: 14px -14px -14px 14px;
}
body[data-variant] .about-section:not([data-emph="1"]) .proof-points {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
@media (max-width: 620px) {
  body[data-variant] .about-section:not([data-emph="1"]) .about-media img {
    aspect-ratio: 16 / 10;
  }
}

/* --- Preview disclosure badge (required on every preview) --- */
.preview-badge {
  position: fixed;
  left: 12px; bottom: 12px;
  z-index: 2000;
  display: inline-flex;
  align-items: stretch;
  background: rgba(10, 18, 34, 0.86);
  font-family: var(--font-sans);
  font-size: 0.72rem;
  line-height: 1;
  border-radius: var(--radius);
  overflow: hidden;
  opacity: 0.92;
}
.preview-badge:hover, .preview-badge:focus-within { opacity: 1; }
.preview-badge a { display: inline-flex; align-items: center; padding: 7px 10px; text-decoration: none; white-space: nowrap; }
.preview-badge a:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.preview-badge-info, .preview-badge-info:hover { color: #fff; }
.preview-badge-cta { background: var(--color-accent); color: var(--color-hero-ink-2); font-weight: 700; }
.preview-badge-cta:hover { background: var(--color-accent); filter: brightness(1.06); color: var(--color-hero-ink-2); }

/* --- Mobile sticky call bar (mobile only; the phone is always one thumb-tap
   away). Ported from trades-static's .mobile-call-btn, single-button (this
   pack already carries a hero + #consult lead form, so the second "quote"
   button trades pairs it with is dropped here). Gated on 5069611951. --- */
.mobile-call-bar {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 150;
  padding-bottom: env(safe-area-inset-bottom, 0);
  box-shadow: 0 -8px 24px -12px rgba(12,20,38,0.35);
}
.mobile-call-bar a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.95rem 1rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.mobile-call-btn { background: var(--color-accent); color: var(--color-hero-ink-2); }
.mobile-call-btn:hover { color: var(--color-hero-ink-2); }
.mobile-call-btn svg { width: 19px; height: 19px; }

/* --- Responsive --- */
@media (max-width: 1024px) {
  .nav-toggle { display: flex; }
  .nav-links {
    position: fixed;
    top: 0; right: -100%;
    width: 280px; height: 100vh;
    background: var(--color-bg);
    flex-direction: column;
    align-items: flex-start;
    padding: 5rem var(--space-lg) var(--space-lg);
    gap: 0.25rem;
    transition: right 0.3s ease;
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
  }
  .nav-links.open { right: 0; }
  /* Block-level, padded rows: a >=44px tap target per drawer link, not just the
     text's own line-height (the desktop gap-only spacing was well under 44px). */
  .nav-links a {
    display: block;
    width: 100%;
    padding: 0.75rem 0;
  }
  .nav:not(.scrolled) .nav-links a { color: var(--color-ink); text-shadow: none; }
  .nav-phone { display: none; }
  .faq-intro { position: static; }
  /* The nav phone pill is gone below this breakpoint: the sticky call bar
     replaces it, so the phone stays one tap away. Everything else that also
     sits fixed at the viewport bottom (back-to-top, the preview badge, and
     the #consult lead form's own submit button/footer) gets offset by the
     bar's ~64px height so nothing is ever occluded. */
  .mobile-call-bar { display: flex; }
  .back-to-top { bottom: calc(64px + 1rem); }
  .preview-badge { bottom: calc(64px + 12px); }
  .consult-section { padding-bottom: calc(64px + var(--space-lg)); }
  .footer { padding-bottom: calc(64px + var(--space-md)); }
  /* Footer link/row tap targets: >=44px hit area per row (icon + text or a
     plain link), not just the compressed 0.88rem text line. */
  .footer-col li {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .footer-contact li { align-items: flex-start; padding-top: 0.6rem; }
  .footer-col a { display: inline-flex; align-items: center; min-height: 44px; }
}

@media (max-width: 900px) {
  .about-grid, .about-grid.no-media { grid-template-columns: 1fr; }
  .about-media { max-width: 560px; }
  .about-media img { height: auto; min-height: 0; aspect-ratio: 4 / 3.4; }
  .about-media::before { inset: 14px -14px -14px 14px; }
  .practice-grid,
  .reviews-grid,
  .matters-grid,
  .steps-grid,
  .team-grid { grid-template-columns: 1fr 1fr; }
  .consult-grid,
  .contact-grid,
  .faq-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-md); }
  /* Split + bandoverlay collapse to a single column on smaller screens. */
  .hero-split .hero-inner { grid-template-columns: 1fr; min-height: auto; }
  .hero-split .hero-content { padding: 7rem clamp(1.5rem, 6vw, 2.5rem) 3rem; }
  .hero-split .hero-figure { order: 2; min-height: 44vh; }
  .hero-split .hero-figure::after { display: none; }
  .hero-bandoverlay .hero-content { max-width: none; }
  /* Hero lead-capture form stacks under the copy on smaller screens. */
  .hero-inner:has(.hero-lead),
  .hero-split .hero-inner:has(.hero-lead),
  .hero-bandoverlay .hero-inner:has(.hero-lead) { grid-template-columns: 1fr; }
  .hero-split .hero-inner:has(.hero-lead) .hero-figure,
  .hero-split .hero-inner:has(.hero-lead) .hero-lead { grid-column: 1; grid-row: auto; }
  .hero-split .hero-inner:has(.hero-lead) .hero-lead { justify-self: stretch; max-width: none; margin: 0; }
  .hero-inner:has(.hero-lead) .hero-content { padding-bottom: 1.5rem; }
}

@media (max-width: 620px) {
  /* On phones the mobile nav is logo + hamburger only; the drawer links + the
     prominent hero CTA carry the action, so the long nav CTA can drop and give
     a long wordmark room to breathe. */
  .nav-cta { display: none; }
  .hero { min-height: 100svh; }
  .hero-content { padding-top: 5.75rem; }
  .hero-split .hero-content { padding-top: 5.75rem; }
  .hero-bandoverlay .hero-inner { min-height: 100svh; }
  /* Tighter mobile hero rhythm (bug fix): the default badge/h1/sub/result
     spacing pushed .hero-actions down far enough that, at initial scroll
     position, the persistent bottom chrome (the mobile call bar + the preview
     disclosure badge, both position:fixed) rendered ON TOP of the primary CTA
     pair — the single most important tap target on the page, unreadable and
     partly untappable on first paint. Measured with Playwright at 390x844:
     .hero-actions was at y=700-837 while the badge+call-bar occupy roughly
     y=742-844. Trimming the vertical rhythm above the CTA row (not the CTA
     row itself) clears it. */
  .hero-badge { margin-bottom: 0.5rem; }
  .hero h1 { margin-bottom: 0.5rem; }
  .hero-sub { margin-bottom: 0.85rem; }
  .hero-result { margin-bottom: 0.85rem; }
  .hero-actions { flex-direction: column; align-items: stretch; gap: 0.5rem; margin-bottom: 1.25rem; }
  .hero-actions .btn { width: 100%; }
  /* Bandoverlay + a hero-lead form: .hero-inner:has(.hero-lead) switches the
     archetype from its normal bottom-anchored flex layout to a stacked grid
     (content row, then the lead-form row) — at that point the archetype's own
     7rem top padding (sized for the old bottom-anchored composition, giving
     the transparent-nav photo room to breathe above) is dead weight that just
     pushes the CTA row down; trim it to the same nav-clearance floor the other
     archetypes use, and shrink its own card padding too. Also reserve the
     fixed bottom chrome's height so nothing downstream of the CTA collides
     with it either. */
  .hero-bandoverlay .hero-inner { padding-top: 5.75rem; padding-bottom: calc(2rem + 96px); }
  .hero-bandoverlay .hero-content { padding-top: 1rem; padding-bottom: 1rem; }
  .practice-grid,
  .reviews-grid,
  .matters-grid,
  .steps-grid,
  .team-grid,
  .proof-points { grid-template-columns: 1fr; }
  .team-grid { max-width: 380px; }
  .form-row { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; gap: 0.5rem; text-align: center; }
  .contact-detail span br { display: none; }
  .about-badge { left: 0; }
  .review-lead { padding: 2.25rem 1.75rem; }
}


/* sw-trust widget skin (frameworks/_base/widgets/trust-bar.css, pack-tinted).
   Shared STRUCTURE across packs; this pack's palette supplies the look. */
.sw-trust { background: var(--color-brand-strong, var(--color-brand)); border-bottom: 1px solid rgba(255,255,255,0.08); }
.sw-trust-inner { max-width: 1120px; margin: 0 auto; padding: 14px 24px; display: flex; flex-wrap: wrap; gap: 10px 40px; justify-content: center; }
.sw-trust-item { display: flex; align-items: baseline; gap: 8px; }
.sw-trust-value { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 1.15rem; color: #fff; }
/* 0.14em: aligns to the pack's mid-tier caption tracking (was 0.06em). */
.sw-trust-label { font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255,255,255,0.75); }
@media (max-width: 640px) { .sw-trust-inner { gap: 8px 22px; padding: 12px 16px; } .sw-trust-value { font-size: 1rem; } }

/* sw-booking action row (widget contract). */
.sw-booking-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.sw-btn-ghost { color: var(--color-brand-strong, var(--color-brand)); text-decoration: underline; text-underline-offset: 3px; font-size: 0.95rem; }
.sw-btn-ghost:hover { opacity: 0.8; }

/* --- Mobile fixed-widget clearance (hero-trust clip fix, 2026-08) ----------
   At phone widths the sticky .mobile-call-bar (64px tall) plus the
   .preview-badge pill pinned above it (bottom: 64px + 12px, ~26px tall) own
   the viewport's bottom ~104px. The bandoverlay hero rests bottom-anchored at
   full viewport height, which parked its last trust chip inside that band,
   clipped behind both badges. Extra bottom padding keeps the hero's last row
   above the fixed stack. Appended last so it wins the cascade over the
   archetype/variant hero rules above. */
@media (max-width: 620px) {
  .hero-bandoverlay .hero-inner { padding-bottom: calc(64px + 12px + 2.5rem); }
}
